diff options
-rw-r--r-- | gcc/cp/decl.c | 8 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr62101.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr80259.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-friend8.C | 12 |
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>(); +} |