diff options
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 21 | ||||
-rw-r--r-- | gcc/cp/pt.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/nsdmi16.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/pr86648.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/static2.C | 2 |
6 files changed, 29 insertions, 12 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4e441ac..4b1f92f 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 56571e3..b0de906 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4d9651a..90dafff 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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)) diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi16.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi16.C new file mode 100644 index 0000000..07bc198 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi16.C @@ -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>{}; +} diff --git a/gcc/testsuite/g++.dg/cpp1z/pr86648.C b/gcc/testsuite/g++.dg/cpp1z/pr86648.C index 20ee4c8..58c611c 100644 --- a/gcc/testsuite/g++.dg/cpp1z/pr86648.C +++ b/gcc/testsuite/g++.dg/cpp1z/pr86648.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp1z/static2.C b/gcc/testsuite/g++.dg/cpp1z/static2.C index 9462e03..5d93a0e7 100644 --- a/gcc/testsuite/g++.dg/cpp1z/static2.C +++ b/gcc/testsuite/g++.dg/cpp1z/static2.C @@ -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; |