diff mbox

Fix wrong code issue in ipa-pure-const

Message ID 20140325215349.GB14078@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka March 25, 2014, 9:53 p.m. UTC
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.
diff mbox

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;