llvm-project/clang/test/Analysis/objc-live-crash.mm

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

31 lines
365 B
Plaintext
Raw Normal View History

[analyzer][NFC] Don't bind values to ObjCForCollectionStmt, replace it with a GDM trait Based on the discussion in D82598#2171312. Thanks @NoQ! D82598 is titled "Get rid of statement liveness, because such a thing doesn't exist", and indeed, expressions express a value, non-expression statements don't. if (a && get() || []{ return true; }()) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ has a value ~ has a value ~~~~~~~~~~ has a value ~~~~~~~~~~~~~~~~~~~~ has a value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doesn't have a value That is simple enough, so it would only make sense if we only assigned symbolic values to expressions in the static analyzer. Yet the interface checkers can access presents, among other strange things, the following two methods: ProgramState::BindExpr(const Stmt *S, const LocationContext *LCtx, SVal V, bool Invalidate=true) ProgramState::getSVal(const Stmt *S, const LocationContext *LCtx) So, what gives? Turns out, we make an exception for ReturnStmt (which we'll leave for another time) and ObjCForCollectionStmt. For any other loops, in order to know whether we should analyze another iteration, among other things, we evaluate it's condition. Which is a problem for ObjCForCollectionStmt, because it simply doesn't have one (CXXForRangeStmt has an implicit one!). In its absence, we assigned the actual statement with a concrete 1 or 0 to indicate whether there are any more iterations left. However, this is wildly incorrect, its just simply not true that the for statement has a value of 1 or 0, we can't calculate its liveness because that doesn't make any sense either, so this patch turns it into a GDM trait. Fixing this allows us to reinstate the assert removed in https://reviews.llvm.org/rG032b78a0762bee129f33e4255ada6d374aa70c71. Differential Revision: https://reviews.llvm.org/D86736
2020-09-11 21:51:25 +08:00
// RUN: %clang --analyze %s -fblocks
// https://reviews.llvm.org/D82598#2171312
@interface Item
// ...
@end
@interface Collection
// ...
@end
typedef void (^Blk)();
struct RAII {
Blk blk;
public:
RAII(Blk blk): blk(blk) {}
~RAII() { blk(); }
};
void foo(Collection *coll) {
RAII raii(^{});
for (Item *item in coll) {}
int i;
{
int j;
}
}