This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR19100: truthvalue_conversion vs. TREE_CONSTANT_OVERFLOW
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 21 Dec 2004 11:11:35 -0700 (MST)
- Subject: [PATCH] PR19100: truthvalue_conversion vs. TREE_CONSTANT_OVERFLOW
The following patch is a fix to PR middle-end/19100 which is a serious
wrong code bug in the C family front-ends. The problem is that the
routine c_common_truthvalue conversion assumes that any INTEGER_CST
that isn't integer_zerop must be integer_nonzerop. Unfortunately, this
assumption falls foul of TREE_CONSTANT_OVERFLOW, where if a constant
has previously overflowed during constant folding both integer_zerop
and integer_nonzerop return false.
The fix below preserves this function's current behaviour of ignoring
TREE_CONSTANT_OVERFLOW, but correctly returns true or false depending
on whether the integer value is zero/non-zero.
Whilst I was there I also noticed two further problems in the cases
directly before and after in c_common_truthvalue_conversion. We
were not only also ignoring TREE_CONSTANT_OVERFLOW for REAL_CSTs,
but also return "true" for NaN. And in the Boolean comparison
cases, we were destructively modifying the tree in-place (which in
the middle-end is generally considered a bad thing). Finally,
whilst updating the Makefile.in dependencies for c-common.o, I
noticed that there were already several missing header file
dependencies, with are also fixed below.
Given that GCC 4.0 does considerably more constant folding at the
tree-level that any previous release, I'd like this patch to be
considered a regression fix, even though the specific testcase in
the PR has always failed.
The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.
Ok for mainline?
2004-12-21 Roger Sayle <roger@eyesopen.com>
PR middle-end/19100
* c-common.c: Include real.h.
(c_common_truthvalue_conversion): Avoid destructively modifying expr.
Correctly handle TREE_CONSTANT_OVERFLOW for INTEGER_CST.
Correctly handle TREE_CONSTANT_OVERFLOW and NaNs for REAL_CST.
* Makefile.in (c-common.o): Update dependencies.
* gcc.dg/conv-3.c: New test case.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.595
diff -c -3 -p -r1.595 c-common.c
*** c-common.c 20 Dec 2004 20:11:15 -0000 1.595
--- c-common.c 21 Dec 2004 15:39:50 -0000
*************** Software Foundation, 59 Temple Place - S
*** 46,51 ****
--- 46,52 ----
#include "hashtab.h"
#include "tree-mudflap.h"
#include "opts.h"
+ #include "real.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
*************** c_common_truthvalue_conversion (tree exp
*** 2326,2342 ****
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
case TRUTH_NOT_EXPR:
! TREE_TYPE (expr) = truthvalue_type_node;
return expr;
case ERROR_MARK:
return expr;
case INTEGER_CST:
! return integer_zerop (expr) ? truthvalue_false_node : truthvalue_true_node;
case REAL_CST:
! return real_zerop (expr) ? truthvalue_false_node : truthvalue_true_node;
case ADDR_EXPR:
{
--- 2327,2350 ----
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
case TRUTH_NOT_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;
case ERROR_MARK:
return expr;
case INTEGER_CST:
! /* Avoid integer_zerop to ignore TREE_CONSTANT_OVERFLOW. */
! return (TREE_INT_CST_LOW (expr) != 0 || TREE_INT_CST_HIGH (expr) != 0)
! ? truthvalue_true_node
! : truthvalue_false_node;
case REAL_CST:
! return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
! ? truthvalue_true_node
! : truthvalue_false_node;
case ADDR_EXPR:
{
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1436
diff -c -3 -p -r1.1436 Makefile.in
*** Makefile.in 20 Dec 2004 21:10:39 -0000 1.1436
--- Makefile.in 21 Dec 2004 15:39:51 -0000
*************** tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB
*** 1428,1437 ****
# A file used by all variants of C.
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
! $(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) toplev.h output.h $(C_PRAGMA_H) intl.h \
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
$(DIAGNOSTIC_H) gt-c-common.h langhooks.h varray.h $(RTL_H) \
! $(TARGET_H) $(C_TREE_H) tree-iterator.h langhooks.h tree-mudflap.h
c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
$(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h \
$(DIAGNOSTIC_H)
--- 1428,1440 ----
# A file used by all variants of C.
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
! $(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) toplev.h output.h $(C_PRAGMA_H) \
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
$(DIAGNOSTIC_H) gt-c-common.h langhooks.h varray.h $(RTL_H) \
! $(TARGET_H) $(C_TREE_H) tree-iterator.h langhooks.h tree-mudflap.h \
! intl.h opts.h real.h $(CPPLIB_H) tree-inline.h $(HASHTAB_H) \
! builtins.def
!
c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
$(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h \
$(DIAGNOSTIC_H)
/* PR middle-end/19100 */
/* { dg-do run } */
/* { dg-options "-O2" } */
void abort (void);
int test (int v)
{
return ((signed char) (v ? 0x100 : 0)) ? 17 : 18;
}
int main()
{
if (test (2) != 18)
abort ();
return 0;
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833