diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:33:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-26 20:33:12 +0000 |
commit | ef915aab0ac566c55bfb0d7a9f6635bb5d94d4af (patch) | |
tree | ac935cfa19985d33098fc13e288b5ac830672dba /lib/StaticAnalyzer | |
parent | 325377b57338e700317f5e423e5b0f1c08d99a39 (diff) | |
download | src-ef915aab0ac566c55bfb0d7a9f6635bb5d94d4af.tar.gz src-ef915aab0ac566c55bfb0d7a9f6635bb5d94d4af.zip |
Vendor import of clang trunk r306325:vendor/clang/clang-trunk-r306325
Notes
Notes:
svn path=/vendor/clang/dist/; revision=320376
svn path=/vendor/clang/clang-trunk-r306325/; revision=320377; tag=vendor/clang/clang-trunk-r306325
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 51 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CloneChecker.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp | 43 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 5 |
6 files changed, 107 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 48d6cd8a527c..097d4198800d 100644 --- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -50,8 +50,10 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE, state = state->assume(ArgSVal.castAs<DefinedOrUnknownSVal>(), true); // FIXME: do we want to warn here? Not right now. The most reports might // come from infeasible paths, thus being false positives. - if (!state) + if (!state) { + C.generateSink(C.getState(), C.getPredecessor()); return true; + } C.addTransition(state); return true; diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 32e3ce9270aa..77c24629d71e 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -120,6 +120,7 @@ public: void evalStdCopy(CheckerContext &C, const CallExpr *CE) const; void evalStdCopyBackward(CheckerContext &C, const CallExpr *CE) const; void evalStdCopyCommon(CheckerContext &C, const CallExpr *CE) const; + void evalMemset(CheckerContext &C, const CallExpr *CE) const; // Utility methods std::pair<ProgramStateRef , ProgramStateRef > @@ -1999,6 +2000,54 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C, C.addTransition(State); } +void CStringChecker::evalMemset(CheckerContext &C, const CallExpr *CE) const { + if (CE->getNumArgs() != 3) + return; + + CurrentFunctionDescription = "memory set function"; + + const Expr *Mem = CE->getArg(0); + const Expr *Size = CE->getArg(2); + ProgramStateRef State = C.getState(); + + // See if the size argument is zero. + const LocationContext *LCtx = C.getLocationContext(); + SVal SizeVal = State->getSVal(Size, LCtx); + QualType SizeTy = Size->getType(); + + ProgramStateRef StateZeroSize, StateNonZeroSize; + std::tie(StateZeroSize, StateNonZeroSize) = + assumeZero(C, State, SizeVal, SizeTy); + + // Get the value of the memory area. + SVal MemVal = State->getSVal(Mem, LCtx); + + // If the size is zero, there won't be any actual memory access, so + // just bind the return value to the Mem buffer and return. + if (StateZeroSize && !StateNonZeroSize) { + StateZeroSize = StateZeroSize->BindExpr(CE, LCtx, MemVal); + C.addTransition(StateZeroSize); + 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; + State = InvalidateBuffer(C, State, Mem, C.getSVal(Mem), + /*IsSourceBuffer*/false, Size); + if (!State) + return; + + State = State->BindExpr(CE, LCtx, MemVal); + C.addTransition(State); +} + static bool isCPPStdLibraryFunction(const FunctionDecl *FD, StringRef Name) { IdentifierInfo *II = FD->getIdentifier(); if (!II) @@ -2032,6 +2081,8 @@ bool CStringChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { evalFunction = &CStringChecker::evalMemcmp; else if (C.isCLibraryFunction(FDecl, "memmove")) evalFunction = &CStringChecker::evalMemmove; + else if (C.isCLibraryFunction(FDecl, "memset")) + evalFunction = &CStringChecker::evalMemset; else if (C.isCLibraryFunction(FDecl, "strcpy")) evalFunction = &CStringChecker::evalStrcpy; else if (C.isCLibraryFunction(FDecl, "strncpy")) diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 1885b0e39203..83955c586b68 100644 --- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -73,12 +73,17 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU, bool ReportNormalClones = Mgr.getAnalyzerOptions().getBooleanOption( "ReportNormalClones", true, this); + StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions().getOptionAsString( + "IgnoredFilesPattern", "", this); + // Let the CloneDetector create a list of clones from all the analyzed // statements. We don't filter for matching variable patterns at this point // because reportSuspiciousClones() wants to search them for errors. std::vector<CloneDetector::CloneGroup> AllCloneGroups; - Detector.findClones(AllCloneGroups, RecursiveCloneTypeIIConstraint(), + Detector.findClones(AllCloneGroups, + FilenamePatternConstraint(IgnoredFilesPattern), + RecursiveCloneTypeIIConstraint(), MinComplexityConstraint(MinComplexity), MinGroupSizeConstraint(2), OnlyLargestCloneConstraint()); diff --git a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index af35c2b0e991..6bbaaac05e6b 100644 --- a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -281,6 +281,9 @@ void NonLocalizedStringChecker::initUIMethods(ASTContext &Ctx) const { IdentifierInfo *setLabelNSSegmentedControl[] = { &Ctx.Idents.get("setLabel"), &Ctx.Idents.get("forSegment")}; ADD_METHOD(NSSegmentedControl, setLabelNSSegmentedControl, 2, 0) + IdentifierInfo *setToolTipNSSegmentedControl[] = { + &Ctx.Idents.get("setToolTip"), &Ctx.Idents.get("forSegment")}; + ADD_METHOD(NSSegmentedControl, setToolTipNSSegmentedControl, 2, 0) NEW_RECEIVER(NSButtonCell) ADD_UNARY_METHOD(NSButtonCell, setTitle, 0) @@ -562,6 +565,46 @@ void NonLocalizedStringChecker::initUIMethods(ASTContext &Ctx) const { IdentifierInfo *setTitleUISegmentedControl[] = { &Ctx.Idents.get("setTitle"), &Ctx.Idents.get("forSegmentAtIndex")}; ADD_METHOD(UISegmentedControl, setTitleUISegmentedControl, 2, 0) + + NEW_RECEIVER(NSAccessibilityCustomRotorItemResult) + IdentifierInfo + *initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult[] = { + &Ctx.Idents.get("initWithItemLoadingToken"), + &Ctx.Idents.get("customLabel")}; + ADD_METHOD(NSAccessibilityCustomRotorItemResult, + initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult, 2, 1) + ADD_UNARY_METHOD(NSAccessibilityCustomRotorItemResult, setCustomLabel, 0) + + NEW_RECEIVER(UIContextualAction) + IdentifierInfo *contextualActionWithStyleUIContextualAction[] = { + &Ctx.Idents.get("contextualActionWithStyle"), &Ctx.Idents.get("title"), + &Ctx.Idents.get("handler")}; + ADD_METHOD(UIContextualAction, contextualActionWithStyleUIContextualAction, 3, + 1) + ADD_UNARY_METHOD(UIContextualAction, setTitle, 0) + + NEW_RECEIVER(NSAccessibilityCustomRotor) + IdentifierInfo *initWithLabelNSAccessibilityCustomRotor[] = { + &Ctx.Idents.get("initWithLabel"), &Ctx.Idents.get("itemSearchDelegate")}; + ADD_METHOD(NSAccessibilityCustomRotor, + initWithLabelNSAccessibilityCustomRotor, 2, 0) + ADD_UNARY_METHOD(NSAccessibilityCustomRotor, setLabel, 0) + + NEW_RECEIVER(NSWindowTab) + ADD_UNARY_METHOD(NSWindowTab, setTitle, 0) + ADD_UNARY_METHOD(NSWindowTab, setToolTip, 0) + + NEW_RECEIVER(NSAccessibilityCustomAction) + IdentifierInfo *initWithNameNSAccessibilityCustomAction[] = { + &Ctx.Idents.get("initWithName"), &Ctx.Idents.get("handler")}; + ADD_METHOD(NSAccessibilityCustomAction, + initWithNameNSAccessibilityCustomAction, 2, 0) + IdentifierInfo *initWithNameTargetNSAccessibilityCustomAction[] = { + &Ctx.Idents.get("initWithName"), &Ctx.Idents.get("target"), + &Ctx.Idents.get("selector")}; + ADD_METHOD(NSAccessibilityCustomAction, + initWithNameTargetNSAccessibilityCustomAction, 3, 0) + ADD_UNARY_METHOD(NSAccessibilityCustomAction, setName, 0) } #define LSF_INSERT(function_name) LSF.insert(&Ctx.Idents.get(function_name)); diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 45ef612ee1d5..11b9f8c4f725 100644 --- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -293,7 +293,7 @@ unsigned AnalyzerOptions::getMaxInlinableSize() { DefaultValue = 4; break; case UMK_Deep: - DefaultValue = 50; + DefaultValue = 100; break; } @@ -332,7 +332,7 @@ unsigned AnalyzerOptions::getMaxNodesPerTopLevelFunction() { DefaultValue = 75000; break; case UMK_Deep: - DefaultValue = 150000; + DefaultValue = 225000; break; } MaxNodesPerTopLevelFunction = getOptionAsInteger("max-nodes", DefaultValue); diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 8f720a2067b1..6f1e8391e67c 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -980,10 +980,9 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, // transfer functions as "0 == E". SVal Result; if (Optional<Loc> LV = V.getAs<Loc>()) { - Loc X = svalBuilder.makeNull(); + Loc X = svalBuilder.makeNullWithType(Ex->getType()); Result = evalBinOp(state, BO_EQ, *LV, X, U->getType()); - } - else if (Ex->getType()->isFloatingType()) { + } else if (Ex->getType()->isFloatingType()) { // FIXME: handle floating point types. Result = UnknownVal(); } else { |