diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2019-01-18 19:46:00 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2019-01-18 19:46:00 +0000 |
commit | 3748d41833787fcbf59cc5624e8d2b042a8991bc (patch) | |
tree | f3fcdba7decca7ee845a1bb3f885cb0baa1b4d83 /include/clang/StaticAnalyzer | |
parent | 55c8788102d8fd203270fabd6513247b2d7fbd87 (diff) | |
parent | e054eb577a1f469b1a4a49fce08572c76e2dddf2 (diff) |
Creating branches/google/stable and tags/google/stable/2019-01-18 from r351319
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@351578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer')
-rw-r--r-- | include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h | 37 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Checkers/CheckerBase.td | 13 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Checkers/Checkers.td | 434 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Checkers/ClangCheckers.h | 22 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/AnalyzerOptions.def | 6 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h | 2 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h | 7 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 1 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | 8 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h | 4 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/RetainSummaryManager.h | 195 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (renamed from include/clang/StaticAnalyzer/Core/CheckerRegistry.h) | 28 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Frontend/FrontendActions.h | 6 |
13 files changed, 478 insertions, 285 deletions
diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h new file mode 100644 index 0000000000..192ac1261c --- /dev/null +++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -0,0 +1,37 @@ +//===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declares the registation functions for the checkers defined in +// libclangStaticAnalyzerCheckers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H +#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_CLANGSACHECKERS_H + +#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" + +namespace clang { + +namespace ento { +class CheckerManager; +class CheckerRegistry; + +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ + void register##CLASS(CheckerManager &mgr); +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS + +} // end ento namespace + +} // end clang namespace + +#endif diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index 15034fc689..453e189fcc 100644 --- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -32,6 +32,18 @@ class ParentPackage<Package P> { Package ParentPackage = P; } /// a '-help'-like command line option. class HelpText<string text> { string HelpText = text; } +/// Describes what kind of documentation exists for the checker. +class DocumentationEnum<bits<2> val> { + bits<2> Documentation = val; +} +def NotDocumented : DocumentationEnum<0>; +def HasDocumentation : DocumentationEnum<1>; +def HasAlphaDocumentation : DocumentationEnum<2>; + +class Documentation<DocumentationEnum val> { + bits<2> Documentation = val.Documentation; +} + /// Describes a checker. Every builtin checker has to be registered with the use /// of this class (out-of-trunk checkers loaded from plugins obviously don't). /// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname, @@ -40,5 +52,6 @@ class HelpText<string text> { string HelpText = text; } class Checker<string name = ""> { string CheckerName = name; string HelpText; + bits<2> Documentation; Package ParentPackage; } diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 9feb5a8766..1bb3da7a24 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -102,84 +102,106 @@ def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>; let ParentPackage = Core in { def DereferenceChecker : Checker<"NullDereference">, - HelpText<"Check for dereferences of null pointers">; + HelpText<"Check for dereferences of null pointers">, + Documentation<HasDocumentation>; def CallAndMessageChecker : Checker<"CallAndMessage">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " - "pointers)">; + "pointers)">, + Documentation<HasDocumentation>; def NonNullParamChecker : Checker<"NonNullParamChecker">, HelpText<"Check for null pointers passed as arguments to a function whose " - "arguments are references or marked with the 'nonnull' attribute">; + "arguments are references or marked with the 'nonnull' attribute">, + Documentation<HasDocumentation>; def VLASizeChecker : Checker<"VLASize">, - HelpText<"Check for declarations of VLA of undefined or zero size">; + HelpText<"Check for declarations of VLA of undefined or zero size">, + Documentation<HasDocumentation>; def DivZeroChecker : Checker<"DivideZero">, - HelpText<"Check for division by zero">; + HelpText<"Check for division by zero">, + Documentation<HasDocumentation>; def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, - HelpText<"Check for undefined results of binary operators">; + HelpText<"Check for undefined results of binary operators">, + Documentation<HasDocumentation>; def StackAddrEscapeChecker : Checker<"StackAddressEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">; + HelpText<"Check that addresses to stack memory do not escape the function">, + Documentation<HasDocumentation>; def DynamicTypePropagation : Checker<"DynamicTypePropagation">, - HelpText<"Generate dynamic type information">; + HelpText<"Generate dynamic type information">, + Documentation<NotDocumented>; def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, - HelpText<"Assume that const string-like globals are non-null">; + HelpText<"Assume that const string-like globals are non-null">, + Documentation<NotDocumented>; } // end "core" let ParentPackage = CoreAlpha in { def BoolAssignmentChecker : Checker<"BoolAssignment">, - HelpText<"Warn about assigning non-{0,1} values to Boolean variables">; + HelpText<"Warn about assigning non-{0,1} values to Boolean variables">, + Documentation<HasAlphaDocumentation>; def CastSizeChecker : Checker<"CastSize">, HelpText<"Check when casting a malloc'ed type T, whether the size is a " - "multiple of the size of T">; + "multiple of the size of T">, + Documentation<HasAlphaDocumentation>; def CastToStructChecker : Checker<"CastToStruct">, - HelpText<"Check for cast from non-struct pointer to struct pointer">; + HelpText<"Check for cast from non-struct pointer to struct pointer">, + Documentation<HasAlphaDocumentation>; def ConversionChecker : Checker<"Conversion">, - HelpText<"Loss of sign/precision in implicit conversions">; + HelpText<"Loss of sign/precision in implicit conversions">, + Documentation<HasAlphaDocumentation>; def IdenticalExprChecker : Checker<"IdenticalExpr">, - HelpText<"Warn about unintended use of identical expressions in operators">; + HelpText<"Warn about unintended use of identical expressions in operators">, + Documentation<HasAlphaDocumentation>; def FixedAddressChecker : Checker<"FixedAddr">, - HelpText<"Check for assignment of a fixed address to a pointer">; + HelpText<"Check for assignment of a fixed address to a pointer">, + Documentation<HasAlphaDocumentation>; def PointerArithChecker : Checker<"PointerArithm">, HelpText<"Check for pointer arithmetic on locations other than array " - "elements">; + "elements">, + Documentation<HasAlphaDocumentation>; def PointerSubChecker : Checker<"PointerSub">, HelpText<"Check for pointer subtractions on two pointers pointing to " - "different memory chunks">; + "different memory chunks">, + Documentation<HasAlphaDocumentation>; def SizeofPointerChecker : Checker<"SizeofPtr">, - HelpText<"Warn about unintended use of sizeof() on pointer expressions">; + HelpText<"Warn about unintended use of sizeof() on pointer expressions">, + Documentation<HasAlphaDocumentation>; def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " - "pointers, and pointer to undefined variables)">; + "pointers, and pointer to undefined variables)">, + Documentation<HasAlphaDocumentation>; def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, HelpText<"Check for division by variable that is later compared against 0. " - "Either the comparison is useless or there is division by zero.">; + "Either the comparison is useless or there is division by zero.">, + Documentation<HasAlphaDocumentation>; def DynamicTypeChecker : Checker<"DynamicTypeChecker">, HelpText<"Check for cases where the dynamic and the static type of an object " - "are unrelated.">; + "are unrelated.">, + Documentation<HasAlphaDocumentation>; def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, - HelpText<"Check that addresses to stack memory do not escape the function">; + HelpText<"Check that addresses to stack memory do not escape the function">, + Documentation<HasAlphaDocumentation>; } // end "alpha.core" @@ -187,33 +209,40 @@ let ParentPackage = Nullability in { def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">, HelpText<"Warns when a null pointer is passed to a pointer which has a " - "_Nonnull type.">; + "_Nonnull type.">, + Documentation<HasDocumentation>; def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">, HelpText<"Warns when a null pointer is returned from a function that has " - "_Nonnull return type.">; + "_Nonnull return type.">, + Documentation<HasDocumentation>; def NullableDereferencedChecker : Checker<"NullableDereferenced">, - HelpText<"Warns when a nullable pointer is dereferenced.">; + HelpText<"Warns when a nullable pointer is dereferenced.">, + Documentation<HasDocumentation>; def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">, HelpText<"Warns when a nullable pointer is passed to a pointer which has a " - "_Nonnull type.">; + "_Nonnull type.">, + Documentation<HasDocumentation>; def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">, HelpText<"Warns when a nullable pointer is returned from a function that has " - "_Nonnull return type.">; + "_Nonnull return type.">, + Documentation<NotDocumented>; } // end "nullability" let ParentPackage = APIModeling in { def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, - HelpText<"Improve modeling of the C standard library functions">; + HelpText<"Improve modeling of the C standard library functions">, + Documentation<NotDocumented>; def TrustNonnullChecker : Checker<"TrustNonnull">, HelpText<"Trust that returns from framework methods annotated with _Nonnull " - "are not null">; + "are not null">, + Documentation<NotDocumented>; } // end "apiModeling" @@ -225,10 +254,12 @@ let ParentPackage = CoreBuiltin in { def NoReturnFunctionChecker : Checker<"NoReturnFunctions">, HelpText<"Evaluate \"panic\" functions that are known to not return to the " - "caller">; + "caller">, + Documentation<NotDocumented>; def BuiltinFunctionChecker : Checker<"BuiltinFunctions">, - HelpText<"Evaluate compiler builtin functions (e.g., alloca())">; + HelpText<"Evaluate compiler builtin functions (e.g., alloca())">, + Documentation<NotDocumented>; } // end "core.builtin" @@ -239,19 +270,24 @@ def BuiltinFunctionChecker : Checker<"BuiltinFunctions">, let ParentPackage = CoreUninitialized in { def UndefinedArraySubscriptChecker : Checker<"ArraySubscript">, - HelpText<"Check for uninitialized values used as array subscripts">; + HelpText<"Check for uninitialized values used as array subscripts">, + Documentation<HasDocumentation>; def UndefinedAssignmentChecker : Checker<"Assign">, - HelpText<"Check for assigning uninitialized values">; + HelpText<"Check for assigning uninitialized values">, + Documentation<HasDocumentation>; def UndefBranchChecker : Checker<"Branch">, - HelpText<"Check for uninitialized values used as branch conditions">; + HelpText<"Check for uninitialized values used as branch conditions">, + Documentation<HasDocumentation>; def UndefCapturedBlockVarChecker : Checker<"CapturedBlockVariable">, - HelpText<"Check for blocks that capture uninitialized values">; + HelpText<"Check for blocks that capture uninitialized values">, + Documentation<NotDocumented>; def ReturnUndefChecker : Checker<"UndefReturn">, - HelpText<"Check for uninitialized values being returned to the caller">; + HelpText<"Check for uninitialized values being returned to the caller">, + Documentation<HasDocumentation>; } // end "core.uninitialized" @@ -263,24 +299,33 @@ let ParentPackage = Cplusplus in { def InnerPointerChecker : Checker<"InnerPointer">, HelpText<"Check for inner pointers of C++ containers used after " - "re/deallocation">; + "re/deallocation">, + Documentation<NotDocumented>; def NewDeleteChecker : Checker<"NewDelete">, HelpText<"Check for double-free and use-after-free problems. Traces memory " - "managed by new/delete.">; + "managed by new/delete.">, + Documentation<HasDocumentation>; def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, - HelpText<"Check for memory leaks. Traces memory managed by new/delete.">; + HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, + Documentation<HasDocumentation>; def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, - HelpText<"Checks C++ copy and move assignment operators for self assignment">; + HelpText<"Checks C++ copy and move assignment operators for self assignment">, + Documentation<NotDocumented>; + +def MoveChecker: Checker<"Move">, + HelpText<"Find use-after-move bugs in C++">, + Documentation<HasDocumentation>; } // end: "cplusplus" let ParentPackage = CplusplusOptIn in { def VirtualCallChecker : Checker<"VirtualCall">, - HelpText<"Check virtual function calls during construction or destruction">; + HelpText<"Check virtual function calls during construction or destruction">, + Documentation<HasDocumentation>; } // end: "optin.cplusplus" @@ -288,26 +333,29 @@ let ParentPackage = CplusplusAlpha in { def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">, HelpText<"Reports destructions of polymorphic objects with a non-virtual " - "destructor in their base class">; + "destructor in their base class">, + Documentation<HasAlphaDocumentation>; def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">, - HelpText<"Check integer to enumeration casts for out of range values">; + HelpText<"Check integer to enumeration casts for out of range values">, + Documentation<HasAlphaDocumentation>; def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">, - HelpText<"Check for use of invalidated iterators">; + HelpText<"Check for use of invalidated iterators">, + Documentation<HasAlphaDocumentation>; def IteratorRangeChecker : Checker<"IteratorRange">, - HelpText<"Check for iterators used outside their valid ranges">; + HelpText<"Check for iterators used outside their valid ranges">, + Documentation<HasAlphaDocumentation>; def MismatchedIteratorChecker : Checker<"MismatchedIterator">, HelpText<"Check for use of iterators of different containers where iterators " - "of the same container are expected">; - -def MoveChecker: Checker<"Move">, - HelpText<"Find use-after-move bugs in C++">; + "of the same container are expected">, + Documentation<HasAlphaDocumentation>; def UninitializedObjectChecker: Checker<"UninitializedObject">, - HelpText<"Reports uninitialized fields after object construction">; + HelpText<"Reports uninitialized fields after object construction">, + Documentation<HasAlphaDocumentation>; } // end: "alpha.cplusplus" @@ -319,13 +367,16 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">, let ParentPackage = Valist in { def UninitializedChecker : Checker<"Uninitialized">, - HelpText<"Check for usages of uninitialized (or already released) va_lists.">; + HelpText<"Check for usages of uninitialized (or already released) va_lists.">, + Documentation<NotDocumented>; def UnterminatedChecker : Checker<"Unterminated">, - HelpText<"Check for va_lists which are not released by a va_end call.">; + HelpText<"Check for va_lists which are not released by a va_end call.">, + Documentation<NotDocumented>; def CopyToSelfChecker : Checker<"CopyToSelf">, - HelpText<"Check for va_lists which are copied onto itself.">; + HelpText<"Check for va_lists which are copied onto itself.">, + Documentation<NotDocumented>; } // end : "valist" @@ -337,14 +388,16 @@ let ParentPackage = DeadCode in { def DeadStoresChecker : Checker<"DeadStores">, HelpText<"Check for values stored to variables that are never read " - "afterwards">; + "afterwards">, + Documentation<HasDocumentation>; } // end DeadCode let ParentPackage = DeadCodeAlpha in { def UnreachableCodeChecker : Checker<"UnreachableCode">, - HelpText<"Check unreachable code">; + HelpText<"Check unreachable code">, + Documentation<HasAlphaDocumentation>; } // end "alpha.deadcode" @@ -355,7 +408,8 @@ def UnreachableCodeChecker : Checker<"UnreachableCode">, let ParentPackage = Performance in { def PaddingChecker : Checker<"Padding">, - HelpText<"Check for excessively padded structs.">; + HelpText<"Check for excessively padded structs.">, + Documentation<NotDocumented>; } // end: "padding" @@ -366,29 +420,40 @@ def PaddingChecker : Checker<"Padding">, let ParentPackage = InsecureAPI in { def bcmp : Checker<"bcmp">, - HelpText<"Warn on uses of the 'bcmp' function">; + HelpText<"Warn on uses of the 'bcmp' function">, + Documentation<HasDocumentation>; def bcopy : Checker<"bcopy">, - HelpText<"Warn on uses of the 'bcopy' function">; + HelpText<"Warn on uses of the 'bcopy' function">, + Documentation<HasDocumentation>; def bzero : Checker<"bzero">, - HelpText<"Warn on uses of the 'bzero' function">; + HelpText<"Warn on uses of the 'bzero' function">, + Documentation<HasDocumentation>; def gets : Checker<"gets">, - HelpText<"Warn on uses of the 'gets' function">; + HelpText<"Warn on uses of the 'gets' function">, + Documentation<HasDocumentation>; def getpw : Checker<"getpw">, - HelpText<"Warn on uses of the 'getpw' function">; + HelpText<"Warn on uses of the 'getpw' function">, + Documentation<HasDocumentation>; def mktemp : Checker<"mktemp">, - HelpText<"Warn on uses of the 'mktemp' function">; + HelpText<"Warn on uses of the 'mktemp' function">, + Documentation<HasDocumentation>; def mkstemp : Checker<"mkstemp">, HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format " - "string">; + "string">, + Documentation<HasDocumentation>; def rand : Checker<"rand">, - HelpText<"Warn on uses of the 'rand', 'random', and related functions">; + HelpText<"Warn on uses of the 'rand', 'random', and related functions">, + Documentation<HasDocumentation>; def strcpy : Checker<"strcpy">, - HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">; + HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">, + Documentation<HasDocumentation>; def vfork : Checker<"vfork">, - HelpText<"Warn on uses of the 'vfork' function">; + HelpText<"Warn on uses of the 'vfork' function">, + Documentation<HasDocumentation>; def UncheckedReturn : Checker<"UncheckedReturn">, HelpText<"Warn on uses of functions whose return values must be always " - "checked">; + "checked">, + Documentation<HasDocumentation>; } // end "security.insecureAPI" @@ -396,29 +461,35 @@ let ParentPackage = Security in { def FloatLoopCounter : Checker<"FloatLoopCounter">, HelpText<"Warn on using a floating point value as a loop counter (CERT: " - "FLP30-C, FLP30-CPP)">; + "FLP30-C, FLP30-CPP)">, + Documentation<HasDocumentation>; } // end "security" let ParentPackage = SecurityAlpha in { def ArrayBoundChecker : Checker<"ArrayBound">, - HelpText<"Warn about buffer overflows (older checker)">; + HelpText<"Warn about buffer overflows (older checker)">, + Documentation<HasAlphaDocumentation>; def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">, - HelpText<"Warn about buffer overflows (newer checker)">; + HelpText<"Warn about buffer overflows (newer checker)">, + Documentation<HasAlphaDocumentation>; def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, - HelpText<"Check for an out-of-bound pointer being returned to callers">; + HelpText<"Check for an out-of-bound pointer being returned to callers">, + Documentation<HasAlphaDocumentation>; def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, - HelpText<"Check for overflows in the arguments to malloc()">; + HelpText<"Check for overflows in the arguments to malloc()">, + Documentation<HasAlphaDocumentation>; // Operating systems specific PROT_READ/PROT_WRITE values is not implemented, // the defaults are correct for several common operating systems though, // but may need to be overridden via the related analyzer-config flags. def MmapWriteExecChecker : Checker<"MmapWriteExec">, - HelpText<"Warn on mmap() calls that are both writable and executable">; + HelpText<"Warn on mmap() calls that are both writable and executable">, + Documentation<HasAlphaDocumentation>; } // end "alpha.security" @@ -429,7 +500,8 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">, let ParentPackage = Taint in { def GenericTaintChecker : Checker<"TaintPropagation">, - HelpText<"Generate taint information used by other checkers">; + HelpText<"Generate taint information used by other checkers">, + Documentation<HasAlphaDocumentation>; } // end "alpha.security.taint" @@ -440,39 +512,49 @@ def GenericTaintChecker : Checker<"TaintPropagation">, let ParentPackage = Unix in { def UnixAPIMisuseChecker : Checker<"API">, - HelpText<"Check calls to various UNIX/Posix functions">; + HelpText<"Check calls to various UNIX/Posix functions">, + Documentation<HasDocumentation>; def MallocChecker: Checker<"Malloc">, HelpText<"Check for memory leaks, double free, and use-after-free problems. " - "Traces memory managed by malloc()/free().">; + "Traces memory managed by malloc()/free().">, + Documentation<HasDocumentation>; def MallocSizeofChecker : Checker<"MallocSizeof">, - HelpText<"Check for dubious malloc arguments involving sizeof">; + HelpText<"Check for dubious malloc arguments involving sizeof">, + Documentation<HasDocumentation>; def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">, - HelpText<"Check for mismatched deallocators.">; + HelpText<"Check for mismatched deallocators.">, + Documentation<HasDocumentation>; def VforkChecker : Checker<"Vfork">, - HelpText<"Check for proper usage of vfork">; + HelpText<"Check for proper usage of vfork">, + Documentation<HasDocumentation>; } // end "unix" let ParentPackage = UnixAlpha in { def ChrootChecker : Checker<"Chroot">, - HelpText<"Check improper use of chroot">; + HelpText<"Check improper use of chroot">, + Documentation<HasAlphaDocumentation>; def PthreadLockChecker : Checker<"PthreadLock">, - HelpText<"Simple lock -> unlock checker">; + HelpText<"Simple lock -> unlock checker">, + Documentation<HasAlphaDocumentation>; def StreamChecker : Checker<"Stream">, - HelpText<"Check stream handling functions">; + HelpText<"Check stream handling functions">, + Documentation<HasAlphaDocumentation>; def SimpleStreamChecker : Checker<"SimpleStream">, - HelpText<"Check for misuses of stream APIs">; + HelpText<"Check for misuses of stream APIs">, + Documentation<HasAlphaDocumentation>; def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, - HelpText<"Check for calls to blocking functions inside a critical section">; + HelpText<"Check for calls to blocking functions inside a critical section">, + Documentation<HasAlphaDocumentation>; } // end "alpha.unix" @@ -480,24 +562,29 @@ let ParentPackage = CString in { def CStringNullArg : Checker<"NullArg">, HelpText<"Check for null pointers being passed as arguments to C string " - "functions">; + "functions">, + Documentation<HasDocumentation>; def CStringSyntaxChecker : Checker<"BadSizeArg">, HelpText<"Check the size argument passed into C string functions for common " - "erroneous patterns">; + "erroneous patterns">, + Documentation<HasDocumentation>; } // end "unix.cstring" let ParentPackage = CStringAlpha in { def CStringOutOfBounds : Checker<"OutOfBounds">, - HelpText<"Check for out-of-bounds access in string functions">; + HelpText<"Check for out-of-bounds access in string functions">, + Documentation<HasAlphaDocumentation>; def CStringBufferOverlap : Checker<"BufferOverlap">, - HelpText<"Checks for overlap in two buffer arguments">; + HelpText<"Checks for overlap in two buffer arguments">, + Documentation<HasAlphaDocumentation>; def CStringNotNullTerm : Checker<"NotNullTerminated">, - HelpText<"Check for arguments which are not null-terminating strings">; + HelpText<"Check for arguments which are not null-terminating strings">, + Documentation<HasAlphaDocumentation>; } // end "alpha.unix.cstring" @@ -509,19 +596,24 @@ let ParentPackage = OSX in { def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, HelpText<"Check for erroneous conversions of objects representing numbers " - "into numbers">; + "into numbers">, + Documentation<NotDocumented>; def MacOSXAPIChecker : Checker<"API">, - HelpText<"Check for proper uses of various Apple APIs">; + HelpText<"Check for proper uses of various Apple APIs">, + Documentation<HasDocumentation>; def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">, - HelpText<"Check for proper uses of Secure Keychain APIs">; + HelpText<"Check for proper uses of Secure Keychain APIs">, + Documentation<HasDocumentation>; def ObjCPropertyChecker : Checker<"ObjCProperty">, - HelpText<"Check for proper uses of Objective-C properties">; + HelpText<"Check for proper uses of Objective-C properties">, + Documentation<NotDocumented>; def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">, - HelpText<"Check for leaks and improper reference count management for OSObject">; + HelpText<"Check for leaks and improper reference count management for OSObject">, + Documentation<NotDocumented>; } // end "osx" @@ -529,66 +621,84 @@ let ParentPackage = Cocoa in { def RunLoopAutoreleaseLeakChecker : Checker<"RunLoopAutoreleaseLeak">, HelpText<"Check for leaked memory in autorelease pools that will never be " - "drained">; + "drained">, + Documentation<NotDocumented>; def ObjCAtSyncChecker : Checker<"AtSync">, - HelpText<"Check for nil pointers used as mutexes for @synchronized">; + HelpText<"Check for nil pointers used as mutexes for @synchronized">, + Documentation<HasDocumentation>; def NilArgChecker : Checker<"NilArg">, - HelpText<"Check for prohibited nil arguments to ObjC method calls">; + HelpText<"Check for prohibited nil arguments to ObjC method calls">, + Documentation<HasDocumentation>; def ClassReleaseChecker : Checker<"ClassRelease">, HelpText<"Check for sending 'retain', 'release', or 'autorelease' directly " - "to a Class">; + "to a Class">, + Documentation<HasDocumentation>; def VariadicMethodTypeChecker : Checker<"VariadicMethodTypes">, HelpText<"Check for passing non-Objective-C types to variadic collection " - "initialization methods that expect only Objective-C types">; + "initialization methods that expect only Objective-C types">, + Documentation<HasDocumentation>; def NSAutoreleasePoolChecker : Checker<"NSAutoreleasePool">, HelpText<"Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC " - "mode">; + "mode">, + Documentation<HasDocumentation>; def ObjCMethSigsChecker : Checker<"IncompatibleMethodTypes">, HelpText<"Warn about Objective-C method signatures with type " - "incompatibilities">; + "incompatibilities">, + Documentation<HasDocumentation>; def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">, - HelpText<"Warn about private ivars that are never used">; + HelpText<"Warn about private ivars that are never used">, + Documentation<HasDocumentation>; def ObjCSelfInitChecker : Checker<"SelfInit">, HelpText<"Check that 'self' is properly initialized inside an initializer " - "method">; + "method">, + Documentation<HasDocumentation>; def ObjCLoopChecker : Checker<"Loops">, - HelpText<"Improved modeling of loops using Cocoa collection types">; + HelpText<"Improved modeling of loops using Cocoa collection types">, + Documentation<NotDocumented>; def ObjCNonNilReturnValueChecker : Checker<"NonNilReturnValue">, - HelpText<"Model the APIs that are guaranteed to return a non-nil value">; + HelpText<"Model the APIs that are guaranteed to return a non-nil value">, + Documentation<NotDocumented>; def ObjCSuperCallChecker : Checker<"MissingSuperCall">, HelpText<"Warn about Objective-C methods that lack a necessary call to " - "super">; + "super">, + Documentation<NotDocumented>; def NSErrorChecker : Checker<"NSError">, - HelpText<"Check usage of NSError** parameters">; + HelpText<"Check usage of NSError** parameters">, + Documentation<HasDocumentation>; def RetainCountChecker : Checker<"RetainCount">, - HelpText<"Check for leaks and improper reference count management">; + HelpText<"Check for leaks and improper reference count management">, + Documentation<HasDocumentation>; def ObjCGenericsChecker : Checker<"ObjCGenerics">, - HelpText<"Check for type errors when using Objective-C generics">; + HelpText<"Check for type errors when using Objective-C generics">, + Documentation<HasDocumentation>; def ObjCDeallocChecker : Checker<"Dealloc">, HelpText<"Warn about Objective-C classes that lack a correct implementation " - "of -dealloc">; + "of -dealloc">, + Documentation<HasDocumentation>; def ObjCSuperDeallocChecker : Checker<"SuperDealloc">, - HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">; + HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">, + Documentation<HasDocumentation>; def AutoreleaseWriteChecker : Checker<"AutoreleaseWrite">, HelpText<"Warn about potentially crashing writes to autoreleasing objects " - "from different autoreleasing pools in Objective-C">; + "from different autoreleasing pools in Objective-C">, + Documentation<NotDocumented>; } // end "osx.cocoa" @@ -596,39 +706,47 @@ let ParentPackage = Performance in { def GCDAntipattern : Checker<"GCDAntipattern">, HelpText<"Check for performance anti-patterns when using Grand Central " - "Dispatch">; + "Dispatch">, + Documentation<NotDocumented>; } // end "optin.performance" let ParentPackage = CocoaAlpha in { def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">, HelpText<"Check that the invalidatable instance variables are invalidated in " - "the methods annotated with objc_instance_variable_invalidator">; + "the methods annotated with objc_instance_variable_invalidator">, + Documentation<HasAlphaDocumentation>; def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">, HelpText<"Check that the invalidation methods are present in classes that " - "contain invalidatable instance variables">; + "contain invalidatable instance variables">, + Documentation<HasAlphaDocumentation>; def DirectIvarAssignment : Checker<"DirectIvarAssignment">, - HelpText<"Check for direct assignments to instance variables">; + HelpText<"Check for direct assignments to instance variables">, + Documentation<HasAlphaDocumentation>; def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentForAnnotatedFunctions">, HelpText<"Check for direct assignments to instance variables in the methods " - "annotated with objc_no_direct_instance_variable_assignment">; + "annotated with objc_no_direct_instance_variable_assignment">, + Documentation<HasAlphaDocumentation>; } // end "alpha.osx.cocoa" let ParentPackage = CoreFoundation in { def CFNumberChecker : Checker<"CFNumber">, - HelpText<"Check for proper uses of CFNumber APIs">; + HelpText<"Check for proper uses of CFNumber APIs">, + Documentation<HasDocumentation>; def CFRetainReleaseChecker : Checker<"CFRetainRelease">, - HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">; + HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">, + Documentation<HasDocumentation>; def CFErrorChecker : Checker<"CFError">, - HelpText<"Check usage of CFErrorRef* parameters">; + HelpText<"Check usage of CFErrorRef* parameters">, + Documentation<HasDocumentation>; } // end "osx.coreFoundation" @@ -636,10 +754,12 @@ let ParentPackage = Containers in { def ObjCContainersASTChecker : Checker<"PointerSizedValues">, HelpText<"Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with " - "non-pointer-size values">; + "non-pointer-size values">, + Documentation<HasDocumentation>; def ObjCContainersChecker : Checker<"OutOfBounds">, - HelpText<"Checks for index out-of-bounds when using 'CFArray' API">; + HelpText<"Checks for index out-of-bounds when using 'CFArray' API">, + Documentation<HasDocumentation>; } // end "osx.coreFoundation.containers" @@ -647,11 +767,13 @@ let ParentPackage = LocalizabilityOptIn in { def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">, HelpText<"Warns about uses of non-localized NSStrings passed to UI methods " - "expecting localized NSStrings">; + "expecting localized NSStrings">, + Documentation<HasDocumentation>; def EmptyLocalizationContextChecker : Checker<"EmptyLocalizationContextChecker">, - HelpText<"Check that NSLocalizedString macros include a comment for context">; + HelpText<"Check that NSLocalizedString macros include a comment for context">, + Documentation<HasDocumentation>; } // end "optin.osx.cocoa.localizability" @@ -659,14 +781,16 @@ let ParentPackage = LocalizabilityAlpha in { def PluralMisuseChecker : Checker<"PluralMisuseChecker">, HelpText<"Warns against using one vs. many plural pattern in code when " - "generating localized strings.">; + "generating localized strings.">, + Documentation<HasAlphaDocumentation>; } // end "alpha.osx.cocoa.localizability" let ParentPackage = MPI in { def MPIChecker : Checker<"MPI-Checker">, - HelpText<"Checks MPI code">; + HelpText<"Checks MPI code">, + Documentation<HasDocumentation>; } // end "optin.mpi" @@ -677,7 +801,8 @@ def MPIChecker : Checker<"MPI-Checker">, let ParentPackage = LLVMAlpha in { def LLVMConventionsChecker : Checker<"Conventions">, - HelpText<"Check code for LLVM codebase conventions">; + HelpText<"Check code for LLVM codebase conventions">, + Documentation<HasAlphaDocumentation>; } // end "llvm" @@ -688,7 +813,8 @@ def LLVMConventionsChecker : Checker<"Conventions">, let ParentPackage = GoogleAPIModeling in { def GTestChecker : Checker<"GTest">, - HelpText<"Model gtest assertion APIs">; + HelpText<"Model gtest assertion APIs">, + Documentation<NotDocumented>; } // end "apiModeling.google" @@ -699,46 +825,64 @@ def GTestChecker : Checker<"GTest">, let ParentPackage = Debug in { def AnalysisOrderChecker : Checker<"AnalysisOrder">, - HelpText<"Print callbacks that are called during analysis in order">; + HelpText<"Print callbacks that are called during analysis in order">, + Documentation<NotDocumented>; def DominatorsTreeDumper : Checker<"DumpDominators">, - HelpText<"Print the dominance tree for a given CFG">; + HelpText<"Print the dominance tree for a given CFG">, + Documentation<NotDocumented>; def LiveVariablesDumper : Checker<"DumpLiveVars">, - HelpText<"Print results of live variable analysis">; + HelpText<"Print results of live variable analysis">, + Documentation<NotDocumented>; + +def LiveStatementsDumper : Checker<"DumpLiveStmts">, + HelpText<"Print results of live statement analysis">, + Documentation<NotDocumented>; def CFGViewer : Checker<"ViewCFG">, - HelpText<"View Control-Flow Graphs using GraphViz">; + HelpText<"View Control-Flow Graphs using GraphViz">, + Documentation<NotDocumented>; def CFGDumper : Checker<"DumpCFG">, - HelpText<"Display Control-Flow Graphs">; + HelpText<"Display Control-Flow Graphs">, + Documentation<NotDocumented>; def CallGraphViewer : Checker<"ViewCallGraph">, - HelpText<"View Call Graph using GraphViz">; + HelpText<"View Call Graph using GraphViz">, + Documentation<NotDocumented>; def CallGraphDumper : Checker<"DumpCallGraph">, - HelpText<"Display Call Graph">; + HelpText<"Display Call Graph">, + Documentation<NotDocumented>; def ConfigDumper : Checker<"ConfigDumper">, - HelpText<"Dump config table">; + HelpText<"Dump config table">, + Documentation<NotDocumented>; def TraversalDumper : Checker<"DumpTraversal">, - HelpText<"Print branch conditions as they are traversed by the engine">; + HelpText<"Print branch conditions as they are traversed by the engine">, + Documentation<NotDocumented>; def CallDumper : Checker<"DumpCalls">, - HelpText<"Print calls as they are traversed by the engine">; + HelpText<"Print calls as they are traversed by the engine">, + Documentation<NotDocumented>; def AnalyzerStatsChecker : Checker<"Stats">, - HelpText<"Emit warnings with analyzer statistics">; + HelpText<"Emit warnings with analyzer statistics">, + Documentation<NotDocumented>; def TaintTesterChecker : Checker<"TaintTest">, - HelpText<"Mark tainted symbols as such.">; + HelpText<"Mark tainted symbols as such.">, + Documentation<NotDocumented>; def ExprInspectionChecker : Checker<"ExprInspection">, - HelpText<"Check the analyzer's understanding of expressions">; + HelpText<"Check the analyzer's understanding of expressions">, + Documentation<NotDocumented>; def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, - HelpText<"View Exploded Graphs using GraphViz">; + HelpText<"View Exploded Graphs using GraphViz">, + Documentation<NotDocumented>; } // end "debug" @@ -750,7 +894,8 @@ def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, let ParentPackage = CloneDetectionAlpha in { def CloneChecker : Checker<"CloneChecker">, - HelpText<"Reports similar pieces of code.">; + HelpText<"Reports similar pieces of code.">, + Documentation<HasAlphaDocumentation>; } // end "clone" @@ -761,6 +906,7 @@ def CloneChecker : Checker<"CloneChecker">, let ParentPackage = PortabilityOptIn in { def UnixAPIPortabilityChecker : Checker<"UnixAPI">, - HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">; + HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">, + Documentation<NotDocumented>; } // end optin.portability diff --git a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h deleted file mode 100644 index cf0a30a73d..0000000000 --- a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h +++ /dev/null @@ -1,22 +0,0 @@ -//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H -#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H - -namespace clang { -namespace ento { -class CheckerRegistry; - -void registerBuiltinCheckers(CheckerRegistry ®istry); - -} // end namespace ento -} // end namespace clang - -#endif diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index 8e5d8d3ad3..3cd54df7b1 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -275,7 +275,7 @@ ANALYZER_OPTION( ANALYZER_OPTION( bool, IsNaiveCTUEnabled, "experimental-enable-naive-ctu-analysis", "Whether naive cross translation unit analysis is enabled. This is an " - "experimental feature to inline functions from another translation units.", + "experimental feature to inline functions from other translation units.", false) ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros", @@ -344,8 +344,8 @@ ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir", "The directory containing the CTU related files.", "") ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name", - "the name of the file containing the CTU index of functions.", - "externalFnMap.txt") + "the name of the file containing the CTU index of definitions.", + "externalDefMap.txt") ANALYZER_OPTION( StringRef, ModelPath, "model-path", diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index 0e80e7bc19..d07525661a 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -16,7 +16,7 @@ namespace clang { namespace categories { extern const char * const CoreFoundationObjectiveC; extern const char * const LogicError; - extern const char * const MemoryCoreFoundationObjectiveC; + extern const char * const MemoryRefCount; extern const char * const MemoryError; extern const char * const UnixAPI; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index a53e8ee693..81dd83fc10 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -1138,9 +1138,16 @@ class CallEventManager { public: CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {} + /// Gets an outside caller given a callee context. CallEventRef<> getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State); + /// Gets a call event for a function call, Objective-C method call, + /// or a 'new' call. + CallEventRef<> + getCall(const Stmt *S, ProgramStateRef State, + const LocationContext *LC); + CallEventRef<> getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index bf01289a40..3d0ff4efa1 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -24,6 +24,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/Type.h" +#include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index f544204497..c3a7028d87 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -555,15 +555,15 @@ public: MemRegionManager& getRegionManager() { return svalBuilder->getRegionManager(); } - const MemRegionManager& getRegionManager() const { + const MemRegionManager &getRegionManager() const { return svalBuilder->getRegionManager(); } CallEventManager &getCallEventManager() { return *CallEventMgr; } - StoreManager& getStoreManager() { return *StoreMgr; } - ConstraintManager& getConstraintManager() { return *ConstraintMgr; } - SubEngine* getOwningEngine() { return Eng; } + StoreManager &getStoreManager() { return *StoreMgr; } + ConstraintManager &getConstraintManager() { return *ConstraintMgr; } + SubEngine &getOwningEngine() { return *Eng; } ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 1b79bfc3f8..0efe96f67f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -530,9 +530,7 @@ public: return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data)); } - bool isNullMemberPointer() const { - return getPTMData().isNull(); - } + bool isNullMemberPointer() const; const DeclaratorDecl *getDecl() const; diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h index de16a1781a..4fcaa794c1 100644 --- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h +++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h @@ -36,9 +36,26 @@ using namespace ento; namespace clang { namespace ento { -/// An ArgEffect summarizes the retain count behavior on an argument or receiver -/// to a function or method. -enum ArgEffect { +/// Determines the object kind of a tracked object. +enum class ObjKind { + /// Indicates that the tracked object is a CF object. + CF, + + /// Indicates that the tracked object is an Objective-C object. + ObjC, + + /// Indicates that the tracked object could be a CF or Objective-C object. + AnyObj, + + /// Indicates that the tracked object is a generalized object. + Generalized, + + /// Indicates that the tracking object is a descendant of a + /// referenced-counted OSObject, used in the Darwin kernel. + OS +}; + +enum ArgEffectKind { /// There is no effect. DoNothing, @@ -46,44 +63,35 @@ enum ArgEffect { /// the referenced object. Autorelease, - /// The argument is treated as if an -dealloc message had been sent to - /// the referenced object. + /// The argument is treated as if the referenced object was deallocated. Dealloc, - /// The argument has its reference count decreased by 1. This is as - /// if CFRelease has been called on the argument. + /// The argument has its reference count decreased by 1. DecRef, - /// The argument has its reference count decreased by 1. This is as - /// if a -release message has been sent to the argument. This differs - /// in behavior from DecRef when ARC is enabled. - DecRefMsg, - /// The argument has its reference count decreased by 1 to model /// a transferred bridge cast under ARC. DecRefBridgedTransferred, - /// The argument has its reference count increased by 1. This is as - /// if a -retain message has been sent to the argument. This differs - /// in behavior from IncRef when ARC is enabled. - IncRefMsg, - - /// The argument has its reference count increased by 1. This is as - /// if CFRetain has been called on the argument. + /// The argument has its reference count increased by 1. IncRef, - /// The argument acts as if has been passed to CFMakeCollectable, which - /// transfers the object to the Garbage Collector under GC. - MakeCollectable, - /// The argument is a pointer to a retain-counted object; on exit, the new - /// value of the pointer is a +0 value or NULL. + /// value of the pointer is a +0 value. UnretainedOutParameter, /// The argument is a pointer to a retain-counted object; on exit, the new - /// value of the pointer is a +1 value or NULL. + /// value of the pointer is a +1 value. RetainedOutParameter, + /// The argument is a pointer to a retain-counted object; on exit, the new + /// value of the pointer is a +1 value iff the return code is zero. + RetainedOutParameterOnZero, + + /// The argument is a pointer to a retain-counted object; on exit, the new + /// value of the pointer is a +1 value iff the return code is non-zero. + RetainedOutParameterOnNonZero, + /// The argument is treated as potentially escaping, meaning that /// even when its reference count hits 0 it should be treated as still /// possibly being alive as someone else *may* be holding onto the object. @@ -108,13 +116,27 @@ enum ArgEffect { /// count of the argument and all typestate tracking on that argument /// should cease. DecRefAndStopTrackingHard, +}; - /// Performs the combined functionality of DecRefMsg and StopTrackingHard. - /// - /// The models the effect that the called function decrements the reference - /// count of the argument and all typestate tracking on that argument - /// should cease. - DecRefMsgAndStopTrackingHard +/// An ArgEffect summarizes the retain count behavior on an argument or receiver +/// to a function or method. +class ArgEffect { + ArgEffectKind K; + ObjKind O; +public: + explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj) + : K(K), O(O) {} + + ArgEffectKind getKind() const { return K; } + ObjKind getObjKind() const { return O; } + + ArgEffect withKind(ArgEffectKind NewK) { + return ArgEffect(NewK, O); + } + + bool operator==(const ArgEffect &Other) const { + return K == Other.K && O == Other.O; + } }; /// RetEffect summarizes a call's retain/release behavior with respect @@ -125,18 +147,19 @@ public: /// Indicates that no retain count information is tracked for /// the return value. NoRet, + /// Indicates that the returned value is an owned (+1) symbol. OwnedSymbol, + /// Indicates that the returned value is an object with retain count /// semantics but that it is not owned (+0). This is the default /// for getters, etc. NotOwnedSymbol, - /// Indicates that the object is not owned and controlled by the - /// Garbage collector. - GCNotOwnedSymbol, + /// Indicates that the return value is an owned object when the /// receiver is also a tracked object. OwnedWhenTrackedReceiver, + // Treat this function as returning a non-tracked symbol even if // the function has been inlined. This is used where the call // site summary is more precise than the summary indirectly produced @@ -144,27 +167,11 @@ public: NoRetHard }; - /// Determines the object kind of a tracked object. - enum ObjKind { - /// Indicates that the tracked object is a CF object. This is - /// important between GC and non-GC code. - CF, - /// Indicates that the tracked object is an Objective-C object. - ObjC, - /// Indicates that the tracked object could be a CF or Objective-C object. - AnyObj, - /// Indicates that the tracked object is a generalized object. - Generalized, - - /// A descendant of OSObject. - OS - }; - private: Kind K; ObjKind O; - RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {} + RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {} public: Kind getKind() const { return K; } @@ -184,7 +191,7 @@ public: } static RetEffect MakeOwnedWhenTrackedReceiver() { - return RetEffect(OwnedWhenTrackedReceiver, ObjC); + return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC); } static RetEffect MakeOwned(ObjKind o) { @@ -193,9 +200,6 @@ public: static RetEffect MakeNotOwned(ObjKind o) { return RetEffect(NotOwnedSymbol, o); } - static RetEffect MakeGCNotOwned() { - return RetEffect(GCNotOwnedSymbol, ObjC); - } static RetEffect MakeNoRet() { return RetEffect(NoRet); } @@ -217,7 +221,9 @@ class CallEffects { RetEffect Ret; ArgEffect Receiver; - CallEffects(const RetEffect &R) : Ret(R) {} + CallEffects(const RetEffect &R, + ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj)) + : Ret(R), Receiver(Receiver) {} public: /// Returns the argument effects for a call. @@ -262,7 +268,8 @@ namespace llvm { template <> struct FoldingSetTrait<ArgEffect> { static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) { - ID.AddInteger((unsigned) X); + ID.AddInteger((unsigned) X.getKind()); + ID.AddInteger((unsigned) X.getObjKind()); } }; template <> struct FoldingSetTrait<RetEffect> { @@ -370,14 +377,15 @@ public: ArgEffect getReceiverEffect() const { return Receiver; } /// \return the effect on the "this" receiver of the method call. + /// This is only meaningful if the summary applies to CXXMethodDecl*. ArgEffect getThisEffect() const { return This; } /// Set the effect of the method on "this". void setThisEffect(ArgEffect e) { This = e; } bool isNoop() const { - return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing - && DefaultArgEffect == MayEscape && This == DoNothing + return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing + && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing && Args.isEmpty(); } @@ -508,9 +516,6 @@ class RetainSummaryManager { /// AF - A factory for ArgEffects objects. ArgEffects::Factory AF; - /// ScratchArgs - A holding buffer for construct ArgEffects. - ArgEffects ScratchArgs; - /// ObjCAllocRetE - Default return effect for methods returning Objective-C /// objects. RetEffect ObjCAllocRetE; @@ -523,10 +528,6 @@ class RetainSummaryManager { /// effects. llvm::FoldingSet<CachedSummaryNode> SimpleSummaries; - /// getArgEffects - Returns a persistent ArgEffects object based on the - /// data in ScratchArgs. - ArgEffects getArgEffects(); - /// Create an OS object at +1. const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD); @@ -542,10 +543,8 @@ class RetainSummaryManager { /// Free the OS object. const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD); - enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable }; - const RetainSummary *getUnarySummary(const FunctionType* FT, - UnaryFuncKind func); + ArgEffectKind AE); const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD); const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD); @@ -553,27 +552,31 @@ class RetainSummaryManager { const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm); - const RetainSummary *getPersistentSummary(RetEffect RetEff, - ArgEffect ReceiverEff = DoNothing, - ArgEffect DefaultEff = MayEscape, - ArgEffect ThisEff = DoNothing) { - RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff, - ThisEff); + const RetainSummary * + getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs, + ArgEffect ReceiverEff = ArgEffect(DoNothing), + ArgEffect DefaultEff = ArgEffect(MayEscape), + ArgEffect ThisEff = ArgEffect(DoNothing)) { + RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff); return getPersistentSummary(Summ); } const RetainSummary *getDoNothingSummary() { - return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); + return getPersistentSummary(RetEffect::MakeNoRet(), + ArgEffects(AF.getEmptyMap()), + ArgEffect(DoNothing), ArgEffect(DoNothing)); } const RetainSummary *getDefaultSummary() { return getPersistentSummary(RetEffect::MakeNoRet(), - DoNothing, MayEscape); + ArgEffects(AF.getEmptyMap()), + ArgEffect(DoNothing), ArgEffect(MayEscape)); } const RetainSummary *getPersistentStopSummary() { - return getPersistentSummary(RetEffect::MakeNoRet(), - StopTracking, StopTracking); + return getPersistentSummary( + RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()), + ArgEffect(StopTracking), ArgEffect(StopTracking)); } void InitializeClassMethodSummaries(); @@ -646,11 +649,9 @@ class RetainSummaryManager { /// Apply the annotation of {@code pd} in function {@code FD} /// to the resulting summary stored in out-parameter {@code Template}. /// \return whether an annotation was applied. - bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd, - unsigned parm_idx, - const FunctionDecl *FD, - ArgEffects::Factory &AF, - RetainSummaryTemplate &Template); + bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx, + const NamedDecl *FD, + RetainSummaryTemplate &Template); public: RetainSummaryManager(ASTContext &ctx, @@ -661,10 +662,10 @@ public: ARCEnabled(usesARC), TrackObjCAndCFObjects(trackObjCAndCFObjects), TrackOSObjects(trackOSObjects), - AF(BPAlloc), ScratchArgs(AF.getEmptyMap()), - ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC) - : RetEffect::MakeOwned(RetEffect::ObjC)), - ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC) + AF(BPAlloc), + ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) + : RetEffect::MakeOwned(ObjKind::ObjC)), + ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) : RetEffect::MakeOwnedWhenTrackedReceiver()) { InitializeClassMethodSummaries(); InitializeMethodSummaries(); @@ -745,16 +746,18 @@ public: RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } - /// \return True if the declaration has an attribute {@code T}, - /// AND we are tracking that attribute. False otherwise. + /// Determine whether a declaration {@code D} of correspondent type (return + /// type for functions/methods) {@code QT} has any of the given attributes, + /// provided they pass necessary validation checks AND tracking the given + /// attribute is enabled. + /// Returns the object kind corresponding to the present attribute, or None, + /// if none of the specified attributes are present. + /// Crashes if passed an attribute which is not explicitly handled. template <class T> - bool hasEnabledAttr(const Decl *D) { - return isAttrEnabled<T>() && D->hasAttr<T>(); - } + Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT); - /// Check whether we are tracking properties specified by the attributes. - template <class T> - bool isAttrEnabled(); + template <class T1, class T2, class... Others> + Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT); friend class RetainSummaryTemplate; }; diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 740754090d..966234492f 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -81,6 +81,8 @@ namespace ento { /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: + CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags); + /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. using InitializationFunction = void (*)(CheckerManager &); @@ -89,12 +91,16 @@ public: InitializationFunction Initialize; StringRef FullName; StringRef Desc; + StringRef DocumentationUri; - CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc) - : Initialize(fn), FullName(name), Desc(desc) {} + CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc, + StringRef DocsUri) + : Initialize(Fn), FullName(Name), Desc(Desc), + DocumentationUri(DocsUri) {} }; using CheckerInfoList = std::vector<CheckerInfo>; + using CheckerInfoSet = llvm::SetVector<const CheckerRegistry::CheckerInfo *>; private: template <typename T> @@ -105,28 +111,27 @@ private: public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction fn, StringRef fullName, - StringRef desc); + void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc, + StringRef DocsUri); /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. template <class T> - void addChecker(StringRef fullName, StringRef desc) { + void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc); + addChecker(&CheckerRegistry::initializeManager<T>, FullName, Desc, DocsUri); } /// Initializes a CheckerManager by calling the initialization functions for /// all checkers specified by the given CheckerOptInfo list. The order of this /// list is significant; later options can be used to reverse earlier ones. /// This can be used to exclude certain checkers in an included package. - void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts, - DiagnosticsEngine &diags) const; + void initializeManager(CheckerManager &mgr, + const AnalyzerOptions &Opts) const; /// Check if every option corresponds to a specific checker or package. - void validateCheckerOptions(const AnalyzerOptions &opts, - DiagnosticsEngine &diags) const; + void validateCheckerOptions(const AnalyzerOptions &opts) const; /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. @@ -134,8 +139,11 @@ public: void printList(raw_ostream &out, const AnalyzerOptions &opts) const; private: + CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const; + mutable CheckerInfoList Checkers; mutable llvm::StringMap<size_t> Packages; + DiagnosticsEngine &Diags; }; } // namespace ento diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 8fd45bf102..2e9d0502e6 100644 --- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -52,9 +52,11 @@ private: llvm::StringMap<Stmt *> &Bodies; }; -void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins); +void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins, + DiagnosticsEngine &diags); void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins, - const AnalyzerOptions &opts); + const AnalyzerOptions &opts, + DiagnosticsEngine &diags); void printAnalyzerConfigList(raw_ostream &OS); } // end GR namespace |