typeck2.c (store_init_value): Diagnose a non-constant initializer for in-class static.
authorJason Merrill <jason@redhat.com>
Thu, 27 Jun 2013 02:35:46 +0000 (22:35 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 27 Jun 2013 02:35:46 +0000 (22:35 -0400)
* typeck2.c (store_init_value): Diagnose a non-constant
initializer for in-class static.

From-SVN: r200450

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp0x/overflow1.C [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc

index 3be2f1e715d0c54b4addecf200719b19412ccdcb..7b40665484f850333901b55230a2926d85b8444c 100644 (file)
@@ -1,4 +1,7 @@
-2013-06-21  Jason Merrill  <jason@redhat.com>
+2013-06-26  Jason Merrill  <jason@redhat.com>
+
+       * typeck2.c (store_init_value): Diagnose a non-constant
+       initializer for in-class static.
 
        PR c++/57408
        * semantics.c (add_capture): Set type to error_mark_node after
index f562546db0c8df2805303da248f68aba07321532..047fd77fd74abb7f83fcc418b347a9c0054cfa4c 100644 (file)
@@ -6346,25 +6346,6 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          cleanups = make_tree_vector ();
          init = check_initializer (decl, init, flags, &cleanups);
 
-         /* Check that the initializer for a static data member was a
-            constant.  Although we check in the parser that the
-            initializer is an integral constant expression, we do not
-            simplify division-by-zero at the point at which it
-            occurs.  Therefore, in:
-
-              struct S { static const int i = 7 / 0; };
-
-            we issue an error at this point.  It would
-            probably be better to forbid division by zero in
-            integral constant expressions.  */
-         if (DECL_EXTERNAL (decl) && init)
-           {
-             error ("%qD cannot be initialized by a non-constant expression"
-                    " when being declared", decl);
-             DECL_INITIALIZED_IN_CLASS_P (decl) = 0;
-             init = NULL_TREE;
-           }
-
          /* Handle:
 
             [dcl.init]
index a44789362e33f5d6dcdc119b302b1f17aadc9c04..79329397a8b45aadf664e4a955bf8645ecd23cc7 100644 (file)
@@ -775,7 +775,8 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
       bool const_init;
       value = fold_non_dependent_expr (value);
       value = maybe_constant_init (value);
-      if (DECL_DECLARED_CONSTEXPR_P (decl))
+      if (DECL_DECLARED_CONSTEXPR_P (decl)
+         || DECL_IN_AGGR_P (decl))
        {
          /* Diagnose a non-constant initializer for constexpr.  */
          if (processing_template_decl
diff --git a/gcc/testsuite/g++.dg/cpp0x/overflow1.C b/gcc/testsuite/g++.dg/cpp0x/overflow1.C
new file mode 100644 (file)
index 0000000..7033e9c
--- /dev/null
@@ -0,0 +1,23 @@
+template <long long i>
+struct Fib
+{
+    static const long long value // { dg-error "overflow" }
+    = Fib<i-1>::value + Fib<i-2>::value;
+};
+
+template <>
+struct Fib<0>
+{
+   static const long long value = 0;
+};
+
+template <>
+struct Fib<1>
+{
+   static const long long value = 1;
+};
+
+int main()
+{
+  return Fib<95>::value;
+}
index f0dcdec080d51a0a8b3f04e380667493f19de0e4..f2f2330cea4380988be893a43678924dce2112b5 100644 (file)
@@ -46,5 +46,6 @@ test02()
 // { dg-error "overflow in multiplication" "" { target *-*-* } 97 }
 // { dg-error "overflow in multiplication" "" { target *-*-* } 99 }
 // { dg-error "overflow in multiplication" "" { target *-*-* } 101 }
+// { dg-error "overflow in constant expression" "" { target *-*-* } 108 }
 // { dg-prune-output "out of range" }
 // { dg-prune-output "not usable in a constant expression" }