[PATCH] Fix PR42528, LTO ICEs with -f[un]signed-char

Richard Guenther rguenther@suse.de
Thu Jan 7 16:20:00 GMT 2010


This fixes ICEs that happen when you build with a non-standard
(but consistent between TUs and compile/link phase) character
signedness.  I believe this is the only mode we can make reliably
work without doing changes to non-LTO parts of the compiler (that is,
think of how to lower plain 'char' for example in builtin
function signatures).

Unfortunately we do not have a good way to gracefully bail out
or to even detect inconsistent flags across TUs or compile/link
phase, but instead people will run into more-or-less uninteresting
ICEs.  I'll think of where to best store such information (the
existing LTO option processing doesn't seem to be designed for this).

Bootstrapped and tested on x86_64-unknown-linux-gnu, tested by
the reporter (I'd say on samba).

Ok?

Thanks,
Richard.

2010-01-07  Richard Guenther  <rguenther@suse.de>

	PR lto/42528
	* c.opt (fsigned-char): Also let LTO handle this option.
	(funsigned-char): Likewise.

	lto/
	* lto-lang.c (lto_handle_option): Handle -f[un]signed-char.
	(lto_init): Do not init char_type_node in a standard way
	but according to flag_signed_char.

	* gcc.dg/lto/20100103-1_0.c: New testcase.
	* gcc.dg/lto/20100103-2_0.c: Likewise.

Index: gcc/c.opt
===================================================================
*** gcc/c.opt	(revision 155591)
--- gcc/c.opt	(working copy)
*************** C ObjC C++ ObjC++
*** 769,775 ****
  When \"signed\" or \"unsigned\" is not given make the bitfield signed
  
  fsigned-char
! C ObjC C++ ObjC++
  Make \"char\" signed by default
  
  fsquangle
--- 769,775 ----
  When \"signed\" or \"unsigned\" is not given make the bitfield signed
  
  fsigned-char
! C ObjC C++ ObjC++ LTO
  Make \"char\" signed by default
  
  fsquangle
*************** C ObjC C++ ObjC++
*** 802,808 ****
  When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
  
  funsigned-char
! C ObjC C++ ObjC++
  Make \"char\" unsigned by default
  
  fuse-cxa-atexit
--- 802,808 ----
  When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
  
  funsigned-char
! C ObjC C++ ObjC++ LTO
  Make \"char\" unsigned by default
  
  fuse-cxa-atexit
Index: gcc/lto/lto-lang.c
===================================================================
*** gcc/lto/lto-lang.c	(revision 155591)
--- gcc/lto/lto-lang.c	(working copy)
*************** lto_handle_option (size_t scode, const c
*** 632,637 ****
--- 632,645 ----
        warn_psabi = value;
        break;
  
+     case OPT_fsigned_char:
+       flag_signed_char = value;
+       break;
+ 
+     case OPT_funsigned_char:
+       flag_signed_char = !value;
+       break;
+ 
      default:
        break;
      }
*************** lto_init (void)
*** 1036,1043 ****
    /* Share char_type_node with whatever would be the default for the target.
       char_type_node will be used for internal types such as
       va_list_type_node but will not be present in the lto stream.  */
    char_type_node
!     = DEFAULT_SIGNED_CHAR ? signed_char_type_node : unsigned_char_type_node;
  
    /* Tell the middle end what type to use for the size of objects.  */
    if (strcmp (SIZE_TYPE, "unsigned int") == 0)
--- 1044,1054 ----
    /* Share char_type_node with whatever would be the default for the target.
       char_type_node will be used for internal types such as
       va_list_type_node but will not be present in the lto stream.  */
+   /* ???  This breaks the more common case of consistent but non-standard
+      setting of flag_signed_char, so share according to flag_signed_char.
+      See PR42528.  */
    char_type_node
!     = flag_signed_char ? signed_char_type_node : unsigned_char_type_node;
  
    /* Tell the middle end what type to use for the size of objects.  */
    if (strcmp (SIZE_TYPE, "unsigned int") == 0)
Index: gcc/testsuite/gcc.dg/lto/20100103-1_0.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/20100103-1_0.c	(revision 0)
--- gcc/testsuite/gcc.dg/lto/20100103-1_0.c	(revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* { dg-lto-do link } */
+ /* { dg-lto-options {{-funsigned-char -flto} {-fsigned-char -flto}} } */
+ 
+ char *foo;
+ int main()
+ {
+   foo = "bar";
+ }
Index: gcc/testsuite/gcc.dg/lto/20100103-2_0.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/20100103-2_0.c	(revision 0)
--- gcc/testsuite/gcc.dg/lto/20100103-2_0.c	(revision 0)
***************
*** 0 ****
--- 1,12 ----
+ /* { dg-lto-do link } */
+ /* { dg-lto-options {{-O -flto -funsigned-char} {-O -flto -fsigned-char}} } */
+ 
+ char p[32] = "";
+ int main ()
+ {
+   if (__builtin___strcpy_chk (p + 1, "vwxyz",
+ 			      __builtin_object_size (p + 1, 0)) != p + 1)
+     __builtin_abort ();
+   return 0;
+ } 
+ 



More information about the Gcc-patches mailing list