Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

A few adjustments that I needed for the P1811 work that also seem
independently correct.  In pushtag, we want to set TREE_PUBLIC sooner so
that check_module_override considers mergeable decls; this also results in
correct -Wbuiltin-declaration-mismatch about reusing names of built-ins.

It was odd that there were a few if (type) bits after 'done:' in
cp_parser_class_head, when all the 'goto done' first set type to NULL_TREE.
That is no longer the case, and they're wrong for P1811, so I moved
those bits before the label.

And in duplicate_decls, for P1811 I will want to skip ahead to freeing
newdecl in more cases.  One existing early return worked with this change,
but a template case did not yet due to newdecl already being in
specialization tables.

gcc/cp/ChangeLog:

        * name-lookup.cc (pushtag): Set TREE_PUBLIC sooner.
        * parser.cc (cp_parser_class_head): Set location and final
        before 'done' label.
        * decl.cc (duplicate_decls): Free duplicate namespace alias.

gcc/testsuite/ChangeLog:

        * g++.dg/lookup/builtin4.C: Expect warning.
        * g++.dg/lookup/hidden-class10.C: Likewise.
---
 gcc/cp/decl.cc                               | 12 ++++++++----
 gcc/cp/name-lookup.cc                        |  5 +++++
 gcc/cp/parser.cc                             |  9 +++++----
 gcc/testsuite/g++.dg/lookup/builtin4.C       |  2 +-
 gcc/testsuite/g++.dg/lookup/hidden-class10.C |  2 +-
 5 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 24c5f0337b9..a14e9a4cb71 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2344,7 +2344,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, 
bool was_hidden)
       if (DECL_NAMESPACE_ALIAS (newdecl)
          && (DECL_NAMESPACE_ALIAS (newdecl)
              == DECL_NAMESPACE_ALIAS (olddecl)))
-       return olddecl;
+       goto return_old;
 
       /* Leave it to update_binding to merge or report error.  */
       return NULL_TREE;
@@ -2595,9 +2595,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool 
hiding, bool was_hidden)
      set OLDDECL's attributes to those of NEWDECL (for template
      explicit specializations that specify their own attributes
      independent of those specified for the primary template).  */
-  const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
-                          || !DECL_TEMPLATE_SPECIALIZATION (newdecl)
-                          || DECL_TEMPLATE_SPECIALIZATION (olddecl));
+  bool merge_attr;
+  merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
+               || !DECL_TEMPLATE_SPECIALIZATION (newdecl)
+               || DECL_TEMPLATE_SPECIALIZATION (olddecl));
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -2816,6 +2817,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, 
bool was_hidden)
            }
        }
 
+      /* FIXME we can't goto return_old here without removing newdecl from more
+        hash tables.  */
       return olddecl;
     }
 
@@ -3580,6 +3583,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, 
bool was_hidden)
        }
     }
 
+ return_old:
   /* Remove the associated constraints for newdecl, if any, before
      reclaiming memory. */
   if (flag_concepts)
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 183ea403ef8..56d21bf50d6 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -8816,6 +8816,11 @@ pushtag (tree name, tree type, TAG_how how)
       DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
       set_originating_module (tdef);
 
+      /* Set TREE_PUBLIC now for built-in warnings and module merging.  */
+      if (TREE_CODE (context) == NAMESPACE_DECL
+         && TREE_PUBLIC (context))
+       TREE_PUBLIC (tdef) = 1;
+
       decl = maybe_process_template_type_declaration
        (type, how == TAG_how::HIDDEN_FRIEND, b);
       if (decl == error_mark_node)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index b98792a5ad5..9c54b2f22e2 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -30925,6 +30925,11 @@ cp_parser_class_head (cp_parser* parser,
   if (type)
     popclass ();
 
+  if (type)
+    DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
+  if (type && (virt_specifiers & VIRT_SPEC_FINAL))
+    CLASSTYPE_FINAL (type) = 1;
+
  done:
   /* Leave the scope given by the nested-name-specifier.  We will
      enter the class scope itself while processing the members.  */
@@ -30937,10 +30942,6 @@ cp_parser_class_head (cp_parser* parser,
       --parser->num_template_parameter_lists;
     }
 
-  if (type)
-    DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
-  if (type && (virt_specifiers & VIRT_SPEC_FINAL))
-    CLASSTYPE_FINAL (type) = 1;
  out:
   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   return type;
diff --git a/gcc/testsuite/g++.dg/lookup/builtin4.C 
b/gcc/testsuite/g++.dg/lookup/builtin4.C
index b1785dcc7fb..e71131b5a99 100644
--- a/gcc/testsuite/g++.dg/lookup/builtin4.C
+++ b/gcc/testsuite/g++.dg/lookup/builtin4.C
@@ -10,6 +10,6 @@ namespace std
   union abort;
 }
 
-union abort;
+union abort;                   // { dg-warning "built-in" }
 
 using std::abort; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class10.C 
b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
index c9b5ca9f663..986241558a6 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-class10.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
@@ -6,6 +6,6 @@
 // function name.
 
 class A {
-  friend class abort;
+  friend class abort;          // { dg-warning "built-in" }
   abort *b;    // { dg-error "type|expected" }
 };

base-commit: fbcafeec06a66175108be68c34aceafba7a453b9
-- 
2.55.0

Reply via email to