PR c++/23056
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 08:55:37 +0000 (08:55 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 08:55:37 +0000 (08:55 +0000)
* typeck.c (ignore_overflows): New helper function.
(build_static_cast_1): Use it.

* g++.dg/opt/pr23056.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103936 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr23056.C [new file with mode: 0644]

index 4c73cfc..6e13cfd 100644 (file)
@@ -1,3 +1,9 @@
+2005-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/23056
+       * typeck.c (ignore_overflows): New helper function.
+       (build_static_cast_1): Use it.
+
 2005-09-06  Kazu Hirata  <kazu@codesourcery.com>
 
        * cp-tree.h, decl.c, decl2.c, semantics.c: Fix comment typos.
index 96da3c6..d8dce75 100644 (file)
@@ -4526,6 +4526,37 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
                             allow_inverse_p, c_cast_p);
 }
 
+/* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return
+   a version of EXPR that has TREE_OVERFLOW and/or TREE_CONSTANT_OVERFLOW
+   set iff they are set in ORIG.  Otherwise, return EXPR unchanged.  */
+
+static tree
+ignore_overflows (tree expr, tree orig)
+{
+  if (TREE_CODE (expr) == INTEGER_CST
+      && CONSTANT_CLASS_P (orig)
+      && TREE_CODE (orig) != STRING_CST
+      && (TREE_OVERFLOW (expr) != TREE_OVERFLOW (orig)
+         || TREE_CONSTANT_OVERFLOW (expr)
+            != TREE_CONSTANT_OVERFLOW (orig)))
+    {
+      if (!TREE_OVERFLOW (orig) && !TREE_CONSTANT_OVERFLOW (orig))
+       /* Ensure constant sharing.  */
+       expr = build_int_cst_wide (TREE_TYPE (expr),
+                                  TREE_INT_CST_LOW (expr),
+                                  TREE_INT_CST_HIGH (expr));
+      else
+       {
+         /* Avoid clobbering a shared constant.  */
+         expr = copy_node (expr);
+         TREE_OVERFLOW (expr) = TREE_OVERFLOW (orig);
+         TREE_CONSTANT_OVERFLOW (expr)
+           = TREE_CONSTANT_OVERFLOW (orig);
+       }
+    }
+  return expr;
+}
+
 /* Perform a static_cast from EXPR to TYPE.  When C_CAST_P is true,
    this static_cast is being attempted as one of the possible casts
    allowed by a C-style cast.  (In that case, accessibility of base
@@ -4629,13 +4660,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
       result = convert_from_reference (result);
 
       /* Ignore any integer overflow caused by the cast.  */
-      if (TREE_CODE (result) == INTEGER_CST
-         && CONSTANT_CLASS_P (orig))
-       {
-         TREE_OVERFLOW (result) = TREE_OVERFLOW (orig);
-         TREE_CONSTANT_OVERFLOW (result)
-           = TREE_CONSTANT_OVERFLOW (orig);
-       }
+      result = ignore_overflows (result, orig);
+
       /* [expr.static.cast]
 
         If T is a reference type, the result is an lvalue; otherwise,
@@ -4678,12 +4704,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
       expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL);
 
       /* Ignore any integer overflow caused by the cast.  */
-      if (TREE_CODE (expr) == INTEGER_CST
-         && CONSTANT_CLASS_P (orig))
-       {
-         TREE_OVERFLOW (expr) = TREE_OVERFLOW (orig);
-         TREE_CONSTANT_OVERFLOW (expr) = TREE_CONSTANT_OVERFLOW (orig);
-       }
+      expr = ignore_overflows (expr, orig);
       return expr;
     }
 
index e1b8b0b..760360f 100644 (file)
@@ -1,5 +1,8 @@
 2005-09-06  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/23056
+       * g++.dg/opt/pr23056.C: New test.
+
        PR rtl-optimization/23098
        * gcc.target/i386/pr23098.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/opt/pr23056.C b/gcc/testsuite/g++.dg/opt/pr23056.C
new file mode 100644 (file)
index 0000000..b9689ec
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/23056
+// { dg-do compile }
+
+template <bool T> struct S { virtual ~S(); };
+void foo ()
+{
+  static_cast<bool>("Foo");
+}
+S<true> a;