diff options
author | Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> | 2019-01-29 10:19:44 +0000 |
---|---|---|
committer | Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> | 2019-01-29 10:19:44 +0000 |
commit | d014d576a9f87c5e952e325cb1c889c7998878d7 (patch) | |
tree | 29278cd8d18fefa71c7bcb3b9e871617a108f6a0 /llvm/lib/Transforms/IPO/IPConstantPropagation.cpp | |
parent | 2c3d49b7183679aaad59f4a45a4017a8b6c26532 (diff) | |
download | bcm5719-llvm-d014d576a9f87c5e952e325cb1c889c7998878d7.tar.gz bcm5719-llvm-d014d576a9f87c5e952e325cb1c889c7998878d7.zip |
[IPCP] Don't crash due to arg count/type mismatch between caller/callee
Summary:
This patch avoids an assert in IPConstantPropagation when
there is a argument count/type mismatch between the caller and
the callee.
While this is actually UB on C-level (clang emits a warning),
the IR verifier seems to accept it. I'm not sure what other
frontends/languages might think about this, so simply bailing out
to avoid hitting an assert (in CallSiteBase<>::getArgOperand or
Value::doRAUW) seems like a simple solution.
The problem is exposed by the fact that AbstractCallSites will look
through a bitcast at the callee position of a call/invoke.
Reviewers: jdoerfert, reames, efriedma
Reviewed By: jdoerfert, efriedma
Subscribers: eli.friedman, efriedma, llvm-commits
Differential Revision: https://reviews.llvm.org/D57052
llvm-svn: 352469
Diffstat (limited to 'llvm/lib/Transforms/IPO/IPConstantPropagation.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/IPConstantPropagation.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp index 8d51c6a27ab..7dc4d9ee9e3 100644 --- a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -66,6 +66,13 @@ static bool PropagateConstantsIntoArguments(Function &F) { if (!ACS) return false; + // Mismatched argument count is undefined behavior. Simply bail out to avoid + // handling of such situations below (avoiding asserts/crashes). + unsigned NumActualArgs = ACS.getNumArgOperands(); + if (F.isVarArg() ? ArgumentConstants.size() > NumActualArgs + : ArgumentConstants.size() != NumActualArgs) + return false; + // Check out all of the potentially constant arguments. Note that we don't // inspect varargs here. Function::arg_iterator Arg = F.arg_begin(); @@ -78,6 +85,11 @@ static bool PropagateConstantsIntoArguments(Function &F) { Value *V = ACS.getCallArgOperand(i); Constant *C = dyn_cast_or_null<Constant>(V); + // Mismatched argument type is undefined behavior. Simply bail out to avoid + // handling of such situations below (avoiding asserts/crashes). + if (C && Arg->getType() != C->getType()) + return false; + // We can only propagate thread independent values through callbacks. // This is different to direct/indirect call sites because for them we // know the thread executing the caller and callee is the same. For |