From 35129fd3a745403bec0a06d62b18fc30ce1bbf8e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 28 Feb 2018 12:32:10 +0000 Subject: [PATCH] [PR c++/84602] ICE with anon-struct https://gcc.gnu.org/ml/gcc-patches/2018-02/msg01577.html PR c++/84602 * name-lookup.h (search_anon_aggr): Add defaulted WANT_TYPE arg. * name-lookup.c (fields_linear_search): Look in an anon-aggr regardless of want_type. (search_anon_aggr): Just use get_class_binding_direct. PR c++/84602 * g++.dg/lookup/pr84602.C: New. From-SVN: r258060 --- gcc/cp/ChangeLog | 8 +++++++ gcc/cp/name-lookup.c | 28 ++++++++--------------- gcc/cp/name-lookup.h | 2 +- gcc/testsuite/ChangeLog | 8 ++++++- gcc/testsuite/g++.dg/lookup/pr84602.C | 32 +++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/pr84602.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0adbc3f93c6..e2d88dcf240 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-28 Nathan Sidwell + + PR c++/84602 + * name-lookup.h (search_anon_aggr): Add defaulted WANT_TYPE arg. + * name-lookup.c (fields_linear_search): Look in an anon-aggr + regardless of want_type. + (search_anon_aggr): Just use get_class_binding_direct. + 2018-02-28 Jakub Jelinek * decl.c (cp_finish_decomp): Don't adjust eltscnt when calling diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index c61f01c4f88..20db0f427da 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1162,11 +1162,10 @@ fields_linear_search (tree klass, tree name, bool want_type) { tree decl = fields; - if (!want_type - && TREE_CODE (decl) == FIELD_DECL + if (TREE_CODE (decl) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) { - if (tree temp = search_anon_aggr (TREE_TYPE (decl), name)) + if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, want_type)) return temp; } @@ -1191,26 +1190,17 @@ fields_linear_search (tree klass, tree name, bool want_type) return NULL_TREE; } -/* Look for NAME field inside of anonymous aggregate ANON. */ +/* Look for NAME member inside of anonymous aggregate ANON. Although + such things should only contain FIELD_DECLs, we check that too + late, and would give very confusing errors if we weren't + permissive here. */ tree -search_anon_aggr (tree anon, tree name) +search_anon_aggr (tree anon, tree name, bool want_type) { gcc_assert (COMPLETE_TYPE_P (anon)); - tree ret; - - if (vec *member_vec = CLASSTYPE_MEMBER_VEC (anon)) - ret = member_vec_linear_search (member_vec, name); - else - ret = fields_linear_search (anon, name, false); - - if (ret) - { - /* Anon members can only contain fields. */ - gcc_assert (!STAT_HACK_P (ret) && !DECL_DECLARES_TYPE_P (ret)); - return ret; - } - return NULL_TREE; + tree ret = get_class_binding_direct (anon, name, want_type); + return ret; } /* Look for NAME as an immediate member of KLASS (including diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index fe15136b227..8c587d3528b 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -307,7 +307,7 @@ extern void pop_decl_namespace (void); extern void do_namespace_alias (tree, tree); extern tree do_class_using_decl (tree, tree); extern tree lookup_arg_dependent (tree, tree, vec *); -extern tree search_anon_aggr (tree, tree); +extern tree search_anon_aggr (tree, tree, bool = false); extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1); extern tree get_class_binding (tree, tree, int type_or_fns = -1); extern tree *find_member_slot (tree klass, tree name); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c036308c6e5..252a33a00d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-28 Nathan Sidwell + + PR c++/84602 + * g++.dg/lookup/pr84602.C: New. + 2018-02-28 Jakub Jelinek PR c++/83871 @@ -5,7 +10,8 @@ * g++.dg/ext/attr-warning.C: Remove -fdump-tree-optimized from dg-options. * g++.dg/ext/attr-nonnull.C: Likewise. - * g++.dg/ext/attr-noinline.C: Fix syntax in scan-tree-dump-not directives. + * g++.dg/ext/attr-noinline.C: Fix syntax in scan-tree-dump-not + directives. * g++.dg/ext/attr-noinline-2.C: Likewise. * g++.dg/ext/attr-noreturn-2.C: Use -fdump-tree-optimized instead of -fdump-tree-eh in dg-options. diff --git a/gcc/testsuite/g++.dg/lookup/pr84602.C b/gcc/testsuite/g++.dg/lookup/pr84602.C new file mode 100644 index 00000000000..d388ae00360 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/pr84602.C @@ -0,0 +1,32 @@ +// PR c++/84602 ICE +// { dg-additional-options "-fpermissive" } + +struct X { + union { + class a; // { dg-warning "can only have" } + }; + a *b; +}; +X::a *a; + +struct Y { + union { + class a; // { dg-warning "can only have" } + int a; + }; + class a *b; +}; + +class Y::a *y; + +struct Z { + union { + // Force MEMBER_VEC creation + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; + class a; // { dg-warning "can only have" } + int a; + }; + class a *b; +}; + +class Z::a *z; -- 2.30.2