r339244 - [analyzer] Fix a typo in `RegionStore.txt`.
Author: henrywong Date: Wed Aug 8 06:37:28 2018 New Revision: 339244 URL: http://llvm.org/viewvc/llvm-project?rev=339244&view=rev Log: [analyzer] Fix a typo in `RegionStore.txt`. Summary: The typo of the description for default bindings can be confusing. Reviewers: NoQ, george.karpenkov Reviewed By: NoQ, george.karpenkov Subscribers: xazax.hun, szepet, a.sidorin, mikhail.ramalho, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D50382 Modified: cfe/trunk/docs/analyzer/RegionStore.txt Modified: cfe/trunk/docs/analyzer/RegionStore.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/RegionStore.txt?rev=339244&r1=339243&r2=339244&view=diff == --- cfe/trunk/docs/analyzer/RegionStore.txt (original) +++ cfe/trunk/docs/analyzer/RegionStore.txt Wed Aug 8 06:37:28 2018 @@ -118,7 +118,7 @@ sometimes zero, for static data, or "uni int manyInts[10]; manyInts[1] = 42; // Creates a Direct binding for manyInts[1]. print(manyInts[1]); // Retrieves the Direct binding for manyInts[1]; - print(manyInts[0]); // There is no Direct binding for manyInts[1]. + print(manyInts[0]); // There is no Direct binding for manyInts[0]. // Is there a Default binding for the entire array? // There is not, but it is a stack variable, so we use // "uninitialized" as the default value (and emit a @@ -166,6 +166,6 @@ Here's a concrete example: return p2.x;// The binding for FieldRegion 'p2.x' is requested. // There is no Direct binding, so we look for a Default // binding to 'p2' and find the LCV. -// Because it's an LCV, we look at our requested region +// Because it's a LCV, we look at our requested region // and see that it's the '.x' field. We ask for the value // of 'p.x' within the snapshot, and get back 42. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r340407 - [analyzer] Improve `CallDescription` to handle c++ method.
Author: henrywong Date: Wed Aug 22 06:30:46 2018 New Revision: 340407 URL: http://llvm.org/viewvc/llvm-project?rev=340407&view=rev Log: [analyzer] Improve `CallDescription` to handle c++ method. Summary: `CallDecription` can only handle function for the time being. If we want to match c++ method, we can only use method name to match and can't improve the matching accuracy through the qualifiers. This patch add the support for `QualifiedName` matching to improve the matching accuracy. Reviewers: xazax.hun, NoQ, george.karpenkov, rnkovacs Reviewed By: xazax.hun, NoQ, rnkovacs Subscribers: Szelethus, szepet, rnkovacs, a.sidorin, mikhail.ramalho, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D48027 Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=340407&r1=340406&r2=340407&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Wed Aug 22 06:30:46 2018 @@ -80,7 +80,9 @@ class CallDescription { mutable IdentifierInfo *II = nullptr; mutable bool IsLookupDone = false; - StringRef FuncName; + // The list of the qualified names used to identify the specified CallEvent, + // e.g. "{a, b}" represent the qualified names, like "a::b". + std::vector QualifiedName; unsigned RequiredArgs; public: @@ -88,16 +90,31 @@ public: /// Constructs a CallDescription object. /// + /// @param QualifiedName The list of the qualified names of the function that + /// will be matched. It does not require the user to provide the full list of + /// the qualified name. The more details provided, the more accurate the + /// matching. + /// + /// @param RequiredArgs The number of arguments that is expected to match a + /// call. Omit this parameter to match every occurrence of call with a given + /// name regardless the number of arguments. + CallDescription(std::vector QualifiedName, + unsigned RequiredArgs = NoArgRequirement) + : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {} + + /// Constructs a CallDescription object. + /// /// @param FuncName The name of the function that will be matched. /// /// @param RequiredArgs The number of arguments that is expected to match a /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement) - : FuncName(FuncName), RequiredArgs(RequiredArgs) {} + : CallDescription(std::vector({FuncName}), NoArgRequirement) { + } /// Get the name of the function that this object matches. - StringRef getFunctionName() const { return FuncName; } + StringRef getFunctionName() const { return QualifiedName.back(); } }; template Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=340407&r1=340406&r2=340407&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Wed Aug 22 06:30:46 2018 @@ -86,14 +86,20 @@ public: }; InnerPointerChecker() - : AppendFn("append"), AssignFn("assign"), ClearFn("clear"), -CStrFn("c_str"), DataFn("data"), EraseFn("erase"), InsertFn("insert"), -PopBackFn("pop_back"), PushBackFn("push_back"), ReplaceFn("replace"), -ReserveFn("reserve"), ResizeFn("resize"), -ShrinkToFitFn("shrink_to_fit"), SwapFn("swap") {} - - /// Check if the object of this member function call is a `basic_string`. - bool isCalledOnStringObject(const CXXInstanceCall *ICall) const; + : AppendFn({"std", "basic_string", "append"}), +AssignFn({"std", "basic_string", "assign"}), +ClearFn({"std", "basic_string", "clear"}), +CStrFn({"std", "basic_string", "c_str"}), +DataFn({"std", "basic_string", "data"}), +EraseFn({"std", "basic_string", "erase"}), +InsertFn({"std", "basic_string", "insert"}), +PopBackFn({"std", "basic_string", "pop_back"}), +PushBackFn({"std", "basic_string", "push_back"}), +ReplaceFn({"std", "basic_string", "replace"}), +ReserveFn({"std", "basic_string", "reserve"}), +ResizeFn({"std", "basic_string", "resize"}), +ShrinkToFitFn({"std", "basic_string", "shrink_to_fi
r332463 - [analyzer] Improve the modeling of memset().
Author: henrywong Date: Wed May 16 05:37:53 2018 New Revision: 332463 URL: http://llvm.org/viewvc/llvm-project?rev=332463&view=rev Log: [analyzer] Improve the modeling of memset(). Since there is no perfect way bind the non-zero value with the default binding, this patch only considers the case where buffer's offset is zero and the char value is 0. And according to the value for overwriting, decide how to update the string length. Reviewers: dcoughlin, NoQ, xazax.hun, a.sidorin, george.karpenkov Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D44934 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp cfe/trunk/test/Analysis/bstring.cpp cfe/trunk/test/Analysis/null-deref-ps-region.c cfe/trunk/test/Analysis/string.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=332463&r1=332462&r2=332463&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Wed May 16 05:37:53 2018 @@ -158,6 +158,10 @@ public: static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx, const MemRegion *MR); + static bool memsetAux(const Expr *DstBuffer, const Expr *CharE, +const Expr *Size, CheckerContext &C, +ProgramStateRef &State); + // Re-usable checks ProgramStateRef checkNonNull(CheckerContext &C, ProgramStateRef state, @@ -999,6 +1003,95 @@ bool CStringChecker::SummarizeRegion(raw } } +bool CStringChecker::memsetAux(const Expr *DstBuffer, const Expr *CharE, + const Expr *Size, CheckerContext &C, + ProgramStateRef &State) { + SVal MemVal = C.getSVal(DstBuffer); + SVal CharVal = C.getSVal(CharE); + SVal SizeVal = C.getSVal(Size); + const MemRegion *MR = MemVal.getAsRegion(); + if (!MR) +return false; + + // We're about to model memset by producing a "default binding" in the Store. + // Our current implementation - RegionStore - doesn't support default bindings + // that don't cover the whole base region. So we should first get the offset + // and the base region to figure out whether the offset of buffer is 0. + RegionOffset Offset = MR->getAsOffset(); + const MemRegion *BR = Offset.getRegion(); + + Optional SizeNL = SizeVal.getAs(); + if (!SizeNL) +return false; + + SValBuilder &svalBuilder = C.getSValBuilder(); + ASTContext &Ctx = C.getASTContext(); + + // void *memset(void *dest, int ch, size_t count); + // For now we can only handle the case of offset is 0 and concrete char value. + if (Offset.isValid() && !Offset.hasSymbolicOffset() && + Offset.getOffset() == 0) { +// Get the base region's extent. +auto *SubReg = cast(BR); +DefinedOrUnknownSVal Extent = SubReg->getExtent(svalBuilder); + +ProgramStateRef StateWholeReg, StateNotWholeReg; +std::tie(StateWholeReg, StateNotWholeReg) = +State->assume(svalBuilder.evalEQ(State, Extent, *SizeNL)); + +// With the semantic of 'memset()', we should convert the CharVal to +// unsigned char. +CharVal = svalBuilder.evalCast(CharVal, Ctx.UnsignedCharTy, Ctx.IntTy); + +ProgramStateRef StateNullChar, StateNonNullChar; +std::tie(StateNullChar, StateNonNullChar) = +assumeZero(C, State, CharVal, Ctx.UnsignedCharTy); + +if (StateWholeReg && !StateNotWholeReg && StateNullChar && +!StateNonNullChar) { + // If the 'memset()' acts on the whole region of destination buffer and + // the value of the second argument of 'memset()' is zero, bind the second + // argument's value to the destination buffer with 'default binding'. + // FIXME: Since there is no perfect way to bind the non-zero character, we + // can only deal with zero value here. In the future, we need to deal with + // the binding of non-zero value in the case of whole region. + State = State->bindDefaultZero(svalBuilder.makeLoc(BR), + C.getLocationContext()); +} else { + // If the destination buffer's extent is not equal to the value of + // third argument, just invalidate buffer. + State = InvalidateBuffer(C, State, DstBuffer, MemVal, + /*IsSourceBuffer*/ false, Size); +} + +if (StateNullChar && !StateNonNullChar) { + // If the value of the second argument of 'memset()' is zero, set the + // string length of destination buffer to 0 directly. + State = setCStringLength(State, MR, + svalBuilder.makeZeroVal(Ctx.getSizeType())); +} else if (!StateNullChar && StateNonNullChar) { + SVal NewStrLen = svalBuilder.getMetadataSymbolVal( +
r325103 - Test commit access
Author: henrywong Date: Tue Feb 13 23:32:27 2018 New Revision: 325103 URL: http://llvm.org/viewvc/llvm-project?rev=325103&view=rev Log: Test commit access Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=325103&r1=325102&r2=325103&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Feb 13 23:32:27 2018 @@ -393,7 +393,7 @@ public: void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// VisitMemberExpr - Transfer function for builtin atomic expressions + /// VisitAtomicExpr - Transfer function for builtin atomic expressions void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r326709 - [analyzer] Improves the logic of GenericTaintChecker identifying stdin.
Author: henrywong Date: Mon Mar 5 07:41:15 2018 New Revision: 326709 URL: http://llvm.org/viewvc/llvm-project?rev=326709&view=rev Log: [analyzer] Improves the logic of GenericTaintChecker identifying stdin. Summary: GenericTaintChecker can't recognize stdin in some cases. The reason is that `if (PtrTy->getPointeeType() == C.getASTContext().getFILEType()` does not hold when stdin is encountered. My platform is ubuntu16.04 64bit, gcc 5.4.0, glibc 2.23. The definition of stdin is as follows: ``` __BEGIN_NAMESPACE_STD /* The opaque type of streams. This is the definition used elsewhere. */ typedef struct _IO_FILE FILE; ___END_NAMESPACE_STD ... /* The opaque type of streams. This is the definition used elsewhere. */ typedef struct _IO_FILE __FILE; ... /* Standard streams. */ extern struct _IO_FILE *stdin; /* Standard input stream. */ extern struct _IO_FILE *stdout; /* Standard output stream. */ extern struct _IO_FILE *stderr; /* Standard error output stream. */ ``` The type of stdin is as follows AST: ``` ElaboratedType 0xc911170'struct _IO_FILE'sugar `-RecordType 0xc911150'struct _IO_FILE' `-CXXRecord 0xc923ff0'_IO_FILE' ``` `C.getASTContext().GetFILEType()` is as follows AST: ``` TypedefType 0xc932710 'FILE' sugar |-Typedef 0xc9111c0 'FILE' `-ElaboratedType 0xc911170 'struct _IO_FILE' sugar `-RecordType 0xc911150 'struct _IO_FILE' `-CXXRecord 0xc923ff0 '_IO_FILE' ``` So I think it's better to use `getCanonicalType()`. Reviewers: zaks.anna, NoQ, george.karpenkov, a.sidorin Reviewed By: zaks.anna, a.sidorin Subscribers: a.sidorin, cfe-commits, xazax.hun, szepet, MTC Differential Revision: https://reviews.llvm.org/D39159 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp cfe/trunk/test/Analysis/taint-generic.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=326709&r1=326708&r2=326709&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Mon Mar 5 07:41:15 2018 @@ -646,7 +646,8 @@ bool GenericTaintChecker::isStdin(const if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC()) if (const PointerType * PtrTy = dyn_cast(D->getType().getTypePtr())) - if (PtrTy->getPointeeType() == C.getASTContext().getFILEType()) + if (PtrTy->getPointeeType().getCanonicalType() == + C.getASTContext().getFILEType().getCanonicalType()) return true; } return false; Modified: cfe/trunk/test/Analysis/taint-generic.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-generic.c?rev=326709&r1=326708&r2=326709&view=diff == --- cfe/trunk/test/Analysis/taint-generic.c (original) +++ cfe/trunk/test/Analysis/taint-generic.c Mon Mar 5 07:41:15 2018 @@ -1,10 +1,16 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s +// RUN: %clang_analyze_cc1 -DFILE_IS_STRUCT -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s int scanf(const char *restrict format, ...); int getchar(void); typedef struct _FILE FILE; +#ifdef FILE_IS_STRUCT +extern struct _FILE *stdin; +#else extern FILE *stdin; +#endif + int fscanf(FILE *restrict stream, const char *restrict format, ...); int sprintf(char *str, const char *format, ...); void setproctitle(const char *fmt, ...); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r326776 - [Analyzer] More accurate modeling about the increment operator of the operand with type bool.
Author: henrywong Date: Tue Mar 6 04:29:09 2018 New Revision: 326776 URL: http://llvm.org/viewvc/llvm-project?rev=326776&view=rev Log: [Analyzer] More accurate modeling about the increment operator of the operand with type bool. Summary: There is a problem with analyzer that a wrong value is given when modeling the increment operator of the operand with type bool. After `rL307604` is applied, a unsigned overflow may occur. Example: ``` void func() { bool b = true; // unsigned overflow occur, 2 -> 0 U1b b++; } ``` The use of an operand of type bool with the ++ operators is deprecated but valid untill C++17. And if the operand of the increment operator is of type bool, it is set to true. This patch includes two parts: - If the operand of the increment operator is of type bool or type _Bool, set to true. - Modify `BasicValueFactory::getTruthValue()`, use `getIntWidth()` instead `getTypeSize()` and use `unsigned` instead `signed`. Reviewers: alexshap, NoQ, dcoughlin, george.karpenkov Reviewed By: NoQ Subscribers: xazax.hun, szepet, a.sidorin, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D43741 Added: cfe/trunk/test/Analysis/_Bool-increment-decrement.c cfe/trunk/test/Analysis/bool-increment.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h?rev=326776&r1=326775&r2=326776&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h Tue Mar 6 04:29:09 2018 @@ -211,7 +211,7 @@ public: } const llvm::APSInt &getTruthValue(bool b, QualType T) { -return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false); +return getValue(b ? 1 : 0, Ctx.getIntWidth(T), true); } const llvm::APSInt &getTruthValue(bool b) { Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=326776&r1=326775&r2=326776&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Tue Mar 6 04:29:09 2018 @@ -1066,6 +1066,7 @@ void ExprEngine::VisitIncrementDecrement // constant value. If the UnaryOperator has location type, create the // constant with int type and pointer width. SVal RHS; +SVal Result; if (U->getType()->isAnyPointerType()) RHS = svalBuilder.makeArrayIndex(1); @@ -1074,7 +1075,14 @@ void ExprEngine::VisitIncrementDecrement else RHS = UnknownVal(); -SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); +// The use of an operand of type bool with the ++ operators is deprecated +// but valid until C++17. And if the operand of the ++ operator is of type +// bool, it is set to true until C++17. Note that for '_Bool', it is also +// set to true when it encounters ++ operator. +if (U->getType()->isBooleanType() && U->isIncrementOp()) + Result = svalBuilder.makeTruthVal(true, U->getType()); +else + Result = evalBinOp(state, Op, V2, RHS, U->getType()); // Conjure a new symbol if necessary to recover precision. if (Result.isUnknown()){ @@ -1096,7 +1104,6 @@ void ExprEngine::VisitIncrementDecrement Constraint = svalBuilder.evalEQ(state, SymVal, svalBuilder.makeZeroVal(U->getType())); - state = state->assume(Constraint, false); assert(state); } Added: cfe/trunk/test/Analysis/_Bool-increment-decrement.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/_Bool-increment-decrement.c?rev=326776&view=auto == --- cfe/trunk/test/Analysis/_Bool-increment-decrement.c (added) +++ cfe/trunk/test/Analysis/_Bool-increment-decrement.c Tue Mar 6 04:29:09 2018 @@ -0,0 +1,140 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify -std=c99 -Dbool=_Bool -Dtrue=1 -Dfalse=0 %s +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify -std=c11 -Dbool=_Bool -Dtrue=1 -Dfalse=0 %s +extern void clang_analyzer_eval(bool); + +void test__Bool_value() { + { +bool b = true; +clang_analyzer_eval(b == 1); // expected-warning{{TRUE}} + } + + { +bool b = false; +clang_analyzer_eval(b == 0); // expected-warning{{TRUE}} + } + + { +bool b = -10; +clang_analyzer_eval(b == 1); // expected-warning{{TRUE}} + } + + { +
r326782 - [analyzer] CStringChecker.cpp: Remove the duplicated check about null dereference on dest-buffer or src-buffer.
Author: henrywong Date: Tue Mar 6 05:38:42 2018 New Revision: 326782 URL: http://llvm.org/viewvc/llvm-project?rev=326782&view=rev Log: [analyzer] CStringChecker.cpp: Remove the duplicated check about null dereference on dest-buffer or src-buffer. Summary: `CheckBufferAccess()` calls `CheckNonNull()`, so there are some calls to `CheckNonNull()` that are useless. Reviewers: dcoughlin, NoQ, xazax.hun, cfe-commits, george.karpenkov Reviewed By: NoQ Subscribers: szepet, rnkovacs, MTC, a.sidorin Differential Revision: https://reviews.llvm.org/D44075 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=326782&r1=326781&r2=326782&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Tue Mar 6 05:38:42 2018 @@ -1033,21 +1033,6 @@ void CStringChecker::evalCopyCommon(Chec if (stateNonZeroSize) { state = stateNonZeroSize; -// Ensure the destination is not null. If it is NULL there will be a -// NULL pointer dereference. -state = checkNonNull(C, state, Dest, destVal); -if (!state) - return; - -// Get the value of the Src. -SVal srcVal = state->getSVal(Source, LCtx); - -// Ensure the source is not null. If it is NULL there will be a -// NULL pointer dereference. -state = checkNonNull(C, state, Source, srcVal); -if (!state) - return; - // Ensure the accesses are valid and that the buffers do not overlap. const char * const writeWarning = "Memory copy function overflows destination buffer"; @@ -2033,12 +2018,6 @@ void CStringChecker::evalMemset(CheckerC return; } - // Ensure the memory area is not null. - // If it is NULL there will be a NULL pointer dereference. - State = checkNonNull(C, StateNonZeroSize, Mem, MemVal); - if (!State) -return; - State = CheckBufferAccess(C, State, Size, Mem); if (!State) return; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r327962 - [analyzer] Fix the crash in IteratorChecker.cpp when 'SymbolConjured' has a null Stmt.
Author: henrywong Date: Tue Mar 20 02:27:02 2018 New Revision: 327962 URL: http://llvm.org/viewvc/llvm-project?rev=327962&view=rev Log: [analyzer] Fix the crash in IteratorChecker.cpp when 'SymbolConjured' has a null Stmt. When the loop has a null terminator statement and sets 'widen-loops=true', 'invalidateRegions' will constructs the 'SymbolConjured' with null 'Stmt'. And this will lead to a crash in 'IteratorChecker.cpp'. This patch use 'dyn_cast_or_null<>' instead of 'dyn_cast<>' in IteratorChecker.cpp. Differential Revision: https://reviews.llvm.org/D44606 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp cfe/trunk/test/Analysis/loop-widening.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp?rev=327962&r1=327961&r2=327962&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp Tue Mar 20 02:27:02 2018 @@ -604,7 +604,7 @@ BinaryOperator::Opcode getOpcode(const S if (const auto *BSE = dyn_cast(SE)) { return BSE->getOpcode(); } else if (const auto *SC = dyn_cast(SE)) { -const auto *COE = dyn_cast(SC->getStmt()); +const auto *COE = dyn_cast_or_null(SC->getStmt()); if (!COE) return BO_Comma; // Extremal value, neither EQ nor NE if (COE->getOperator() == OO_EqualEqual) { Modified: cfe/trunk/test/Analysis/loop-widening.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-widening.c?rev=327962&r1=327961&r2=327962&view=diff == --- cfe/trunk/test/Analysis/loop-widening.c (original) +++ cfe/trunk/test/Analysis/loop-widening.c Tue Mar 20 02:27:02 2018 @@ -1,4 +1,5 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s +// RUN: %clang_analyze_cc1 -DTEST_NULL_TERM -analyzer-checker=core,unix.Malloc,debug.ExprInspection,alpha.cplusplus.IteratorRange -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s void clang_analyzer_eval(int); void clang_analyzer_warnIfReached(); @@ -188,3 +189,16 @@ void nested_loop_inner_widen() { } clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} } + +#ifdef TEST_NULL_TERM +void null_terminator_loop_widen(int *a) { + int c; + // Loop widening will call 'invalidateRegions()' and 'invalidateRegions()' + // will construct the SymbolConjured with null Stmt because of the null + // terminator statement. Accessing the null Stmt will cause a crash. + for (;;) { +c = *a; // no-crash +a++; + } +} +#endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r333531 - [analyzer] Remove the redundant check about same state transition in `ArrayBoundCheckerV2.cpp`.
Author: henrywong Date: Wed May 30 04:46:45 2018 New Revision: 333531 URL: http://llvm.org/viewvc/llvm-project?rev=333531&view=rev Log: [analyzer] Remove the redundant check about same state transition in `ArrayBoundCheckerV2.cpp`. Summary: Since the `addTransitionImpl()` has a check about same state transition, there is no need to check it in `ArrayBoundCheckerV2.cpp`. Reviewers: NoQ, xazax.hun, george.karpenkov Reviewed By: NoQ Subscribers: szepet, rnkovacs, a.sidorin, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D47451 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp?rev=333531&r1=333530&r2=333531&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp Wed May 30 04:46:45 2018 @@ -125,7 +125,6 @@ void ArrayBoundCheckerV2::checkLocation( // have some flexibility in defining the base region, we can achieve // various levels of conservatism in our buffer overflow checking. ProgramStateRef state = checkerContext.getState(); - ProgramStateRef originalState = state; SValBuilder &svalBuilder = checkerContext.getSValBuilder(); const RegionRawOffsetV2 &rawOffset = @@ -224,8 +223,7 @@ void ArrayBoundCheckerV2::checkLocation( } while (false); - if (state != originalState) -checkerContext.addTransition(state); + checkerContext.addTransition(state); } void ArrayBoundCheckerV2::reportOOB( ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r347635 - [clangd] NFC: Prefer `isa<>` to `dyn_cast<>` to do the checking.
Author: henrywong Date: Mon Nov 26 20:27:00 2018 New Revision: 347635 URL: http://llvm.org/viewvc/llvm-project?rev=347635&view=rev Log: [clangd] NFC: Prefer `isa<>` to `dyn_cast<>` to do the checking. Summary: Prefer `isa<>` to `dyn_cast<>` when there only need a checking. Reviewers: ilya-biryukov, MaskRay Reviewed By: ilya-biryukov, MaskRay Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D54878 Modified: clang-tools-extra/trunk/clangd/AST.cpp Modified: clang-tools-extra/trunk/clangd/AST.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.cpp?rev=347635&r1=347634&r2=347635&view=diff == --- clang-tools-extra/trunk/clangd/AST.cpp (original) +++ clang-tools-extra/trunk/clangd/AST.cpp Mon Nov 26 20:27:00 2018 @@ -95,11 +95,11 @@ std::string printName(const ASTContext & return Out.str(); } // The name was empty, so present an anonymous entity. - if (llvm::dyn_cast(&ND)) + if (isa(ND)) return "(anonymous namespace)"; if (auto *Cls = llvm::dyn_cast(&ND)) return ("(anonymous " + Cls->getKindName() + ")").str(); - if (llvm::dyn_cast(&ND)) + if (isa(ND)) return "(anonymous enum)"; return "(anonymous)"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r330095 - [analyzer] Do not invalidate the `this` pointer.
Author: henrywong Date: Sun Apr 15 03:34:06 2018 New Revision: 330095 URL: http://llvm.org/viewvc/llvm-project?rev=330095&view=rev Log: [analyzer] Do not invalidate the `this` pointer. Summary: `this` pointer is not an l-value, although we have modeled `CXXThisRegion` for `this` pointer, we can only bind it once, which is when we start to inline method. And this patch fixes https://bugs.llvm.org/show_bug.cgi?id=35506. In addition, I didn't find any other cases other than loop-widen that could invalidate `this` pointer. Reviewers: NoQ, george.karpenkov, a.sidorin, seaneveson, szepet Reviewed By: NoQ Subscribers: xazax.hun, rnkovacs, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D45491 Added: cfe/trunk/test/Analysis/this-pointer.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp?rev=330095&r1=330094&r2=330095&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp Sun Apr 15 03:34:06 2018 @@ -59,6 +59,18 @@ ProgramStateRef getWidenedLoopState(Prog ITraits.setTrait(Region, RegionAndSymbolInvalidationTraits::TK_EntireMemSpace); } + + // 'this' pointer is not an lvalue, we should not invalidate it. If the loop + // is located in a method, constructor or destructor, the value of 'this' + // pointer shoule remain unchanged. + if (const CXXMethodDecl *CXXMD = dyn_cast(STC->getDecl())) { +const CXXThisRegion *ThisR = MRMgr.getCXXThisRegion( +CXXMD->getThisType(STC->getAnalysisDeclContext()->getASTContext()), +STC); +ITraits.setTrait(ThisR, + RegionAndSymbolInvalidationTraits::TK_PreserveContents); + } + return PrevState->invalidateRegions(Regions, getLoopCondition(LoopStmt), BlockCount, LCtx, true, nullptr, nullptr, &ITraits); Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=330095&r1=330094&r2=330095&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Sun Apr 15 03:34:06 2018 @@ -2050,6 +2050,9 @@ RegionStoreManager::bind(RegionBindingsC R = GetElementZeroRegion(SR, T); } + assert((!isa(R) || !B.lookup(R)) && + "'this' pointer is not an l-value and is not assignable"); + // Clear out bindings that may overlap with this binding. RegionBindingsRef NewB = removeSubRegionBindings(B, cast(R)); return NewB.addBinding(BindingKey::Make(R, BindingKey::Direct), V); Added: cfe/trunk/test/Analysis/this-pointer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/this-pointer.cpp?rev=330095&view=auto == --- cfe/trunk/test/Analysis/this-pointer.cpp (added) +++ cfe/trunk/test/Analysis/this-pointer.cpp Sun Apr 15 03:34:06 2018 @@ -0,0 +1,88 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config widen-loops=true -analyzer-disable-retry-exhausted -verify %s + +void clang_analyzer_eval(bool); +void clang_analyzer_dump(int); + +// 'this' pointer is not an lvalue, we should not invalidate it. +namespace this_pointer_after_loop_widen { +class A { +public: + A() { +int count = 10; +do { +} while (count--); + } +}; + +void goo(A a); +void test_temporary_object() { + goo(A()); // no-crash +} + +struct B { + int mem; + B() : mem(0) { +for (int i = 0; i < 10; ++i) { +} +mem = 0; + } +}; + +void test_ctor() { + B b; + clang_analyzer_eval(b.mem == 0); // expected-warning{{TRUE}} +} + +struct C { + int mem; + C() : mem(0) {} + void set() { +for (int i = 0; i < 10; ++i) { +} +mem = 10; + } +}; + +void test_method() { + C c; + clang_analyzer_eval(c.mem == 0); // expected-warning{{TRUE}} + c.set(); + clang_analyzer_eval(c.mem == 10); // expected-warning{{TRUE}} +} + +struct D { + int mem; + D() : mem(0) {} + void set() { +for (int i = 0; i < 10; ++i) { +} +mem = 10; + } +}; + +void test_new() { + D *d = new D; + clang_analyzer_eval(d->mem == 0); // expected-warning{{TRUE}} + d->set(); + clang_analyzer_eval(d->mem == 10); // expected-warning{{TRUE}} +} + +struct E { + int mem; + E() : mem(0) {} + void set() { +for (int i = 0; i < 10; ++i) { +} +setAux(); + } + void setAux() { +this->mem = 10; + } +}; + +void test_chained_method_call() { + E e; + e.set(); + clang_analyzer_e
r330589 - [analyzer] CStringChecker.cpp - Code refactoring on bug report.
Author: henrywong Date: Mon Apr 23 06:36:51 2018 New Revision: 330589 URL: http://llvm.org/viewvc/llvm-project?rev=330589&view=rev Log: [analyzer] CStringChecker.cpp - Code refactoring on bug report. Reviewers: NoQ, george.karpenkov, xazax.hun Reviewed By: george.karpenkov Differential Revision: https://reviews.llvm.org/D44557 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=330589&r1=330588&r2=330589&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Mon Apr 23 06:36:51 2018 @@ -194,6 +194,14 @@ public: const Stmt *First, const Stmt *Second) const; + void emitNullArgBug(CheckerContext &C, ProgramStateRef State, const Stmt *S, + StringRef WarningMsg) const; + void emitOutOfBoundsBug(CheckerContext &C, ProgramStateRef State, + const Stmt *S, StringRef WarningMsg) const; + void emitNotCStringBug(CheckerContext &C, ProgramStateRef State, + const Stmt *S, StringRef WarningMsg) const; + void emitAdditionOverflowBug(CheckerContext &C, ProgramStateRef State) const; + ProgramStateRef checkAdditionOverflow(CheckerContext &C, ProgramStateRef state, NonLoc left, @@ -239,30 +247,14 @@ ProgramStateRef CStringChecker::checkNon std::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType()); if (stateNull && !stateNonNull) { -if (!Filter.CheckCStringNullArg) - return nullptr; - -ExplodedNode *N = C.generateErrorNode(stateNull); -if (!N) - return nullptr; - -if (!BT_Null) - BT_Null.reset(new BuiltinBug( - Filter.CheckNameCStringNullArg, categories::UnixAPI, - "Null pointer argument in call to byte string function")); +if (Filter.CheckCStringNullArg) { + SmallString<80> buf; + llvm::raw_svector_ostream os(buf); + assert(CurrentFunctionDescription); + os << "Null pointer argument in call to " << CurrentFunctionDescription; -SmallString<80> buf; -llvm::raw_svector_ostream os(buf); -assert(CurrentFunctionDescription); -os << "Null pointer argument in call to " << CurrentFunctionDescription; - -// Generate a report for this bug. -BuiltinBug *BT = static_cast(BT_Null.get()); -auto report = llvm::make_unique(*BT, os.str(), N); - -report->addRange(S->getSourceRange()); -bugreporter::trackNullOrUndefValue(N, S, *report); -C.emitReport(std::move(report)); + emitNullArgBug(C, stateNull, S, os.str()); +} return nullptr; } @@ -305,31 +297,14 @@ ProgramStateRef CStringChecker::CheckLoc ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true); ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false); if (StOutBound && !StInBound) { -ExplodedNode *N = C.generateErrorNode(StOutBound); -if (!N) - return nullptr; - -CheckName Name; // These checks are either enabled by the CString out-of-bounds checker // explicitly or the "basic" CStringNullArg checker support that Malloc // checker enables. assert(Filter.CheckCStringOutOfBounds || Filter.CheckCStringNullArg); -if (Filter.CheckCStringOutOfBounds) - Name = Filter.CheckNameCStringOutOfBounds; -else - Name = Filter.CheckNameCStringNullArg; -if (!BT_Bounds) { - BT_Bounds.reset(new BuiltinBug( - Name, "Out-of-bound array access", - "Byte string function accesses out-of-bound array element")); -} -BuiltinBug *BT = static_cast(BT_Bounds.get()); - -// Generate a report for this bug. -std::unique_ptr report; +// Emit a bug report. if (warningMsg) { - report = llvm::make_unique(*BT, warningMsg, N); + emitOutOfBoundsBug(C, StOutBound, S, warningMsg); } else { assert(CurrentFunctionDescription); assert(CurrentFunctionDescription[0] != '\0'); @@ -339,15 +314,8 @@ ProgramStateRef CStringChecker::CheckLoc os << toUppercase(CurrentFunctionDescription[0]) << &CurrentFunctionDescription[1] << " accesses out-of-bound array element"; - report = llvm::make_unique(*BT, os.str(), N); + emitOutOfBoundsBug(C, StOutBound, S, os.str()); } - -// FIXME: It would be nice to eventually make this diagnostic more clear, -// e.g., by referencing the original declaration or by saying *why* this -// reference is outside the range. - -report->addRange(S->getSourceRange()); -C.emitReport(std::move(report)); return nullptr; } @@ -567,6 +535,79 @@ void CStringChecker::
r330596 - [analyzer] Move `TaintBugVisitor` from `GenericTaintChecker.cpp` to `BugReporterVisitors.h`.
Author: henrywong Date: Mon Apr 23 07:41:17 2018 New Revision: 330596 URL: http://llvm.org/viewvc/llvm-project?rev=330596&view=rev Log: [analyzer] Move `TaintBugVisitor` from `GenericTaintChecker.cpp` to `BugReporterVisitors.h`. Summary: `TaintBugVisitor` is a universal visitor, and many checkers rely on it, such as `ArrayBoundCheckerV2.cpp`, `DivZeroChecker.cpp` and `VLASizeChecker.cpp`. Moving `TaintBugVisitor` to `BugReporterVisitors.h` enables other checker can also track where `tainted` value came from. Reviewers: NoQ, george.karpenkov, xazax.hun Reviewed By: george.karpenkov Subscribers: szepet, rnkovacs, a.sidorin, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D45682 Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h?rev=330596&r1=330595&r2=330596&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h Mon Apr 23 07:41:17 2018 @@ -343,6 +343,22 @@ public: BugReport &BR) override; }; +/// The bug visitor prints a diagnostic message at the location where a given +/// variable was tainted. +class TaintBugVisitor final : public BugReporterVisitorImpl { +private: + const SVal V; + +public: + TaintBugVisitor(const SVal V) : V(V) {} + void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); } + + std::shared_ptr VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) override; +}; + namespace bugreporter { /// Attempts to add visitors to trace a null or undefined value back to its Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=330596&r1=330595&r2=330596&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Mon Apr 23 07:41:17 2018 @@ -100,23 +100,6 @@ private: bool generateReportIfTainted(const Expr *E, const char Msg[], CheckerContext &C) const; - /// The bug visitor prints a diagnostic message at the location where a given - /// variable was tainted. - class TaintBugVisitor - : public BugReporterVisitorImpl { - private: -const SVal V; - - public: -TaintBugVisitor(const SVal V) : V(V) {} -void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); } - -std::shared_ptr VisitNode(const ExplodedNode *N, - const ExplodedNode *PrevN, - BugReporterContext &BRC, - BugReport &BR) override; - }; - typedef SmallVector ArgVector; /// \brief A struct used to specify taint propagation rules for a function. @@ -214,28 +197,6 @@ const char GenericTaintChecker::MsgTaint /// points to data, which should be tainted on return. REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned) -std::shared_ptr -GenericTaintChecker::TaintBugVisitor::VisitNode(const ExplodedNode *N, -const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) { - - // Find the ExplodedNode where the taint was first introduced - if (!N->getState()->isTainted(V) || PrevN->getState()->isTainted(V)) -return nullptr; - - const Stmt *S = PathDiagnosticLocation::getStmt(N); - if (!S) -return nullptr; - - const LocationContext *NCtx = N->getLocationContext(); - PathDiagnosticLocation L = - PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx); - if (!L.isValid() || !L.asLocation().isValid()) -return nullptr; - - return std::make_shared( - L, "Taint originated here"); -} - GenericTaintChecker::TaintPropagationRule GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule( const FunctionDecl *FDecl, Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=330596&r1=330595&r2=330596&view=diff
r331345 - [analyzer] Add `TaintBugVisitor` to the ArrayBoundV2, DivideZero and VLASize.
Author: henrywong Date: Wed May 2 05:11:22 2018 New Revision: 331345 URL: http://llvm.org/viewvc/llvm-project?rev=331345&view=rev Log: [analyzer] Add `TaintBugVisitor` to the ArrayBoundV2, DivideZero and VLASize. Summary: Add `TaintBugVisitor` to the ArrayBoundV2, DivideZero, VLASize to be able to indicate where the taint information originated from. Reviewers: NoQ, george.karpenkov, xazax.hun, a.sidorin Reviewed By: NoQ Subscribers: szepet, rnkovacs, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D46007 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp cfe/trunk/test/Analysis/taint-diagnostic-visitor.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp?rev=331345&r1=331344&r2=331345&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp Wed May 2 05:11:22 2018 @@ -33,8 +33,8 @@ class ArrayBoundCheckerV2 : enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted }; - void reportOOB(CheckerContext &C, ProgramStateRef errorState, - OOB_Kind kind) const; + void reportOOB(CheckerContext &C, ProgramStateRef errorState, OOB_Kind kind, + std::unique_ptr Visitor = nullptr) const; public: void checkLocation(SVal l, bool isLoad, const Stmt*S, @@ -205,8 +205,10 @@ void ArrayBoundCheckerV2::checkLocation( // If we are under constrained and the index variables are tainted, report. if (state_exceedsUpperBound && state_withinUpperBound) { - if (state->isTainted(rawOffset.getByteOffset())) { -reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted); + SVal ByteOffset = rawOffset.getByteOffset(); + if (state->isTainted(ByteOffset)) { +reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted, + llvm::make_unique(ByteOffset)); return; } } else if (state_exceedsUpperBound) { @@ -226,9 +228,9 @@ void ArrayBoundCheckerV2::checkLocation( checkerContext.addTransition(state); } -void ArrayBoundCheckerV2::reportOOB(CheckerContext &checkerContext, -ProgramStateRef errorState, -OOB_Kind kind) const { +void ArrayBoundCheckerV2::reportOOB( +CheckerContext &checkerContext, ProgramStateRef errorState, OOB_Kind kind, +std::unique_ptr Visitor) const { ExplodedNode *errorNode = checkerContext.generateErrorNode(errorState); if (!errorNode) @@ -255,8 +257,9 @@ void ArrayBoundCheckerV2::reportOOB(Chec break; } - checkerContext.emitReport( - llvm::make_unique(*BT, os.str(), errorNode)); + auto BR = llvm::make_unique(*BT, os.str(), errorNode); + BR->addVisitor(std::move(Visitor)); + checkerContext.emitReport(std::move(BR)); } #ifndef NDEBUG Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp?rev=331345&r1=331344&r2=331345&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp Wed May 2 05:11:22 2018 @@ -24,22 +24,23 @@ using namespace ento; namespace { class DivZeroChecker : public Checker< check::PreStmt > { mutable std::unique_ptr BT; - void reportBug(const char *Msg, - ProgramStateRef StateZero, - CheckerContext &C) const ; + void reportBug(const char *Msg, ProgramStateRef StateZero, CheckerContext &C, + std::unique_ptr Visitor = nullptr) const; + public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; } // end anonymous namespace -void DivZeroChecker::reportBug(const char *Msg, - ProgramStateRef StateZero, - CheckerContext &C) const { +void DivZeroChecker::reportBug( +const char *Msg, ProgramStateRef StateZero, CheckerContext &C, +std::unique_ptr Visitor) const { if (ExplodedNode *N = C.generateErrorNode(StateZero)) { if (!BT) BT.reset(new BuiltinBug(this, "Division by zero")); auto R = llvm::make_unique(*BT, Msg, N); +R->addVisitor(std::move(Visitor)); bugreporter::trackNullOrUndefValue(N, bugreporter::GetDenomExpr(N), *R); C.emitReport(std::move(R)); } @@ -78,7 +79,8 @@ void DivZeroChecker::checkPreStmt(const bool TaintedD = C.getState()->isTainted(*DV); if ((stateNotZero && stateZero && TaintedD)) { -reportBug("Division by a taint
r328860 - [analyzer] Remove the unused method declaration in `ValistChecker.cpp`.
Author: henrywong Date: Fri Mar 30 06:37:50 2018 New Revision: 328860 URL: http://llvm.org/viewvc/llvm-project?rev=328860&view=rev Log: [analyzer] Remove the unused method declaration in `ValistChecker.cpp`. Summary: `getVariableNameFromRegion()` seems useless. Reviewers: xazax.hun, george.karpenkov Reviewed By: xazax.hun Subscribers: szepet, rnkovacs, a.sidorin, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D45081 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp?rev=328860&r1=328859&r2=328860&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp Fri Mar 30 06:37:50 2018 @@ -56,7 +56,6 @@ public: private: const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr, bool &IsSymbolic, CheckerContext &C) const; - StringRef getVariableNameFromRegion(const MemRegion *Reg) const; const ExplodedNode *getStartCallSite(const ExplodedNode *N, const MemRegion *Reg) const; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r328919 - [analyzer] Unroll the loop when it has a unsigned counter.
Author: henrywong Date: Sat Mar 31 05:46:46 2018 New Revision: 328919 URL: http://llvm.org/viewvc/llvm-project?rev=328919&view=rev Log: [analyzer] Unroll the loop when it has a unsigned counter. Summary: The original implementation in the `LoopUnrolling.cpp` didn't consider the case where the counter is unsigned. This case is only handled in `simpleCondition()`, but this is not enough, we also need to deal with the unsinged counter with the counter initialization. Since `IntegerLiteral` is `signed`, there is a `ImplicitCastExpr` in `unsigned counter = IntergerLiteral`. This patch add the `ignoringParenImpCasts()` in the `IntegerLiteral` matcher. Reviewers: szepet, a.sidorin, NoQ, george.karpenkov Reviewed By: szepet, george.karpenkov Subscribers: xazax.hun, rnkovacs, cfe-commits, MTC Differential Revision: https://reviews.llvm.org/D45086 Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp cfe/trunk/test/Analysis/loop-unrolling.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp?rev=328919&r1=328918&r2=328919&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp Sat Mar 31 05:46:46 2018 @@ -141,13 +141,15 @@ static internal::Matcher forLoopMa return forStmt( hasCondition(simpleCondition("initVarName")), // Initialization should match the form: 'int i = 6' or 'i = 42'. - hasLoopInit(anyOf( - declStmt(hasSingleDecl(varDecl( - allOf(hasInitializer(integerLiteral().bind("initNum")), - equalsBoundNode("initVarName"), - binaryOperator(hasLHS(declRefExpr(to( -varDecl(equalsBoundNode("initVarName"), -hasRHS(integerLiteral().bind("initNum"), + hasLoopInit( + anyOf(declStmt(hasSingleDecl( + varDecl(allOf(hasInitializer(ignoringParenImpCasts( + integerLiteral().bind("initNum"))), + equalsBoundNode("initVarName"), + binaryOperator(hasLHS(declRefExpr(to(varDecl( + equalsBoundNode("initVarName"), + hasRHS(ignoringParenImpCasts( + integerLiteral().bind("initNum")), // Incrementation should be a simple increment or decrement // operator call. hasIncrement(unaryOperator( Modified: cfe/trunk/test/Analysis/loop-unrolling.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-unrolling.cpp?rev=328919&r1=328918&r2=328919&view=diff == --- cfe/trunk/test/Analysis/loop-unrolling.cpp (original) +++ cfe/trunk/test/Analysis/loop-unrolling.cpp Sat Mar 31 05:46:46 2018 @@ -36,6 +36,29 @@ int simple_unroll2() { return 0; } +int simple_unroll3_unsigned() { + int a[9]; + int k = 42; + for (unsigned i = 0; i < 9; i++) { +clang_analyzer_numTimesReached(); // expected-warning {{9}} +a[i] = 42; + } + int b = 22 / (k - 42); // expected-warning {{Division by zero}} + return 0; +} + +int simple_unroll4_unsigned() { + int a[9]; + int k = 42; + unsigned i; + for (i = (0); i < 9; i++) { +clang_analyzer_numTimesReached(); // expected-warning {{9}} +a[i] = 42; + } + int b = 22 / (k - 42); // expected-warning {{Division by zero}} + return 0; +} + int simple_no_unroll1() { int a[9]; int k = 42; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits