Commit 7eae5d36 by Jason Merrill Committed by Jason Merrill

re PR c++/58170 ([c++11] Crash when aliasing a template class that is a member…

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
parent d2c81d20
2014-02-21 Jason Merrill <jason@redhat.com> 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 PR c++/60108
* semantics.c (expand_or_defer_fn_1): Check DECL_DEFAULTED_FN. * semantics.c (expand_or_defer_fn_1): Check DECL_DEFAULTED_FN.
......
...@@ -14763,7 +14763,7 @@ cp_parser_type_name (cp_parser* parser) ...@@ -14763,7 +14763,7 @@ cp_parser_type_name (cp_parser* parser)
instantiation of an alias template... */ instantiation of an alias template... */
type_decl = cp_parser_template_id (parser, type_decl = cp_parser_template_id (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/false, /*check_dependency_p=*/true,
none_type, none_type,
/*is_declaration=*/false); /*is_declaration=*/false);
/* Note that this must be an instantiation of an alias template /* Note that this must be an instantiation of an alias template
...@@ -18083,7 +18083,16 @@ cp_parser_type_specifier_seq (cp_parser* parser, ...@@ -18083,7 +18083,16 @@ cp_parser_type_specifier_seq (cp_parser* parser,
type-specifier-seq at all. */ type-specifier-seq at all. */
if (!seen_type_specifier) 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; type_specifier_seq->type = error_mark_node;
return; return;
} }
......
// 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>();
}
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
struct A 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" }
}; };
...@@ -16,12 +16,12 @@ struct B2 ...@@ -16,12 +16,12 @@ struct B2
struct B3 struct B3
{ {
virtual auto f() -> final void; // { dg-error "expected type-specifier" } virtual auto f() -> final void; // { dg-error "type" }
}; };
struct B4 struct B4
{ {
virtual auto f() -> final void {} // { dg-error "expected type-specifier" } virtual auto f() -> final void {} // { dg-error "type" }
}; };
struct D : B struct D : B
...@@ -36,10 +36,10 @@ struct D2 : B ...@@ -36,10 +36,10 @@ struct D2 : B
struct D3 : 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 struct D4 : B
{ {
virtual auto g() -> override void {} // { dg-error "expected type-specifier" } virtual auto g() -> override void {} // { dg-error "type" }
}; };
...@@ -8,7 +8,7 @@ template<typename T> ...@@ -8,7 +8,7 @@ template<typename T>
{ typedef __underlying_type(T) type; }; // { dg-error "not an enumeration" } { typedef __underlying_type(T) type; }; // { dg-error "not an enumeration" }
__underlying_type(int) i1; // { dg-error "not an enumeration|invalid" } __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(B) i3; // { dg-error "not an enumeration|invalid" }
__underlying_type(U) i4; // { dg-error "not an enumeration|invalid" } __underlying_type(U) i4; // { dg-error "not an enumeration|invalid" }
......
...@@ -5,5 +5,5 @@ void ...@@ -5,5 +5,5 @@ void
foo (bool b) foo (bool b)
{ {
if (b) if (b)
try { throw 0; } catch (X) { } // { dg-error "expected type-specifier before" } try { throw 0; } catch (X) { } // { dg-error "type" }
} }
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
int main() int main()
{ {
int* p = new foo; // { dg-error "16:expected type-specifier" } int* p = new foo; // { dg-error "16:type" }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment