aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-06-16 00:20:58 -0400
committerJason Merrill <jason@redhat.com>2020-06-17 15:08:42 -0400
commitda2c9054f1596b71e3c81efd62b6cef348e445b4 (patch)
tree59b9bf926db8129c48e0f022ac5217fd6e932596 /gcc/cp/decl2.c
parentd2384b7b24f8557b66f6958a05ea99ff4307e75c (diff)
downloadgcc-da2c9054f1596b71e3c81efd62b6cef348e445b4.zip
gcc-da2c9054f1596b71e3c81efd62b6cef348e445b4.tar.gz
gcc-da2c9054f1596b71e3c81efd62b6cef348e445b4.tar.bz2
c++: Treat in-class default/delete as definitions.
We were complaining about a constrained defaulted non-template friend in a template class because funcdef_flag wasn't set. grokdeclarator would set it for default/delete, but grokfield wasn't passing the 'initialized' values needed. Fixing that revealed some errors in existing tests that we weren't diagnosing. Since we accepted them for so long, I'm reducing the error to a pedwarn to ease compiler upgrade. gcc/cp/ChangeLog: * decl2.c (grokfield): Pass SD_DEFAULTED and SD_DELETED. * decl.c (duplicate_decls): Reduce error for delete after earlier declaration to pedwarn. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/pr62101.C: Expect error. * g++.dg/cpp0x/pr80259.C: Expect error. * g++.dg/cpp2a/concepts-friend8.C: New test.
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 449c86c..93e3034 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -838,7 +838,17 @@ grokfield (const cp_declarator *declarator,
&& TREE_CHAIN (init) == NULL_TREE)
init = NULL_TREE;
- value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
+ int initialized;
+ if (init == ridpointers[(int)RID_DELETE])
+ initialized = SD_DELETED;
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ initialized = SD_DEFAULTED;
+ else if (init)
+ initialized = SD_INITIALIZED;
+ else
+ initialized = SD_UNINITIALIZED;
+
+ value = grokdeclarator (declarator, declspecs, FIELD, initialized, &attrlist);
if (! value || value == error_mark_node)
/* friend or constructor went bad. */
return error_mark_node;
@@ -916,18 +926,8 @@ grokfield (const cp_declarator *declarator,
{
if (init == ridpointers[(int)RID_DELETE])
{
- if (friendp && decl_defined_p (value))
- {
- error ("redefinition of %q#D", value);
- inform (DECL_SOURCE_LOCATION (value),
- "%q#D previously defined here", value);
- }
- else
- {
- DECL_DELETED_FN (value) = 1;
- DECL_DECLARED_INLINE_P (value) = 1;
- DECL_INITIAL (value) = error_mark_node;
- }
+ DECL_DELETED_FN (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
}
else if (init == ridpointers[(int)RID_DEFAULT])
{
@@ -936,6 +936,9 @@ grokfield (const cp_declarator *declarator,
DECL_DEFAULTED_FN (value) = 1;
DECL_INITIALIZED_IN_CLASS_P (value) = 1;
DECL_DECLARED_INLINE_P (value) = 1;
+ /* grokfndecl set this to error_mark_node, but we want to
+ leave it unset until synthesize_method. */
+ DECL_INITIAL (value) = NULL_TREE;
}
}
else if (TREE_CODE (init) == DEFERRED_PARSE)