From 65bddf289ea2e8b9f7de201af6c2ad322a904d7e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 14 Apr 2016 16:14:49 -0400 Subject: [PATCH] re PR c++/70622 (auto specifier don't deduce value type and its pointer type within single declaration.) PR c++/70622 * parser.c (cp_parser_init_declarator): Add auto_result parm. (cp_parser_simple_declaration): Pass it. (strip_declarator_types): New. From-SVN: r234991 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/parser.c | 56 +++++++++++++++++++++++++++++-------- gcc/testsuite/g++.dg/cpp0x/auto47.C | 7 +++++ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto47.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 01f13b7..6384ab8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2016-04-14 Jason Merrill + PR c++/70622 + * parser.c (cp_parser_init_declarator): Add auto_result parm. + (cp_parser_simple_declaration): Pass it. + (strip_declarator_types): New. + PR c++/70543 * pt.c (value_dependent_expression_p) [VAR_DECL]: A type-dependent initializer also makes the variable value-dependent. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 00e211e..cba2d65 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2193,7 +2193,7 @@ static tree cp_parser_decltype static tree cp_parser_init_declarator (cp_parser *, cp_decl_specifier_seq *, vec *, - bool, bool, int, bool *, tree *, location_t *); + bool, bool, int, bool *, tree *, location_t *, tree *); static cp_declarator *cp_parser_declarator (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool); static cp_declarator *cp_parser_direct_declarator @@ -12337,10 +12337,9 @@ cp_parser_simple_declaration (cp_parser* parser, && !cp_parser_error_occurred (parser)) cp_parser_commit_to_tentative_parse (parser); - tree last_type, auto_node; + tree last_type; last_type = NULL_TREE; - auto_node = type_uses_auto (decl_specifiers.type); /* Keep going until we hit the `;' at the end of the simple declaration. */ @@ -12351,6 +12350,7 @@ cp_parser_simple_declaration (cp_parser* parser, cp_token *token; bool function_definition_p; tree decl; + tree auto_result = NULL_TREE; if (saw_declarator) { @@ -12376,7 +12376,8 @@ cp_parser_simple_declaration (cp_parser* parser, declares_class_or_enum, &function_definition_p, maybe_range_for_decl, - &init_loc); + &init_loc, + &auto_result); /* If an error occurred while parsing tentatively, exit quickly. (That usually happens when in the body of a function; each statement is treated as a declaration-statement until proven @@ -12384,10 +12385,10 @@ cp_parser_simple_declaration (cp_parser* parser, if (cp_parser_error_occurred (parser)) goto done; - if (auto_node) + if (auto_result) { - tree type = TREE_TYPE (decl); - if (last_type && !same_type_p (type, last_type)) + if (last_type && last_type != error_mark_node + && !same_type_p (auto_result, last_type)) { /* If the list of declarators contains more than one declarator, the type of each declared variable is determined as described @@ -12395,10 +12396,11 @@ cp_parser_simple_declaration (cp_parser* parser, the same in each deduction, the program is ill-formed. */ error_at (decl_specifiers.locations[ds_type_spec], "inconsistent deduction for %qT: %qT and then %qT", - decl_specifiers.type, last_type, type); - auto_node = NULL_TREE; + decl_specifiers.type, last_type, auto_result); + last_type = error_mark_node; } - last_type = type; + else + last_type = auto_result; } /* Handle function definitions specially. */ @@ -18221,6 +18223,31 @@ cp_parser_asm_definition (cp_parser* parser) } } +/* Given the type TYPE of a declaration with declarator DECLARATOR, return the + type that comes from the decl-specifier-seq. */ + +static tree +strip_declarator_types (tree type, cp_declarator *declarator) +{ + for (cp_declarator *d = declarator; d;) + switch (d->kind) + { + case cdk_id: + case cdk_error: + d = NULL; + break; + + default: + if (TYPE_PTRMEMFUNC_P (type)) + type = TYPE_PTRMEMFUNC_FN_TYPE (type); + type = TREE_TYPE (type); + d = d->declarator; + break; + } + + return type; +} + /* Declarators [gram.dcl.decl] */ /* Parse an init-declarator. @@ -18286,7 +18313,8 @@ cp_parser_init_declarator (cp_parser* parser, int declares_class_or_enum, bool* function_definition_p, tree* maybe_range_for_decl, - location_t* init_loc) + location_t* init_loc, + tree* auto_result) { cp_token *token = NULL, *asm_spec_start_token = NULL, *attributes_start_token = NULL; @@ -18677,6 +18705,10 @@ cp_parser_init_declarator (cp_parser* parser, finish_fully_implicit_template (parser, /*member_decl_opt=*/0); } + if (auto_result && is_initialized && decl_specifiers->type + && type_uses_auto (decl_specifiers->type)) + *auto_result = strip_declarator_types (TREE_TYPE (decl), declarator); + return decl; } @@ -25808,7 +25840,7 @@ cp_parser_single_declaration (cp_parser* parser, member_p, declares_class_or_enum, &function_definition_p, - NULL, NULL); + NULL, NULL, NULL); /* 7.1.1-1 [dcl.stc] diff --git a/gcc/testsuite/g++.dg/cpp0x/auto47.C b/gcc/testsuite/g++.dg/cpp0x/auto47.C new file mode 100644 index 0000000..0d80be6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto47.C @@ -0,0 +1,7 @@ +// PR c++/70622 +// { dg-do compile { target c++11 } } + +int main() +{ + auto x = 0, *y = &x; +} -- 2.7.4