From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 7BC183858D20; Fri, 20 Oct 2023 14:50:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7BC183858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697813446; bh=xAh11meiH32ocR7Gurhg3IO93T2GXUviRoi5P/CRYrE=; h=From:To:Subject:Date:From; b=ZHjpUX+7mDUBEpD13QvVNAvRLmYwFTgPdk/JEktbYAl/hwAxG/Yh/s+OY72PV+b4G V3HbmXxsdzfnJgnsA+rt4OmFZHngddd8qD7aHyF9o42dlAUBVRoJWxJaRQpJ9+QqyE jmdx9tSvSwMWCCX7nT3UrEZ/sQJpxzooeUue0ID0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4795] c++: non-static memfn call dependence cleanup [PR106086] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/master X-Git-Oldrev: cd0e05b7ac3dee11287078acd00a19e52a738963 X-Git-Newrev: 909672f02ff75a6a94c88dee4aa41e92edb1d1ed Message-Id: <20231020145046.7BC183858D20@sourceware.org> Date: Fri, 20 Oct 2023 14:50:46 +0000 (GMT) List-Id: https://gcc.gnu.org/g:909672f02ff75a6a94c88dee4aa41e92edb1d1ed commit r14-4795-g909672f02ff75a6a94c88dee4aa41e92edb1d1ed Author: Patrick Palka Date: Fri Oct 20 10:50:19 2023 -0400 c++: non-static memfn call dependence cleanup [PR106086] In cp_parser_postfix_expression, and in the CALL_EXPR case of tsubst_copy_and_build, we essentially repeat the type-dependent and COMPONENT_REF callee cases of finish_call_expr. This patch deduplicates this logic by making both spots consistently go through finish_call_expr. This allows us to easily fix PR106086 -- which is about us neglecting to capture 'this' when we resolve a use of a non-static member function of the current instantiation only at lambda regeneration time -- by moving the call to maybe_generic_this_capture from the parser to finish_call_expr so that we consider capturing 'this' at regeneration time as well. PR c++/106086 gcc/cp/ChangeLog: * parser.cc (cp_parser_postfix_expression): Consolidate three calls to finish_call_expr, one to build_new_method_call and one to build_min_nt_call_vec into one call to finish_call_expr. Don't call maybe_generic_this_capture here. * pt.cc (tsubst_copy_and_build) : Remove COMPONENT_REF callee handling. (type_dependent_expression_p): Use t_d_object_e_p instead of t_d_e_p for COMPONENT_REF and OFFSET_REF. * semantics.cc (finish_call_expr): In the type-dependent case, call maybe_generic_this_capture here instead. gcc/testsuite/ChangeLog: * g++.dg/template/crash127.C: Expect additional error due to being able to check the member access expression ahead of time. Strengthen the test by not instantiating the class template. * g++.dg/cpp1y/lambda-generic-this5.C: New test. Diff: --- gcc/cp/parser.cc | 52 +++-------------------- gcc/cp/pt.cc | 27 +----------- gcc/cp/semantics.cc | 12 ++++-- gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C | 22 ++++++++++ gcc/testsuite/g++.dg/template/crash127.C | 3 +- 5 files changed, 38 insertions(+), 78 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index c77e93ef104f..5483121f51c1 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -8055,54 +8055,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, close_paren_loc); iloc_sentinel ils (combined_loc); - if (TREE_CODE (postfix_expression) == COMPONENT_REF) - { - tree instance = TREE_OPERAND (postfix_expression, 0); - tree fn = TREE_OPERAND (postfix_expression, 1); - - if (processing_template_decl - && (type_dependent_object_expression_p (instance) - || (!BASELINK_P (fn) - && TREE_CODE (fn) != FIELD_DECL) - || type_dependent_expression_p (fn) - || any_type_dependent_arguments_p (args))) - { - maybe_generic_this_capture (instance, fn); - postfix_expression - = build_min_nt_call_vec (postfix_expression, args); - } - else if (BASELINK_P (fn)) - { - postfix_expression - = (build_new_method_call - (instance, fn, &args, NULL_TREE, - (idk == CP_ID_KIND_QUALIFIED - ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL - : LOOKUP_NORMAL), - /*fn_p=*/NULL, - complain)); - } - else - postfix_expression - = finish_call_expr (postfix_expression, &args, - /*disallow_virtual=*/false, - /*koenig_p=*/false, - complain); - } - else if (TREE_CODE (postfix_expression) == OFFSET_REF - || TREE_CODE (postfix_expression) == MEMBER_REF - || TREE_CODE (postfix_expression) == DOTSTAR_EXPR) + if (TREE_CODE (postfix_expression) == OFFSET_REF + || TREE_CODE (postfix_expression) == MEMBER_REF + || TREE_CODE (postfix_expression) == DOTSTAR_EXPR) postfix_expression = (build_offset_ref_call_from_tree (postfix_expression, &args, complain)); - else if (idk == CP_ID_KIND_QUALIFIED) - /* A call to a static class member, or a namespace-scope - function. */ - postfix_expression - = finish_call_expr (postfix_expression, &args, - /*disallow_virtual=*/true, - koenig_p, - complain); else /* All other function calls. */ { @@ -8115,12 +8073,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, "not permitted in intervening code"); parser->omp_for_parse_state->fail = true; } + bool disallow_virtual = (idk == CP_ID_KIND_QUALIFIED); postfix_expression = finish_call_expr (postfix_expression, &args, - /*disallow_virtual=*/false, + disallow_virtual, koenig_p, complain); } + if (close_paren_loc != UNKNOWN_LOCATION) postfix_expression.set_location (combined_loc); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d2756c3ffb3a..bd84054ae12d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21364,31 +21364,6 @@ tsubst_copy_and_build (tree t, || TREE_CODE (function) == MEMBER_REF) ret = build_offset_ref_call_from_tree (function, &call_args, complain); - else if (TREE_CODE (function) == COMPONENT_REF) - { - tree instance = TREE_OPERAND (function, 0); - tree fn = TREE_OPERAND (function, 1); - - if (processing_template_decl - && (type_dependent_expression_p (instance) - || (!BASELINK_P (fn) - && TREE_CODE (fn) != FIELD_DECL) - || type_dependent_expression_p (fn) - || any_type_dependent_arguments_p (call_args))) - ret = build_min_nt_call_vec (function, call_args); - else if (!BASELINK_P (fn)) - ret = finish_call_expr (function, &call_args, - /*disallow_virtual=*/false, - /*koenig_p=*/false, - complain); - else - ret = (build_new_method_call - (instance, fn, - &call_args, NULL_TREE, - qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL, - /*fn_p=*/NULL, - complain)); - } else if (concept_check_p (function)) { /* FUNCTION is a template-id referring to a concept definition. */ @@ -28585,7 +28560,7 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == COMPONENT_REF || TREE_CODE (expression) == OFFSET_REF) { - if (type_dependent_expression_p (TREE_OPERAND (expression, 0))) + if (type_dependent_object_expression_p (TREE_OPERAND (expression, 0))) return true; expression = TREE_OPERAND (expression, 1); if (identifier_p (expression)) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 5ccfa14b9b05..dc3c11461fbc 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2793,18 +2793,19 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, (c++/89780, c++/107363). This also suppresses the -Wredundant-move warning. */ suppress_warning (result, OPT_Wpessimizing_move); - if (is_overloaded_fn (fn)) - fn = get_fns (fn); if (cfun) { bool abnormal = true; - for (lkp_iterator iter (fn); abnormal && iter; ++iter) + for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter) { tree fndecl = STRIP_TEMPLATE (*iter); if (TREE_CODE (fndecl) != FUNCTION_DECL || !TREE_THIS_VOLATILE (fndecl)) - abnormal = false; + { + abnormal = false; + break; + } } /* FIXME: Stop warning about falling off end of non-void function. But this is wrong. Even if we only see @@ -2814,6 +2815,9 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, if (abnormal) current_function_returns_abnormally = 1; } + if (TREE_CODE (fn) == COMPONENT_REF) + maybe_generic_this_capture (TREE_OPERAND (fn, 0), + TREE_OPERAND (fn, 1)); return result; } orig_args = make_tree_vector_copy (*args); diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C new file mode 100644 index 000000000000..42f917094d9e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C @@ -0,0 +1,22 @@ +// PR c++/106086 +// { dg-do compile { target c++14 } } + +template +struct A { + void f(int) const; + static void g(int); +}; + +template +struct B : A { + auto f() const { + auto l1 = [&](auto x) { A::f(x); }; + auto l2 = [&](auto x) { A::g(x); }; + static_assert(sizeof(l1) == sizeof(this), ""); + static_assert(sizeof(l2) == 1, ""); + l1(0); + l2(0); + } +}; + +template struct B; diff --git a/gcc/testsuite/g++.dg/template/crash127.C b/gcc/testsuite/g++.dg/template/crash127.C index b7c03251f8c6..fcf72d871db6 100644 --- a/gcc/testsuite/g++.dg/template/crash127.C +++ b/gcc/testsuite/g++.dg/template/crash127.C @@ -16,7 +16,6 @@ struct C : public A { B < &A::A > b; // { dg-error "taking address of constructor 'A::A" "" { target c++98_only } } // { dg-error "taking address of constructor 'constexpr A::A" "" { target c++11 } .-1 } + // { dg-error "template argument 1 is invalid" "" { target *-*-* } .-2 } } }; - -template class C < int >;