This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]