This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Avoid infinite loop with duplicate anonymous union fields
- From: Bogdan Harjoc <harjoc at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 Jul 2018 13:27:27 +0300
- Subject: [PATCH] Avoid infinite loop with duplicate anonymous union fields
(this patch is already uploaded to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86690 )
If a struct contains an anonymous union and both have a field with the
same name, detect_field_duplicates_hash() will replace one of them
with NULL. If compilation doesn't stop immediately, it may later call
lookup_field() on the union, which falsely assumes the union's
LANG_SPECIFIC array is sorted, and may loop indefinitely because of
this.
Reproduced on amd64 since gcc-5, on ubuntu-18.04 and gentoo.
The patch falls back to iterating via DECL_CHAIN if there was an error
earlier during compilation.
I ran the gcc testsuite with the result (the FAIL seems unrelated to the patch):
FAIL: gcc.dg/cpp/_Pragma3.c (test for excess errors)
=== gcc Summary ===
# of expected passes 135094
# of unexpected failures 1
# of expected failures 398
# of unsupported tests 2140
gcc-build/gcc/xgcc version 8.0.1 20180424 (experimental) (GCC)
--- gcc-8.0.1-20180424/gcc/c/c-typeck.c 2018-07-26 20:00:55.475792602 +0300
+++ gcc-8.0.1-20180424/gcc/c/c-typeck.c 2018-07-26 21:39:13.312629356 +0300
@@ -2207,9 +2207,14 @@
/* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
to the field elements. Use a binary search on this array to quickly
find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC
- will always be set for structures which have many elements. */
+ will always be set for structures which have many elements.
+
+ Duplicate field checking replaces duplicates with NULL_TREE so
+ TYPE_LANG_SPECIFIC arrays are potentially no longer sorted. In that
+ case just iterate using DECL_CHAIN. */
- if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s)
+ if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s
+ && diagnostic_kind_count(global_dc, DK_ERROR) == 0)
{
int bot, top, half;
tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0];