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]

PATCH to output_constant for middle-end/27724


The problem in 27724 was that sometimes NOP_EXPRs or CONVERT_EXPRs passed to output_constant are significant, and stripping them leads to bad sign extension. Previously we gave an internal error in such cases, but it's better just to leave the conversions alone so expand_expr will do the sign extension.

Tested x86_64-pc-linux-gnu, applied to trunk and 4.1.

2006-09-07  Jason Merrill  <jason@redhat.com>

	PR middle-end/27724
	* varasm.c (output_constant): Only strip actual no-op conversions.

Index: varasm.c
===================================================================
*** varasm.c	(revision 116703)
--- varasm.c	(working copy)
*************** output_constant (tree exp, unsigned HOST
*** 4039,4048 ****
        if (type_size > op_size
  	  && TREE_CODE (exp) != VIEW_CONVERT_EXPR
  	  && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
! 	internal_error ("no-op convert from %wd to %wd bytes in initializer",
! 			op_size, type_size);
! 
!       exp = TREE_OPERAND (exp, 0);
      }
  
    code = TREE_CODE (TREE_TYPE (exp));
--- 4039,4048 ----
        if (type_size > op_size
  	  && TREE_CODE (exp) != VIEW_CONVERT_EXPR
  	  && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
! 	/* Keep the conversion. */
! 	break;
!       else
! 	exp = TREE_OPERAND (exp, 0);
      }
  
    code = TREE_CODE (TREE_TYPE (exp));
Index: testsuite/gcc.dg/long-long-cst1.c
===================================================================
*** testsuite/gcc.dg/long-long-cst1.c	(revision 0)
--- testsuite/gcc.dg/long-long-cst1.c	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ /* PR middle-end/27724 */
+ /* { dg-do run } */
+ /* { dg-options "" } */
+ 
+ extern void abort();
+ 
+ struct st{
+   int _mark;
+ };
+ unsigned long long t = ((int)&(((struct st*)16)->_mark) - 32);
+ 
+ int main()
+ {
+   if (t != (unsigned long long)(int)-16)
+     abort ();
+ }
+ 

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