aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-08-30 17:27:36 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-08-30 17:27:36 -0400
commitd9cdfea55f31e461e54db7039fbc2281824ef527 (patch)
tree2850b461ca153992dde9c8f08603f7d02461e9b3 /gcc
parent90677b8d915a4abc6366d38c0470c7cf0438e18c (diff)
downloadgcc-d9cdfea55f31e461e54db7039fbc2281824ef527.zip
gcc-d9cdfea55f31e461e54db7039fbc2281824ef527.tar.gz
gcc-d9cdfea55f31e461e54db7039fbc2281824ef527.tar.bz2
re PR c++/50084 ([C++0x] ICE: decltype + remove_reference + new)
PR c++/50084 * cp-tree.h (cp_decl_specifier_seq): Rename user_defined_type_p to type_definition_p. * parser.c (cp_parser_set_decl_spec_type): Likewise. * decl.c (grokdeclarator): Check it. From-SVN: r178340
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c1
-rw-r--r--gcc/cp/parser.c29
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype33.C18
6 files changed, 44 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2a919ac..96ac237 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2011-08-30 Jason Merrill <jason@redhat.com>
+ PR c++/50084
+ * cp-tree.h (cp_decl_specifier_seq): Rename user_defined_type_p
+ to type_definition_p.
+ * parser.c (cp_parser_set_decl_spec_type): Likewise.
+ * decl.c (grokdeclarator): Check it.
+
PR c++/50089
* semantics.c (finish_id_expression): Use
current_nonlambda_class_type for qualified-ids.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d125642..d18599b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4551,8 +4551,8 @@ typedef struct cp_decl_specifier_seq {
/* The storage class specified -- or sc_none if no storage class was
explicitly specified. */
cp_storage_class storage_class;
- /* True iff TYPE_SPEC indicates a user-defined type. */
- BOOL_BITFIELD user_defined_type_p : 1;
+ /* True iff TYPE_SPEC defines a class or enum. */
+ BOOL_BITFIELD type_definition_p : 1;
/* True iff multiple types were (erroneously) specified for this
decl-specifier-seq. */
BOOL_BITFIELD multiple_types_p : 1;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9090b11..39a0b0e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9643,6 +9643,7 @@ grokdeclarator (const cp_declarator *declarator,
&& TYPE_NAME (type)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& TYPE_ANONYMOUS_P (type)
+ && declspecs->type_definition_p
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
{
tree t;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c862a7d..7d766d13 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12577,7 +12577,7 @@ cp_parser_type_specifier (cp_parser* parser,
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/true);
return type_spec;
}
else
@@ -12606,7 +12606,7 @@ cp_parser_type_specifier (cp_parser* parser,
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/true);
return type_spec;
}
@@ -12628,7 +12628,7 @@ cp_parser_type_specifier (cp_parser* parser,
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/false);
return type_spec;
case RID_CONST:
@@ -12821,7 +12821,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/false);
return type;
@@ -12831,7 +12831,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/false);
return type;
@@ -12848,7 +12848,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token->location,
- /*user_defined_p=*/true);
+ /*type_definition_p=*/false);
cp_lexer_consume_token (parser->lexer);
return type;
}
@@ -12865,7 +12865,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
cp_parser_set_decl_spec_type (decl_specs,
type,
token->location,
- /*user_defined=*/false);
+ /*type_definition_p=*/false);
if (decl_specs)
decl_specs->any_specifiers_p = true;
@@ -12940,7 +12940,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (type && decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token->location,
- /*user_defined=*/true);
+ /*type_definition_p=*/false);
}
/* If we didn't get a type-name, issue an error message. */
@@ -21004,15 +21004,14 @@ cp_parser_set_storage_class (cp_parser *parser,
decl_specs->conflicting_specifiers_p = true;
}
-/* Update the DECL_SPECS to reflect the TYPE_SPEC. If USER_DEFINED_P
- is true, the type is a user-defined type; otherwise it is a
- built-in type specified by a keyword. */
+/* Update the DECL_SPECS to reflect the TYPE_SPEC. If TYPE_DEFINITION_P
+ is true, the type is a class or enum definition. */
static void
cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
tree type_spec,
location_t location,
- bool user_defined_p)
+ bool type_definition_p)
{
decl_specs->any_specifiers_p = true;
@@ -21022,7 +21021,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
declarations so that G++ can work with system headers that are not
C++-safe. */
if (decl_specs->specs[(int) ds_typedef]
- && !user_defined_p
+ && !type_definition_p
&& (type_spec == boolean_type_node
|| type_spec == char16_type_node
|| type_spec == char32_type_node
@@ -21037,7 +21036,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
if (!decl_specs->type)
{
decl_specs->type = type_spec;
- decl_specs->user_defined_type_p = false;
+ decl_specs->type_definition_p = false;
decl_specs->type_location = location;
}
}
@@ -21046,7 +21045,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
else
{
decl_specs->type = type_spec;
- decl_specs->user_defined_type_p = user_defined_p;
+ decl_specs->type_definition_p = type_definition_p;
decl_specs->redefined_builtin_type = NULL_TREE;
decl_specs->type_location = location;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cfc0a3f..9ae62ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2011-08-30 Jason Merrill <jason@redhat.com>
+ PR c++/50084
+ * g++.dg/cpp0x/decltype33.C: New.
+
PR c++/50089
* g++.dg/cpp0x/lambda/lambda-qualified.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype33.C b/gcc/testsuite/g++.dg/cpp0x/decltype33.C
new file mode 100644
index 0000000..d022d16
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype33.C
@@ -0,0 +1,18 @@
+// PR c++/50084
+// { dg-options "-std=c++0x -fno-inline" }
+
+template<typename> struct remove_reference;
+template<typename T> struct remove_reference<T&> { typedef T type; };
+
+template <class T> void f(T) { }
+
+void g()
+{
+ struct { } * v = 0;
+
+ typedef remove_reference<decltype(*v)>::type at;
+
+ // The typedef should't assign the name "at" to the struct.
+ // { dg-final { scan-assembler "_Z1fIZ1gvEUt_EvT_" } }
+ f(at());
+}