]> granicus.if.org Git - clang/commitdiff
Allow direct navigation to static analysis checker documentation through SARIF exports.
authorAaron Ballman <aaron@aaronballman.com>
Thu, 20 Dec 2018 20:20:20 +0000 (20:20 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Thu, 20 Dec 2018 20:20:20 +0000 (20:20 +0000)
This adds anchors to all of the documented checks so that you can directly link to a check by a stable name. This is useful because the SARIF file format has a field for specifying a URI to documentation for a rule and some viewers, like CodeSonar, make use of this information. These links are then exposed through the SARIF exporter.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349812 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/clang/Driver/CC1Options.td
include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
include/clang/StaticAnalyzer/Checkers/CheckerBase.td
include/clang/StaticAnalyzer/Checkers/Checkers.td
include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
utils/TableGen/ClangSACheckersEmitter.cpp
www/analyzer/alpha_checks.html
www/analyzer/available_checks.html

index 742787bf0ca5ed2b69ab62d2ca05b7c5cec1bf9b..c0e73e56d7abf6b873c9ee6d5288b070fbba250d 100644 (file)
@@ -108,7 +108,7 @@ def analyzer_checker : Separate<["-"], "analyzer-checker">,
   ValuesCode<[{
     const char *Values =
     #define GET_CHECKERS
-    #define CHECKER(FULLNAME, CLASS, HT)  FULLNAME ","
+    #define CHECKER(FULLNAME, CLASS, HT, DOC_URI)  FULLNAME ","
     #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
     #undef GET_CHECKERS
     #define GET_PACKAGES
index cd42cd6cd3d3b49bed6b3b3024a74d62a5bc8af8..192ac1261c7673a24ad3f18d477060ec3a3e9956 100644 (file)
@@ -24,7 +24,7 @@ class CheckerManager;
 class CheckerRegistry;
 
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
   void register##CLASS(CheckerManager &mgr);
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef CHECKER
index 15034fc689482ade7df34fdb555ba2f8c0da7994..453e189fccb01b4a4e51166ddf535028a4bb7bae 100644 (file)
@@ -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;
 }
index 0d16de1ccc6df00b14f8f1854d7a7689915d45da..1bb3da7a245845276c2c8f3aa6e40e5add5ec421 100644 (file)
@@ -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,27 +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++">;
+   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"
 
@@ -291,23 +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">;
+           "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,49 +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">;
+  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"
 
@@ -753,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"
 
@@ -764,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
index 3599833d2c3be690cb17dabb91ebda3d92390f5b..966234492fe08fcf8e957b48ef7a5d4f10adb577 100644 (file)
@@ -91,9 +91,12 @@ 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>;
@@ -108,16 +111,16 @@ 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
index d9b63c209d492762148a233d01fd4a5a5cb610c7..0588c2bd3d35c81e99eabb5ef8308b548e73d1e5 100644 (file)
@@ -34,7 +34,7 @@ std::vector<StringRef>
 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
   static const StringRef StaticAnalyzerChecks[] = {
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
   FULLNAME,
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef CHECKER
index 36046f0cfd106ff7069fe2a8ac55ca015902a53c..9e9690ca0b35781b434862beaee9fa3ff8cecc01 100644 (file)
@@ -257,7 +257,7 @@ static json::Object createResult(const PathDiagnostic &Diag, json::Array &Files,
 static StringRef getRuleDescription(StringRef CheckName) {
   return llvm::StringSwitch<StringRef>(CheckName)
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
   .Case(FULLNAME, HELPTEXT)
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef CHECKER
@@ -265,12 +265,29 @@ static StringRef getRuleDescription(StringRef CheckName) {
       ;
 }
 
+static StringRef getRuleHelpURIStr(StringRef CheckName) {
+  return llvm::StringSwitch<StringRef>(CheckName)
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
+  .Case(FULLNAME, DOC_URI)
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+      ;
+}
+
 static json::Object createRule(const PathDiagnostic &Diag) {
   StringRef CheckName = Diag.getCheckName();
-  return json::Object{
+  json::Object Ret{
       {"fullDescription", createMessage(getRuleDescription(CheckName))},
       {"name", createMessage(CheckName)},
       {"id", CheckName}};
+
+  std::string RuleURI = getRuleHelpURIStr(CheckName);
+  if (!RuleURI.empty())
+    Ret["helpURI"] = RuleURI;
+
+  return Ret;
 }
 
 static json::Array createRules(std::vector<const PathDiagnostic *> &Diags,
index 86cf62a163600911aec26476eb523b340f15bdf0..620c0e588906a2a361b7850437a9ecb68705ce13 100644 (file)
@@ -42,8 +42,8 @@ static bool isCompatibleAPIVersion(const char *versionString) {
 CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins,
                                  DiagnosticsEngine &diags) : Diags(diags) {
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
-  addChecker(register##CLASS, FULLNAME, HELPTEXT);
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
+  addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI);
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef CHECKER
 #undef GET_CHECKERS
@@ -115,7 +115,7 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
 
   for (const std::pair<std::string, bool> &opt : Opts.CheckersControlList) {
     // Use a binary search to find the possible start of the package.
-    CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, "");
+    CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, "", "");
     auto firstRelatedChecker =
       std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT);
 
@@ -147,13 +147,13 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
   return enabledCheckers;
 }
 
-void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name,
-                                 StringRef desc) {
-  Checkers.push_back(CheckerInfo(fn, name, desc));
+void CheckerRegistry::addChecker(InitializationFunction Fn, StringRef Name,
+                                 StringRef Desc, StringRef DocsUri) {
+  Checkers.emplace_back(Fn, Name, Desc, DocsUri);
 
   // Record the presence of the checker in its packages.
   StringRef packageName, leafName;
-  std::tie(packageName, leafName) = name.rsplit(PackageSeparator);
+  std::tie(packageName, leafName) = Name.rsplit(PackageSeparator);
   while (!leafName.empty()) {
     Packages[packageName] += 1;
     std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);
index 4b581b2e0f9510803478f20338864df2a51d4652..15880baa4e0dd98c5a970a4f371f39f5ab992dfb 100644 (file)
@@ -29,6 +29,7 @@
             "fullDescription": {
               "text": "Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)"
             },
+            "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.CallAndMessage",
             "id": "core.CallAndMessage",
             "name": {
               "text": "core.CallAndMessage"
@@ -38,6 +39,7 @@
             "fullDescription": {
               "text": "Check for division by zero"
             },
+            "helpURI": "https://clang-analyzer.llvm.org/available_checks.html#core.DivideZero",
             "id": "core.DivideZero",
             "name": {
               "text": "core.DivideZero"
index e01d55c527f1957d43f4f6e8d763a916f38ad6da..4f20274334a65ea3363bb4c183149dc1f064b9c9 100644 (file)
@@ -57,6 +57,36 @@ static std::string getStringValue(const Record &R, StringRef field) {
   return std::string();
 }
 
+// Calculates the integer value representing the BitsInit object
+static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
+  assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!");
+
+  uint64_t Value = 0;
+  for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) {
+    const auto *Bit = cast<BitInit>(B->getBit(i));
+    Value |= uint64_t(Bit->getValue()) << i;
+  }
+  return Value;
+}
+
+static std::string getCheckerDocs(const Record &R) {
+  StringRef LandingPage;
+  if (BitsInit *BI = R.getValueAsBitsInit("Documentation")) {
+    uint64_t V = getValueFromBitsInit(BI);
+    if (V == 1)
+      LandingPage = "available_checks.html";
+    else if (V == 2)
+      LandingPage = "alpha_checks.html";
+  }
+  
+  if (LandingPage.empty())
+    return "";
+
+  return (llvm::Twine("https://clang-analyzer.llvm.org/") + LandingPage + "#" +
+          getCheckerFullName(&R))
+      .str();
+}
+
 namespace clang {
 void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
   std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");
@@ -64,6 +94,9 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
 
   using SortedRecords = llvm::StringMap<const Record *>;
 
+  OS << "// This file is automatically generated. Do not edit this file by "
+        "hand.\n";
+
   OS << "\n#ifdef GET_PACKAGES\n";
   {
     SortedRecords sortedPackages;
@@ -89,7 +122,10 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
     OS.write_escaped(getCheckerFullName(&R)) << "\", ";
     OS << R.getName() << ", ";
     OS << "\"";
-    OS.write_escaped(getStringValue(R, "HelpText")) << '\"';
+    OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
+    OS << "\"";
+    OS.write_escaped(getCheckerDocs(R));
+    OS << "\"";
     OS << ")\n";
   }
   OS << "#endif // GET_CHECKERS\n\n";
index a9a30b2d3614f49fbffe1398ed63fb982b2dbe7a..beab87b6b36a59eb8062bf0cba26e8576e62bfac 100644 (file)
@@ -43,10 +43,10 @@ Patches welcome!
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.clone.CloneChecker"><div class="namedescr expandable"><span class="name">
 alpha.clone.CloneChecker</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Reports similar pieces of code.</div></div></td>
+Reports similar pieces of code.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void log();
@@ -74,10 +74,10 @@ int maxClone(int x, int y) { // similar code here
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.BoolAssignment"><div class="namedescr expandable"><span class="name">
 alpha.core.BoolAssignment</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warn about assigning non-{0,1} values to boolean variables.</div></div></td>
+Warn about assigning non-{0,1} values to boolean variables.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -86,11 +86,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.CallAndMessageUnInitRefArg"><div class="namedescr expandable"><span class="name">
 alpha.core.CallAndMessageUnInitRefArg</span><span class="lang">
 (C, C++)</span><div class="descr">
-Check for uninitialized arguments in function calls and Objective-C 
-message expressions.</div></div></td>
+Check for uninitialized arguments in function calls and Objective-C
+message expressions.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(void) {
@@ -109,13 +109,13 @@ void test(void) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.CastSize"><div class="namedescr expandable"><span class="name">
 alpha.core.CastSize</span><span class="lang">
 (C)</span><div class="descr">
-Check when casting a malloc'ed type T, whether the size is a multiple of the 
+Check when casting a malloc'ed type T, whether the size is a multiple of the
 size of T (Works only with <span class="name">unix.Malloc</span>
-or <span class="name">alpha.unix.MallocWithAnnotations</span> 
-checks enabled).</div></div></td>
+or <span class="name">alpha.unix.MallocWithAnnotations</span>
+checks enabled).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -124,10 +124,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.CastToStruct"><div class="namedescr expandable"><span class="name">
 alpha.core.CastToStruct</span><span class="lang">
 (C, C++)</span><div class="descr">
-Check for cast from non-struct pointer to struct pointer.</div></div></td>
+Check for cast from non-struct pointer to struct pointer.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C
@@ -147,10 +147,10 @@ void test(int *p) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.Conversion"><div class="namedescr expandable"><span class="name">
 alpha.core.Conversion</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Loss of sign or precision in implicit conversions</div></div></td>
+Loss of sign or precision in implicit conversions</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(unsigned U, signed S) {
@@ -172,26 +172,26 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.DynamicTypeChecker"><div class="namedescr expandable"><span class="name">
 alpha.core.DynamicTypeChecker</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for cases where the dynamic and the static type of an 
-object are unrelated.</div></div></td>
+Check for cases where the dynamic and the static type of an
+object are unrelated.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 id date = [NSDate date];
 
-// Warning: Object has a dynamic type 'NSDate *' which is 
+// Warning: Object has a dynamic type 'NSDate *' which is
 // incompatible with static type 'NSNumber *'"
 NSNumber *number = date;
 [number doubleValue];
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.FixedAddr"><div class="namedescr expandable"><span class="name">
 alpha.core.FixedAddr</span><span class="lang">
 (C)</span><div class="descr">
-Check for assignment of a fixed address to a pointer.</div></div></td>
+Check for assignment of a fixed address to a pointer.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -201,10 +201,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.IdenticalExpr"><div class="namedescr expandable"><span class="name">
 alpha.core.IdenticalExpr</span><span class="lang">
 (C, C++)</span><div class="descr">
-Warn about suspicious uses of identical expressions.</div></div></td>
+Warn about suspicious uses of identical expressions.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C
@@ -232,11 +232,11 @@ void test(bool b) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.PointerArithm"><div class="namedescr expandable"><span class="name">
 alpha.core.PointerArithm</span><span class="lang">
 (C)</span><div class="descr">
-Check for pointer arithmetic on locations other than array 
-elements.</div></div></td>
+Check for pointer arithmetic on locations other than array
+elements.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -247,11 +247,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.PointerSub"><div class="namedescr expandable"><span class="name">
 alpha.core.PointerSub</span><span class="lang">
 (C)</span><div class="descr">
-Check for pointer subtractions on two pointers pointing to different memory 
-chunks.</div></div></td>
+Check for pointer subtractions on two pointers pointing to different memory
+chunks.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -261,60 +261,60 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.SizeofPtr"><div class="namedescr expandable"><span class="name">
 alpha.core.SizeofPtr</span><span class="lang">
 (C)</span><div class="descr">
-Warn about unintended use of <code>sizeof()</code> on pointer 
-expressions.</div></div></td>
+Warn about unintended use of <code>sizeof()</code> on pointer
+expressions.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 struct s {};
 
 int test(struct s *p) {
-  return sizeof(p); 
+  return sizeof(p);
     // warn: sizeof(ptr) can produce an unexpected result
 }
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.StackAddressAsyncEscape"><div class="namedescr expandable"><span class="name">
 alpha.core.StackAddressAsyncEscape</span><span class="lang">
 (C)</span><div class="descr">
 Check that addresses to stack memory do not escape the function that involves
 <code>dispatch_after</code> or <code>dispatch_async</code>. This checker is
 a part of core.StackAddressEscape, but is
 <a href=https://reviews.llvm.org/D41042>temporarily disabled</a> until some
-false positives are fixed.</div></div></td>
+false positives are fixed.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 dispatch_block_t test_block_inside_block_async_leak() {
   int x = 123;
   void (^inner)(void) = ^void(void) {
     int y = x;
-    ++y; 
+    ++y;
   };
   void (^outer)(void) = ^void(void) {
     int z = x;
     ++z;
-    inner(); 
-  }; 
+    inner();
+  };
   return outer; // warn: address of stack-allocated block is captured by a
                 //       returned block
 }
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.core.TestAfterDivZero"><div class="namedescr expandable"><span class="name">
 alpha.core.TestAfterDivZero</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Check for division by variable that is later compared against 0. 
+Check for division by variable that is later compared against 0.
 Either the comparison is useless or there is division by zero.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(int x) {
   var = 77 / x;
-  if (x == 0) { } // warn 
+  if (x == 0) { } // warn
 }
 </pre></div></div></td></tr>
 
@@ -329,12 +329,12 @@ void test(int x) {
 <tbody>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.DeleteWithNonVirtualDtor"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.DeleteWithNonVirtualDtor</span><span class="lang">
 (C++)</span><div class="descr">
 Reports destructions of polymorphic objects with a non-virtual destructor in
 their base class
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 NonVirtual *create() {
@@ -349,11 +349,11 @@ void sink(NonVirtual *x) {
 }
 </pre></div></div></td></tr>
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.EnumCastOutOfRange"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.EnumCastOutOfRange</span><span class="lang">
 (C++)</span><div class="descr">
   Check for integer to enumeration casts that could result in undefined values.
-</div></div></td>
+</div></div></a></td>
   <td><div class="exampleContainer expandable">
     <div class="example"><pre>
 enum TestEnum {
@@ -368,11 +368,11 @@ void foo() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.InvalidatedIterator"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.InvalidatedIterator</span><span class="lang">
 (C++)</span><div class="descr">
 Check for use of invalidated iterators.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void bad_copy_assign_operator_list1(std::list<int> &L1,
@@ -384,11 +384,11 @@ void bad_copy_assign_operator_list1(std::list<int> &L1,
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.IteratorRange"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.IteratorRange</span><span class="lang">
 (C++)</span><div class="descr">
 Check for iterators used outside their valid ranges.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void simple_bad_end(const std::vector<int> &v) {
@@ -398,12 +398,12 @@ void simple_bad_end(const std::vector<int> &v) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.MismatchedIterator"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.MismatchedIterator</span><span class="lang">
 (C++)</span><div class="descr">
 Check for use of iterators of different containers where iterators of the same
 container are expected.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
@@ -424,12 +424,12 @@ void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
-alpha.cplusplus.MisusedMovedObject</span><span class="lang">
+<tr><td><a id="alpha.cplusplus.Move"><div class="namedescr expandable"><span class="name">
+alpha.cplusplus.Move</span><span class="lang">
 (C++)</span><div class="descr">
 Method calls on a moved-from object and copying a moved-from object will be
 reported.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 struct A {
@@ -444,7 +444,7 @@ void f() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.cplusplus.UninitializedObject"><div class="namedescr expandable"><span class="name">
 alpha.cplusplus.UninitializedObject</span><span class="lang">
 (C++)</span><div class="descr">
 This checker reports uninitialized fields in objects created after a constructor
@@ -481,7 +481,7 @@ It has several options:
 
     <code>-analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"</code>.
   </li>
-</ul></div></div></td>
+</ul></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // With Pedantic and CheckPointeeInitialization set to true
@@ -568,10 +568,10 @@ void f() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.deadcode.UnreachableCode"><div class="namedescr expandable"><span class="name">
 alpha.deadcode.UnreachableCode</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Check unreachable code.</div></div></td>
+Check unreachable code.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C
@@ -609,7 +609,7 @@ void test(id x) {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.llvm.Conventions"><div class="namedescr expandable"><span class="name">
 alpha.llvm.Conventions</span><span class="lang">
 (C)</span><div class="descr">
 Check code for LLVM codebase conventions:
@@ -618,7 +618,7 @@ Check code for LLVM codebase conventions:
   whose lifetime is shorter than the <code>StringRef</code>'s.</li>
   <li>Clang AST nodes should not have fields that can allocate memory.</li>
 </ul>
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 <!-- TODO: Add examples, as currently it's hard to get this checker working. -->
@@ -634,11 +634,11 @@ Check code for LLVM codebase conventions:
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignment"><div class="namedescr expandable"><span class="name">
 alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check that Objective C properties follow the following rule: the property 
-should be set with the setter, not though a direct assignment.</div></div></td>
+Check that Objective C properties follow the following rule: the property
+should be set with the setter, not though a direct assignment.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyClass : NSObject {}
@@ -654,11 +654,11 @@ should be set with the setter, not though a direct assignment.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions"><div class="namedescr expandable"><span class="name">
 alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for direct assignments to instance variables in the methods annotated 
-with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></td>
+Check for direct assignments to instance variables in the methods annotated
+with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyClass : NSObject {}
@@ -679,17 +679,17 @@ with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.osx.cocoa.InstanceVariableInvalidation"><div class="namedescr expandable"><span class="name">
 alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
 (ObjC)</span><div class="descr">
 Check that the invalidatable instance variables are invalidated in the methods
-annotated with <code>objc_instance_variable_invalidator</code>.</div></div></td>
+annotated with <code>objc_instance_variable_invalidator</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @protocol Invalidation &lt;NSObject&gt;
-- (void) invalidate 
+- (void) invalidate
   __attribute__((annotate("objc_instance_variable_invalidator")));
-@end 
+@end
 
 @interface InvalidationImpObj : NSObject &lt;Invalidation&gt;
 @end
@@ -707,15 +707,15 @@ annotated with <code>objc_instance_variable_invalidator</code>.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.osx.cocoa.MissingInvalidationMethod"><div class="namedescr expandable"><span class="name">
 alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check that the invalidation methods are present in classes that contain 
-invalidatable instance variables.</div></div></td>
+Check that the invalidation methods are present in classes that contain
+invalidatable instance variables.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @protocol Invalidation &lt;NSObject&gt;
-- (void)invalidate 
+- (void)invalidate
   __attribute__((annotate("objc_instance_variable_invalidator")));
 @end
 
@@ -732,25 +732,25 @@ invalidatable instance variables.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.osx.cocoa.localizability.PluralMisuseChecker"><div class="namedescr expandable"><span class="name">
 alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns against using one vs. many plural pattern in code 
+Warns against using one vs. many plural pattern in code
 when generating localized strings.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
-NSString *reminderText = 
+NSString *reminderText =
   NSLocalizedString(@"None", @"Indicates no reminders");
 if (reminderCount == 1) {
   // Warning: Plural cases are not supported across all languages.
   // Use a .stringsdict file instead
-  reminderText = 
+  reminderText =
     NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
 } else if (reminderCount >= 2) {
   // Warning: Plural cases are not supported across all languages.
   // Use a .stringsdict file instead
-  reminderText = 
+  reminderText =
     [NSString stringWithFormat:
       NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
         reminderCount];
@@ -766,10 +766,10 @@ if (reminderCount == 1) {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.ArrayBound"><div class="namedescr expandable"><span class="name">
 alpha.security.ArrayBound</span><span class="lang">
 (C)</span><div class="descr">
-Warn about buffer overflows (older checker).</div></div></td>
+Warn about buffer overflows (older checker).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -791,7 +791,7 @@ void test() {
 }
 </pre></div><div class="separator"></div>
 <div class="example"><pre>
-// note: requires unix.Malloc or 
+// note: requires unix.Malloc or
 // alpha.unix.MallocWithAnnotations checks enabled.
 void test() {
   int *p = malloc(12);
@@ -807,10 +807,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.ArrayBoundV2"><div class="namedescr expandable"><span class="name">
 alpha.security.ArrayBoundV2</span><span class="lang">
 (C)</span><div class="descr">
-Warn about buffer overflows (newer checker).</div></div></td>
+Warn about buffer overflows (newer checker).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -844,10 +844,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.MallocOverflow"><div class="namedescr expandable"><span class="name">
 alpha.security.MallocOverflow</span><span class="lang">
 (C)</span><div class="descr">
-Check for overflows in the arguments to <code>malloc()</code>.</div></div></td>
+Check for overflows in the arguments to <code>malloc()</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(int n) {
@@ -856,11 +856,11 @@ void test(int n) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.MmapWriteExec"><div class="namedescr expandable"><span class="name">
 alpha.security.MmapWriteExec</span><span class="lang">
 (C)</span><div class="descr">
 Warn on <code>mmap()<code> calls that are both writable and executable.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(int n) {
@@ -873,10 +873,10 @@ void test(int n) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.ReturnPtrRange"><div class="namedescr expandable"><span class="name">
 alpha.security.ReturnPtrRange</span><span class="lang">
 (C)</span><div class="descr">
-Check for an out-of-bound pointer being returned to callers.</div></div></td>
+Check for an out-of-bound pointer being returned to callers.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 static int A[10];
@@ -894,10 +894,10 @@ int test(void) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.security.taint.TaintPropagation"><div class="namedescr expandable"><span class="name">
 alpha.security.taint.TaintPropagation</span><span class="lang">
 (C)</span><div class="descr">
-Generate taint information used by other checkers.</div></div></td>
+Generate taint information used by other checkers.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -907,7 +907,7 @@ void test() {
 </pre></div><div class="separator"></div>
 <div class="example"><pre>
 // note: compiler internally checks if the second param to
-// sprintf is a string literal or not. 
+// sprintf is a string literal or not.
 // Use -Wno-format-security to suppress compiler warning.
 void test() {
   char s[10], buf[10];
@@ -920,7 +920,7 @@ void test() {
 void test() {
   size_t ts;
   scanf("%zd", &ts); // 'ts' marked as tainted
-  int *p = (int *)malloc(ts * sizeof(int)); 
+  int *p = (int *)malloc(ts * sizeof(int));
     // warn: untrusted data as buffer size
 }
 </pre></div></div></td></tr>
@@ -935,7 +935,7 @@ void test() {
 <tbody>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.BlockInCriticalSection"><div class="namedescr expandable"><span class="name">
 alpha.unix.BlockInCriticalSection</span><span class="lang">
 (C)</span><div class="descr">
 Check for calls to blocking functions inside a critical section. Applies to:
@@ -955,7 +955,7 @@ mtx_trylock<br>
 mtx_unlock<br>
 lock_guard<br>
 unique_lock</div>
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -968,10 +968,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.Chroot"><div class="namedescr expandable"><span class="name">
 alpha.unix.Chroot</span><span class="lang">
 (C)</span><div class="descr">
-Check improper use of <code>chroot</code>.</div></div></td>
+Check improper use of <code>chroot</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void f();
@@ -983,7 +983,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.PthreadLock"><div class="namedescr expandable"><span class="name">
 alpha.unix.PthreadLock</span><span class="lang">
 (C)</span><div class="descr">
 Simple lock -> unlock checker; applies to:<div class=functions>
@@ -1002,14 +1002,14 @@ lck_rw_try_lock_shared<br>
 pthread_mutex_unlock<br>
 pthread_rwlock_unlock<br>
 lck_mtx_unlock<br>
-lck_rw_done</div></div></div></td>
+lck_rw_done</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 pthread_mutex_t mtx;
 
 void test() {
   pthread_mutex_lock(&mtx);
-  pthread_mutex_lock(&mtx); 
+  pthread_mutex_lock(&mtx);
     // warn: this lock has already been acquired
 }
 </pre></div><div class="separator"></div>
@@ -1019,7 +1019,7 @@ lck_mtx_t lck1, lck2;
 void test() {
   lck_mtx_lock(&lck1);
   lck_mtx_lock(&lck2);
-  lck_mtx_unlock(&lck1); 
+  lck_mtx_unlock(&lck1);
     // warn: this was not the most recently acquired lock
 }
 </pre></div><div class="separator"></div>
@@ -1037,7 +1037,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.SimpleStream"><div class="namedescr expandable"><span class="name">
 alpha.unix.SimpleStream</span><span class="lang">
 (C)</span><div class="descr">
 Check for misuses of stream APIs:<div class=functions>
@@ -1046,7 +1046,7 @@ fclose</div>(demo checker, the subject of the demo
 (<a href="http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
 ,<a href="https://youtu.be/kdxlsP5QVPw">Video</a>)
 by Anna Zaks and Jordan Rose presented at the <a href="http://llvm.org/devmtg/2012-11/">
-2012 LLVM Developers' Meeting).</a></div></div></td>
+2012 LLVM Developers' Meeting).</a></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1065,7 +1065,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.Stream"><div class="namedescr expandable"><span class="name">
 alpha.unix.Stream</span><span class="lang">
 (C)</span><div class="descr">
 Check stream handling functions:<div class=functions>fopen<br>
@@ -1081,7 +1081,7 @@ fsetpos<br>
 clearerr<br>
 feof<br>
 ferror<br>
-fileno</div></div></div></td>
+fileno</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1092,7 +1092,7 @@ void test() {
 void test() {
   FILE *p = fopen("foo", "r");
   fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
-  fclose(p); 
+  fclose(p);
 }
 </pre></div><div class="separator"></div>
 <div class="example"><pre>
@@ -1103,13 +1103,13 @@ void test() {
     fseek(p, 1, 3);
      // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
 
-  fclose(p); 
+  fclose(p);
 }
 </pre></div><div class="separator"></div>
 <div class="example"><pre>
 void test() {
   FILE *p = fopen("foo", "r");
-  fclose(p); 
+  fclose(p);
   fclose(p); // warn: already closed
 }
 </pre></div><div class="separator"></div>
@@ -1122,12 +1122,12 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.cstring.BufferOverlap"><div class="namedescr expandable"><span class="name">
 alpha.unix.cstring.BufferOverlap</span><span class="lang">
 (C)</span><div class="descr">
 Checks for overlap in two buffer arguments; applies to:<div class=functions>
 memcpy<br>
-mempcpy</div></div></div></td>
+mempcpy</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1137,7 +1137,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.cstring.NotNullTerminated"><div class="namedescr expandable"><span class="name">
 alpha.unix.cstring.NotNullTerminated</span><span class="lang">
 (C)</span><div class="descr">
 Check for arguments which are not null-terminated strings; applies
@@ -1153,16 +1153,16 @@ strncat</div></div></div></td>
 void test() {
   int y = strlen((char *)&test); // warn
 }
-</pre></div></div></td></tr>
+</pre></div></div></a></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="alpha.unix.cstring.OutOfBounds"><div class="namedescr expandable"><span class="name">
 alpha.unix.cstring.OutOfBounds</span><span class="lang">
 (C)</span><div class="descr">
 Check for out-of-bounds access in string functions; applies
 to:<div class=functions>
 strncopy<br>
-strncat</div></div></div></td>
+strncat</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(char *y) {
index d5eb0eaeccecf20ad84ec750cfdc473f452cdb76..6ca3f8490eb266262cef4f0493b503dfcd7f8757 100644 (file)
@@ -52,11 +52,11 @@ Experimental (Alpha) Checkers</a>.
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.CallAndMessage"><div class="namedescr expandable"><span class="name">
 core.CallAndMessage</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
 Check for logical errors for function calls and Objective-C message expressions
-(e.g., uninitialized arguments, null function pointers).</div></div></td>
+(e.g., uninitialized arguments, null function pointers).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C
@@ -153,10 +153,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.DivideZero"><div class="namedescr expandable"><span class="name">
 core.DivideZero</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Check for division by zero.</div></div></td>
+Check for division by zero.</div></div></a>co</td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(int z) {
@@ -172,11 +172,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.NonNullParamChecker"><div class="namedescr expandable"><span class="name">
 core.NonNullParamChecker</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
 Check for null pointers passed as arguments to a function whose arguments are
-marked with the <code>nonnull</code> attribute.</div></div></td>
+marked with the <code>nonnull</code> attribute.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 int f(int *p) __attribute__((nonnull));
@@ -188,10 +188,10 @@ void test(int *p) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.NullDereference"><div class="namedescr expandable"><span class="name">
 core.NullDereference</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Check for dereferences of null pointers.</div></div></td>
+Check for dereferences of null pointers.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C
@@ -236,10 +236,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.StackAddressEscape"><div class="namedescr expandable"><span class="name">
 core.StackAddressEscape</span><span class="lang">
 (C)</span><div class="descr">
-Check that addresses of stack memory do not escape the function.</div></div></td>
+Check that addresses of stack memory do not escape the function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 char const *p;
@@ -263,10 +263,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.UndefinedBinaryOperatorResult"><div class="namedescr expandable"><span class="name">
 core.UndefinedBinaryOperatorResult</span><span class="lang">
 (C)</span><div class="descr">
-Check for undefined results of binary operators.</div></div></td>
+Check for undefined results of binary operators.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -276,10 +276,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.VLASize"><div class="namedescr expandable"><span class="name">
 core.VLASize</span><span class="lang">
 (C)</span><div class="descr">
-Check for declarations of VLA of undefined or zero size.</div></div></td>
+Check for declarations of VLA of undefined or zero size.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -295,10 +295,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.uninitialized.ArraySubscript"><div class="namedescr expandable"><span class="name">
 core.uninitialized.ArraySubscript</span><span class="lang">
 (C)</span><div class="descr">
-Check for uninitialized values used as array subscripts.</div></div></td>
+Check for uninitialized values used as array subscripts.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -308,10 +308,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.uninitialized.Assign"><div class="namedescr expandable"><span class="name">
 core.uninitialized.Assign</span><span class="lang">
 (C)</span><div class="descr">
-Check for assigning uninitialized values.</div></div></td>
+Check for assigning uninitialized values.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -321,10 +321,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.uninitialized.Branch"><div class="namedescr expandable"><span class="name">
 core.uninitialized.Branch</span><span class="lang">
 (C)</span><div class="descr">
-Check for uninitialized values used as branch conditions.</div></div></td>
+Check for uninitialized values used as branch conditions.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -335,10 +335,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.uninitialized.CapturedBlockVariable"><div class="namedescr expandable"><span class="name">
 core.uninitialized.CapturedBlockVariable</span><span class="lang">
 (C)</span><div class="descr">
-Check for blocks that capture uninitialized values.</div></div></td>
+Check for blocks that capture uninitialized values.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -348,10 +348,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="core.uninitialized.UndefReturn"><div class="namedescr expandable"><span class="name">
 core.uninitialized.UndefReturn</span><span class="lang">
 (C)</span><div class="descr">
-Check for uninitialized values being returned to the caller.</div></div></td>
+Check for uninitialized values being returned to the caller.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 int test() {
@@ -369,11 +369,11 @@ int test() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="cplusplus.NewDelete"><div class="namedescr expandable"><span class="name">
 cplusplus.NewDelete</span><span class="lang">
 (C++)</span><div class="descr">
 Check for double-free, use-after-free and offset problems involving C++ <code>
-delete</code>.</div></div></td>
+delete</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void f(int *p);
@@ -423,11 +423,11 @@ void test() {
 }
 </pre></div></div></td></tr>
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="cplusplus.NewDeleteLeaks"><div class="namedescr expandable"><span class="name">
 cplusplus.NewDeleteLeaks</span><span class="lang">
 (C++)</span><div class="descr">
 Check for memory leaks. Traces memory managed by <code>new</code>/<code>
-delete</code>.</div></div></td>
+delete</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -444,10 +444,10 @@ void test() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="deadcode.DeadStores"><div class="namedescr expandable"><span class="name">
 deadcode.DeadStores</span><span class="lang">
 (C)</span><div class="descr">
-Check for values stored to variables that are never read afterwards.</div></div></td>
+Check for values stored to variables that are never read afterwards.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -465,11 +465,11 @@ void test() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="nullability.NullPassedToNonnull"><div class="namedescr expandable"><span class="name">
 nullability.NullPassedToNonnull</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns when a null pointer is passed to a pointer which has a 
-_Nonnull type.</div></div></td>
+Warns when a null pointer is passed to a pointer which has a
+_Nonnull type.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 if (name != nil)
@@ -479,11 +479,11 @@ NSString *greeting = [@"Hello " stringByAppendingString:name];
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="nullability.NullReturnedFromNonnull"><div class="namedescr expandable"><span class="name">
 nullability.NullReturnedFromNonnull</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns when a null pointer is returned from a function that has 
-_Nonnull return type.</div></div></td>
+Warns when a null pointer is returned from a function that has
+_Nonnull return type.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 - (nonnull id)firstChild {
@@ -491,17 +491,17 @@ _Nonnull return type.</div></div></td>
   if ([_children count] > 0)
     result = _children[0];
 
-  // Warning: nil returned from a method that is expected 
+  // Warning: nil returned from a method that is expected
   // to return a non-null value
   return result;
 }
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="nullability.NullableDereferenced"><div class="namedescr expandable"><span class="name">
 nullability.NullableDereferenced</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns when a nullable pointer is dereferenced.</div></div></td>
+Warns when a nullable pointer is dereferenced.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 struct LinkedList {
@@ -519,10 +519,10 @@ void updateNextData(struct LinkedList *list, int newData) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="nullability.NullablePassedToNonnull"><div class="namedescr expandable"><span class="name">
 nullability.NullablePassedToNonnull</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.</div></div></td>
+Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 typedef struct Dummy { int val; } Dummy;
@@ -545,16 +545,16 @@ void test() {
 
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="optin.cplusplus.VirtualCall"><div class="namedescr expandable"><span class="name">
 optin.cplusplus.VirtualCall</span><span class="lang">
 (C++)</span><div class="descr">
-Check virtual member function calls during construction or 
-destruction.</div></div></td>
+Check virtual member function calls during construction or
+destruction.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 class A {
 public:
-  A() { 
+  A() {
     f(); // warn
   }
   virtual void f();
@@ -571,16 +571,16 @@ public:
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="optin.mpi.MPI-Checker"><div class="namedescr expandable"><span class="name">
 optin.mpi.MPI-Checker</span><span class="lang">
 (C)</span><div class="descr">
-Checks MPI code</div></div></td>
+Checks MPI code</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
   double buf = 0;
   MPI_Request sendReq1;
-  MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 
+  MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
       0, MPI_COMM_WORLD, &sendReq1);
 } // warn: request 'sendReq1' has no matching wait.
 </pre></div><div class="separator"></div>
@@ -604,10 +604,10 @@ void missingNonBlocking() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="optin.osx.cocoa.localizability.EmptyLocalizationContextChecker"><div class="namedescr expandable"><span class="name">
 optin.osx.cocoa.localizability.EmptyLocalizationContextChecker</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check that NSLocalizedString macros include a comment for context.</div></div></td>
+Check that NSLocalizedString macros include a comment for context.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 - (void)test {
@@ -619,14 +619,14 @@ Check that NSLocalizedString macros include a comment for context.</div></div></
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="optin.osx.cocoa.localizability.NonLocalizedStringChecker"><div class="namedescr expandable"><span class="name">
 optin.osx.cocoa.localizability.NonLocalizedStringChecker</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warns about uses of non-localized NSStrings passed to UI methods 
-expecting localized NSStrings</div></div></td>
+Warns about uses of non-localized NSStrings passed to UI methods
+expecting localized NSStrings</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
-NSString *alarmText = 
+NSString *alarmText =
   NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
 if (!isEnabled) {
   alarmText = @"Disabled";
@@ -646,11 +646,11 @@ UILabel *alarmStateLabel = [[UILabel alloc] init];
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.API"><div class="namedescr expandable"><span class="name">
 osx.API</span><span class="lang">
 (C)</span><div class="descr">
 Check for proper uses of various Apple APIs:<div class=functions>
-dispatch_once</div></div></div></td>
+dispatch_once</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -660,15 +660,15 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.NumberObjectConversion"><div class="namedescr expandable"><span class="name">
 osx.NumberObjectConversion</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
-Check for erroneous conversions of objects representing numbers 
-into numbers</div></div></td>
+Check for erroneous conversions of objects representing numbers
+into numbers</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
-// Warning: Comparing a pointer value of type 'NSNumber *' 
+// Warning: Comparing a pointer value of type 'NSNumber *'
 // to a scalar integer value
 if (photoCount > 0) {
   [self displayPhotos];
@@ -676,7 +676,7 @@ if (photoCount > 0) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.SecKeychainAPI"><div class="namedescr expandable"><span class="name">
 osx.SecKeychainAPI</span><span class="lang">
 (C)</span><div class="descr">
 Check for improper uses of the Security framework's Keychain APIs:<div class=functions>
@@ -685,7 +685,7 @@ SecKeychainFindGenericPassword<br>
 SecKeychainFindInternetPassword<br>
 SecKeychainItemFreeContent<br>
 SecKeychainItemCopyAttributesAndData<br>
-SecKeychainItemFreeAttributesAndData</div></div></div></td>
+SecKeychainItemFreeAttributesAndData</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -756,10 +756,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.AtSync"><div class="namedescr expandable"><span class="name">
 osx.cocoa.AtSync</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></td>
+Check for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(id x) {
@@ -775,11 +775,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.ClassRelease"><div class="namedescr expandable"><span class="name">
 osx.cocoa.ClassRelease</span><span class="lang">
 (ObjC)</span><div class="descr">
 Check for sending <code>retain</code>, <code>release</code>, or <code>
-autorelease</code> directly to a class.</div></div></td>
+autorelease</code> directly to a class.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyClass : NSObject
@@ -791,16 +791,16 @@ void test(void) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.Dealloc"><div class="namedescr expandable"><span class="name">
 osx.cocoa.Dealloc</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warn about Objective-C classes that lack a correct implementation 
+Warn about Objective-C classes that lack a correct implementation
 of <code>-dealloc</code>.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyObject : NSObject {
-  id _myproperty;  
+  id _myproperty;
 }
 @end
 
@@ -851,10 +851,10 @@ of <code>-dealloc</code>.
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.IncompatibleMethodTypes"><div class="namedescr expandable"><span class="name">
 osx.cocoa.IncompatibleMethodTypes</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for an incompatible type signature when overriding an Objective-C method.</div></div></td>
+Check for an incompatible type signature when overriding an Objective-C method.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyClass1 : NSObject
@@ -875,13 +875,13 @@ Check for an incompatible type signature when overriding an Objective-C method.<
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
-alpha.osx.cocoa.MissingSuperCall</span><span class="lang">
+<tr><td><a id="osx.cocoa.MissingSuperCall"><div class="namedescr expandable"><span class="name">
+osx.cocoa.MissingSuperCall</span><span class="lang">
 (ObjC)</span><div class="descr">
 Warn about Objective-C methods that lack a necessary call to super. (Note: The
 compiler now has a warning for methods annotated with <code>objc_requires_super</code>
 attribute. The checker exists to check methods in the Cocoa frameworks
-that haven't yet adopted this attribute.)</div></div></td>
+that haven't yet adopted this attribute.)</div></div></a></td>
 <td><div class="example"><pre>
 @interface Test : UIViewController
 @end
@@ -891,11 +891,11 @@ that haven't yet adopted this attribute.)</div></div></td>
 </pre></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.NSAutoreleasePool"><div class="namedescr expandable"><span class="name">
 osx.cocoa.NSAutoreleasePool</span><span class="lang">
 (ObjC)</span><div class="descr">
 Warn for suboptimal uses of NSAutoreleasePool in Objective-C
-GC mode (<code>-fobjc-gc</code> compiler option).</div></div></td>
+GC mode (<code>-fobjc-gc</code> compiler option).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -905,10 +905,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.NSError"><div class="namedescr expandable"><span class="name">
 osx.cocoa.NSError</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check usage of <code>NSError**</code> parameters.</div></div></td>
+Check usage of <code>NSError**</code> parameters.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface A : NSObject
@@ -936,7 +936,7 @@ Check usage of <code>NSError**</code> parameters.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.NilArg"><div class="namedescr expandable"><span class="name">
 osx.cocoa.NilArg</span><span class="lang">
 (ObjC)</span><div class="descr">
 Check for prohibited nil arguments in specific Objective-C method calls:<div class=functions>
@@ -946,7 +946,7 @@ Check for prohibited nil arguments in specific Objective-C method calls:<div cla
 - compare:options:range:<br>
 - compare:options:range:locale:<br>
 - componentsSeparatedByCharactersInSet:<br>
-- initWithFormat:</div></div></div></td>
+- initWithFormat:</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 NSComparisonResult test(NSString *s) {
@@ -958,25 +958,25 @@ NSComparisonResult test(NSString *s) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.ObjCGenerics"><div class="namedescr expandable"><span class="name">
 osx.cocoa.ObjCGenerics</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for type errors when using Objective-C generics</div></div></td>
+Check for type errors when using Objective-C generics</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 NSMutableArray<NSString *> *names = [NSMutableArray array];
 NSMutableArray *birthDates = names;
 
-// Warning: Conversion from value of type 'NSDate *' 
+// Warning: Conversion from value of type 'NSDate *'
 // to incompatible type 'NSString *'
 [birthDates addObject: [NSDate date]];
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.RetainCount"><div class="namedescr expandable"><span class="name">
 osx.cocoa.RetainCount</span><span class="lang">
 (ObjC)</span><div class="descr">
-Check for leaks and violations of the Cocoa Memory Management rules.</div></div></td>
+Check for leaks and violations of the Cocoa Memory Management rules.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -991,11 +991,11 @@ CFStringRef test(char *bytes) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.SelfInit"><div class="namedescr expandable"><span class="name">
 osx.cocoa.SelfInit</span><span class="lang">
 (ObjC)</span><div class="descr">
 Check that <code>self</code> is properly initialized inside an initializer
-method.</div></div></td>
+method.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyObj : NSObject {
@@ -1027,10 +1027,10 @@ method.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.SuperDealloc"><div class="namedescr expandable"><span class="name">
 osx.cocoa.SuperDealloc</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warn about improper use of '[super dealloc]' in Objective-C</div></div></td>
+Warn about improper use of '[super dealloc]' in Objective-C</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface SuperDeallocThenReleaseIvarClass : NSObject {
@@ -1047,10 +1047,10 @@ Warn about improper use of '[super dealloc]' in Objective-C</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.UnusedIvars"><div class="namedescr expandable"><span class="name">
 osx.cocoa.UnusedIvars</span><span class="lang">
 (ObjC)</span><div class="descr">
-Warn about private ivars that are never used.</div></div></td>
+Warn about private ivars that are never used.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 @interface MyObj : NSObject {
@@ -1064,11 +1064,11 @@ Warn about private ivars that are never used.</div></div></td>
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.cocoa.VariadicMethodTypes"><div class="namedescr expandable"><span class="name">
 osx.cocoa.VariadicMethodTypes</span><span class="lang">
 (ObjC)</span><div class="descr">
 Check for passing non-Objective-C types to variadic collection initialization
-methods that expect only Objective-C types.</div></div></td>
+methods that expect only Objective-C types.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1078,10 +1078,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.coreFoundation.CFError"><div class="namedescr expandable"><span class="name">
 osx.coreFoundation.CFError</span><span class="lang">
 (C)</span><div class="descr">
-Check usage of <code>CFErrorRef*</code> parameters.</div></div></td>
+Check usage of <code>CFErrorRef*</code> parameters.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(CFErrorRef *error) {
@@ -1097,10 +1097,10 @@ int foo(CFErrorRef *error) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.coreFoundation.CFNumber"><div class="namedescr expandable"><span class="name">
 osx.coreFoundation.CFNumber</span><span class="lang">
 (C)</span><div class="descr">
-Check for improper uses of <code>CFNumberCreate</code>.</div></div></td>
+Check for improper uses of <code>CFNumberCreate</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 CFNumberRef test(unsigned char x) {
@@ -1110,11 +1110,11 @@ CFNumberRef test(unsigned char x) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.coreFoundation.CFRetainRelease"><div class="namedescr expandable"><span class="name">
 osx.coreFoundation.CFRetainRelease</span><span class="lang">
 (C)</span><div class="descr">
 Check for null arguments to <code>CFRetain</code>, <code>CFRelease</code>,
-<code>CFMakeCollectable</code>.</div></div></td>
+<code>CFMakeCollectable</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test(CFTypeRef p) {
@@ -1132,10 +1132,10 @@ void test(int x, CFTypeRef p) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.coreFoundation.containers.OutOfBounds"><div class="namedescr expandable"><span class="name">
 osx.coreFoundation.containers.OutOfBounds</span><span class="lang">
 (C)</span><div class="descr">
-Checks for index out-of-bounds when using <code>CFArray</code> API.</div></div></td>
+Checks for index out-of-bounds when using <code>CFArray</code> API.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1145,11 +1145,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="osx.coreFoundation.containers.PointerSizedValues"><div class="namedescr expandable"><span class="name">
 osx.coreFoundation.containers.PointerSizedValues</span><span class="lang">
 (C)</span><div class="descr">
 Warns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are
-created with non-pointer-size values.</div></div></td>
+created with non-pointer-size values.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1168,11 +1168,11 @@ void test() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.FloatLoopCounter"><div class="namedescr expandable"><span class="name">
 security.FloatLoopCounter</span><span class="lang">
 (C)</span><div class="descr">
 Warn on using a floating point value as a loop counter (CERT: FLP30-C,
-FLP30-CPP).</div></div></td>
+FLP30-CPP).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1181,7 +1181,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.UncheckedReturn"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.UncheckedReturn</span><span class="lang">
 (C)</span><div class="descr">
 Warn on uses of functions whose return values must be always checked:<div class=functions>
@@ -1190,7 +1190,7 @@ setgid<br>
 seteuid<br>
 setegid<br>
 setreuid<br>
-setregid</div></div></div></td>
+setregid</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1199,10 +1199,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.bcmp"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.bcmp</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>bcmp</code> function.</div></div></td>
+Warn on uses of the <code>bcmp</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1210,10 +1210,10 @@ void test() {
 }
 </pre></div></div></td></tr>
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.bcopy"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.bcopy</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>bcopy</code> function.</div></div></td>
+Warn on uses of the <code>bcopy</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1221,10 +1221,10 @@ void test() {
 }
 </pre></div></div></td></tr>
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.bzero"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.bzero</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>bzero</code> function.</div></div></td>
+Warn on uses of the <code>bzero</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1233,10 +1233,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.getpw"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.getpw</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>getpw</code> function.</div></div></td>
+Warn on uses of the <code>getpw</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1246,10 +1246,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.gets"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.gets</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>gets</code> function.</div></div></td>
+Warn on uses of the <code>gets</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1259,12 +1259,12 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.mkstemp"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.mkstemp</span><span class="lang">
 (C)</span><div class="descr">
 Warn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or
 <code>mkdtemp</code> is passed fewer than 6
-X's in the format string.</div></div></td>
+X's in the format string.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1273,10 +1273,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.mktemp"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.mktemp</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>mktemp</code> function.</div></div></td>
+Warn on uses of the <code>mktemp</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1285,7 +1285,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.rand"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.rand</span><span class="lang">
 (C)</span><div class="descr">
 Warn on uses of inferior random number generating functions (only if <code>arc4random</code>
@@ -1298,7 +1298,7 @@ lrand48<br>
 mrand48<br>
 nrand48<br>
 random<br>
-rand_r</div></div></div></td>
+rand_r</div></div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1307,10 +1307,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.strcpy"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.strcpy</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></td>
+Warn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1322,10 +1322,10 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="security.insecureAPI.vfork"><div class="namedescr expandable"><span class="name">
 security.insecureAPI.vfork</span><span class="lang">
 (C)</span><div class="descr">
-Warn on uses of the <code>vfork</code> function.</div></div></td>
+Warn on uses of the <code>vfork</code> function.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1342,7 +1342,7 @@ void test() {
 <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.API"><div class="namedescr expandable"><span class="name">
 unix.API</span><span class="lang">
 (C)</span><div class="descr">
 Check calls to various UNIX/POSIX functions:<div class=functions>
@@ -1351,7 +1351,7 @@ pthread_once<br>
 calloc<br>
 malloc<br>
 realloc<br>
-alloca<br>
+alloca<br></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // Currently the check is performed for apple targets only.
@@ -1398,11 +1398,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.Malloc"><div class="namedescr expandable"><span class="name">
 unix.Malloc</span><span class="lang">
 (C)</span><div class="descr">
 Check for memory leaks, double free, and use-after-free and offset problems
-involving <code>malloc</code>.</div></div></td>
+involving <code>malloc</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1440,11 +1440,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.MallocSizeof"><div class="namedescr expandable"><span class="name">
 unix.MallocSizeof</span><span class="lang">
 (C)</span><div class="descr">
 Check for dubious <code>malloc</code>, <code>calloc</code> or
-<code>realloc</code> arguments involving <code>sizeof</code>.</div></div></td>
+<code>realloc</code> arguments involving <code>sizeof</code>.</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1456,11 +1456,11 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.MismatchedDeallocator"><div class="namedescr expandable"><span class="name">
 unix.MismatchedDeallocator</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
 Check for mismatched deallocators (e.g. passing a pointer allocating
-with <code>new</code> to <code>free()</code>).</div></div></td>
+with <code>new</code> to <code>free()</code>).</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 // C, C++
@@ -1527,10 +1527,10 @@ void test(NSUInteger dataLength) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.Vfork"><div class="namedescr expandable"><span class="name">
 unix.Vfork</span><span class="lang">
 (C)</span><div class="descr">
-Check for proper usage of vfork</div></div></td>
+Check for proper usage of vfork</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 int test(int x) {
@@ -1559,13 +1559,13 @@ int test(int x) {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.cstring.BadSizeArg"><div class="namedescr expandable"><span class="name">
 unix.cstring.BadSizeArg</span><span class="lang">
 (C)</span><div class="descr">
 Check the size argument passed to <code>strncat</code> for common erroneous
 patterns. Use <code>-Wno-strncat-size</code> compiler option to mute other
 <code>strncat</code>-related compiler warnings.
-</div></div></td>
+</div></div></a></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
 void test() {
@@ -1576,7 +1576,7 @@ void test() {
 </pre></div></div></td></tr>
 
 
-<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><a id="unix.cstring.NullArg"><div class="namedescr expandable"><span class="name">
 unix.cstring.NullArg</span><span class="lang">
 (C)</span><div class="descr">
 Check for null pointers being passed as arguments to C string functions:<div class=functions>
@@ -1589,7 +1589,7 @@ strncat<br>
 strcmp<br>
 strncmp<br>
 strcasecmp<br>
-strncasecmp</div></div></div></td>
+strncasecmp</div></div></div></a></td>
 <td><div class="example"><pre>
 int test() {
   return strlen(0); // warn