Patchwork Fix wrong code issue in ipa-pure-const

login
register
mail settings
Submitter Jan Hubicka
Date March 25, 2014, 9:53 p.m.
Message ID <20140325215349.GB14078@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/333730/
State New
Headers show

Comments

Jan Hubicka - March 25, 2014, 9:53 p.m.
Hi,
this patch fixes issue I run into while working on other fix. ipa-pure-const is happy
to make inline clone pure when it proves it is, but because decls are shared with master
clone, it actually makes offline copy and the master clone pure, too.
This may lead to wrong code issues if function contains indirect call and only in some
instances this call was resolved to call to a pure function.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* ipa-pure-const.c (propagate_pure_const, propagate_nothrow):
	Do not modify inline clones.

Patch

Index: ipa-pure-const.c
===================================================================
--- ipa-pure-const.c	(revision 208802)
+++ ipa-pure-const.c	(working copy)
@@ -1327,35 +1327,39 @@  propagate_pure_const (void)
 	  w_l->pure_const_state = this_state;
 	  w_l->looping = this_looping;
 
-	  switch (this_state)
-	    {
-	    case IPA_CONST:
-	      if (!TREE_READONLY (w->decl))
-		{
-		  warn_function_const (w->decl, !this_looping);
-		  if (dump_file)
-		    fprintf (dump_file, "Function found to be %sconst: %s\n",
-			     this_looping ? "looping " : "",
-			     w->name ());
-		}
-	      cgraph_set_const_flag (w, true, this_looping);
-	      break;
+	  /* Inline clones share declaration with their offline copies;
+	     do not modify their declarations since the offline copy may
+	     be different.  */
+	  if (!w->global.inlined_to)
+	    switch (this_state)
+	      {
+	      case IPA_CONST:
+		if (!TREE_READONLY (w->decl))
+		  {
+		    warn_function_const (w->decl, !this_looping);
+		    if (dump_file)
+		      fprintf (dump_file, "Function found to be %sconst: %s\n",
+			       this_looping ? "looping " : "",
+			       w->name ());
+		  }
+		cgraph_set_const_flag (w, true, this_looping);
+		break;
 
-	    case IPA_PURE:
-	      if (!DECL_PURE_P (w->decl))
-		{
-		  warn_function_pure (w->decl, !this_looping);
-		  if (dump_file)
-		    fprintf (dump_file, "Function found to be %spure: %s\n",
-			     this_looping ? "looping " : "",
-			     w->name ());
-		}
-	      cgraph_set_pure_flag (w, true, this_looping);
-	      break;
+	      case IPA_PURE:
+		if (!DECL_PURE_P (w->decl))
+		  {
+		    warn_function_pure (w->decl, !this_looping);
+		    if (dump_file)
+		      fprintf (dump_file, "Function found to be %spure: %s\n",
+			       this_looping ? "looping " : "",
+			       w->name ());
+		  }
+		cgraph_set_pure_flag (w, true, this_looping);
+		break;
 
-	    default:
-	      break;
-	    }
+	      default:
+		break;
+	      }
 	  w_info = (struct ipa_dfs_info *) w->aux;
 	  w = w_info->next_cycle;
 	}
@@ -1448,10 +1452,16 @@  propagate_nothrow (void)
 	  funct_state w_l = get_function_state (w);
 	  if (!can_throw && !TREE_NOTHROW (w->decl))
 	    {
-	      cgraph_set_nothrow_flag (w, true);
-	      if (dump_file)
-		fprintf (dump_file, "Function found to be nothrow: %s\n",
-			 w->name ());
+	      /* Inline clones share declaration with their offline copies;
+		 do not modify their declarations since the offline copy may
+		 be different.  */
+	      if (!w->global.inlined_to)
+		{
+		  cgraph_set_nothrow_flag (w, true);
+		  if (dump_file)
+		    fprintf (dump_file, "Function found to be nothrow: %s\n",
+			     w->name ());
+		}
 	    }
 	  else if (can_throw && !TREE_NOTHROW (w->decl))
 	    w_l->can_throw = true;