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