aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-04-14 16:14:49 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-04-14 16:14:49 -0400
commit65bddf289ea2e8b9f7de201af6c2ad322a904d7e (patch)
treee4bf4b8c4a8144e120461ac5c0a4b613ad2ebe8c /gcc
parentd25a101fe78834db307bb868056b0ff5152e0eb3 (diff)
downloadgcc-65bddf289ea2e8b9f7de201af6c2ad322a904d7e.zip
gcc-65bddf289ea2e8b9f7de201af6c2ad322a904d7e.tar.gz
gcc-65bddf289ea2e8b9f7de201af6c2ad322a904d7e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/parser.c56
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto47.C7
3 files changed, 56 insertions, 12 deletions
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 <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
* 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<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
(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;
+}