PR c++/91644 - ICE with constinit in function template.
authorMarek Polacek <polacek@redhat.com>
Thu, 5 Sep 2019 15:37:52 +0000 (15:37 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 5 Sep 2019 15:37:52 +0000 (15:37 +0000)
* decl.c (start_decl): Call retrofit_lang_decl for constinit variables.
* pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for
constinit variables.

* g++.dg/cpp2a/constinit13.C: New test.

From-SVN: r275421

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/constinit13.C [new file with mode: 0644]

index 3162bed785ed966b85a52227b39e1c4dbd5ebadb..31a04ef226a84ca4ee52102745ad43e50c73a8ae 100644 (file)
@@ -1,3 +1,10 @@
+2019-09-05  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/91644 - ICE with constinit in function template.
+       * decl.c (start_decl): Call retrofit_lang_decl for constinit variables.
+       * pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for
+       constinit variables.
+
 2019-09-05  Nathan Sidwell  <nathan@acm.org>
 
        * cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P.
index 6de95cdfe798d03fac9da6e2d02fc0d8fb921d7d..825e1e61b5eb9100b9885d35daa6418277e2d919 100644 (file)
@@ -5308,7 +5308,14 @@ start_decl (const cp_declarator *declarator,
     decl = maybe_push_decl (decl);
 
   if (processing_template_decl)
-    decl = push_template_decl (decl);
+    {
+      /* Make sure that for a `constinit' decl push_template_decl creates
+        a DECL_TEMPLATE_INFO info for us, so that cp_finish_decl can then set
+        TINFO_VAR_DECLARED_CONSTINIT.  */
+      if (decl_spec_seq_has_spec_p (declspecs, ds_constinit))
+       retrofit_lang_decl (decl);
+      decl = push_template_decl (decl);
+    }
   if (decl == error_mark_node)
     return error_mark_node;
 
index 15cc4b20a41ad85d3fb432e0de7b4628d1680051..cec9798eef46976b92af299d3b3abe4a6b35f0f4 100644 (file)
@@ -17108,6 +17108,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        else
          {
            init = DECL_INITIAL (decl);
+           /* The following tsubst call will clear the DECL_TEMPLATE_INFO
+              for local variables, so save if DECL was declared constinit.  */
+           const bool constinit_p
+             = (VAR_P (decl)
+                && DECL_LANG_SPECIFIC (decl)
+                && DECL_TEMPLATE_INFO (decl)
+                && TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (decl)));
            decl = tsubst (decl, args, complain, in_decl);
            if (decl != error_mark_node)
              {
@@ -17146,7 +17153,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                  }
                else
                  {
-                   int const_init = false;
+                   bool const_init = false;
                    unsigned int cnt = 0;
                    tree first = NULL_TREE, ndecl = error_mark_node;
                    maybe_push_decl (decl);
@@ -17167,7 +17174,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                    if (ndecl != error_mark_node)
                      cp_maybe_mangle_decomp (ndecl, first, cnt);
 
-                   cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+                   cp_finish_decl (decl, init, const_init, NULL_TREE,
+                                   constinit_p ? LOOKUP_CONSTINIT : 0);
 
                    if (ndecl != error_mark_node)
                      cp_finish_decomp (ndecl, first, cnt);
index 3a905cb31569f765bf655f79d98bc5070d09de2d..9940cec8879759f0087bd6e50724dffd9b432140 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-05  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/91644 - ICE with constinit in function template.
+       * g++.dg/cpp2a/constinit13.C: New test.
+
 2019-09-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/91001
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit13.C b/gcc/testsuite/g++.dg/cpp2a/constinit13.C
new file mode 100644 (file)
index 0000000..8ea64cc
--- /dev/null
@@ -0,0 +1,33 @@
+// PR c++/91644 - ICE with constinit in function template.
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+static void fn1 ()
+{
+  static __constinit auto v1 = 0;
+  static __constinit int v2 = 0;
+}
+
+int nonconst;
+
+template <typename T>
+static void fn2 ()
+{
+  static __constinit auto v1 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
+  static __constinit int v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
+}
+
+template <typename T>
+static void fn3 ()
+{
+  static __constinit T v1 = 0;
+  static __constinit T v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
+}
+
+void
+g ()
+{
+  fn1<int>();
+  fn2<int>();
+  fn3<int>();
+}