c++: Immediately deduce auto member [PR94926].

In r9-297 I was trying to be more flexible and treat static data members of
class templates more like variable templates, where the type need not be
determined until the variable is instantiated, but I suppose that in a class
the types of all the non-template members need to be determined at the time
of class instantiation.

gcc/cp/ChangeLog:

	PR c++/94926
	* decl.c (cp_finish_decl): Revert r9-297 change.
	(check_static_variable_definition): Likewise.
	* constexpr.c (ensure_literal_type_for_constexpr_object): Likewise.
	* pt.c (instantiate_decl): Return early on type error.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp1z/pr86648.C: Expect error.
	* g++.dg/cpp1z/static2.C: Expect error.
	* g++.dg/cpp0x/nsdmi16.C: New test.
This commit is contained in:
Jason Merrill 2020-05-28 00:35:56 -04:00
parent c83027f32d
commit 7b599b9f9a
6 changed files with 29 additions and 12 deletions

View File

@ -96,8 +96,6 @@ ensure_literal_type_for_constexpr_object (tree decl)
if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
/* Don't complain here, we'll complain about incompleteness
when we try to initialize the variable. */;
else if (type_uses_auto (type))
/* We don't know the actual type yet. */;
else if (!literal_type_p (type))
{
if (DECL_DECLARED_CONSTEXPR_P (decl))

View File

@ -7467,18 +7467,24 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
&& (DECL_INITIAL (decl) || init))
DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
/* Do auto deduction unless decl is a function or an uninstantiated
template specialization. */
if (TREE_CODE (decl) != FUNCTION_DECL
&& !(init == NULL_TREE
&& DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INSTANTIATION (decl)
&& !DECL_TEMPLATE_INSTANTIATED (decl))
&& (auto_node = type_uses_auto (type)))
{
tree d_init;
if (init == NULL_TREE)
gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (auto_node));
{
if (DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INSTANTIATION (decl)
&& !DECL_TEMPLATE_INSTANTIATED (decl))
{
/* init is null because we're deferring instantiating the
initializer until we need it. Well, we need it now. */
instantiate_decl (decl, /*defer_ok*/true, /*expl*/false);
return;
}
gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (auto_node));
}
d_init = init;
if (d_init)
{
@ -10171,7 +10177,6 @@ check_static_variable_definition (tree decl, tree type)
in check_initializer. Similarly for inline static data members. */
else if (DECL_P (decl)
&& (DECL_DECLARED_CONSTEXPR_P (decl)
|| undeduced_auto_decl (decl)
|| DECL_VAR_DECLARED_INLINE_P (decl)))
;
else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))

View File

@ -25293,6 +25293,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
d = DECL_CLONED_FUNCTION (d);
if (DECL_TEMPLATE_INSTANTIATED (d)
|| TREE_TYPE (d) == error_mark_node
|| (TREE_CODE (d) == FUNCTION_DECL
&& DECL_DEFAULTED_FN (d) && DECL_INITIAL (d))
|| DECL_TEMPLATE_SPECIALIZATION (d))

View File

@ -0,0 +1,11 @@
// PR c++/94926
// { dg-do compile { target c++11 } }
template<typename>
struct A {
static auto self_reference = A{}; // { dg-error "incomplete" }
};
int main() {
A<void>{};
}

View File

@ -1,5 +1,7 @@
// { dg-do compile { target c++17 } }
template <typename> class A;
template <class T> struct B { static A a{T::a}; };
template <class T> struct B {
static A a{T::a}; // { dg-error "int" }
};
void foo () { B<int> a; }

View File

@ -3,7 +3,7 @@
template <class T>
struct A
{
static constexpr auto x = T::x;
static constexpr auto x = T::x; // { dg-error "incomplete" }
};
struct B;