aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/constexpr.c2
-rw-r--r--gcc/cp/decl.c21
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi16.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/pr86648.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/static2.C2
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;