re PR c++/56438 (ICE in value_dependent_expression_p, at cp/pt.c:19551)
authorJason Merrill <jason@redhat.com>
Tue, 26 Feb 2013 04:27:40 +0000 (23:27 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 26 Feb 2013 04:27:40 +0000 (23:27 -0500)
PR c++/56438
* semantics.c (potential_constant_expression_1): In C++98, a cast
to non-integral type can't be a constant expression.

From-SVN: r196274

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/template/cast3.C [new file with mode: 0644]

index eaa43e1e1b7c07c9fc000ec37e9559fc7f394b42..eb98b044633504be0d55dff1dd7ad0fe5acb3b3c 100644 (file)
@@ -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
index 458ed26d330bf0a3f68f77b43446f0a5aea4f0e9..60271b511ad03b04f16e6ce509f5d222dba3900c 100644 (file)
@@ -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 (file)
index 0000000..b343ee4
--- /dev/null
@@ -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" }
+}