[PATCH] D14350: [FunctionAttrs] Fix an iterator wraparound bug
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 4 14:37:44 PST 2015
sanjoy created this revision.
sanjoy added reviewers: chandlerc, reames.
sanjoy added a subscriber: llvm-commits.
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.
http://reviews.llvm.org/D14350
Files:
lib/Transforms/IPO/FunctionAttrs.cpp
test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll
Index: test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll
===================================================================
--- /dev/null
+++ test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll
@@ -0,0 +1,30 @@
+; RUN: opt -functionattrs -S < %s | FileCheck %s
+
+; This checks for an iterator wraparound bug in FunctionAttrs. The previous
+; "incorrect" behavior was inferring readonly for the %x argument in @caller.
+; Inferring readonly for %x *is* actually correct, since @va_func is marked
+; readonly, but FunctionAttrs was inferring readonly for the wrong reasons (and
+; we _need_ the readonly on @va_func to trigger the problematic code path). It
+; is possible that in the future FunctionAttrs becomes smart enough to infer
+; readonly for %x for the right reasons, and at that point this test will have
+; to be marked invalid.
+
+declare void @llvm.va_start(i8*)
+declare void @llvm.va_end(i8*)
+
+define void @va_func(i32* readonly %b, ...) readonly nounwind {
+; CHECK-LABEL: define void @va_func(i32* nocapture readonly %b, ...)
+ entry:
+ %valist = alloca i8
+ call void @llvm.va_start(i8* %valist)
+ call void @llvm.va_end(i8* %valist)
+ %x = call i32 @caller(i32* %b)
+ ret void
+}
+
+define i32 @caller(i32* %x) {
+; CHECK-LABEL: define i32 @caller(i32* nocapture %x)
+ entry:
+ call void(i32*,...) @va_func(i32* null, i32 0, i32 0, i32 0, i32* %x)
+ ret i32 42
+}
Index: lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- lib/Transforms/IPO/FunctionAttrs.cpp
+++ lib/Transforms/IPO/FunctionAttrs.cpp
@@ -442,9 +442,11 @@
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) {
+ bool InVarArgSection = false;
+ for (CallSite::arg_iterator A = B; A != E; ++A) {
+ InVarArgSection |= (AI == AE);
if (A->get() == V) {
- if (AI == AE) {
+ if (InVarArgSection) {
assert(F->isVarArg() &&
"More params than args in non-varargs call.");
return Attribute::None;
@@ -457,6 +459,8 @@
if (!CS.doesNotAccessMemory(A - B))
IsRead = true;
}
+ if (!InVarArgSection)
+ ++AI;
}
AddUsersToWorklistIfCapturing();
break;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14350.39260.patch
Type: text/x-patch
Size: 2414 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151104/8b54e48e/attachment.bin>
More information about the llvm-commits
mailing list