+2008-09-03 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR middle-end/37293
+ * cgraphunit.c (update_call_expr): Remove eh regions from statements
+ which become non throw.
+ (cgraph_function_versioning): Also clear DECL_WEAK. Call
+ update_call_expr after updating the flags on the decl.
+
2008-09-03 Jan Hubicka <jh@suse.cz>
PR tree-optimization/37315
/* Update the call expr on the edges to call the new version. */
for (e = new_version->callers; e; e = e->next_caller)
- gimple_call_set_fndecl (e->call_stmt, new_version->decl);
+ {
+ struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
+ gimple_call_set_fndecl (e->call_stmt, new_version->decl);
+ /* Update EH information too, just in case. */
+ if (!stmt_could_throw_p (e->call_stmt)
+ && lookup_stmt_eh_region_fn (inner_function, e->call_stmt))
+ remove_stmt_from_eh_region_fn (inner_function, e->call_stmt);
+ }
}
/* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip);
- /* Update the call_expr on the edges to call the new version node. */
- update_call_expr (new_version_node);
/* Update the new version's properties.
- Make The new version visible only within this translation unit.
+ Make The new version visible only within this translation unit. Make sure
+ that is not weak also.
??? We cannot use COMDAT linkage because there is no
ABI support for this. */
DECL_EXTERNAL (new_version_node->decl) = 0;
DECL_ONE_ONLY (new_version_node->decl) = 0;
TREE_PUBLIC (new_version_node->decl) = 0;
DECL_COMDAT (new_version_node->decl) = 0;
+ DECL_WEAK (new_version_node->decl) = 0;
new_version_node->local.externally_visible = 0;
new_version_node->local.local = 1;
new_version_node->lowered = true;
+
+ /* Update the call_expr on the edges to call the new version node. */
+ update_call_expr (new_version_node);
+
cgraph_call_function_insertion_hooks (new_version_node);
return new_version_node;
}
--- /dev/null
+/* { dg-do compile } */
+
+// With IPA-CP, this caused a problem on darwin, where
+// _M_reset is being cloned, it was still being marked
+// as weak and then we had to change the calls to the
+// newly marked function for the non throwing behavior.
+
+int& f(int&);
+inline void _M_reset(int &_M_vbp) throw()
+{
+ f(_M_vbp);
+}
+extern int _S_last_request;
+void _M_allocate_single_object() throw()
+{
+ _M_reset(_S_last_request);
+ _M_reset(_S_last_request);
+}