diff options
| author | Kuba Mracek <mracek@apple.com> | 2017-04-14 16:53:25 +0000 |
|---|---|---|
| committer | Kuba Mracek <mracek@apple.com> | 2017-04-14 16:53:25 +0000 |
| commit | 5e5e4e790f8758000fe08bc784d9cf6187d5e950 (patch) | |
| tree | fc2656862ecceb04699f2f9a30ec05e1fce8b7ba /clang/lib | |
| parent | 01545beb75566e16db480e929068f6cd9f3b98ef (diff) | |
| download | bcm5719-llvm-5e5e4e790f8758000fe08bc784d9cf6187d5e950.tar.gz bcm5719-llvm-5e5e4e790f8758000fe08bc784d9cf6187d5e950.zip | |
[ObjC] Fix lifetime markers of loop variable in EmitObjCForCollectionStmt [take 2]
CodeGenFunction::EmitObjCForCollectionStmt currently emits lifetime markers for the loop variable in an inconsistent way: lifetime.start is emitted before the loop is entered, but lifetime.end is emitted inside the loop. AddressSanitizer uses these markers to track out-of-scope accesses to local variables, and we get false positives in Obj-C foreach loops (in the 2nd iteration of the loop). This patch keeps the loop variable alive for the whole loop by extending ForScope and registering the cleanup function inside EmitAutoVarAlloca.
Differential Revision: https://reviews.llvm.org/D32029
llvm-svn: 300340
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 4 |
2 files changed, 8 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index bb876c1be70..0f959043a22 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1118,6 +1118,12 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { if (D.hasAttr<AnnotateAttr>()) EmitVarAnnotations(&D, address.getPointer()); + // Make sure we call @llvm.lifetime.end. + if (emission.useLifetimeMarkers()) + EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, + emission.getAllocatedAddress(), + emission.getSizeForLifetimeMarkers()); + return emission; } @@ -1408,13 +1414,6 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { const VarDecl &D = *emission.Variable; - // Make sure we call @llvm.lifetime.end. This needs to happen - // *last*, so the cleanup needs to be pushed *first*. - if (emission.useLifetimeMarkers()) - EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, - emission.getAllocatedAddress(), - emission.getSizeForLifetimeMarkers()); - // Check the type for a cleanup. if (QualType::DestructionKind dtorKind = D.getType().isDestructedType()) emitAutoVarTypeCleanup(emission, dtorKind); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 929bda9099b..c011ab4dfc9 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1469,6 +1469,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ if (DI) DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); + RunCleanupsScope ForScope(*this); + // The local variable comes into scope immediately. AutoVarEmission variable = AutoVarEmission::invalid(); if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) @@ -1499,8 +1501,6 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ ArrayType::Normal, 0); Address ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); - RunCleanupsScope ForScope(*this); - // Emit the collection pointer. In ARC, we do a retain. llvm::Value *Collection; if (getLangOpts().ObjCAutoRefCount) { |

