[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 --- Comment #6 from CVS Commits --- The master branch has been updated by Patrick Palka : https://gcc.gnu.org/g:a8cef3cba6945730c69e15dcdad726e74b50fe58 commit r11-6878-ga8cef3cba6945730c69e15dcdad726e74b50fe58 Author: Patrick Palka Date: Sat Jan 23 00:24:17 2021 -0500 c++: 'this' injection and static member functions [PR97399] In the testcase pr97399.C below, finish_qualified_id_expr at parse time adds an implicit 'this->' to the expression tmp::integral (because it's type-dependent, and also current_class_ptr is set at this point) within the trailing return type. Later when substituting into this trailing return type we crash because we can't resolve the 'this', since tsubst_function_type does inject_this_parm only for non-static member functions, which tmp::func is not. This patch fixes this issue by removing the type-dependence check in finish_qualified_id_expr added by r9-5972, and instead relaxes shared_member_p to handle dependent USING_DECLs: > I think I was wrong in my assertion around Alex's patch that > shared_member_p should abort on a dependent USING_DECL; it now seems > appropriate for it to return false if we don't know, we just need to > adjust the comment to say that. And when parsing a friend function declaration, we shouldn't be setting current_class_ptr at all, so this patch additionally suppresses inject_this_parm in this case. Finally, the self-contained change to cp_parser_init_declarator is so that we properly communicate static-ness to cp_parser_direct_declarator when parsing a member function template. This lets us reject the explicit use of 'this' in the testcase this2.C below. gcc/cp/ChangeLog: PR c++/97399 * cp-tree.h (shared_member_p): Adjust declaration. * parser.c (cp_parser_init_declarator): If the storage class specifier is sc_static, pass true for static_p to cp_parser_declarator. (cp_parser_direct_declarator): Don't do inject_this_parm when the declarator is a friend. * search.c (shared_member_p): Change return type to bool and adjust function body accordingly. Return false for a dependent USING_DECL instead of aborting. * semantics.c (finish_qualified_id_expr): Rely on shared_member_p even when type-dependent. gcc/testsuite/ChangeLog: PR c++/88548 PR c++/97399 * g++.dg/cpp0x/this2.C: New test. * g++.dg/template/pr97399.C: New test.
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Marek Polacek changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #5 from Marek Polacek --- Should be fixed for GCC 9.
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 --- Comment #4 from Marek Polacek --- Author: mpolacek Date: Tue Jan 8 17:37:51 2019 New Revision: 267731 URL: https://gcc.gnu.org/viewcvs?rev=267731=gcc=rev Log: PR c++/88548 - this accepted in static member functions. * parser.c (cp_debug_parser): Adjust printing of local_variables_forbidden_p. (cp_parser_new): Set local_variables_forbidden_p to 0 rather than false. (cp_parser_primary_expression): When checking local_variables_forbidden_p, use THIS_FORBIDDEN or LOCAL_VARS_FORBIDDEN. (cp_parser_lambda_body): Update the type of local_variables_forbidden_p. Set it to 0 rather than false. (cp_parser_condition): Adjust call to cp_parser_declarator. (cp_parser_explicit_instantiation): Likewise. (cp_parser_init_declarator): Likewise. (cp_parser_declarator): New parameter. Use it. (cp_parser_direct_declarator): New parameter. Use it to set local_variables_forbidden_p. Adjust call to cp_parser_declarator. (cp_parser_type_id_1): Adjust call to cp_parser_declarator. (cp_parser_parameter_declaration): Likewise. (cp_parser_default_argument): Update the type of local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN rather than true. (cp_parser_member_declaration): Tell cp_parser_declarator if we saw 'static' or 'friend'. (cp_parser_exception_declaration): Adjust call to cp_parser_declarator. (cp_parser_late_parsing_default_args): Update the type of local_variables_forbidden_p. Set it to LOCAL_VARS_AND_THIS_FORBIDDEN rather than true. (cp_parser_cache_defarg): Adjust call to cp_parser_declarator. (cp_parser_objc_class_ivars): Likewise. (cp_parser_objc_struct_declaration): Likewise. (cp_parser_omp_for_loop_init): Likewise. * parser.h (cp_parser): Change the type of local_variables_forbidden_p to unsigned char. (LOCAL_VARS_FORBIDDEN, LOCAL_VARS_AND_THIS_FORBIDDEN, THIS_FORBIDDEN): Define. * g++.dg/cpp0x/this1.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp0x/this1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/cp/parser.h trunk/gcc/testsuite/ChangeLog
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 --- Comment #3 from Marek Polacek --- Related testcase that should also be rejected: struct S { friend auto bar() -> decltype(this); };
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Marek Polacek changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Richard Biener changed: What|Removed |Added Priority|P3 |P1
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Jakub Jelinek changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2018-12-19 CC||jason at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from Jakub Jelinek --- The problem I see is that we don't really pass the information that it is a static member function rather than member function through the parser: #1 0x00a2df0e in cp_parser_late_return_type_opt (parser=0x77ff6ab0, declarator=0x33153f0, requires_clause=@0x7fffd378: , quals=0) at ../../gcc/cp/parser.c:21466 #2 0x00a2c2a7 in cp_parser_direct_declarator (parser=0x77ff6ab0, dcl_kind=CP_PARSER_DECLARATOR_NAMED, flags=32, ctor_dtor_or_conv_p=0x7fffd5b4, member_p=true, friend_p=false) at ../../gcc/cp/parser.c:20645 #3 0x00a2bf81 in cp_parser_declarator (parser=0x77ff6ab0, dcl_kind=CP_PARSER_DECLARATOR_NAMED, flags=32, ctor_dtor_or_conv_p=0x7fffd5b4, parenthesized_p=0x0, member_p=true, friend_p=false) at ../../gcc/cp/parser.c:20472 #4 0x00a33fe4 in cp_parser_member_declaration (parser=0x77ff6ab0) at ../../gcc/cp/parser.c:24387 where cp_parser_member_declaration knows this information (decl_specifiers.storage_class == sc_static), but cp_parser_declarator/cp_parser_direct_declarator/cp_parser_late_return_type_opt don't. Similarly for the noexcept: #1 0x00a3510e in cp_parser_noexcept_specification_opt (parser=0x77ff6ab0, require_constexpr=true, consumed_expr=0x0, return_cond=false) at ../../gcc/cp/parser.c:24961 #2 0x00a352bc in cp_parser_exception_specification_opt (parser=0x77ff6ab0) at ../../gcc/cp/parser.c:25023 #3 0x00a2c245 in cp_parser_direct_declarator (parser=0x77ff6ab0, dcl_kind=CP_PARSER_DECLARATOR_NAMED, flags=32, ctor_dtor_or_conv_p=0x7fffd5b4, member_p=true, friend_p=false) at ../../gcc/cp/parser.c:20636 #4 0x00a2bf81 in cp_parser_declarator (parser=0x77ff6ab0, dcl_kind=CP_PARSER_DECLARATOR_NAMED, flags=32, ctor_dtor_or_conv_p=0x7fffd5b4, parenthesized_p=0x0, member_p=true, friend_p=false) at ../../gcc/cp/parser.c:20472 #5 0x00a33fe4 in cp_parser_member_declaration (parser=0x77ff6ab0) at ../../gcc/cp/parser.c:24387 We could say change member_p from bool to enum { NONMEMBER, MEMBER, STATIC_MEMBER }; or similar. But then there is also a problem how to make the diagnostic user friendly. Because, if I just return in the debugger in inject_this_parameter in the third and fourth case, I get: pr88548.C:5:33: error: invalid use of ‘this’ at top level 5 | static auto m3 () -> decltype(this->a) { return 0; } | ^~~~ pr88548.C:5:33: error: invalid use of ‘this’ at top level pr88548.C:6:39: error: invalid use of ‘this’ at top level 6 | static void m4 () noexcept(noexcept(this->a)) { } | ^~~~ errors (for some reason the first one twice), while clang++/icpc talk about this not being available in static member functions. finish_this_expr has nice diagnostics: 2643 tree fn = current_nonlambda_function (); 2644 if (fn && DECL_STATIC_FUNCTION_P (fn)) 2645error ("% is unavailable for static member functions"); 2646 else if (fn) 2647error ("invalid use of % in non-member function"); 2648 else 2649error ("invalid use of % at top level"); but to get the 2645 diagnostics current_function_decl needs to be built and marked as static member, which is something we don't have when parsing the late return type or noexcept.
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek --- And since r175671 we accept it also in late return type: struct S { int a; auto m1 () -> decltype(this->a) { return 0; } void m2 () noexcept(noexcept(this->a)) { } static auto m3 () -> decltype(this->a) { return 0; } static void m4 () noexcept(noexcept(this->a)) { } }; Godbolt shows that clang++ and icpc both reject m3 and m4.
[Bug c++/88548] [9 Regression] this accepted in static member functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88548 Marek Polacek changed: What|Removed |Added Keywords||accepts-invalid Target Milestone|--- |9.0