Message ID | efd12365-35b4-41a6-d919-1fadef556c2d@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] Fix some locations | expand |
On Fri, Jun 1, 2018 at 5:03 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > while working on some bugs I noticed that in a few places in decl.c we could > do better in terms of locations within the current infrastructure, some > simple, straightforward improvements. I'm attaching below a tiny first > patch, more to follow, I hope. > > For example, a function which could be improved in many places is > grok_ctor_properties and, before going ahead, I'd like to ask about > something I noticed yesterday: > > /* There can be no default arguments. */ > for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg)) > if (TREE_PURPOSE (arg)) > { > TREE_PURPOSE (arg) = NULL_TREE; > if (operator_code == POSTINCREMENT_EXPR > || operator_code == POSTDECREMENT_EXPR) > pedwarn (input_location, OPT_Wpedantic, > "%qD cannot have default arguments", decl); > else > { > error ("%qD cannot have default arguments", decl); > return false; > } > } > > the special casing seems weird, so far I haven't been able to find anything > in the standard about it and all the other compilers I have at hand (Oracle, > Intel, Clang) don't seem to have it. Shall we keep it or not? Maybe with an > additional comment explaining the rationale? The affected testcases would be > parse/defarg11.C and g++.jason/operator.C. I think in the olden days, with a default argument one function could support both prefix and postfix inc/decrement syntax: struct A { A& operator++(int = 0); }; int main() { A a; ++a; a++; } ...but that hasn't actually worked in forever, so it shouldn't be a problem to make the ++ case an error, too. Jason
Hi, On 01/06/2018, 23:29, Jason Merrill wrote: > On Fri, Jun 1, 2018 at 5:03 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: >> while working on some bugs I noticed that in a few places in decl.c we could >> do better in terms of locations within the current infrastructure, some >> simple, straightforward improvements. I'm attaching below a tiny first >> patch, more to follow, I hope. >> >> For example, a function which could be improved in many places is >> grok_ctor_properties and, before going ahead, I'd like to ask about >> something I noticed yesterday: >> >> /* There can be no default arguments. */ >> for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg)) >> if (TREE_PURPOSE (arg)) >> { >> TREE_PURPOSE (arg) = NULL_TREE; >> if (operator_code == POSTINCREMENT_EXPR >> || operator_code == POSTDECREMENT_EXPR) >> pedwarn (input_location, OPT_Wpedantic, >> "%qD cannot have default arguments", decl); >> else >> { >> error ("%qD cannot have default arguments", decl); >> return false; >> } >> } >> >> the special casing seems weird, so far I haven't been able to find anything >> in the standard about it and all the other compilers I have at hand (Oracle, >> Intel, Clang) don't seem to have it. Shall we keep it or not? Maybe with an >> additional comment explaining the rationale? The affected testcases would be >> parse/defarg11.C and g++.jason/operator.C. > I think in the olden days, with a default argument one function could > support both prefix and postfix inc/decrement syntax: > > struct A { > A& operator++(int = 0); > }; > > int main() > { > A a; > ++a; > a++; > } > > ...but that hasn't actually worked in forever, so it shouldn't be a > problem to make the ++ case an error, too. Thanks for the explanation. If we can remove the special casing, fixing some other issues will be easier, for example setting TREE_PURPOSE unconditionally error_mark_node fixes a Bugzilla bug (I don't have the number with me, more when I'm back home next week ;) Thanks, Paolo.
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 261078) +++ cp/decl.c (working copy) @@ -8674,8 +8674,9 @@ grokfndecl (tree ctype, if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) { if (funcdef_flag) - error ("defining explicit specialization %qD in friend declaration", - orig_declarator); + error_at (location, + "defining explicit specialization %qD in friend declaration", + orig_declarator); else { tree fns = TREE_OPERAND (orig_declarator, 0); @@ -8684,9 +8685,10 @@ grokfndecl (tree ctype, if (PROCESSING_REAL_TEMPLATE_DECL_P ()) { /* Something like `template <class T> friend void f<T>()'. */ - error ("invalid use of template-id %qD in declaration " - "of primary template", - orig_declarator); + error_at (location, + "invalid use of template-id %qD in declaration " + "of primary template", + orig_declarator); return NULL_TREE; } Index: testsuite/g++.dg/template/friend64.C =================================================================== --- testsuite/g++.dg/template/friend64.C (nonexistent) +++ testsuite/g++.dg/template/friend64.C (working copy) @@ -0,0 +1,6 @@ +template <class T> void foo (int); + +template <class T> +class Q { + friend void foo<T> (int) { } // { dg-error "15:defining explicit specialization" } +}; Index: testsuite/g++.old-deja/g++.other/friend4.C =================================================================== --- testsuite/g++.old-deja/g++.other/friend4.C (revision 261078) +++ testsuite/g++.old-deja/g++.other/friend4.C (working copy) @@ -11,7 +11,7 @@ template <class A, class B> void foo(); template <class C> class bar { int i; // { dg-message "" } private - template <class B> friend void foo<C,B>(); // { dg-error "" } bogus declaration + template <class B> friend void foo<C,B>(); // { dg-error "34:invalid use of template-id" } }; template <class A, class B> void foo() { bar<A> baz; baz.i = 1; // { dg-error "" } foo cannot access bar<int>::i Index: testsuite/g++.old-deja/g++.pt/crash23.C =================================================================== --- testsuite/g++.old-deja/g++.pt/crash23.C (revision 261078) +++ testsuite/g++.old-deja/g++.pt/crash23.C (working copy) @@ -4,7 +4,7 @@ template <class A, class B> void foo(); template <class C> class bar { public: int i; - template <class B> friend void foo<C,B>(); // { dg-error "" } template-id + template <class B> friend void foo<C,B>(); // { dg-error "34:invalid use of template-id" } }; template <class A, class B> void foo() { bar<A> baz; baz.i = 1;