re PR c++/47207 ([C++0x] ICE: in decl_constant_var_p, at cp/decl2.c:3563 on invalid...
authorJason Merrill <jason@redhat.com>
Mon, 21 Feb 2011 15:35:44 +0000 (10:35 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 21 Feb 2011 15:35:44 +0000 (10:35 -0500)
PR c++/47207
* decl2.c (decl_constant_var_p): A constexpr var needs an
initializer to be constant.
* semantics.c (cxx_eval_constant_expression): Complain about
constexpr var used in its own initializer.
* call.c (set_up_extended_ref_temp): Set
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P too.

From-SVN: r170365

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl2.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-diag2.C [new file with mode: 0644]

index 9fde00c2bfe0c4abd207bc4b1fb3f6863e884d5b..208bb8ca237e9a96b54af64049b4fc6cc1907f40 100644 (file)
@@ -1,3 +1,13 @@
+2011-02-21  Jason Merrill  <jason@redhat.com>
+
+       PR c++/47207
+       * decl2.c (decl_constant_var_p): A constexpr var needs an
+       initializer to be constant.
+       * semantics.c (cxx_eval_constant_expression): Complain about
+       constexpr var used in its own initializer.
+       * call.c (set_up_extended_ref_temp): Set
+       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P too.
+
 2011-02-20  Jason Merrill  <jason@redhat.com>
 
        PR c++/47199
index 078542aae976fe5f65f8600b87770f8e49b4aa6a..8dccbbef4124f5e31b7b5f0c0f782f034743f505 100644 (file)
@@ -8149,6 +8149,7 @@ set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
             Currently this is only useful for initializer_list temporaries,
             since reference vars can't appear in constant expressions.  */
          DECL_DECLARED_CONSTEXPR_P (var) = true;
+         DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true;
          TREE_CONSTANT (var) = true;
        }
       DECL_INITIAL (var) = init;
index a4b7dfa9bee4ddcdeaf2dace18c06c641f160077..93d44a4d6b5f3bd59d2bc49aff884348d0db558b 100644 (file)
@@ -3550,20 +3550,21 @@ decl_constant_var_p (tree decl)
   tree type = TREE_TYPE (decl);
   if (TREE_CODE (decl) != VAR_DECL)
     return false;
-  if (DECL_DECLARED_CONSTEXPR_P (decl))
-    ret = true;
-  else if (CP_TYPE_CONST_NON_VOLATILE_P (type)
-          && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+  if (DECL_DECLARED_CONSTEXPR_P (decl)
+      || (CP_TYPE_CONST_NON_VOLATILE_P (type)
+         && INTEGRAL_OR_ENUMERATION_TYPE_P (type)))
     {
       /* We don't know if a template static data member is initialized with
-        a constant expression until we instantiate its initializer.  */
+        a constant expression until we instantiate its initializer.  Even
+        in the case of a constexpr variable, we can't treat it as a
+        constant until its initializer is complete in case it's used in
+        its own initializer.  */
       mark_used (decl);
       ret = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl);
     }
   else
     ret = false;
 
-  gcc_assert (!ret || DECL_INITIAL (decl));
   return ret;
 }
 
index b7ed5250e0aa9cb9be196a442b4024e77d54ee28..6a9c6a08d18a1f6ad8aea7d5c229be22b9f273ee 100644 (file)
@@ -6768,7 +6768,10 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
              tree type = TREE_TYPE (r);
              error ("the value of %qD is not usable in a constant "
                     "expression", r);
-             if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+             if (DECL_DECLARED_CONSTEXPR_P (r))
+               inform (DECL_SOURCE_LOCATION (r),
+                       "%qD used in its own initializer", r);
+             else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
                {
                  if (!CP_TYPE_CONST_P (type))
                    inform (DECL_SOURCE_LOCATION (r),
index 77b0bef5ef38cbc0651e9f9d55b32dfa1eaa8a84..3c989f802f99c763c48cec584bb5ea795b3c7e39 100644 (file)
@@ -1,3 +1,7 @@
+2011-02-21  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/constexpr-diag2.C: New.
+
 2011-02-20  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/constexpr-ctor7.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag2.C
new file mode 100644 (file)
index 0000000..c78416e
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/47207
+// { dg-options -std=c++0x }
+
+constexpr int X (X);           // { dg-error "not usable" }
+// { dg-message "own initializer" "" { target *-*-* } 4 }