aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-02-22 00:50:12 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-02-22 00:50:12 -0500
commit7eae5d361e34f2286b133096e66bbc69ed191956 (patch)
tree7c1ad343bef80249818319fe50113d319bf97998
parentd2c81d20aa350ddbdfbcbd046d6695189f11d532 (diff)
downloadgcc-7eae5d361e34f2286b133096e66bbc69ed191956.zip
gcc-7eae5d361e34f2286b133096e66bbc69ed191956.tar.gz
gcc-7eae5d361e34f2286b133096e66bbc69ed191956.tar.bz2
re PR c++/58170 ([c++11] Crash when aliasing a template class that is a member of its template base class.)
PR c++/58170 * parser.c (cp_parser_type_name): Always check dependency. (cp_parser_type_specifier_seq): Call cp_parser_parse_and_diagnose_invalid_type_name. From-SVN: r208040
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/parser.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C33
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/error8.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/override4.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/underlying_type1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/crash48.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/error49.C2
8 files changed, 57 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 53f6c21..1b204dc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2014-02-21 Jason Merrill <jason@redhat.com>
+ PR c++/58170
+ * parser.c (cp_parser_type_name): Always check dependency.
+ (cp_parser_type_specifier_seq): Call
+ cp_parser_parse_and_diagnose_invalid_type_name.
+
PR c++/60108
* semantics.c (expand_or_defer_fn_1): Check DECL_DEFAULTED_FN.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 47a67c4..1e98032 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14763,7 +14763,7 @@ cp_parser_type_name (cp_parser* parser)
instantiation of an alias template... */
type_decl = cp_parser_template_id (parser,
/*template_keyword_p=*/false,
- /*check_dependency_p=*/false,
+ /*check_dependency_p=*/true,
none_type,
/*is_declaration=*/false);
/* Note that this must be an instantiation of an alias template
@@ -18083,7 +18083,16 @@ cp_parser_type_specifier_seq (cp_parser* parser,
type-specifier-seq at all. */
if (!seen_type_specifier)
{
- cp_parser_error (parser, "expected type-specifier");
+ /* Set in_declarator_p to avoid skipping to the semicolon. */
+ int in_decl = parser->in_declarator_p;
+ parser->in_declarator_p = true;
+
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+ || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
+ cp_parser_error (parser, "expected type-specifier");
+
+ parser->in_declarator_p = in_decl;
+
type_specifier_seq->type = error_mark_node;
return;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
new file mode 100644
index 0000000..f8bff78
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
@@ -0,0 +1,33 @@
+// PR c++/58170
+// { dg-require-effective-target c++11 }
+// { dg-prune-output "not declared" }
+// { dg-prune-output "expected" }
+
+template <typename T, typename U>
+struct base {
+ template <typename V>
+ struct derived;
+};
+
+template <typename T, typename U>
+template <typename V>
+struct base<T, U>::derived : public base<T, V> {
+};
+
+// This (wrong?) alias declaration provokes the crash.
+template <typename T, typename U, typename V>
+using alias = base<T, U>::derived<V>; // { dg-error "template|typename" }
+
+// This one works:
+// template <typename T, typename U, typename V>
+// using alias = typename base<T, U>::template derived<V>;
+
+template <typename T>
+void f() {
+ alias<T, bool, char> m{};
+ (void) m;
+}
+
+int main() {
+ f<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/error8.C b/gcc/testsuite/g++.dg/cpp0x/error8.C
index cc4f877..a992077 100644
--- a/gcc/testsuite/g++.dg/cpp0x/error8.C
+++ b/gcc/testsuite/g++.dg/cpp0x/error8.C
@@ -3,5 +3,5 @@
struct A
{
- int* p = new foo; // { dg-error "16:expected type-specifier" }
+ int* p = new foo; // { dg-error "16:foo. does not name a type" }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/override4.C b/gcc/testsuite/g++.dg/cpp0x/override4.C
index aec5c2c..695f9a3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/override4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/override4.C
@@ -16,12 +16,12 @@ struct B2
struct B3
{
- virtual auto f() -> final void; // { dg-error "expected type-specifier" }
+ virtual auto f() -> final void; // { dg-error "type" }
};
struct B4
{
- virtual auto f() -> final void {} // { dg-error "expected type-specifier" }
+ virtual auto f() -> final void {} // { dg-error "type" }
};
struct D : B
@@ -36,10 +36,10 @@ struct D2 : B
struct D3 : B
{
- virtual auto g() -> override void; // { dg-error "expected type-specifier" }
+ virtual auto g() -> override void; // { dg-error "type" }
};
struct D4 : B
{
- virtual auto g() -> override void {} // { dg-error "expected type-specifier" }
+ virtual auto g() -> override void {} // { dg-error "type" }
};
diff --git a/gcc/testsuite/g++.dg/ext/underlying_type1.C b/gcc/testsuite/g++.dg/ext/underlying_type1.C
index a8f68d3..999cd9f 100644
--- a/gcc/testsuite/g++.dg/ext/underlying_type1.C
+++ b/gcc/testsuite/g++.dg/ext/underlying_type1.C
@@ -8,7 +8,7 @@ template<typename T>
{ typedef __underlying_type(T) type; }; // { dg-error "not an enumeration" }
__underlying_type(int) i1; // { dg-error "not an enumeration|invalid" }
-__underlying_type(A) i2; // { dg-error "expected" }
+__underlying_type(A) i2; // { dg-error "expected|type" }
__underlying_type(B) i3; // { dg-error "not an enumeration|invalid" }
__underlying_type(U) i4; // { dg-error "not an enumeration|invalid" }
diff --git a/gcc/testsuite/g++.dg/parse/crash48.C b/gcc/testsuite/g++.dg/parse/crash48.C
index 4541548..020ddf0 100644
--- a/gcc/testsuite/g++.dg/parse/crash48.C
+++ b/gcc/testsuite/g++.dg/parse/crash48.C
@@ -5,5 +5,5 @@ void
foo (bool b)
{
if (b)
- try { throw 0; } catch (X) { } // { dg-error "expected type-specifier before" }
+ try { throw 0; } catch (X) { } // { dg-error "type" }
}
diff --git a/gcc/testsuite/g++.dg/parse/error49.C b/gcc/testsuite/g++.dg/parse/error49.C
index d5ec0c8..9d392af 100644
--- a/gcc/testsuite/g++.dg/parse/error49.C
+++ b/gcc/testsuite/g++.dg/parse/error49.C
@@ -2,5 +2,5 @@
int main()
{
- int* p = new foo; // { dg-error "16:expected type-specifier" }
+ int* p = new foo; // { dg-error "16:type" }
}