c++: non-static memfn call dependence cleanup

Message ID 20230926142112.1779722-1-ppalka@redhat.com
State Unresolved
Headers
Series c++: non-static memfn call dependence cleanup |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Patrick Palka Sept. 26, 2023, 2:21 p.m. UTC
  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

Krishna Narayanan Sept. 26, 2023, 3:07 p.m. UTC | #1
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
>
>
  

Patch

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 >;