aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/decl2.c29
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr62101.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr80259.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-friend8.C12
5 files changed, 37 insertions, 16 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 539609e..1d960be 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2067,13 +2067,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
"previous declaration of %qD", olddecl);
}
+ /* [dcl.fct.def.delete] A deleted definition of a function shall be the
+ first declaration of the function or, for an explicit specialization
+ of a function template, the first declaration of that
+ specialization. */
if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
&& DECL_TEMPLATE_SPECIALIZATION (newdecl)))
{
if (DECL_DELETED_FN (newdecl))
{
auto_diagnostic_group d;
- error_at (newdecl_loc, "deleted definition of %qD", newdecl);
+ pedwarn (newdecl_loc, OPT_Wpedantic,
+ "deleted definition of %qD is not first declaration",
+ newdecl);
inform (olddecl_loc,
"previous declaration of %qD", olddecl);
}
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)
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr62101.C b/gcc/testsuite/g++.dg/cpp0x/pr62101.C
index 5fc579c..07ab1b7 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr62101.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr62101.C
@@ -17,7 +17,7 @@ void g(Y, double);
struct Y
{
// { dg-prune-output "note" }
- friend void g(Y, int) = delete;
+ friend void g(Y, int) = delete; // { dg-error "not first declaration" }
friend void g(Y, double) {}
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr80259.C b/gcc/testsuite/g++.dg/cpp0x/pr80259.C
index 9d2a109..adb354b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr80259.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr80259.C
@@ -7,7 +7,7 @@ void bar ();
struct A
{
friend void foo () = delete; // { dg-error "redefinition of" }
- friend void bar () = delete; // { dg-message "previously defined here" }
+ friend void bar () = delete; // { dg-error "not first declaration" }
};
void bar () {} // { dg-error "redefinition of" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-friend8.C b/gcc/testsuite/g++.dg/cpp2a/concepts-friend8.C
new file mode 100644
index 0000000..e4930bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-friend8.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A
+{
+ friend bool operator==(const A&, const A&) requires true = default;
+};
+
+int main()
+{
+ A<int>() == A<int>();
+}