Commit 65bddf28 by Jason Merrill Committed by Jason Merrill

re PR c++/70622 (auto specifier don't deduce value type and its pointer type…

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
parent d25a101f
2016-04-14 Jason Merrill <jason@redhat.com> 2016-04-14 Jason Merrill <jason@redhat.com>
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 PR c++/70543
* pt.c (value_dependent_expression_p) [VAR_DECL]: A type-dependent * pt.c (value_dependent_expression_p) [VAR_DECL]: A type-dependent
initializer also makes the variable value-dependent. initializer also makes the variable value-dependent.
......
...@@ -2193,7 +2193,7 @@ static tree cp_parser_decltype ...@@ -2193,7 +2193,7 @@ static tree cp_parser_decltype
static tree cp_parser_init_declarator static tree cp_parser_init_declarator
(cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *, (cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *,
bool, bool, int, bool *, tree *, location_t *); bool, bool, int, bool *, tree *, location_t *, tree *);
static cp_declarator *cp_parser_declarator static cp_declarator *cp_parser_declarator
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool); (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool);
static cp_declarator *cp_parser_direct_declarator static cp_declarator *cp_parser_direct_declarator
...@@ -12337,10 +12337,9 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12337,10 +12337,9 @@ cp_parser_simple_declaration (cp_parser* parser,
&& !cp_parser_error_occurred (parser)) && !cp_parser_error_occurred (parser))
cp_parser_commit_to_tentative_parse (parser); cp_parser_commit_to_tentative_parse (parser);
tree last_type, auto_node; tree last_type;
last_type = NULL_TREE; last_type = NULL_TREE;
auto_node = type_uses_auto (decl_specifiers.type);
/* Keep going until we hit the `;' at the end of the simple /* Keep going until we hit the `;' at the end of the simple
declaration. */ declaration. */
...@@ -12351,6 +12350,7 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12351,6 +12350,7 @@ cp_parser_simple_declaration (cp_parser* parser,
cp_token *token; cp_token *token;
bool function_definition_p; bool function_definition_p;
tree decl; tree decl;
tree auto_result = NULL_TREE;
if (saw_declarator) if (saw_declarator)
{ {
...@@ -12376,7 +12376,8 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12376,7 +12376,8 @@ cp_parser_simple_declaration (cp_parser* parser,
declares_class_or_enum, declares_class_or_enum,
&function_definition_p, &function_definition_p,
maybe_range_for_decl, maybe_range_for_decl,
&init_loc); &init_loc,
&auto_result);
/* If an error occurred while parsing tentatively, exit quickly. /* If an error occurred while parsing tentatively, exit quickly.
(That usually happens when in the body of a function; each (That usually happens when in the body of a function; each
statement is treated as a declaration-statement until proven statement is treated as a declaration-statement until proven
...@@ -12384,10 +12385,10 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12384,10 +12385,10 @@ cp_parser_simple_declaration (cp_parser* parser,
if (cp_parser_error_occurred (parser)) if (cp_parser_error_occurred (parser))
goto done; goto done;
if (auto_node) if (auto_result)
{ {
tree type = TREE_TYPE (decl); if (last_type && last_type != error_mark_node
if (last_type && !same_type_p (type, last_type)) && !same_type_p (auto_result, last_type))
{ {
/* If the list of declarators contains more than one declarator, /* If the list of declarators contains more than one declarator,
the type of each declared variable is determined as described the type of each declared variable is determined as described
...@@ -12395,10 +12396,11 @@ cp_parser_simple_declaration (cp_parser* parser, ...@@ -12395,10 +12396,11 @@ cp_parser_simple_declaration (cp_parser* parser,
the same in each deduction, the program is ill-formed. */ the same in each deduction, the program is ill-formed. */
error_at (decl_specifiers.locations[ds_type_spec], error_at (decl_specifiers.locations[ds_type_spec],
"inconsistent deduction for %qT: %qT and then %qT", "inconsistent deduction for %qT: %qT and then %qT",
decl_specifiers.type, last_type, type); decl_specifiers.type, last_type, auto_result);
auto_node = NULL_TREE; last_type = error_mark_node;
} }
last_type = type; else
last_type = auto_result;
} }
/* Handle function definitions specially. */ /* Handle function definitions specially. */
...@@ -18221,6 +18223,31 @@ cp_parser_asm_definition (cp_parser* parser) ...@@ -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] */ /* Declarators [gram.dcl.decl] */
/* Parse an init-declarator. /* Parse an init-declarator.
...@@ -18286,7 +18313,8 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -18286,7 +18313,8 @@ cp_parser_init_declarator (cp_parser* parser,
int declares_class_or_enum, int declares_class_or_enum,
bool* function_definition_p, bool* function_definition_p,
tree* maybe_range_for_decl, 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, cp_token *token = NULL, *asm_spec_start_token = NULL,
*attributes_start_token = NULL; *attributes_start_token = NULL;
...@@ -18677,6 +18705,10 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -18677,6 +18705,10 @@ cp_parser_init_declarator (cp_parser* parser,
finish_fully_implicit_template (parser, /*member_decl_opt=*/0); 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; return decl;
} }
...@@ -25808,7 +25840,7 @@ cp_parser_single_declaration (cp_parser* parser, ...@@ -25808,7 +25840,7 @@ cp_parser_single_declaration (cp_parser* parser,
member_p, member_p,
declares_class_or_enum, declares_class_or_enum,
&function_definition_p, &function_definition_p,
NULL, NULL); NULL, NULL, NULL);
/* 7.1.1-1 [dcl.stc] /* 7.1.1-1 [dcl.stc]
// PR c++/70622
// { dg-do compile { target c++11 } }
int main()
{
auto x = 0, *y = &x;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment