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&)
+{
+}

Reply via email to