summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/DeadArgumentElimination.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/IPO/DeadArgumentElimination.cpp')
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 6ee6162ac3..8621f1a78d 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -357,6 +357,19 @@ bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
return false;
+ // If a function seen at compile time is not necessarily the one linked to
+ // the binary being built, it is illegal to change the actual arguments
+ // passing to it. These functions can be captured by isWeakForLinker().
+ // *NOTE* that mayBeOverridden() is insufficient for this purpose as it
+ // dosen't include linkage types like AvailableExternallyLinkage and
+ // LinkOnceODRLinkage. Take link_odr* as an example, it indicates a set of
+ // *EQUIVALENT* globals that can be merged at link-time. However, the
+ // semantic of *EQUIVALENT*-functions includes parameters. Changing
+ // parameters breaks the assumption.
+ //
+ if (Fn.isWeakForLinker())
+ return false;
+
if (Fn.use_empty())
return false;