Fix odr ICE on Ada LTO

Jan Hubicka hubicka@ucw.cz
Sun Feb 10 10:48:00 GMT 2019


> 
> This caused:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89272

My apologizes for that. Fixed by the attached patch. This is about ICE
with -fno-lto-odr-type-merging which is option I think we should drop
(probably next stage1 but if it shows to cause troubles, I would not be
against dropping it from gcc 9)

It is not useful and only leads to code duplication.

lto-bootstrapped/regtested x86_64-linux, comitted.

Honza

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 267609)
+++ ChangeLog	(working copy)
@@ -1,4 +1,14 @@
+2019-01-03  Jan Hubicka  <hubicka@ucw.cz>
+	Backport from mainline
+	2018-08-29  Jan Hubicka  <jh@suse.cz>
+
+	PR lto/86517
+	PR lto/88185
+	* lto-opts.c (lto_write_options): Always stream PIC/PIE mode.
+	* lto-wrapper.c (merge_and_complain): Fix merging of PIC/PIE.
+
 2019-01-04  Aaron Sawdey  <acsawdey@linux.ibm.com>
+
 	Backport from mainline
 	2018-11-28  Aaron Sawdey  <acsawdey@linux.ibm.com>
 
Index: lto-opts.c
===================================================================
--- lto-opts.c	(revision 267609)
+++ lto-opts.c	(working copy)
@@ -78,6 +78,21 @@ lto_write_options (void)
       && !global_options.x_flag_openacc)
     append_to_collect_gcc_options (&temporary_obstack, &first_p,
 				   "-fno-openacc");
+  /* Append PIC/PIE mode because its default depends on target and it is
+     subject of merging in lto-wrapper.  */
+  if (!global_options_set.x_flag_pic && !global_options_set.x_flag_pie)
+    {
+       append_to_collect_gcc_options (&temporary_obstack, &first_p,
+				      global_options.x_flag_pic == 2
+				      ? "-fPIC"
+				      : global_options.x_flag_pic == 1
+				      ? "-fpic"
+				      : global_options.x_flag_pie == 2
+				      ? "-fPIE"
+				      : global_options.x_flag_pie == 1
+				      ? "-fpie"
+				      : "-fno-pie");
+    }
 
   /* Append options from target hook and store them to offload_lto section.  */
   if (lto_stream_offload_p)
Index: lto-wrapper.c
===================================================================
--- lto-wrapper.c	(revision 267609)
+++ lto-wrapper.c	(working copy)
@@ -408,6 +408,11 @@ merge_and_complain (struct cl_decoded_op
      It is a common mistake to mix few -fPIC compiled objects into otherwise
      non-PIC code.  We do not want to build everything with PIC then.
 
+     Similarly we merge PIE options, however in addition we keep
+      -fPIC + -fPIE = -fPIE
+      -fpic + -fPIE = -fpie
+      -fPIC/-fpic + -fpie = -fpie
+
      It would be good to warn on mismatches, but it is bit hard to do as
      we do not know what nothing translates to.  */
     
@@ -415,11 +420,38 @@ merge_and_complain (struct cl_decoded_op
     if ((*decoded_options)[j].opt_index == OPT_fPIC
         || (*decoded_options)[j].opt_index == OPT_fpic)
       {
-	if (!pic_option
-	    || (pic_option->value > 0) != ((*decoded_options)[j].value > 0))
-	  remove_option (decoded_options, j, decoded_options_count);
-	else if (pic_option->opt_index == OPT_fPIC
-		 && (*decoded_options)[j].opt_index == OPT_fpic)
+	/* -fno-pic in one unit implies -fno-pic everywhere.  */
+	if ((*decoded_options)[j].value == 0)
+	  j++;
+	/* If we have no pic option or merge in -fno-pic, we still may turn
+	   existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present.  */
+	else if ((pic_option && pic_option->value == 0)
+		 || !pic_option)
+	  {
+	    if (pie_option)
+	      {
+		bool big = (*decoded_options)[j].opt_index == OPT_fPIC
+			   && pie_option->opt_index == OPT_fPIE;
+	        (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
+		if (pie_option->value)
+	          (*decoded_options)[j].canonical_option[0] = big ? "-fPIE" : "-fpie";
+		else
+	          (*decoded_options)[j].canonical_option[0] = big ? "-fno-pie" : "-fno-pie";
+		(*decoded_options)[j].value = pie_option->value;
+	        j++;
+	      }
+	    else if (pic_option)
+	      {
+	        (*decoded_options)[j] = *pic_option;
+	        j++;
+	      }
+	    /* We do not know if target defaults to pic or not, so just remove
+	       option if it is missing in one unit but enabled in other.  */
+	    else
+	      remove_option (decoded_options, j, decoded_options_count);
+	  }
+	else if (pic_option->opt_index == OPT_fpic
+		 && (*decoded_options)[j].opt_index == OPT_fPIC)
 	  {
 	    (*decoded_options)[j] = *pic_option;
 	    j++;
@@ -430,11 +462,42 @@ merge_and_complain (struct cl_decoded_op
    else if ((*decoded_options)[j].opt_index == OPT_fPIE
             || (*decoded_options)[j].opt_index == OPT_fpie)
       {
-	if (!pie_option
-	    || pie_option->value != (*decoded_options)[j].value)
-	  remove_option (decoded_options, j, decoded_options_count);
-	else if (pie_option->opt_index == OPT_fPIE
-		 && (*decoded_options)[j].opt_index == OPT_fpie)
+	/* -fno-pie in one unit implies -fno-pie everywhere.  */
+	if ((*decoded_options)[j].value == 0)
+	  j++;
+	/* If we have no pie option or merge in -fno-pie, we still preserve
+	   PIE/pie if pic/PIC is present.  */
+	else if ((pie_option && pie_option->value == 0)
+		 || !pie_option)
+	  {
+	    /* If -fPIC/-fpic is given, merge it with -fPIE/-fpie.  */
+	    if (pic_option)
+	      {
+		if (pic_option->opt_index == OPT_fpic
+		    && (*decoded_options)[j].opt_index == OPT_fPIE)
+		  {
+	            (*decoded_options)[j].opt_index = OPT_fpie;
+	            (*decoded_options)[j].canonical_option[0]
+			 = pic_option->value ? "-fpie" : "-fno-pie";
+		  }
+		else if (!pic_option->value)
+		  (*decoded_options)[j].canonical_option[0] = "-fno-pie";
+		(*decoded_options)[j].value = pic_option->value;
+		j++;
+	      }
+	    else if (pie_option)
+	      {
+	        (*decoded_options)[j] = *pie_option;
+		j++;
+	      }
+	    /* Because we always append pic/PIE options this code path should
+	       not happen unless the LTO object was built by old lto1 which
+	       did not contain that logic yet.  */
+	    else
+	      remove_option (decoded_options, j, decoded_options_count);
+	  }
+	else if (pie_option->opt_index == OPT_fpie
+		 && (*decoded_options)[j].opt_index == OPT_fPIE)
 	  {
 	    (*decoded_options)[j] = *pie_option;
 	    j++;



More information about the Gcc-patches mailing list