aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-10-20 10:50:19 -0400
committerPatrick Palka <ppalka@redhat.com>2023-10-20 10:50:19 -0400
commit909672f02ff75a6a94c88dee4aa41e92edb1d1ed (patch)
tree5d586e5a4604b078e2f8630ef3729ba1bdff3513 /gcc
parentcd0e05b7ac3dee11287078acd00a19e52a738963 (diff)
downloadgcc-909672f02ff75a6a94c88dee4aa41e92edb1d1ed.zip
gcc-909672f02ff75a6a94c88dee4aa41e92edb1d1ed.tar.gz
gcc-909672f02ff75a6a94c88dee4aa41e92edb1d1ed.tar.bz2
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) <case CALL_EXPR>: 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.cc52
-rw-r--r--gcc/cp/pt.cc27
-rw-r--r--gcc/cp/semantics.cc12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-this5.C22
-rw-r--r--gcc/testsuite/g++.dg/template/crash127.C3
5 files changed, 38 insertions, 78 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index c77e93e..5483121 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 d2756c3..bd84054 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 5ccfa14..dc3c114 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -2793,18 +2793,19 @@ finish_call_expr (tree fn, vec<tree, va_gc> **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<tree, va_gc> **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 0000000..42f9170
--- /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<class T>
+struct A {
+ void f(int) const;
+ static void g(int);
+};
+
+template<class T>
+struct B : A<T> {
+ auto f() const {
+ auto l1 = [&](auto x) { A<T>::f(x); };
+ auto l2 = [&](auto x) { A<T>::g(x); };
+ static_assert(sizeof(l1) == sizeof(this), "");
+ static_assert(sizeof(l2) == 1, "");
+ l1(0);
+ l2(0);
+ }
+};
+
+template struct B<void>;
diff --git a/gcc/testsuite/g++.dg/template/crash127.C b/gcc/testsuite/g++.dg/template/crash127.C
index b7c0325..fcf72d8 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 >;