Hi, The problem here is that the use of an elaborated-type-specifier (introduced via 'struct') does not find USING_DECLs, whereas it does for a simple-type-specifier. That's caused by xref_tag (through lookup_and_check_tag) that does not strip USING_DECLs and thus fails to return a type when it happens to be the target of the USING_DECL.
Unfortunately, just stripping the USING_DECL in lookup_and_check_tag does not really work because some diagnotic codes expect the USING_DECL not to be stripped. Consequently, I have fixed it by introcucing a new parameter to xref_tag whose purpose is to know if stripping USING_DECLs is desirable. Not very exciting to fix it this way, but that is the only solution I managed to find. Tested x86_64 linux without regressions. OK to commit to trunk ? And branches after some weeks of incubation ? gcc/cp/ChangeLog 2014-09-24 Fabien Chêne <fab...@gcc.gnu.org> * cp-tree.h (xref_tag): Add a new bool parameter. * parser.c (cp_parser_elaborated_type_specifier): Call xref_tag with strip_using_p set to true. (cp_parser_class_head): Call xref_tag with strip_using_p set to false. * rtti.c (init_rtti_processing): Likewise. (build_dynamic_cast_1): Likewise. (tinfo_base_init): Likewise. (emit_support_tinfos): Likewise. * lambda.c (begin_lambda_type): Likewise. (vla_capture_type): Likewise. * decl.c (lookup_and_check_tag): Add a new bool parameter. Strip the USING_DECL if strip_using_p is set. Declare the variable t at the use. (xref_tag_1): Add a new bool parameter. Forward strip_using_p to lookup_and_check_tag. (xref_tag): Add a new bool parameter. Forward strip_using_p to xref_tag_1. (xref_tag_from_type): Call xref_tag with strip_using_p set to false. (start_enum): Call lookup_and_check_tag with strip_using_p set to false. Call xref_tag with strip_using_p set to false. gcc/testsuite/ChangeLog 2014-09-24 Fabien Chêne <fab...@gcc.gnu.org> PR c++/56243 * g++.dg/lookup/using56.C: New. -- Fabien
Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (révision 209870) +++ gcc/cp/parser.c (copie de travail) @@ -15202,7 +15202,8 @@ cp_parser_elaborated_type_specifier (cp_ token->location, /*declarator=*/NULL)) return error_mark_node; - type = xref_tag (tag_type, identifier, ts, template_p); + type = xref_tag (tag_type, identifier, ts, template_p, + /*strip_using_p=*/true); } } @@ -19930,7 +19931,7 @@ cp_parser_class_head (cp_parser* parser, if (!id) id = make_anon_name (); type = xref_tag (class_key, id, /*tag_scope=*/ts_current, - parser->num_template_parameter_lists); + parser->num_template_parameter_lists, false); } /* Indicate whether this class was declared as a `class' or as a Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (révision 209870) +++ gcc/cp/cp-tree.h (copie de travail) @@ -5245,7 +5245,8 @@ extern tree get_scope_of_declarator (co extern void grok_special_member_properties (tree); extern int grok_ctor_properties (const_tree, const_tree); extern bool grok_op_properties (tree, bool); -extern tree xref_tag (enum tag_types, tree, tag_scope, bool); +extern tree xref_tag (enum tag_types, tree, tag_scope, + bool, bool); extern tree xref_tag_from_type (tree, tree, tag_scope); extern bool xref_basetypes (tree, tree); extern tree start_enum (tree, tree, tree, bool, bool *); Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (révision 209870) +++ gcc/cp/decl.c (copie de travail) @@ -92,7 +92,7 @@ static int typename_compare (const void static tree local_variable_p_walkfn (tree *, int *, void *); static tree record_builtin_java_type (const char *, int); static const char *tag_name (enum tag_types); -static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool); +static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool, bool); static int walk_namespaces_r (tree, walk_namespaces_fn, void *); static void maybe_deduce_size_from_array_init (tree, tree); static void layout_var_decl (tree); @@ -11944,9 +11944,9 @@ check_elaborated_type_specifier (enum ta static tree lookup_and_check_tag (enum tag_types tag_code, tree name, - tag_scope scope, bool template_header_p) + tag_scope scope, bool template_header_p, + bool strip_using_p) { - tree t; tree decl; if (scope == ts_global) { @@ -11973,6 +11973,9 @@ lookup_and_check_tag (enum tag_types tag && DECL_TEMPLATE_TEMPLATE_PARM_P (decl)))) decl = DECL_TEMPLATE_RESULT (decl); + if (strip_using_p) + decl = strip_using_decl (decl); + if (decl && TREE_CODE (decl) == TYPE_DECL) { /* Look for invalid nested type: @@ -12003,10 +12006,10 @@ lookup_and_check_tag (enum tag_types tag class C *c2; // DECL_SELF_REFERENCE_P is true }; */ - t = check_elaborated_type_specifier (tag_code, - decl, - template_header_p - | DECL_SELF_REFERENCE_P (decl)); + tree t = check_elaborated_type_specifier (tag_code, + decl, + template_header_p + | DECL_SELF_REFERENCE_P (decl)); return t; } else if (decl && TREE_CODE (decl) == TREE_LIST) @@ -12036,7 +12039,8 @@ lookup_and_check_tag (enum tag_types tag static tree xref_tag_1 (enum tag_types tag_code, tree name, - tag_scope orig_scope, bool template_header_p) + tag_scope orig_scope, bool template_header_p, + bool strip_using_p) { enum tree_code code; tree t; @@ -12072,7 +12076,8 @@ xref_tag_1 (enum tag_types tag_code, tre t = NULL_TREE; else t = lookup_and_check_tag (tag_code, name, - scope, template_header_p); + scope, template_header_p, + strip_using_p); if (t == error_mark_node) return error_mark_node; @@ -12184,12 +12189,14 @@ xref_tag_1 (enum tag_types tag_code, tre tree xref_tag (enum tag_types tag_code, tree name, - tag_scope scope, bool template_header_p) + tag_scope scope, bool template_header_p, + bool strip_using_p) { tree ret; bool subtime; subtime = timevar_cond_start (TV_NAME_LOOKUP); - ret = xref_tag_1 (tag_code, name, scope, template_header_p); + ret = xref_tag_1 (tag_code, name, scope, template_header_p, + strip_using_p); timevar_cond_stop (TV_NAME_LOOKUP, subtime); return ret; } @@ -12208,7 +12215,7 @@ xref_tag_from_type (tree old, tree id, t if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (tag_kind, id, scope, false); + return xref_tag (tag_kind, id, scope, false, false); } /* Create the binfo hierarchy for REF with (possibly NULL) base list @@ -12490,7 +12497,8 @@ start_enum (tree name, tree enumtype, tr if (!enumtype) enumtype = lookup_and_check_tag (enum_type, name, /*tag_scope=*/ts_current, - /*template_header_p=*/false); + /*template_header_p=*/false, + /*strip_using_p=*/false); /* In case of a template_decl, the only check that should be deferred to instantiation time is the comparison of underlying types. */ @@ -12562,7 +12570,7 @@ start_enum (tree name, tree enumtype, tr } else enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, - false); + false, false); if (enumtype == error_mark_node) return error_mark_node; Index: gcc/cp/lambda.c =================================================================== --- gcc/cp/lambda.c (révision 209870) +++ gcc/cp/lambda.c (copie de travail) @@ -138,7 +138,8 @@ begin_lambda_type (tree lambda) type = xref_tag (/*tag_code=*/record_type, name, /*scope=*/ts_lambda, - /*template_header_p=*/false); + /*template_header_p=*/false, + /*strip_using_p=*/false); if (type == error_mark_node) return error_mark_node; } @@ -416,7 +417,7 @@ static tree vla_capture_type (tree array_type) { static tree ptr_id, max_id; - tree type = xref_tag (record_type, make_anon_name (), ts_current, false); + tree type = xref_tag (record_type, make_anon_name (), ts_current, false, false); xref_basetypes (type, NULL_TREE); type = begin_class_definition (type); if (!ptr_id) Index: gcc/cp/rtti.c =================================================================== --- gcc/cp/rtti.c (révision 209870) +++ gcc/cp/rtti.c (copie de travail) @@ -152,7 +152,7 @@ init_rtti_processing (void) push_namespace (std_identifier); type_info_type = xref_tag (class_type, get_identifier ("type_info"), - /*tag_scope=*/ts_current, false); + /*tag_scope=*/ts_current, false, false); pop_namespace (); const_type_info_type_node = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST); @@ -731,7 +731,7 @@ build_dynamic_cast_1 (tree type, tree ex push_abi_namespace (); tinfo_ptr = xref_tag (class_type, get_identifier ("__class_type_info"), - /*tag_scope=*/ts_current, false); + /*tag_scope=*/ts_current, false, false); tinfo_ptr = build_pointer_type (cp_build_qualified_type @@ -913,7 +913,7 @@ tinfo_base_init (tinfo_s *ti, tree targe tree real_type; push_abi_namespace (); real_type = xref_tag (class_type, ti->name, - /*tag_scope=*/ts_current, false); + /*tag_scope=*/ts_current, false, false); pop_abi_namespace (); if (!COMPLETE_TYPE_P (real_type)) @@ -1536,7 +1536,7 @@ emit_support_tinfos (void) push_abi_namespace (); bltn_type = xref_tag (class_type, get_identifier ("__fundamental_type_info"), - /*tag_scope=*/ts_current, false); + /*tag_scope=*/ts_current, false, false); pop_abi_namespace (); if (!COMPLETE_TYPE_P (bltn_type)) return; Index: gcc/testsuite/g++.dg/lookup/using54.C =================================================================== --- gcc/testsuite/g++.dg/lookup/using54.C (révision 0) +++ gcc/testsuite/g++.dg/lookup/using54.C (révision 0) @@ -0,0 +1,16 @@ +// PR c++/60894 + +struct B +{ + struct S {}; +}; + +struct D : B +{ + using B::S; + void doIt(struct S&); +}; + +void D::doIt(struct S&) +{ +}