c++: ICE with bogus late return type [PR99803]
Here we ICE when compiling this code in C++20, because we're trying to slam a 'typename' after the ->. The cp_parser_template_id call just before the spot I'm changing parsed A::template A<int> as a BASELINK that contains a constructor, but make_typename_type crashes on that. This patch makes make_typename_type more robust instead of checking for is_overloaded_fn prior calling it. gcc/cp/ChangeLog: PR c++/99803 * decl.c (make_typename_type): Give an error and return when name is is_overloaded_fn. * parser.c (cp_parser_class_name): Don't check is_overloaded_fn before calling make_typename_type. gcc/testsuite/ChangeLog: PR c++/99803 * g++.dg/cpp2a/typename14.C: Don't expect particular error messages. * g++.dg/cpp2a/typename19.C: New test.
This commit is contained in:
parent
eb8c931e0d
commit
70f2bff43a
|
@ -4055,6 +4055,12 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
|
||||||
error ("%qD used without template arguments", name);
|
error ("%qD used without template arguments", name);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
else if (is_overloaded_fn (name))
|
||||||
|
{
|
||||||
|
if (complain & tf_error)
|
||||||
|
error ("%qD is a function, not a type", name);
|
||||||
|
return error_mark_node;
|
||||||
|
}
|
||||||
gcc_assert (identifier_p (name));
|
gcc_assert (identifier_p (name));
|
||||||
gcc_assert (TYPE_P (context));
|
gcc_assert (TYPE_P (context));
|
||||||
|
|
||||||
|
|
|
@ -24730,9 +24730,7 @@ cp_parser_class_name (cp_parser *parser,
|
||||||
decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
|
decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
|
||||||
|
|
||||||
/* If this is a typename, create a TYPENAME_TYPE. */
|
/* If this is a typename, create a TYPENAME_TYPE. */
|
||||||
if (typename_p
|
if (typename_p && decl != error_mark_node)
|
||||||
&& decl != error_mark_node
|
|
||||||
&& !is_overloaded_fn (decl))
|
|
||||||
{
|
{
|
||||||
decl = make_typename_type (scope, decl, typename_type,
|
decl = make_typename_type (scope, decl, typename_type,
|
||||||
/*complain=*/tf_error);
|
/*complain=*/tf_error);
|
||||||
|
|
|
@ -8,7 +8,7 @@ template<typename> struct A
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
A<T>::A<U> () // { dg-error "partial specialization" }
|
A<T>::A<U> () // { dg-error "" }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ template<typename> struct B
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
B<T>::foo<int>(int) // { dg-error "partial specialization|declaration" }
|
B<T>::foo<int>(int) // { dg-error "" }
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PR c++/99803
|
||||||
|
// { dg-do compile { target c++20 } }
|
||||||
|
|
||||||
|
struct A { template<typename T> A(T); };
|
||||||
|
auto A(unsigned) -> A::template A<int>; // { dg-error "not a type" }
|
Loading…
Reference in New Issue