ahatanak added a comment.
I found another problem with the current patch: it can generate IR that doesn't
pass asan's use-after-scope check. For example, IRGen generates the following
IR for function move_lifetime_start in lifetime2.c when this patch is applied:
entry:
%i = alloca i32, align 4
%0 = bitcast i32* %i to i8*
call void @llvm.lifetime.start(i64 4, i8* nonnull %0) #3
%cmp = icmp eq i32 %a, 2
br label %label1
label1: ; preds = %if.end, %entry
%p.0 = phi i32* [ null, %entry ], [ %i, %if.end ]
%tobool = icmp eq i32* %p.0, null
br i1 %tobool, label %if.end, label %if.then
...
if.end: ; preds = %label1
call void @llvm.lifetime.end(i64 4, i8* nonnull %0) #3
br i1 %cmp, label %cleanup3.loopexit, label %label1
cleanup3.loopexit: ; preds = %if.end
br label %cleanup3
use-after-scope poisons the memory for "%i" after llvm.lifetime.end and
unpoisons it after llvm.lifetime.start, so when the code in block "if.end"
jumps back to "label1", it ends up accessing the memory that is still poisoned.
I think this can be fixed by making changes in CGCleanup.cpp and moving
lifetime.end to block "cleanup3.loopexit", but I'm thinking maybe I should take
a different approach.
What if we analyze the AST before IRGen (probably we can do it in
VarBypassDetector) and mark those variables whose lifetimes need to be extended
and pretend when doing IRGen that those variables are declared at the beginning
of their enclosing compound statements? Basically, EmitVarDecl is called for
the variables that need extended lifetime before EmitCompoundStmt does IRGen
for the body of the compound statement and later when the VarDecl's for those
variables are visited, EmitVarDecl returns without doing anything.
I haven't thought through all the details yet, but do you see any problems with
this approach?
https://reviews.llvm.org/D27680
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits