diff options
author | Jason Merrill <jason@redhat.com> | 2014-02-22 00:50:12 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-02-22 00:50:12 -0500 |
commit | 7eae5d361e34f2286b133096e66bbc69ed191956 (patch) | |
tree | 7c1ad343bef80249818319fe50113d319bf97998 | |
parent | d2c81d20aa350ddbdfbcbd046d6695189f11d532 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/error8.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/override4.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/underlying_type1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/crash48.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/error49.C | 2 |
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" } } |