From: Bogdan Harjoc Date: Fri, 3 Aug 2018 15:25:35 +0000 (+0000) Subject: Avoid infinite loop with duplicate anonymous union fields (PR c/86690). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e5e7e50d4f75749e3ad3af44d364ccfcb81ced9e;p=gcc.git Avoid infinite loop with duplicate anonymous union fields (PR c/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. 2018-08-03 Bogdan Harjoc PR c/86690 gcc/c: * c-typeck.c (lookup_field): Do not use TYPE_LANG_SPECIFIC after errors. gcc/testsuite: * gcc.dg/union-duplicate-field.c: New test. From-SVN: r263294 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 6e682cdb140..40e56f3aaaa 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-08-03 Bogdan Harjoc + + PR c/86690 + * c-typeck.c (lookup_field): Do not use TYPE_LANG_SPECIFIC after + errors. + 2018-08-01 Martin Sebor PR tree-optimization/86650 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index f6a326c8152..2e9338e3458 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2207,9 +2207,14 @@ lookup_field (tree type, tree component) /* 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. - if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s) + 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 + && !seen_error ()) { int bot, top, half; tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0]; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 966c13b33cf..ba0c4c6ef5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-03 Bogdan Harjoc + + PR c/86690 + * gcc.dg/union-duplicate-field.c: New test. + 2018-08-03 Jason Merrill PR c++/86706 diff --git a/gcc/testsuite/gcc.dg/union-duplicate-field.c b/gcc/testsuite/gcc.dg/union-duplicate-field.c new file mode 100644 index 00000000000..da9a945d9f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-duplicate-field.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99" } */ + +int a0; + +struct S +{ + int a1; + union { + int a0; + int a1; /* { dg-error "duplicate member" } */ + int a2, a3, a4, a5, a6, a7, a8, a9; + int a10, a11, a12, a13, a14, a15; + }; +}; + +int f() +{ + struct S s; + return s.a0; +}