From: Jakub Jelinek Date: Wed, 7 Feb 2018 22:30:51 +0000 (+0100) Subject: re PR c++/84082 (ICE with broken template function definition) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8f1f526b9a5b0bd27422b3392f1930f107809675;p=gcc.git re PR c++/84082 (ICE with broken template function definition) PR c++/84082 * parser.c (cp_parser_dot_deref_incomplete): New function. (cp_parser_postfix_dot_deref_expression): Use it. * g++.dg/template/incomplete11.C: New test. * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too. From-SVN: r257466 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 42c3cbf4b3c..0b710e9140f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-07 Jakub Jelinek + + PR c++/84082 + * parser.c (cp_parser_dot_deref_incomplete): New function. + (cp_parser_postfix_dot_deref_expression): Use it. + 2018-02-07 David Malcolm PR c++/81610 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 222db0cad3f..ac5277db9ad 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7387,6 +7387,60 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, return postfix_expression; } +/* A subroutine of cp_parser_postfix_dot_deref_expression. Handle dot + dereference of incomplete type, returns true if error_mark_node should + be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION + and *DEPENDENT_P. */ + +bool +cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression, + bool *dependent_p) +{ + /* In a template, be permissive by treating an object expression + of incomplete type as dependent (after a pedwarn). */ + diagnostic_t kind = (processing_template_decl + && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR); + + switch (TREE_CODE (*postfix_expression)) + { + case CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case STATIC_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case IMPLICIT_CONV_EXPR: + case VIEW_CONVERT_EXPR: + case NON_LVALUE_EXPR: + kind = DK_ERROR; + break; + case OVERLOAD: + /* Don't emit any diagnostic for OVERLOADs. */ + kind = DK_IGNORED; + break; + default: + /* Avoid clobbering e.g. DECLs. */ + if (!EXPR_P (*postfix_expression)) + kind = DK_ERROR; + break; + } + + if (kind == DK_IGNORED) + return false; + + location_t exploc = location_of (*postfix_expression); + cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind); + if (!MAYBE_CLASS_TYPE_P (*scope)) + return true; + if (kind == DK_ERROR) + *scope = *postfix_expression = error_mark_node; + else if (processing_template_decl) + { + *dependent_p = true; + *scope = TREE_TYPE (*postfix_expression) = NULL_TREE; + } + return false; +} + /* A subroutine of cp_parser_postfix_expression that also gets hijacked by cp_parser_builtin_offsetof. We're looking for @@ -7451,26 +7505,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, { scope = complete_type (scope); if (!COMPLETE_TYPE_P (scope) - /* Avoid clobbering e.g. OVERLOADs or DECLs. */ - && EXPR_P (postfix_expression)) - { - /* In a template, be permissive by treating an object expression - of incomplete type as dependent (after a pedwarn). */ - diagnostic_t kind = (processing_template_decl - && MAYBE_CLASS_TYPE_P (scope) - ? DK_PEDWARN - : DK_ERROR); - cxx_incomplete_type_diagnostic - (location_of (postfix_expression), - postfix_expression, scope, kind); - if (!MAYBE_CLASS_TYPE_P (scope)) - return error_mark_node; - if (processing_template_decl) - { - dependent_p = true; - scope = TREE_TYPE (postfix_expression) = NULL_TREE; - } - } + && cp_parser_dot_deref_incomplete (&scope, &postfix_expression, + &dependent_p)) + return error_mark_node; } if (!dependent_p) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d82e4e2d74..6e266415765 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-07 Jakub Jelinek + + PR c++/84082 + * g++.dg/template/incomplete11.C: New test. + * g++.dg/parse/crash67.C: Expect an incomplete type diagnostics too. + 2018-02-07 Steven G. Kargl PR fortran/82994 diff --git a/gcc/testsuite/g++.dg/parse/crash67.C b/gcc/testsuite/g++.dg/parse/crash67.C index 0befc9e2457..dee0fc72212 100644 --- a/gcc/testsuite/g++.dg/parse/crash67.C +++ b/gcc/testsuite/g++.dg/parse/crash67.C @@ -3,4 +3,4 @@ class x0; template x2() { // { dg-error "declared|type" } -x0 x3 = x3. // { dg-error "expected" } +x0 x3 = x3. // { dg-error "expected|incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/incomplete11.C b/gcc/testsuite/g++.dg/template/incomplete11.C new file mode 100644 index 00000000000..38c92e3d337 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete11.C @@ -0,0 +1,10 @@ +// PR c++/84082 +// { dg-do compile } +// { dg-options "" } + +struct A; + +template void foo() +{ + static int a[A().operator=(A())]; // { dg-error "invalid use of incomplete type 'struct A'" } +}