Bug 35430 - [4.3 regression] ICE with complex arithmetic
Summary: [4.3 regression] ICE with complex arithmetic
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: ice-checking, ice-on-valid-code, monitored, patch
Depends on:
Blocks:
 
Reported: 2008-03-03 20:03 UTC by Volker Reichelt
Modified: 2010-04-20 13:42 UTC (History)
2 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work: 4.4.0
Known to fail: 4.3.4
Last reconfirmed: 2008-03-26 17:39:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Volker Reichelt 2008-03-03 20:03:04 UTC
The following valid code snippet triggers an ICE since GCC 4.0.0 when compiled
with "-W":

================================
void foo(__complex__ int i)
{
  i == 0u;
}
================================

bug.c: In function 'foo':
bug.c:3: internal compiler error: tree check: expected integer_type or enumeral_type or boolean_type or real_type or fixed_point_type, have complex_type in int_fits_type_p, at tree.c:6173
Please submit a full bug report, [etc.]
Comment 1 Andrew Pinski 2008-03-26 17:38:02 UTC
This is a front-end issue.

C++ calls it at:
3952              /* Do not warn if the comparison is an equality operation,
3953                 the unsigned quantity is an integral constant and it does
3954                 not use the most significant bit of result_type.  */
3955              else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
3956                       && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST
3957                            && int_fits_type_p (orig_op1, c_common_signed_type
3958                                                (result_type)))


While C does:
8499                      /* Do not warn if the comparison is an equality operation,
8500                         the unsigned quantity is an integral constant, and it
8501                         would fit in the result if the result were signed.  */
8502                      else if (TREE_CODE (uop) == INTEGER_CST
8503                               && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
8504                               && int_fits_type_p
8505                               (uop, c_common_signed_type (result_type)))
Comment 2 Andrew Pinski 2008-03-26 17:39:08 UTC
I am going to fix this bug but not until tonight.
Comment 3 Andrew Pinski 2008-03-29 19:44:12 UTC
This is the patch which I am testing:
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 133711)
+++ cp/typeck.c (working copy)
@@ -3917,6 +3917,10 @@ cp_build_binary_op (enum tree_code code,
          int unsignedp0, unsignedp1;
          tree primop0 = get_narrower (op0, &unsignedp0);
          tree primop1 = get_narrower (op1, &unsignedp1);
+         tree undertype = result_type;
+
+         if (TREE_CODE (undertype) == COMPLEX_TYPE)
+           undertype = TREE_TYPE (undertype);

          /* Check for comparison of different enum types.  */
          if (TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE
@@ -3937,7 +3941,7 @@ cp_build_binary_op (enum tree_code code,
          /* Do not warn if the comparison is being done in a signed type,
             since the signed type will only be chosen if it can represent
             all the values of the unsigned type.  */
-         if (!TYPE_UNSIGNED (result_type))
+         if (!TYPE_UNSIGNED (undertype))
            /* OK */;
          /* Do not warn if both operands are unsigned.  */
          else if (op0_signed == op1_signed)
@@ -3955,10 +3959,10 @@ cp_build_binary_op (enum tree_code code,
          else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
                   && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST
                        && int_fits_type_p (orig_op1, c_common_signed_type
-                                           (result_type)))
+                                           (undertype)))
                        || (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST
                            && int_fits_type_p (orig_op0, c_common_signed_type
-                                               (result_type)))))
+                                               (undertype)))))
            /* OK */;
          else if (complain & tf_warning)
            warning (OPT_Wsign_compare,
Index: c-typeck.c
===================================================================
--- c-typeck.c  (revision 133711)
+++ c-typeck.c  (working copy)
@@ -8483,6 +8483,9 @@ build_binary_op (enum tree_code code, tr
                {
                  tree sop, uop;
                  bool ovf;
+                 tree undertype = result_type;
+                 if (TREE_CODE (undertype) == COMPLEX_TYPE)
+                   undertype = TREE_TYPE (undertype);

                  if (op0_signed)
                    sop = xop0, uop = xop1;
@@ -8502,7 +8505,7 @@ build_binary_op (enum tree_code code, tr
                  else if (TREE_CODE (uop) == INTEGER_CST
                           && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
                           && int_fits_type_p
-                          (uop, c_common_signed_type (result_type)))
+                          (uop, c_common_signed_type (undertype)))
                    /* OK */;
                  /* Do not warn if the unsigned quantity is an enumeration
                     constant and its maximum value would fit in the result
@@ -8511,7 +8514,7 @@ build_binary_op (enum tree_code code, tr
                           && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
                           && int_fits_type_p
                           (TYPE_MAX_VALUE (TREE_TYPE (uop)),
-                           c_common_signed_type (result_type)))
+                           c_common_signed_type (undertype)))
                    /* OK */;
                  else
                    warning (OPT_Wsign_compare, "comparison between signed and unsigned");
Comment 4 Joseph S. Myers 2008-07-04 22:35:36 UTC
Closing 4.1 branch.
Comment 5 Jakub Jelinek 2008-11-04 20:53:19 UTC
Subject: Bug 35430

Author: jakub
Date: Tue Nov  4 20:51:38 2008
New Revision: 141587

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141587
Log:
	PR c/35430
	* c-common.c (warn_for_sign_compare): For complex result_type
	use component's type.

	* gcc.dg/pr35430.c: New test.
	* g++.dg/warn/Wsign-compare-2.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/warn/Wsign-compare-2.C
    trunk/gcc/testsuite/gcc.dg/pr35430.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-common.c
    trunk/gcc/testsuite/ChangeLog

Comment 6 Jakub Jelinek 2008-11-04 21:03:38 UTC
Fixed on the trunk.
Comment 7 Joseph S. Myers 2009-03-31 20:45:43 UTC
Closing 4.2 branch.
Comment 8 Andrew Pinski 2009-04-16 15:44:47 UTC
I am no longer working on this one.
Comment 9 Richard Biener 2009-08-04 12:28:51 UTC
GCC 4.3.4 is being released, adjusting target milestone.
Comment 10 Richard Biener 2010-04-20 13:42:03 UTC
WONTFIX on the 4.3 branch.