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