mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
d25a101fe7
commit
65bddf289e
|
|
@ -1,5 +1,10 @@
|
||||||
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
|
||||||
|
|
||||||
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,
|
||||||
&& !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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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,
|
||||||
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,
|
||||||
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,
|
||||||
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]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PR c++/70622
|
||||||
|
// { dg-do compile { target c++11 } }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
auto x = 0, *y = &x;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue