PR c++/47207
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Feb 2011 15:35:44 +0000 (15:35 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Feb 2011 15:35:44 +0000 (15:35 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170365 138bc75d-0d04-0410-961f-82ee72b054a4

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 9fde00c..208bb8c 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 078542a..8dccbbe 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 a4b7dfa..93d44a4 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 b7ed525..6a9c6a0 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 77b0bef..3c989f8 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 }