re PR middle-end/20539 (ICE in simplify_subreg, at simplify-rtx.c:3674)
authorRoger Sayle <roger@eyesopen.com>
Mon, 21 Mar 2005 03:30:08 +0000 (03:30 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 21 Mar 2005 03:30:08 +0000 (03:30 +0000)
PR middle-end/20539
* fold-const.c (fold_binary): Fix type mismatch between
TRUTH_{AND,OR,XOR}_EXPR nodes an their operands' types.
(fold_binary) <TRUTH_XOR_EXPR>: Avoid calling invert_truthvalue
for non-truth-valued expressions.

* c-common.c (c_common_truthvalue_conversion): Handle ERROR_MARK
and FUNCTION_DECL in the main switch.
<TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR, TRUTH_AND_EXPR, TRUTH_OR_EXPR,
TRUTH_XOR_EXPR>: When changing the result type of these tree nodes,
we also need to convert their operands to match.
<TRUTH_NOT_EXPR>: Likewise.

* gcc.c-torture/compile/pr13066-1.c: New test case.
* gcc.c-torture/compile/pr20539-1.c: Likewise.
* g++.dg/opt/pr13066-1.C: Likewise.

From-SVN: r96777

gcc/ChangeLog
gcc/c-common.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr13066-1.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr13066-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr20539-1.c [new file with mode: 0644]

index 34e1a5d..cf4a6c9 100644 (file)
@@ -1,3 +1,18 @@
+2005-03-20  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/20539
+       * fold-const.c (fold_binary): Fix type mismatch between
+       TRUTH_{AND,OR,XOR}_EXPR nodes an their operands' types.
+       (fold_binary) <TRUTH_XOR_EXPR>: Avoid calling invert_truthvalue
+       for non-truth-valued expressions.
+
+       * c-common.c (c_common_truthvalue_conversion): Handle ERROR_MARK
+       and FUNCTION_DECL in the main switch.
+       <TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR, TRUTH_AND_EXPR, TRUTH_OR_EXPR,
+       TRUTH_XOR_EXPR>: When changing the result type of these tree nodes,
+       we also need to convert their operands to match.
+       <TRUTH_NOT_EXPR>: Likewise.
+
 2005-03-21  Joseph S. Myers  <joseph@codesourcery.com>
 
        * c-common.c (lvalue_or_else): Replace by lvalue_error; only give
index 9c6a9d1..a18520d 100644 (file)
@@ -2327,33 +2327,33 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
 tree
 c_common_truthvalue_conversion (tree expr)
 {
-  if (TREE_CODE (expr) == ERROR_MARK)
-    return expr;
-
-  if (TREE_CODE (expr) == FUNCTION_DECL)
-    expr = build_unary_op (ADDR_EXPR, expr, 0);
-
   switch (TREE_CODE (expr))
     {
     case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
     case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
     case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
     case ORDERED_EXPR: case UNORDERED_EXPR:
+      if (TREE_TYPE (expr) == truthvalue_type_node)
+       return expr;
+      return build2 (TREE_CODE (expr), truthvalue_type_node,
+                    TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
+
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
     case TRUTH_XOR_EXPR:
-      if (TREE_TYPE (expr) != truthvalue_type_node)
-       return build2 (TREE_CODE (expr), truthvalue_type_node,
-                      TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
-      return expr;
+      if (TREE_TYPE (expr) == truthvalue_type_node)
+       return expr;
+      return build2 (TREE_CODE (expr), truthvalue_type_node,
+                lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)),
+                lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 1)));
 
     case TRUTH_NOT_EXPR:
-      if (TREE_TYPE (expr) != truthvalue_type_node)
-       return build1 (TREE_CODE (expr), truthvalue_type_node,
-                      TREE_OPERAND (expr, 0));
-      return expr;
+      if (TREE_TYPE (expr) == truthvalue_type_node)
+       return expr;
+      return build1 (TREE_CODE (expr), truthvalue_type_node,
+                lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)));
 
     case ERROR_MARK:
       return expr;
@@ -2369,6 +2369,10 @@ c_common_truthvalue_conversion (tree expr)
             ? truthvalue_true_node
             : truthvalue_false_node;
 
+    case FUNCTION_DECL:
+      expr = build_unary_op (ADDR_EXPR, expr, 0);
+      /* Fall through.  */
+
     case ADDR_EXPR:
       {
        if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL
index bc17c1d..848b167 100644 (file)
@@ -7159,13 +7159,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
       tem = fold (build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
                          : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
                          : TRUTH_XOR_EXPR,
-                         type, fold_convert (boolean_type_node, arg0),
+                         boolean_type_node,
+                         fold_convert (boolean_type_node, arg0),
                          fold_convert (boolean_type_node, arg1)));
 
       if (code == EQ_EXPR)
        tem = invert_truthvalue (tem);
 
-      return tem;
+      return fold_convert (type, tem);
     }
 
   if (TREE_CODE_CLASS (code) == tcc_comparison
@@ -8717,7 +8718,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
        return non_lvalue (fold_convert (type, arg0));
       /* If the second arg is constant true, this is a logical inversion.  */
       if (integer_onep (arg1))
-       return non_lvalue (fold_convert (type, invert_truthvalue (arg0)));
+       {
+         /* Only call invert_truthvalue if operand is a truth value.  */
+         if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
+           tem = fold (build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg0), arg0));
+         else
+           tem = invert_truthvalue (arg0);
+         return non_lvalue (fold_convert (type, tem));
+       }
       /* Identical arguments cancel to zero.  */
       if (operand_equal_p (arg0, arg1, 0))
        return omit_one_operand (type, integer_zero_node, arg0);
index 7921dd4..3f850f5 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-20  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/20539
+       * gcc.c-torture/compile/pr13066-1.c: New test case.
+       * gcc.c-torture/compile/pr20539-1.c: Likewise.
+       * g++.dg/opt/pr13066-1.C: Likewise.
+
 2005-03-20  Joseph S. Myers  <joseph@codesourcery.com>
 
        * gcc.dg/bitfld-14.c, gcc.dg/enum3.c: New tests.
diff --git a/gcc/testsuite/g++.dg/opt/pr13066-1.C b/gcc/testsuite/g++.dg/opt/pr13066-1.C
new file mode 100644 (file)
index 0000000..67f8534
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+class nsIURI;
+
+struct nsCOMPtr
+{
+  operator nsIURI*() const
+  {
+    return mRawPtr;
+  }
+
+  nsIURI *mRawPtr;
+};
+
+void func()
+{
+  nsCOMPtr u1;
+  if (!u1 == !u1)
+    return;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr13066-1.c b/gcc/testsuite/gcc.c-torture/compile/pr13066-1.c
new file mode 100644 (file)
index 0000000..c2930f9
--- /dev/null
@@ -0,0 +1,10 @@
+void *g, *c;
+int a, b;
+
+int f()
+{
+  if ((0 == a) != (b || g == c))
+    return 1;
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr20539-1.c b/gcc/testsuite/gcc.c-torture/compile/pr20539-1.c
new file mode 100644 (file)
index 0000000..f67f06b
--- /dev/null
@@ -0,0 +1,10 @@
+char l7_en;
+long long l6_data_Z_0th;
+int t;
+void f()
+{
+  if (((char )(l6_data_Z_0th>>1 & 1U)) & ((l6_data_Z_0th & 1U)
+     | !(((char )(l6_data_Z_0th>>35 & 15U))==14U)))
+    t = 0ULL;
+}
+