aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-06-27 02:35:46 +0000
committerJason Merrill <jason@redhat.com>2013-06-27 02:35:46 +0000
commit679149ed95334ae1c7d5031fb3a7ec43a6424d8f (patch)
treecde2acd08fb5a853014aca34e776bdf9be527196
parent6972631b6382e8599421e2bcef1707ef7644a3cf (diff)
* typeck2.c (store_init_value): Diagnose a non-constant
initializer for in-class static. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@200450 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/typeck2.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/overflow1.C23
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc1
5 files changed, 30 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3be2f1e715d..7b40665484f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f562546db0c..047fd77fd74 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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]
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index a44789362e3..79329397a8b 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 00000000000..7033e9c451a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/overflow1.C
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc
index f0dcdec080d..f2f2330cea4 100644
--- a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow_neg.cc
@@ -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" }