aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/semantics.c12
-rw-r--r--gcc/testsuite/g++.dg/template/cast3.C22
3 files changed, 40 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index eaa43e1..eb98b04 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/56438
+ * semantics.c (potential_constant_expression_1): In C++98, a cast
+ to non-integral type can't be a constant expression.
+
2013-02-24 Jakub Jelinek <jakub@redhat.com>
PR c++/56403
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 458ed26..60271b5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8607,6 +8607,18 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case IMPLICIT_CONV_EXPR:
+ if (cxx_dialect < cxx0x
+ && !dependent_type_p (TREE_TYPE (t))
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)))
+ /* In C++98, a conversion to non-integral type can't be part of a
+ constant expression. */
+ {
+ if (flags & tf_error)
+ error ("cast to non-integral type %qT in a constant expression",
+ TREE_TYPE (t));
+ return false;
+ }
+
return (potential_constant_expression_1
(TREE_OPERAND (t, 0),
TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE, flags));
diff --git a/gcc/testsuite/g++.dg/template/cast3.C b/gcc/testsuite/g++.dg/template/cast3.C
new file mode 100644
index 0000000..b343ee4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/cast3.C
@@ -0,0 +1,22 @@
+// PR c++/56438
+
+struct A { };
+A& operator<<(A&, const char*);
+
+struct B {
+ int size();
+};
+
+struct C { };
+
+template <class S, class T>
+S bar(const S& s, const T& t) {
+ return s;
+}
+
+template<class S, class T>
+void foo() {
+ A a;
+ B b;
+ a << bar(b.size(), C()); // { dg-error "no match" }
+}