xazax.hun updated this revision to Diff 232968. xazax.hun edited the summary of this revision. xazax.hun added a comment.
- Added a test. More rigorous tests will come in the FuchsiaHandleChecker. - Added a new PSK_ entry. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71224/new/ https://reviews.llvm.org/D71224 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/include/clang/StaticAnalyzer/Core/CheckerManager.h clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp clang/test/Analysis/analyzer-config.c clang/test/Analysis/ponter-escape-on-conservative-calls.c
Index: clang/test/Analysis/ponter-escape-on-conservative-calls.c =================================================================== --- /dev/null +++ clang/test/Analysis/ponter-escape-on-conservative-calls.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PointerEscape=true -analyzer-config debug.AnalysisOrder:PostCall=true %s 2>&1 | FileCheck %s + + +void f(int *); + +int main() { + int a; + f(&a); + return 0; +} + +// CHECK: PostCall +// CHECK-NEXT: PointerEscape Index: clang/test/Analysis/analyzer-config.c =================================================================== --- clang/test/Analysis/analyzer-config.c +++ clang/test/Analysis/analyzer-config.c @@ -37,6 +37,7 @@ // CHECK-NEXT: debug.AnalysisOrder:EndFunction = false // CHECK-NEXT: debug.AnalysisOrder:LiveSymbols = false // CHECK-NEXT: debug.AnalysisOrder:NewAllocator = false +// CHECK-NEXT: debug.AnalysisOrder:PointerEscape = false // CHECK-NEXT: debug.AnalysisOrder:PostCall = false // CHECK-NEXT: debug.AnalysisOrder:PostStmtArraySubscriptExpr = false // CHECK-NEXT: debug.AnalysisOrder:PostStmtCXXNewExpr = false @@ -97,4 +98,4 @@ // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 94 +// CHECK-NEXT: num-entries = 95 Index: clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -592,9 +592,71 @@ for (auto I : dstCallEvaluated) finishArgumentConstruction(dstArgumentCleanup, I, Call); - // Finally, run any post-call checks. - getCheckerManager().runCheckersForPostCall(Dst, dstArgumentCleanup, + ExplodedNodeSet dstPostCall; + getCheckerManager().runCheckersForPostCall(dstPostCall, dstArgumentCleanup, Call, *this); + + // Escaping symbols conjured during invalidationg the regions above. + // Note that, for inlined calls the nodes were put back into the worklist, + // so we can assume that every node belongs to a conservative call at this + // point. + class CollectReachableSymbolsCallback final : public SymbolVisitor { + ProgramStateRef State; + InvalidatedSymbols &Symbols; + + public: + explicit CollectReachableSymbolsCallback(ProgramStateRef State, + InvalidatedSymbols &Symbols) + : State(State), Symbols(Symbols) {} + + bool VisitSymbol(SymbolRef Sym) override { return true; } + bool VisitMemRegion(const MemRegion *MR) override { + if (MR->hasStackStorage()) + return false; + QualType T; + if (const TypedRegion *TR = dyn_cast<TypedRegion>(MR)) + T = TR->getLocationType(); + else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) + T = SR->getSymbol()->getType(); + if (T->isVoidPointerType()) + return false; + SVal StoredVal = State->getSVal(MR); + if (SymbolRef Sym = StoredVal.getAsSymbol()) + Symbols.insert(Sym); + return true; + } + }; + + // Run pointerEscape callback with the newly conjured symbols. + for (auto I : dstPostCall) { + NodeBuilder B(I, Dst, *currBldrCtx); + InvalidatedSymbols Symbols; + ProgramStateRef State = I->getState(); + CollectReachableSymbolsCallback Scanner(State, Symbols); + const FunctionDecl *FuncDecl = + dyn_cast_or_null<FunctionDecl>(Call.getDecl()); + if (FuncDecl) { + for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) { + if (Arg >= FuncDecl->getNumParams()) + break; + QualType ParamTy = FuncDecl->getParamDecl(Arg)->getType(); + if (ParamTy.isNull() || + (!ParamTy->isPointerType() && !ParamTy->isReferenceType())) + continue; + if (ParamTy->getPointeeType().isConstQualified()) + continue; + State->scanReachableSymbols(Call.getArgSVal(Arg), Scanner); + } + } + + State = getCheckerManager().runCheckersForPointerEscape( + State, Symbols, &Call, PSK_EscapeOnConservativeCall, nullptr); + + if (State == I->getState()) + Dst.insert(I); + else + B.generateNode(I->getLocation(), State, I); + } } ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, @@ -670,8 +732,7 @@ // Conservatively evaluate call by invalidating regions and binding // a conjured return value. void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, - ExplodedNode *Pred, - ProgramStateRef State) { + ExplodedNode *Pred, ProgramStateRef State) { State = Call.invalidateRegions(currBldrCtx->blockCount(), State); State = bindReturnValue(Call, Pred->getLocationContext(), State); Index: clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -40,6 +40,7 @@ check::EndFunction, check::NewAllocator, check::Bind, + check::PointerEscape, check::RegionChanges, check::LiveSymbols> { @@ -165,6 +166,15 @@ llvm::errs() << "RegionChanges\n"; return State; } + + ProgramStateRef checkPointerEscape(ProgramStateRef State, + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind) const { + if (isCallbackEnabled(State, "PointerEscape")) + llvm::errs() << "PointerEscape\n"; + return State; + } }; } // end anonymous namespace Index: clang/include/clang/StaticAnalyzer/Core/CheckerManager.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -85,6 +85,11 @@ /// argument to a function. PSK_IndirectEscapeOnCall, + + /// Escape for a new symbol that was generated into a region + /// that the analyzer cannot follow during a conservative call. + PSK_EscapeOnConservativeCall, + /// The reason for pointer escape is unknown. For example, /// a region containing this pointer is invalidated. PSK_EscapeOther Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1268,6 +1268,12 @@ "false", Released, Hide>, + CmdLineOption<Boolean, + "PointerEscape", + "", + "false", + Released, + Hide>, CmdLineOption<Boolean, "*", "Enables all callbacks.",
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits