c++: non-static memfn call dependence cleanup
Checks
Commit Message
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?
-- >8 --
In cp_parser_postfix_expression, we essentially repeat the
type-dependent and COMPONENT_REF callee cases of finish_call_expr.
This patch deduplicates this logic.
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.
* pt.cc (type_dependent_expression_p): Use t_d_object_e_p
instead of t_d_e_p for COMPONENT_REF and OFFSET_REF.
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.
---
gcc/cp/parser.cc | 60 ++++++------------------
gcc/cp/pt.cc | 2 +-
gcc/testsuite/g++.dg/template/crash127.C | 3 +-
3 files changed, 16 insertions(+), 49 deletions(-)
Comments
On Tue, Sep 26, 2023, 19:52 Patrick Palka <ppalka@redhat.com> wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?
>
> -- >8 --
>
> In cp_parser_postfix_expression, we essentially repeat the
> type-dependent and COMPONENT_REF callee cases of finish_call_expr.
> This patch deduplicates this logic.
>
> 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.
> * pt.cc (type_dependent_expression_p): Use t_d_object_e_p
> instead of t_d_e_p for COMPONENT_REF and OFFSET_REF.
>
> 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.
> ---
> gcc/cp/parser.cc | 60 ++++++------------------
> gcc/cp/pt.cc | 2 +-
> gcc/testsuite/g++.dg/template/crash127.C | 3 +-
> 3 files changed, 16 insertions(+), 49 deletions(-)
>
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index f3abae716fe..78082ee7284 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -8047,54 +8047,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. */
> {
> @@ -8107,12 +8065,22 @@ 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 (type_dependent_expression_p (postfix_expression))
> + {
> + tree fn = CALL_EXPR_FN (postfix_expression);
> + if (TREE_CODE (fn) == COMPONENT_REF)
> + maybe_generic_this_capture (TREE_OPERAND (fn, 0),
> + TREE_OPERAND (fn, 1));
> + }
> }
> +
> 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 382db4dd01d..b19b634690a 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -28585,7 +28585,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/testsuite/g++.dg/template/crash127.C
> b/gcc/testsuite/g++.dg/template/crash127.C
> index b7c03251f8c..fcf72d871db 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 >;
> --
> 2.42.0.270.gbcb6cae296
>
>
@@ -8047,54 +8047,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. */
{
@@ -8107,12 +8065,22 @@ 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 (type_dependent_expression_p (postfix_expression))
+ {
+ tree fn = CALL_EXPR_FN (postfix_expression);
+ if (TREE_CODE (fn) == COMPONENT_REF)
+ maybe_generic_this_capture (TREE_OPERAND (fn, 0),
+ TREE_OPERAND (fn, 1));
+ }
}
+
if (close_paren_loc != UNKNOWN_LOCATION)
postfix_expression.set_location (combined_loc);
@@ -28585,7 +28585,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))
@@ -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 >;