decl.c (cp_finish_decl): Don't instantiate auto variable.
authorJason Merrill <jason@redhat.com>
Fri, 11 May 2018 02:54:52 +0000 (22:54 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 11 May 2018 02:54:52 +0000 (22:54 -0400)
* decl.c (cp_finish_decl): Don't instantiate auto variable.

(check_static_variable_definition): Allow auto.
* constexpr.c (ensure_literal_type_for_constexpr_object): Likewise.

From-SVN: r260150

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/decl.c
gcc/testsuite/g++.dg/cpp1z/static2.C [new file with mode: 0644]

index bee1112..920bed4 100644 (file)
@@ -1,4 +1,8 @@
-2018-05-09  Jason Merrill  <jason@redhat.com>
+2018-05-10  Jason Merrill  <jason@redhat.com>
+
+       * decl.c (cp_finish_decl): Don't instantiate auto variable.
+       (check_static_variable_definition): Allow auto.
+       * constexpr.c (ensure_literal_type_for_constexpr_object): Likewise.
 
        * cp-tree.h (DECL_CONSTRUCTOR_P): Use DECL_CXX_CONSTRUCTOR_P.
        (DECL_DESTRUCTOR_P): Use DECL_CXX_DESTRUCTOR_P.
index b4bcc6a..d9a4cab 100644 (file)
@@ -91,6 +91,8 @@ 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))
index d589647..20ca28f 100644 (file)
@@ -6803,24 +6803,18 @@ 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)
-       {
-         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));
-       }
+       gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (auto_node));
       d_init = init;
       if (d_init)
        {
@@ -9368,6 +9362,7 @@ check_static_variable_definition (tree decl, tree type)
      in check_initializer.  Similarly for inline static data members.  */
   if (DECL_P (decl)
       && (DECL_DECLARED_CONSTEXPR_P (decl)
+         || undeduced_auto_decl (decl)
          || DECL_VAR_DECLARED_INLINE_P (decl)))
     return 0;
   else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
diff --git a/gcc/testsuite/g++.dg/cpp1z/static2.C b/gcc/testsuite/g++.dg/cpp1z/static2.C
new file mode 100644 (file)
index 0000000..b87bfec
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-additional-options -std=c++17 }
+
+template <class T>
+struct A
+{
+  static constexpr auto x = T::x;
+};
+
+struct B;
+A<B> a;
+
+struct B
+{
+  static constexpr auto x = 42;
+};
+
+auto x = a.x;