From: Paolo Carlini Date: Tue, 9 Oct 2018 21:16:09 +0000 (+0000) Subject: re PR c++/84423 ([concepts] ICE with invalid using declaration) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5abdb369eb2f38272bb8ee2ea0488194942c7cff;p=gcc.git re PR c++/84423 ([concepts] ICE with invalid using declaration) /cp 2018-10-09 Paolo Carlini PR c++/84423 * pt.c (convert_template_argument): Immediately return error_mark_node if the second argument is erroneous. * parser.c (cp_parser_type_id): Add location_t * parameter. (cp_parser_type_id_1): Likewise. (cp_parser_alias_declaration): Adjust cp_parser_type_id call, obtain the location of the type and save it. (cp_parser_template_type_arg): Adjust. (cp_parser_trailing_type_id): Likewise. * decl.c (grokdeclarator): Improve error message for 'auto' in alias declaration. /testsuite 2018-10-09 Paolo Carlini PR c++/84423 * g++.dg/concepts/pr84423-1.C: New. * g++.dg/concepts/pr84423-2.C: Likewise. * g++.dg/cpp0x/auto39.C: Test location too. * g++.dg/cpp0x/auto9.C: Likewise. * g++.dg/cpp1y/pr60384.C: Likewise. From-SVN: r264996 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9a0a5ea5d3f..975f866c0b7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2018-10-09 Paolo Carlini + + PR c++/84423 + * pt.c (convert_template_argument): Immediately return error_mark_node + if the second argument is erroneous. + * parser.c (cp_parser_type_id): Add location_t * parameter. + (cp_parser_type_id_1): Likewise. + (cp_parser_alias_declaration): Adjust cp_parser_type_id call, + obtain the location of the type and save it. + (cp_parser_template_type_arg): Adjust. + (cp_parser_trailing_type_id): Likewise. + * decl.c (grokdeclarator): Improve error message for 'auto' in + alias declaration. + 2018-10-08 Paolo Carlini PR c++/71128 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2d9d56ef6e1..5ebfaaf85e6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11879,6 +11879,7 @@ grokdeclarator (const cp_declarator *declarator, /* If this is declaring a typedef name, return a TYPE_DECL. */ if (typedef_p && decl_context != TYPENAME) { + bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias); tree decl; /* This declaration: @@ -11901,7 +11902,12 @@ grokdeclarator (const cp_declarator *declarator, if (type_uses_auto (type)) { - error ("typedef declared %"); + if (alias_p) + error_at (declspecs->locations[ds_type_spec], + "% not allowed in alias declaration"); + else + error_at (declspecs->locations[ds_type_spec], + "typedef declared %"); type = error_mark_node; } @@ -11961,7 +11967,7 @@ grokdeclarator (const cp_declarator *declarator, inlinep, friendp, raises != NULL_TREE, declspecs->locations); - if (decl_spec_seq_has_spec_p (declspecs, ds_alias)) + if (alias_p) /* Acknowledge that this was written: `using analias = atype;'. */ TYPE_DECL_ALIAS_P (decl) = 1; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 032108abfd3..5e83b20360a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2216,12 +2216,12 @@ static tree cp_parser_late_return_type_opt static tree cp_parser_declarator_id (cp_parser *, bool); static tree cp_parser_type_id - (cp_parser *); + (cp_parser *, location_t * = NULL); static tree cp_parser_template_type_arg (cp_parser *); static tree cp_parser_trailing_type_id (cp_parser *); static tree cp_parser_type_id_1 - (cp_parser *, bool, bool); + (cp_parser *, bool, bool, location_t *); static void cp_parser_type_specifier_seq (cp_parser *, bool, bool, cp_decl_specifier_seq *); static tree cp_parser_parameter_declaration_clause @@ -19034,7 +19034,7 @@ static tree cp_parser_alias_declaration (cp_parser* parser) { tree id, type, decl, pushed_scope = NULL_TREE, attributes; - location_t id_location; + location_t id_location, type_location; cp_declarator *declarator; cp_decl_specifier_seq decl_specs; bool member_p; @@ -19086,7 +19086,7 @@ cp_parser_alias_declaration (cp_parser* parser) G_("types may not be defined in alias template declarations"); } - type = cp_parser_type_id (parser); + type = cp_parser_type_id (parser, &type_location); /* Restore the error message if need be. */ if (parser->num_template_parameter_lists) @@ -19120,6 +19120,7 @@ cp_parser_alias_declaration (cp_parser* parser) set_and_check_decl_spec_loc (&decl_specs, ds_alias, using_token); + decl_specs.locations[ds_type_spec] = type_location; if (parser->num_template_parameter_lists && !cp_parser_check_template_parameters (parser, @@ -21110,7 +21111,7 @@ cp_parser_declarator_id (cp_parser* parser, bool optional_p) static tree cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg, - bool is_trailing_return) + bool is_trailing_return, location_t * type_location) { cp_decl_specifier_seq type_specifier_seq; cp_declarator *abstract_declarator; @@ -21119,6 +21120,9 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg, cp_parser_type_specifier_seq (parser, /*is_declaration=*/false, is_trailing_return, &type_specifier_seq); + if (type_location) + *type_location = type_specifier_seq.locations[ds_type_spec]; + if (is_template_arg && type_specifier_seq.type && TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM && CLASS_PLACEHOLDER_TEMPLATE (type_specifier_seq.type)) @@ -21184,9 +21188,9 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg, } static tree -cp_parser_type_id (cp_parser *parser) +cp_parser_type_id (cp_parser *parser, location_t * type_location) { - return cp_parser_type_id_1 (parser, false, false); + return cp_parser_type_id_1 (parser, false, false, type_location); } static tree @@ -21196,7 +21200,7 @@ cp_parser_template_type_arg (cp_parser *parser) const char *saved_message = parser->type_definition_forbidden_message; parser->type_definition_forbidden_message = G_("types may not be defined in template arguments"); - r = cp_parser_type_id_1 (parser, true, false); + r = cp_parser_type_id_1 (parser, true, false, NULL); parser->type_definition_forbidden_message = saved_message; if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r)) { @@ -21209,7 +21213,7 @@ cp_parser_template_type_arg (cp_parser *parser) static tree cp_parser_trailing_type_id (cp_parser *parser) { - return cp_parser_type_id_1 (parser, false, true); + return cp_parser_type_id_1 (parser, false, true, NULL); } /* Parse a type-specifier-seq. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aced6f2d721..f290cb32fc2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7776,7 +7776,7 @@ convert_template_argument (tree parm, tree val; int is_type, requires_type, is_tmpl_type, requires_tmpl_type; - if (parm == error_mark_node) + if (parm == error_mark_node || error_operand_p (arg)) return error_mark_node; /* Trivially convert placeholders. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1256e0faaa3..978ecdaa5ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2018-10-09 Paolo Carlini + + PR c++/84423 + * g++.dg/concepts/pr84423-1.C: New. + * g++.dg/concepts/pr84423-2.C: Likewise. + * g++.dg/cpp0x/auto39.C: Test location too. + * g++.dg/cpp0x/auto9.C: Likewise. + * g++.dg/cpp1y/pr60384.C: Likewise. + 2018-10-09 Paul A. Clarke * gcc.target/powerpc/sse3-check.h: New file. diff --git a/gcc/testsuite/g++.dg/concepts/pr84423-1.C b/gcc/testsuite/g++.dg/concepts/pr84423-1.C new file mode 100644 index 00000000000..9f772dc3c22 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr84423-1.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fconcepts" } + +template using A = auto; // { dg-error "30:.auto. not allowed in alias declaration" } + +template class> struct B {}; + +B b; diff --git a/gcc/testsuite/g++.dg/concepts/pr84423-2.C b/gcc/testsuite/g++.dg/concepts/pr84423-2.C new file mode 100644 index 00000000000..b4d00c31381 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr84423-2.C @@ -0,0 +1,18 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fconcepts" } + +using A = auto; // { dg-error "11:.auto. not allowed in alias declaration" } + +using A1 = const auto; // { dg-error "18:.auto. not allowed in alias declaration" } + +using A2 = volatile auto; // { dg-error "21:.auto. not allowed in alias declaration" } + +using A3 = const volatile auto; // { dg-error "27:.auto. not allowed in alias declaration" } + +typedef auto B; // { dg-error "9:typedef declared .auto." } + +typedef const auto B1; // { dg-error "15:typedef declared .auto." } + +typedef volatile auto B2; // { dg-error "18:typedef declared .auto." } + +typedef const volatile auto B3; // { dg-error "24:typedef declared .auto." } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto39.C b/gcc/testsuite/g++.dg/cpp0x/auto39.C index dfa1fb4e9e8..ef830806630 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto39.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto39.C @@ -1,6 +1,6 @@ // PR c++/58560 // { dg-do compile { target c++11 } } -typedef auto T; // { dg-error "typedef declared 'auto'" } +typedef auto T; // { dg-error "9:typedef declared 'auto'" } void foo() { T(); } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto9.C b/gcc/testsuite/g++.dg/cpp0x/auto9.C index 40b4ef2233e..8e49a01beb2 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto9.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto9.C @@ -120,4 +120,4 @@ void qq (auto); // { dg-error "auto" "" { target { ! concepts } } } void qr (auto*); // { dg-error "auto" "" { target { ! concepts } } } // PR c++/46145 -typedef auto autot; // { dg-error "auto" } +typedef auto autot; // { dg-error "9:typedef declared .auto." } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60384.C b/gcc/testsuite/g++.dg/cpp1y/pr60384.C index 44806cd69e6..a6d7debfb99 100644 --- a/gcc/testsuite/g++.dg/cpp1y/pr60384.C +++ b/gcc/testsuite/g++.dg/cpp1y/pr60384.C @@ -5,5 +5,5 @@ template int foo(); struct A { - typedef auto foo<>(); // { dg-error "typedef declared 'auto'" } + typedef auto foo<>(); // { dg-error "11:typedef declared 'auto'" } };