This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] PR19543: Check modes in varasm.c:compare_constant
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: fortran at gcc dot gnu dot org
- Date: Sun, 19 Feb 2006 17:33:05 -0700 (MST)
- Subject: [Committed] PR19543: Check modes in varasm.c:compare_constant
The following patch fixes a obscure problem handling integer CONST_DECLs
in the middle-end. varasm.c maintains a hashtable of constants that
have been written. This allows multiple uses of the same constant to
use the same assembler label to refer to it. Unfortunately, the
gfortran front-end's LOGICALs expose a bug in the "equality" testing
of these constants. The code in compare_constant for INTEGER_CSTs
considers two values equivalent if they have the same value and the
same TYPE_PRECISION. Unfortunately, LOGICAL*1, LOGICAL*2, LOGICAL*4
and LOGICAL*8 all have the same precision (a single-bit), but different
modes! This means that in the testcase below, we'd replace a reference
to an eight byte constant, with the label of a single byte!
The obvious fix is to compare both the TYPE_PRECISION and the TYPE_MODE
when considering the equality of constants.
The following patch has been tested on x86_64-unknown-linux-gnu with
a full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures. The new
gfortran.dg testcase passes with this patch, but fails without.
Committed to mainline as revision 11294.
2006-02-19 Roger Sayle <roger@eyesopen.com>
PR middle-end/19543
* varasm.c (compare_constant) <INTEGER_CST>: Integer constants are
only equivalent if the have both the same mode and precision.
* gfortran.dg/logical_1.f90: New test case.
Index: varasm.c
===================================================================
*** varasm.c (revision 111226)
--- varasm.c (working copy)
*************** compare_constant (const tree t1, const t
*** 2370,2375 ****
--- 2370,2377 ----
/* Integer constants are the same only if the same width of type. */
if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
return 0;
+ if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
+ return 0;
return tree_int_cst_equal (t1, t2);
case REAL_CST:
! { dg-do run }
! PR middle-end/19543
program logical_1
implicit none
logical(1), parameter :: t1 = .TRUE., f1 = .FALSE.
logical(2), parameter :: t2 = .TRUE., f2 = .FALSE.
logical(4), parameter :: t4 = .TRUE., f4 = .FALSE.
logical(8), parameter :: t8 = .TRUE., f8 = .FALSE.
character*2 :: t(4), f(4)
write(t(1),*) t1
write(f(1),*) f1
write(t(2),*) t2
write(f(2),*) f2
write(t(3),*) t4
write(f(3),*) f4
write(t(4),*) t8
write(f(4),*) f8
if (any(t .ne. " T")) call abort
if (any(f .ne. " F")) call abort
end
Roger
--