Nice! On May 16, 2012, at 9:01 AM, Jordy Rose <[email protected]> wrote:
> Author: jrose > Date: Wed May 16 11:01:07 2012 > New Revision: 156919 > > URL: http://llvm.org/viewvc/llvm-project?rev=156919&view=rev > Log: > [analyzer] Introduce clang_analyzer_eval for regression test constraint > checks. > > The new debug.ExprInspection checker looks for calls to clang_analyzer_eval, > and emits a warning of TRUE, FALSE, or UNKNOWN (or UNDEFINED) based on the > constrained value of its (boolean) argument. It does not modify the analysis > state though the conditions tested can result in branches (e.g. through the > use of short-circuit operators). > > Added: > cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp > Modified: > cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt > cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td > cfe/trunk/test/Analysis/global-region-invalidation.c > > Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=156919&r1=156918&r2=156919&view=diff > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original) > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Wed May 16 11:01:07 > 2012 > @@ -31,6 +31,7 @@ > DebugCheckers.cpp > DereferenceChecker.cpp > DivZeroChecker.cpp > + ExprInspectionChecker.cpp > FixedAddressChecker.cpp > GenericTaintChecker.cpp > IdempotentOperationChecker.cpp > > Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td?rev=156919&r1=156918&r2=156919&view=diff > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td (original) > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td Wed May 16 11:01:07 2012 > @@ -483,5 +483,9 @@ > HelpText<"Mark tainted symbols as such.">, > DescFile<"TaintTesterChecker.cpp">; > > +def ExprInspectionChecker : Checker<"ExprInspection">, > + HelpText<"Check the analyzer's understanding of expressions">, > + DescFile<"ExprInspectionChecker.cpp">; > + > } // end "debug" > > > Added: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp?rev=156919&view=auto > ============================================================================== > --- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp (added) > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Wed May > 16 11:01:07 2012 > @@ -0,0 +1,85 @@ > +//==- ExprInspectionChecker.cpp - Used for regression tests ------*- C++ > -*-==// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "ClangSACheckers.h" > +#include "clang/StaticAnalyzer/Core/Checker.h" > +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" > +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" > + > +using namespace clang; > +using namespace ento; > + > +namespace { > +class ExprInspectionChecker : public Checker< eval::Call > { > + mutable OwningPtr<BugType> BT; > +public: > + bool evalCall(const CallExpr *CE, CheckerContext &C) const; > +}; > +} > + > +bool ExprInspectionChecker::evalCall(const CallExpr *CE, > + CheckerContext &C) const { > + // These checks should have no effect on the surrounding environment > + // (globals should not be evaluated, etc), hence the use of evalCall. > + ExplodedNode *N = C.getPredecessor(); > + const LocationContext *LC = N->getLocationContext(); > + > + if (!C.getCalleeName(CE).equals("clang_analyzer_eval")) > + return false; > + > + // A specific instantiation of an inlined function may have more > constrained > + // values than can generally be assumed. Skip the check. > + if (LC->getParent() != 0) > + return true; > + > + const char *Msg = 0; > + > + if (CE->getNumArgs() == 0) > + Msg = "Missing assertion argument"; > + else { > + ProgramStateRef State = N->getState(); > + const Expr *Assertion = CE->getArg(0); > + SVal AssertionVal = State->getSVal(Assertion, LC); > + > + if (AssertionVal.isUndef()) > + Msg = "UNDEFINED"; > + else { > + ProgramStateRef StTrue, StFalse; > + llvm::tie(StTrue, StFalse) = > + State->assume(cast<DefinedOrUnknownSVal>(AssertionVal)); > + > + if (StTrue) { > + if (StFalse) > + Msg = "UNKNOWN"; > + else > + Msg = "TRUE"; > + } else { > + if (StFalse) > + Msg = "FALSE"; > + else > + llvm_unreachable("Invalid constraint; neither true or false."); > + } > + } > + } > + > + assert(Msg); > + > + if (!BT) > + BT.reset(new BugType("Checking analyzer assumptions", "debug")); > + > + BugReport *R = new BugReport(*BT, Msg, N); > + C.EmitReport(R); > + > + return true; > +} > + > +void ento::registerExprInspectionChecker(CheckerManager &Mgr) { > + Mgr.registerChecker<ExprInspectionChecker>(); > +} > + > > Modified: cfe/trunk/test/Analysis/global-region-invalidation.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/global-region-invalidation.c?rev=156919&r1=156918&r2=156919&view=diff > ============================================================================== > --- cfe/trunk/test/Analysis/global-region-invalidation.c (original) > +++ cfe/trunk/test/Analysis/global-region-invalidation.c Wed May 16 11:01:07 > 2012 > @@ -1,4 +1,6 @@ > -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free > -analyzer-eagerly-assume > -analyzer-checker=core,deadcode,experimental.security.taint,debug.TaintTest > -verify %s > +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free > -analyzer-eagerly-assume > -analyzer-checker=core,deadcode,experimental.security.taint,debug.TaintTest,debug.ExprInspection > -verify %s > + > +void clang_analyzer_eval(int); > > // Note, we do need to include headers here, since the analyzer checks if the > function declaration is located in a system header. > #include "system-header-simulator.h" > @@ -73,3 +75,12 @@ > } > return 0; > } > + > +void testAnalyzerEvalIsPure() { > + extern int someGlobal; > + if (someGlobal == 0) { > + clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} > + clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} > + } > +} > + > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
