summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-11-07 01:55:53 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-11-07 01:55:53 +0000
commit436e2397f8ce4802793c27dac37b88427bc52c90 (patch)
tree4eba744c8aa6abda88c5c716f7380bb20889f19b /llvm/lib/Transforms/IPO
parent906c872db9344ce483282938f83ee5d4a262f3e6 (diff)
downloadbcm5719-llvm-436e2397f8ce4802793c27dac37b88427bc52c90.tar.gz
bcm5719-llvm-436e2397f8ce4802793c27dac37b88427bc52c90.zip
[FunctionAttrs] Fix an iterator wraparound bug
Summary: This change fixes an iterator wraparound bug in `determinePointerReadAttrs`. Ideally, ++'ing off the `end()` of an iplist should result in a failed assert, but currently iplist seems to silently wrap to the head of the list on `end()++`. This is why the bad behavior is difficult to demonstrate. Reviewers: chandlerc, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14350 llvm-svn: 252386
Diffstat (limited to 'llvm/lib/Transforms/IPO')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp37
1 files changed, 19 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index a9bc8e4c6de..6024137bfe3 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -394,7 +394,6 @@ determinePointerReadAttrs(Argument *A,
while (!Worklist.empty()) {
Use *U = Worklist.pop_back_val();
Instruction *I = cast<Instruction>(U->getUser());
- Value *V = U->get();
switch (I->getOpcode()) {
case Instruction::BitCast:
@@ -438,24 +437,26 @@ determinePointerReadAttrs(Argument *A,
return Attribute::None;
}
- Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
- for (CallSite::arg_iterator A = B; A != E; ++A, ++AI) {
- if (A->get() == V) {
- if (AI == AE) {
- assert(F->isVarArg() &&
- "More params than args in non-varargs call.");
- return Attribute::None;
- }
- Captures &= !CS.doesNotCapture(A - B);
- if (SCCNodes.count(&*AI))
- continue;
- if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(A - B))
- return Attribute::None;
- if (!CS.doesNotAccessMemory(A - B))
- IsRead = true;
- }
+ // Note: the callee and the two successor blocks *follow* the argument
+ // operands. This means there is no need to adjust UseIndex to account
+ // for these.
+
+ unsigned UseIndex = std::distance(CS.arg_begin(), U);
+
+ assert(UseIndex < CS.arg_size() && "Non-argument use?");
+ if (UseIndex >= F->arg_size()) {
+ assert(F->isVarArg() && "More params than args in non-varargs call");
+ return Attribute::None;
}
+
+ Captures &= !CS.doesNotCapture(UseIndex);
+ if (!SCCNodes.count(std::next(F->arg_begin(), UseIndex))) {
+ if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(UseIndex))
+ return Attribute::None;
+ if (!CS.doesNotAccessMemory(UseIndex))
+ IsRead = true;
+ }
+
AddUsersToWorklistIfCapturing();
break;
}
OpenPOWER on IntegriCloud