summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-08 05:28:13 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-08 05:28:13 +0000
commit63d0c62f0a5222c6a8b205d7703bfaa23cb28d27 (patch)
treeeed58ea0402d2c32facb43dbede2512affbfe906
parenteed3fb17feddf8942693ba720aa0c2cb96cb7bd0 (diff)
downloadgcc-63d0c62f0a5222c6a8b205d7703bfaa23cb28d27.tar.gz
PR c++/48003
* pt.c (convert_nontype_argument): Fix -fpermissive allowing integer overflow. * semantics.c (potential_constant_expression_1): Check TREE_OVERFLOW. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170771 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/cp/semantics.c15
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/init/member1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/constant4.C2
-rw-r--r--gcc/testsuite/g++.dg/template/nontype20.C11
-rw-r--r--gcc/testsuite/g++.dg/template/qualified-id3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash10.C1
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc5
11 files changed, 58 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a82947f205f..f18ce9cc215 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2011-03-07 Jason Merrill <jason@redhat.com>
+ PR c++/48003
+ * pt.c (convert_nontype_argument): Fix -fpermissive allowing
+ integer overflow.
+ * semantics.c (potential_constant_expression_1): Check TREE_OVERFLOW.
+
PR c++/48015
* init.c (constant_value_1): Always require init to be TREE_CONSTANT.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dfc972870f4..076224c46df 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5402,11 +5402,19 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
if (complain & tf_error)
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is a non-constant expression", expr, type);
- cxx_constant_value (expr);
+ int errs = errorcount, warns = warningcount;
+ expr = cxx_constant_value (expr);
+ if (errorcount > errs || warningcount > warns)
+ inform (EXPR_LOC_OR_HERE (expr),
+ "in template argument for type %qT ", type);
+ if (expr == error_mark_node)
+ return NULL_TREE;
+ /* else cxx_constant_value complained but gave us
+ a real constant, so go ahead. */
+ gcc_assert (TREE_CODE (expr) == INTEGER_CST);
}
- return NULL_TREE;
+ else
+ return NULL_TREE;
}
}
/* [temp.arg.nontype]/5, bullet 2
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 52a962dce09..a0f48c0ed45 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7275,7 +7275,20 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
return false;
}
if (CONSTANT_CLASS_P (t))
- return true;
+ {
+ if (TREE_OVERFLOW (t))
+ {
+ if (flags & tf_error)
+ {
+ permerror (EXPR_LOC_OR_HERE (t),
+ "overflow in constant expression");
+ if (flag_permissive)
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
switch (TREE_CODE (t))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b27cd59e5eb..bdf3ccac070 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2011-03-07 Jason Merrill <jason@redhat.com>
+ * g++.dg/template/nontype20.C: New.
+ * g++.dg/init/member1.C: Adjust expected errors.
+ * g++.dg/parse/constant4.C: Likewise.
+ * g++.dg/template/qualified-id3.C: Likewise.
+ * g++.old-deja/g++.pt/crash10.C: Likewise.
+
* g++.dg/cpp0x/regress/non-const1.C: New.
2011-03-07 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/g++.dg/init/member1.C b/gcc/testsuite/g++.dg/init/member1.C
index aededf23e7b..88f9b313465 100644
--- a/gcc/testsuite/g++.dg/init/member1.C
+++ b/gcc/testsuite/g++.dg/init/member1.C
@@ -12,7 +12,7 @@ template<typename T> struct C
{
static const int i = A<T>::i; // { dg-error "incomplete" }
static const int j = i;
- B<j> b; // { dg-error "not a valid template arg" }
+ B<j> b;
};
C<int> c;
diff --git a/gcc/testsuite/g++.dg/parse/constant4.C b/gcc/testsuite/g++.dg/parse/constant4.C
index 4d9814fb485..a1be5dd0260 100644
--- a/gcc/testsuite/g++.dg/parse/constant4.C
+++ b/gcc/testsuite/g++.dg/parse/constant4.C
@@ -18,7 +18,7 @@ void Foo ()
static const unsigned J = X<T>::J; // { dg-message "not initialized with a constant expression" }
- Y<J> j; // { dg-error "constant" "" }
+ Y<J> j; // { dg-error "constant|template argument" "" }
}
struct A
diff --git a/gcc/testsuite/g++.dg/template/nontype20.C b/gcc/testsuite/g++.dg/template/nontype20.C
new file mode 100644
index 00000000000..e4aba322771
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/nontype20.C
@@ -0,0 +1,11 @@
+// PR c++/48003
+// { dg-options "-fpermissive -w" }
+// Test that we allow integer overflow in constant exprs with -fpermissive
+
+template<int N>
+struct test
+{
+ typedef test<N - 1> prior;
+};
+
+test<-2147483647-1> f;
diff --git a/gcc/testsuite/g++.dg/template/qualified-id3.C b/gcc/testsuite/g++.dg/template/qualified-id3.C
index bbfb51e4ce1..c769a529cdc 100644
--- a/gcc/testsuite/g++.dg/template/qualified-id3.C
+++ b/gcc/testsuite/g++.dg/template/qualified-id3.C
@@ -3,7 +3,7 @@
template <const int N> struct A { };
template <class T> struct B {
static const int c; // { dg-message "not initialized with a constant expression" }
- typedef A<B<T>::c> C; // { dg-error "constant expression" }
+ typedef A<B<T>::c> C; // { dg-error "constant expression|template argument" }
};
template <class T> const int B<T>::c = sizeof (T);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
index af0e919fe5f..86f386150d9 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash10.C
@@ -5,6 +5,7 @@ class GCD {
public:
enum { val = (N == 0) ? M : GCD<N, M % N>::val }; // { dg-warning "division" "division" }
// { dg-error "constant expression" "valid" { target *-*-* } 6 }
+// { dg-message "template argument" "valid" { target *-*-* } 6 }
};
int main() {
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 3d32dec46a1..44c87bece9f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-07 Jason Merrill <jason@redhat.com>
+
+ * testsuite/20_util/ratio/cons/cons_overflow_neg.cc: Adjust
+ expected errors.
+
2011-03-07 Benjamin Kosnik <bkoz@redhat.com>
Matthias Klose <doko@ubuntu.com>
Jonathan Wakely <redi@gcc.gnu.org>
diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc
index 51dcdac4b2d..ca91e46c84d 100644
--- a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc
@@ -51,7 +51,4 @@ test04()
// { dg-error "instantiated from here" "" { target *-*-* } 46 }
// { dg-error "denominator cannot be zero" "" { target *-*-* } 155 }
// { dg-error "out of range" "" { target *-*-* } 156 }
-// { dg-error "non-constant expression" "" { target *-*-* } 61 }
-// { dg-error "overflow in constant expression" "" { target *-*-* } 61 }
-// { dg-error "not a member" "" { target *-*-* } 164 }
-// { dg-error "not a valid template argument" "" { target *-*-* } 166 }
+// { dg-error "overflow in constant expression" "" { target *-*-* } 74 }