aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl.c21
-rw-r--r--gcc/cp/parser.c3
-rw-r--r--gcc/testsuite/ChangeLog24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib27.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/struct1.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/elab1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/elab2.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/int-as-enum1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef3.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef4.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef5.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash26.C2
-rw-r--r--gcc/testsuite/g++.dg/template/nontype4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/line1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/elab1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/syntax4.C2
22 files changed, 97 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9d8f47b..6833fc3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2011-11-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51145
+ * decl.c (check_elaborated_type_specifier): Gracefully handle
+ error_mark_node. Accept bound template template parameters.
+ Update diagnostics for alias template specializations. Update
+ comment.
+ * parser.c (cp_parser_elaborated_type_specifier): Use
+ check_elaborated_type_specifier for simple-template-ids as well.
+
2011-11-22 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/51265
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b77963b..8406432 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11342,6 +11342,9 @@ check_elaborated_type_specifier (enum tag_types tag_code,
{
tree type;
+ if (decl == error_mark_node)
+ return error_mark_node;
+
/* In the case of:
struct S { struct S *p; };
@@ -11361,10 +11364,15 @@ check_elaborated_type_specifier (enum tag_types tag_code,
type, tag_name (tag_code));
return error_mark_node;
}
+ /* Accept bound template template parameters. */
+ else if (allow_template_p
+ && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ ;
/* [dcl.type.elab]
- If the identifier resolves to a typedef-name or a template
- type-parameter, the elaborated-type-specifier is ill-formed.
+ If the identifier resolves to a typedef-name or the
+ simple-template-id resolves to an alias template
+ specialization, the elaborated-type-specifier is ill-formed.
In other words, the only legitimate declaration to use in the
elaborated type specifier is the implicit typedef created when
@@ -11373,8 +11381,13 @@ check_elaborated_type_specifier (enum tag_types tag_code,
&& !DECL_SELF_REFERENCE_P (decl)
&& tag_code != typename_type)
{
- error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
- error ("%q+D has a previous declaration here", decl);
+ if (alias_template_specialization_p (type))
+ error ("using alias template specialization %qT after %qs",
+ type, tag_name (tag_code));
+ else
+ error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
+ inform (DECL_SOURCE_LOCATION (decl),
+ "%qD has a previous declaration here", decl);
return error_mark_node;
}
else if (TREE_CODE (type) != RECORD_TYPE
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d0adaa0..2fdd675 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13960,7 +13960,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
type = NULL_TREE;
else
- type = TREE_TYPE (decl);
+ type = check_elaborated_type_specifier (tag_type, decl,
+ /*allow_template_p=*/true);
}
if (!type)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 27365e4..9b3b01f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,27 @@
+2011-11-22 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/51145
+ * g++.dg/cpp0x/alias-decl-14.C: New test.
+ * g++.dg/cpp0x/alias-decl-2.C: Adjust for tests that were wrongly
+ passing before.
+ * g++.dg/cpp0x/alias-decl-10.C: Likewise and adjust for diagnostic
+ change.
+ * g++.dg/ext/attrib27.C: Adjust for diagnostic change.
+ * g++.dg/lookup/struct1.C: Likewise.
+ * g++.dg/parse/elab1.C: Likewise.
+ * g++.dg/parse/elab2.C: Likewise.
+ * g++.dg/parse/int-as-enum1.C: Likewise.
+ * g++.dg/parse/typedef1.C: Likewise.
+ * g++.dg/parse/typedef3.C: Likewise.
+ * g++.dg/parse/typedef4.C: Likewise.
+ * g++.dg/parse/typedef5.C: Likewise.
+ * g++.dg/template/crash26.C: Likewise.
+ * g++.dg/template/nontype4.C: Likewise.
+ * g++.old-deja/g++.benjamin/typedef01.C: Likewise.
+ * g++.old-deja/g++.brendan/line1.C: Likewise.
+ * g++.old-deja/g++.other/elab1.C: Likewise.
+ * g++.old-deja/g++.other/syntax4.C: Likewise.
+
2011-11-22 Tom de Vries <tom@codesourcery.com>
PR rtl-optimization/50764
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C
index 856e429..733e791 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-10.C
@@ -3,16 +3,24 @@
template <class T> using Ptr = T*;
Ptr<unsigned>; // { dg-error "does not declare anything" }
Ptr<char><int>; // { dg-error "not a template|does not declare anything" }
-template class Ptr<int>;//{ dg-error "explicit instantiation|non-class templ|does not decl|anything" }
+template class Ptr<int>;//{ dg-error "alias template specialization\[^\n\r\]*after\[^\n\r\]*class" }
template <class T> using Arg = T;
struct A {};
-template class Arg<A>;// { dg-error "explicit instantiation|non-class templ" }
+template class Arg<A>;// { dg-error "alias templ\[^\n\r\]*specialization\[^\n\r\]*Arg<A>\[^\n\r\]*after\[^\n\r\]*class" }
template <template <class> class TT, class T> using Instantiate = TT<T>;
template <class> struct Vector {};
-template class Instantiate<Vector, int>; // OK Vector<int> can be explicitely instantiated
+
+// The below is not OK, because of [dcl.type.elab]:
+//
+// If the identifier resolves to a typedef-name or the
+// simple-template-id resolves to an alias template
+// specialization, the elaborated-type-specifier is ill-formed.
+//
+template class Instantiate<Vector, int>;//{ dg-error "alias template specialization\[^\n\r\]*after\[^\n\r\]*class" }
template <class T> struct S {};
template<class T> using SFor = S<T>;
-template class SFor<int>; // OK, S<int> can be explicitely instantiated
+// Likewise, this is not OK.
+template class SFor<int>; //{ dg-error "alias template specialization\[^\n\r\]*after\[^\n\r\]*class" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C
new file mode 100644
index 0000000..1a99802
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-14.C
@@ -0,0 +1,14 @@
+// Origin: PR c++/51145
+// { dg-options "-std=c++0x" }
+
+struct A {};
+
+template<class>
+using X = A;
+
+struct X<int>* px; // { dg-error "using\[^\n\r\]*alias\[^\n\r\]*specialization\[^\n\r\]*X<int>\[^\n\r\]*after\[^\n\r\]*struct|invalid type in declaration before\[^\n\r\]*;" }
+
+template<int>
+using Y = A;
+
+struct Y<0>* py;// { dg-error "alias\[^\n\r\]*specialization\[^\n\r\]*Y<0>\[^\n\r\]*after\[^\n\r\]*struct|invalid type in declaration before\[^\n\r\]*;" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C
index 2e03dd8..6b5b42f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-2.C
@@ -6,7 +6,7 @@ template<class T> using AS0 = S0<T>;
template<template<class> class TT>
void f(TT<int>);
-template class AS0<char>;
+template class AS0<char>; // { dg-error "alias templ\[^\n\r\]*specialization\[^\n\r\]*after\[^\n\r\]*class" }
void
foo()
diff --git a/gcc/testsuite/g++.dg/ext/attrib27.C b/gcc/testsuite/g++.dg/ext/attrib27.C
index 4f629aa..b770c1c 100644
--- a/gcc/testsuite/g++.dg/ext/attrib27.C
+++ b/gcc/testsuite/g++.dg/ext/attrib27.C
@@ -1,5 +1,5 @@
//PR c++/29980
-struct A { typedef int X; }; // { dg-error "previous declaration" }
+struct A { typedef int X; }; // { dg-message "previous declaration" }
struct __attribute__((unused)) A::X; // { dg-error "typedef-name" }
diff --git a/gcc/testsuite/g++.dg/lookup/struct1.C b/gcc/testsuite/g++.dg/lookup/struct1.C
index f4b83ec..7c1e38c 100644
--- a/gcc/testsuite/g++.dg/lookup/struct1.C
+++ b/gcc/testsuite/g++.dg/lookup/struct1.C
@@ -2,10 +2,10 @@
// the definition of C.
struct A;
-typedef struct A B; // { dg-error "previous declaration" }
+typedef struct A B; // { dg-message "previous declaration" }
struct B; // { dg-error "using typedef-name" }
-typedef struct { int i; } C; // { dg-error "previous declaration" }
+typedef struct { int i; } C; // { dg-message "previous declaration" }
struct C; // { dg-error "using typedef-name" }
struct D;
diff --git a/gcc/testsuite/g++.dg/parse/elab1.C b/gcc/testsuite/g++.dg/parse/elab1.C
index 92fcd1c..8108e1d 100644
--- a/gcc/testsuite/g++.dg/parse/elab1.C
+++ b/gcc/testsuite/g++.dg/parse/elab1.C
@@ -1,6 +1,6 @@
namespace Name {
- typedef void *(*Function)( void *, int ); // { dg-error "previous declaration" }
+ typedef void *(*Function)( void *, int ); // { dg-message "previous declaration" }
struct Foo {
struct Function xyz[5]; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/parse/elab2.C b/gcc/testsuite/g++.dg/parse/elab2.C
index 6b42aed..bf59f1b 100644
--- a/gcc/testsuite/g++.dg/parse/elab2.C
+++ b/gcc/testsuite/g++.dg/parse/elab2.C
@@ -2,6 +2,6 @@ struct A {};
struct B
{
- typedef A T; // { dg-error "previous declaration" }
+ typedef A T; // { dg-message "previous declaration" }
friend struct T; // { dg-error "" }
};
diff --git a/gcc/testsuite/g++.dg/parse/int-as-enum1.C b/gcc/testsuite/g++.dg/parse/int-as-enum1.C
index 7c37eb0..c5ed261 100644
--- a/gcc/testsuite/g++.dg/parse/int-as-enum1.C
+++ b/gcc/testsuite/g++.dg/parse/int-as-enum1.C
@@ -2,5 +2,5 @@
// Origin: <wanderer@rsu.ru>
// { dg-do compile }
-typedef int A; // { dg-error "previous" }
+typedef int A; // { dg-message "previous" }
enum ::A {}; // { dg-error "typedef-name|expected unqualified-id" }
diff --git a/gcc/testsuite/g++.dg/parse/typedef1.C b/gcc/testsuite/g++.dg/parse/typedef1.C
index c4fbb95..4d6f5b4 100644
--- a/gcc/testsuite/g++.dg/parse/typedef1.C
+++ b/gcc/testsuite/g++.dg/parse/typedef1.C
@@ -1,3 +1,3 @@
// PR c++/6477
-typedef struct A_ *A; // { dg-error "previous declaration" }
+typedef struct A_ *A; // { dg-message "previous declaration" }
typedef struct A B; // { dg-error "typedef|invalid type" }
diff --git a/gcc/testsuite/g++.dg/parse/typedef3.C b/gcc/testsuite/g++.dg/parse/typedef3.C
index 6b4e531..3f6a7cb 100644
--- a/gcc/testsuite/g++.dg/parse/typedef3.C
+++ b/gcc/testsuite/g++.dg/parse/typedef3.C
@@ -2,6 +2,6 @@
// Origin: Travis J.I. Corcoran <tjic@permabit.com>
// { dg-do compile }
-struct A { typedef A* Ptr; }; // { dg-error "previous declaration" }
+struct A { typedef A* Ptr; }; // { dg-message "previous declaration" }
struct A::Ptr; // { dg-error "typedef|not declare anything" }
diff --git a/gcc/testsuite/g++.dg/parse/typedef4.C b/gcc/testsuite/g++.dg/parse/typedef4.C
index 8599fd1..d4cec7f 100644
--- a/gcc/testsuite/g++.dg/parse/typedef4.C
+++ b/gcc/testsuite/g++.dg/parse/typedef4.C
@@ -7,6 +7,6 @@
template<class T> class smart_ptr2 {
T* real_ptr;
public:
- typedef typename T::subT td; // { dg-error "previous declaration" }
+ typedef typename T::subT td; // { dg-message "previous declaration" }
friend class td; // { dg-error "typedef|not name a class" }
};
diff --git a/gcc/testsuite/g++.dg/parse/typedef5.C b/gcc/testsuite/g++.dg/parse/typedef5.C
index 7079f37..ecd1d51 100644
--- a/gcc/testsuite/g++.dg/parse/typedef5.C
+++ b/gcc/testsuite/g++.dg/parse/typedef5.C
@@ -1,6 +1,6 @@
namespace A
{
- typedef int T; // { dg-error "previous declaration" }
+ typedef int T; // { dg-message "previous declaration" }
}
class A::T x; // { dg-error "using typedef-name|invalid type" }
diff --git a/gcc/testsuite/g++.dg/template/crash26.C b/gcc/testsuite/g++.dg/template/crash26.C
index f1bc399..3be7ff9 100644
--- a/gcc/testsuite/g++.dg/template/crash26.C
+++ b/gcc/testsuite/g++.dg/template/crash26.C
@@ -4,5 +4,5 @@
// PR c++/18471: ICE redeclaration of typedef as class template
-typedef int X; // { dg-error "previous" }
+typedef int X; // { dg-message "previous" }
template<X> struct X {}; // { dg-error "typedef-name" }
diff --git a/gcc/testsuite/g++.dg/template/nontype4.C b/gcc/testsuite/g++.dg/template/nontype4.C
index ab39ed4..41e3e22 100644
--- a/gcc/testsuite/g++.dg/template/nontype4.C
+++ b/gcc/testsuite/g++.dg/template/nontype4.C
@@ -7,7 +7,7 @@
template <int> struct A
{
- typedef A<0> B; // { dg-error "previous declaration" }
+ typedef A<0> B; // { dg-message "previous declaration" }
template <B> struct B {}; // { dg-error "not a valid type|typedef" }
};
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
index 79a965b..d5ed39a 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
@@ -18,7 +18,7 @@ typedef I I;
//p3--cannot redefine to a different type in a given scope
class complex2 { /* ... */ };// { dg-error "" } .*
typedef int complex2;// { dg-error "" } .*
-typedef int complex3;// { dg-error "" } .*
+typedef int complex3;// { dg-message "" } .*
class complex3 { /* ... */ };// { dg-error "" } .*
@@ -37,7 +37,7 @@ struct S {
~S();
};
-typedef struct S T; // { dg-error "previous declaration" }
+typedef struct S T; // { dg-message "previous declaration" }
S a = T(); // OK
struct T * p; // { dg-error "" } using typedef after struct
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/line1.C b/gcc/testsuite/g++.old-deja/g++.brendan/line1.C
index b14ed8e..94130ec 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/line1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/line1.C
@@ -1,4 +1,4 @@
// { dg-do assemble }
// GROUPS passed error-messages
-typedef struct s S;// { dg-error "" } previous.*
+typedef struct s S;// { dg-message "" } previous.*
struct S { int member:1; }; // the lineno for this should be 2, not 0// { dg-error "" } conflicting types.*
diff --git a/gcc/testsuite/g++.old-deja/g++.other/elab1.C b/gcc/testsuite/g++.old-deja/g++.other/elab1.C
index 5588651..f09ff6f 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/elab1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/elab1.C
@@ -1,5 +1,5 @@
// { dg-do assemble }
-typedef struct {} S; // { dg-error "" } Previous declaration of S
+typedef struct {} S; // { dg-message "" } Previous declaration of S
S s1;
struct S* s2; // { dg-error "" } S is a typedef name
diff --git a/gcc/testsuite/g++.old-deja/g++.other/syntax4.C b/gcc/testsuite/g++.old-deja/g++.other/syntax4.C
index 7aed1f5..445c539 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/syntax4.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/syntax4.C
@@ -17,7 +17,7 @@ class X {
class Y {
public:
- typedef ::X W; // { dg-error "" } previous declaration
+ typedef ::X W; // { dg-message "" } previous declaration
class Z;
};