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
This commit is contained in:
parent
d2c81d20aa
commit
7eae5d361e
8 changed files with 57 additions and 10 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
33
gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/alias-decl-40.C
Normal file
|
@ -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>();
|
||||
}
|
|
@ -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" }
|
||||
};
|
||||
|
|
|
@ -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" }
|
||||
};
|
||||
|
|
|
@ -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" }
|
||||
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
int main()
|
||||
{
|
||||
int* p = new foo; // { dg-error "16:expected type-specifier" }
|
||||
int* p = new foo; // { dg-error "16:type" }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue