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

Reply via email to