[Bug c++/80259] [5/6/7 Regression] ICE deleting friend function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80259 Richard Biener changed: What|Removed |Added Priority|P3 |P2
[Bug c++/80259] [5/6/7 Regression] ICE deleting friend function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80259 --- Comment #3 from Jakub Jelinek --- With untested: --- gcc/decl2.c.jj 2017-02-21 18:59:36.0 +0100 +++ gcc/decl2.c 2017-03-30 10:16:03.972113673 +0200 @@ -888,9 +888,18 @@ grokfield (const cp_declarator *declarat { if (init == ridpointers[(int)RID_DELETE]) { - DECL_DELETED_FN (value) = 1; - DECL_DECLARED_INLINE_P (value) = 1; - DECL_INITIAL (value) = error_mark_node; + 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; + } } else if (init == ridpointers[(int)RID_DEFAULT]) { I get: pr80259.C:5:23: error: redefinition of ‘void foo()’ friend void foo() = delete; ^~ pr80259.C:1:6: note: ‘void foo()’ previously defined here void foo() {} ^~~ but no idea if you don't want to resolve it differently.
[Bug c++/80259] [5/6/7 Regression] ICE deleting friend function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80259 --- Comment #2 from Jakub Jelinek --- duplicate_decls is called with the DECL_INITIAL is still being NULL on the newdecl (and olddecl has it a BLOCK). #0 duplicate_decls (newdecl=, olddecl=, newdecl_is_friend=true) at ../../gcc/cp/decl.c:1401 #1 0x00a2420c in pushdecl_maybe_friend_1 (x=, is_friend=true) at ../../gcc/cp/name-lookup.c:835 #2 0x00a27940 in pushdecl_maybe_friend (x=, is_friend=true) at ../../gcc/cp/name-lookup.c:1352 #3 0x00a2aaff in pushdecl_with_scope_1 (x=, level=0x7fffefade000, is_friend=true) at ../../gcc/cp/name-lookup.c:2349 #4 0x00a2aba2 in pushdecl_with_scope (x=, level=0x7fffefade000, is_friend=true) at ../../gcc/cp/name-lookup.c:2363 #5 0x00a30b81 in pushdecl_namespace_level (x=, is_friend=true) at ../../gcc/cp/name-lookup.c:3978 #6 0x0097cf07 in do_friend (ctype=, declarator=, decl=, attrlist=, flags=NO_SPECIAL, funcdef_flag=false) at ../../gcc/cp/friend.c:640 #7 0x007c9f6a in grokdeclarator (declarator=0x2ad2a00, declspecs=0x7fffd830, decl_context=FIELD, initialized=1, attrlist=0x7fffd770) at ../../gcc/cp/decl.c:12060 #8 0x008b879f in grokfield (declarator=0x2ad2a60, declspecs=0x7fffd830, init=, init_const_expr_p=true, asmspec_tree=, attrlist=) at ../../gcc/cp/decl2.c:806 And only afterwards grokfield reaches: 889 if (init == ridpointers[(int)RID_DELETE]) 890 { 891 DECL_DELETED_FN (value) = 1; 892 DECL_DECLARED_INLINE_P (value) = 1; 893 DECL_INITIAL (value) = error_mark_node; 894 } At this point I think we can't call redeclaration_error_message, because we don't have the new decl anymore, only the merged (old one). Perhaps custom error message here if value is a friend and it has non-NULL (or non-NULL and non-error_mark_node?) DECL_INITIAL and use there location_t for the new decl from declarator->id_loc (that would be the foo) or input_location (that would be the deleted) or something similar?
[Bug c++/80259] [5/6/7 Regression] ICE deleting friend function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80259 Jakub Jelinek changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2017-03-30 CC||jakub at gcc dot gnu.org, ||jason at gcc dot gnu.org Target Milestone|--- |5.5 Ever confirmed|0 |1 --- Comment #1 from Jakub Jelinek --- Started with r213974. Before that we've rejected it with: pr80259.C:5:23: error: can’t initialize friend function ‘foo’ friend void foo() = delete; ^ clang++ gives: pr80259.C:5:15: error: inline declaration of 'foo' follows non-inline definition friend void foo() = delete; ^ pr80259.C:1:6: note: previous definition is here void foo() {} ^ So, what diagnostics would be best here? What about: void foo(); struct A { friend void foo() = delete; }; void foo() {} ? With/without the first declaration we emit: pr80259-2.C: In function ‘void foo()’: pr80259-2.C:6:6: error: redefinition of ‘void foo()’ void foo() {} ^~~ pr80259-2.C:4:15: note: ‘void foo()’ previously defined here friend void foo() = delete; ^~~ which looks fine to me. So is the #c0 testcase a redefinition of the function that should be diagnosed the same way? For void foo() {} inline void foo () {} we emit: pr80259-3.C: In function ‘void foo()’: pr80259-3.C:2:13: error: redefinition of ‘void foo()’ inline void foo () {} ^~~ pr80259-3.C:1:6: note: ‘void foo()’ previously defined here void foo() {} ^~~ while clang++ emits: pr80259-3.C:2:13: error: inline declaration of 'foo' follows non-inline definition inline void foo () {} ^ pr80259-3.C:1:6: note: previous definition is here void foo() {} ^ so at least for now I'd say we should just emit a normal redefinition message.