https://github.com/gamesh411 updated https://github.com/llvm/llvm-project/pull/97032
From b11a113682a1b998395139e5e4736689c0f9be84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fu...@sigmatechnology.com> Date: Wed, 26 Jun 2024 11:09:33 +0200 Subject: [PATCH 1/2] [clang][analyzer][doc] Migrate checkers-related docs from HTML to RST Documentation for the checkers is kept up to date in RST files. This patch removes duplication by replacing the HTML docs with links to docs generated from the RST. --- clang/www/analyzer/alpha_checks.html | 932 +----------- clang/www/analyzer/available_checks.html | 1736 +--------------------- 2 files changed, 2 insertions(+), 2666 deletions(-) diff --git a/clang/www/analyzer/alpha_checks.html b/clang/www/analyzer/alpha_checks.html index 501a9bcbc82a9..80a3ebe4c6166 100644 --- a/clang/www/analyzer/alpha_checks.html +++ b/clang/www/analyzer/alpha_checks.html @@ -17,938 +17,8 @@ <!--#include virtual="menu.html.incl"--> <div id="content"> -<h1>Alpha Checkers</h1> -Experimental checkers in addition to the <a href = "available_checks.html"> -Default Checkers</a>. These are checkers with known issues or limitations that -keep them from being on by default. They are likely to have false positives. -Bug reports are welcome but will likely not be investigated for some time. -Patches welcome! -<ul> -<li><a href="#clone_alpha_checkers">Clone Alpha Checkers</a></li> -<li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li> -<li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li> -<li><a href="#llvm_alpha_checkers">LLVM Checkers</a></li> -<li><a href="#valist_alpha_checkers">Variable Argument Alpha Checkers</a></li> -<li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li> -<li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li> -<li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li> -<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li> -<li><a href="#nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</a></li> -</ul> -<!-- ============================= clone alpha ============================= --> - -<h3 id="clone_alpha_checkers">Clone Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void log(); - -int max(int a, int b) { // warn - log(); - if (a > b) - return a; - return b; -} - -int maxClone(int x, int y) { // similar code here - log(); - if (x > y) - return x; - return y; -} -</pre></div></div></td></tr> -</tbody></table> - -<!-- ============================= core alpha ============================= --> -<h3 id="core_alpha_checkers">Core Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - BOOL b = -1; // warn -} -</pre></div></div></td></tr> - - -<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 -size of T (Works only with <span class="name">unix.Malloc</span> -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() { - int *x = (int *)malloc(11); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C -struct s {}; - -void test(int *p) { - struct s *ps = (struct s *) p; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// C++ -class c {}; - -void test(int *p) { - c *pc = (c *) p; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(unsigned U, signed S) { - if (S > 10) { - if (U < S) { - } - } - if (S < -10) { - if (U < S) { // warn (loss of sign) - } - } -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - long long A = 1LL << 60; - short X = A; // warn (loss of precision) -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -id date = [NSDate date]; - -// 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><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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int *p; - p = (int *) 0x10000; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C -void test() { - int a = 5; - int b = a | 4 | a; // warn: identical expr on both sides -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// C++ -bool f(void); - -void test(bool b) { - int i = 10; - if (f()) { // warn: true and false branches are identical - do { - i--; - } while (f()); - } else { - do { - i--; - } while (f()); - } -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - int *p; - p = &x + 1; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x, y; - int d = &y - &x; // warn -} -</pre></div></div></td></tr> - - -<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></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; - }; - void (^outer)(void) = ^void(void) { - int z = x; - ++z; - inner(); - }; - return outer; // warn: address of stack-allocated block is captured by a - // returned block -} -</pre></div></div></td></tr> - - -<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. -Either the comparison is useless or there is division by zero. -</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(int x) { - var = 77 / x; - if (x == 0) { } // warn -} -</pre></div></div></td></tr> - - -</tbody></table> - -<!-- =========================== cplusplus alpha =========================== --> -<h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> -<tbody> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -NonVirtual *create() { - NonVirtual *x = new NVDerived(); // note: Casting from 'NVDerived' to - // 'NonVirtual' here - return x; -} - -void sink(NonVirtual *x) { - delete x; // warn: destruction of a polymorphic object with no virtual - // destructor -} -</pre></div></div></td></tr> - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void bad_copy_assign_operator_list1(std::list<int> &L1, - const std::list<int> &L2) { - auto i0 = L1.cbegin(); - L1 = L2; - *i0; // warn: invalidated iterator accessed -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void simple_bad_end(const std::vector<int> &v) { - auto i = v.end(); - *i; // warn: iterator accessed outside of its range -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) { - v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed - // using foreign - // iterator argument - v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of - // different containers - // used where the same - // container is - // expected - v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of - // different containers - // used where the same - // container is - // expected -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -struct A { - void foo() {} -}; - -void f() { - A a; - A b = std::move(a); // note: 'a' became 'moved-from' here - a.foo(); // warn: method call on a 'moved-from' object 'a' -} -</pre></div></div></td></tr> - - -</tbody></table> - - -<!-- =========================== dead code alpha =========================== --> -<h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C -int test() { - int x = 1; - while(x); - return x; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// C++ -void test() { - int a = 2; - - while (a > 1) - a--; - - if (a > 1) - a++; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// Objective-C -void test(id x) { - return; - [x retain]; // warn -} -</pre></div></div></td></tr> -</tbody></table> - -<!-- =========================== llvm alpha =========================== --> -<h3 id="llvm_alpha_checkers">LLVM Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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: -<ul> - <li>A <code>StringRef</code> should not be bound to a temporary std::string - 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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -<!-- TODO: Add examples, as currently it's hard to get this checker working. --> -</pre></div></div></td></tr> - -</tbody></table> - - -<!-- ============================== OS X alpha ============================== --> -<h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyClass : NSObject {} -@property (readonly) id A; -- (void) foo; -@end - -@implementation MyClass -- (void) foo { - _A = 0; // warn -} -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyClass : NSObject {} -@property (readonly) id A; -- (void) fAnnotated __attribute__(( - annotate("objc_no_direct_instance_variable_assignment"))); -- (void) fNotAnnotated; -@end - -@implementation MyClass -- (void) fAnnotated { - _A = 0; // warn -} -- (void) fNotAnnotated { - _A = 0; // no warn -} -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@protocol Invalidation <NSObject> -- (void) invalidate - __attribute__((annotate("objc_instance_variable_invalidator"))); -@end - -@interface InvalidationImpObj : NSObject <Invalidation> -@end - -@interface SubclassInvalidationImpObj : InvalidationImpObj { - InvalidationImpObj *var; -} -- (void)invalidate; -@end - -@implementation SubclassInvalidationImpObj -- (void) invalidate {} -@end -// warn: var needs to be invalidated or set to nil -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@protocol Invalidation <NSObject> -- (void)invalidate - __attribute__((annotate("objc_instance_variable_invalidator"))); -@end - -@interface NeedInvalidation : NSObject <Invalidation> -@end - -@interface MissingInvalidationMethodDecl : NSObject { - NeedInvalidation *Var; // warn -} -@end - -@implementation MissingInvalidationMethodDecl -@end -</pre></div></div></td></tr> - - -<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 -when generating localized strings. -</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -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 = - 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 = - [NSString stringWithFormat: - NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"), - reminderCount]; -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== security alpha =========================== --> -<h3 id="security_alpha_checkers">Security Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char *s = ""; - char c = s[1]; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -struct seven_words { - int c[7]; -}; - -void test() { - struct seven_words a, *p; - p = &a; - p[0] = a; - p[1] = a; - p[2] = a; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// note: requires unix.Malloc or -// alpha.unix.MallocWithAnnotations checks enabled. -void test() { - int *p = malloc(12); - p[3] = 4; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - char a[2]; - int *b = (int*)a; - b[1] = 3; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char *s = ""; - char c = s[1]; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - int buf[100]; - int *p = buf; - p = p + 99; - p[1] = 1; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// note: compiler has internal check for this. -// Use -Wno-array-bounds to suppress compiler warning. -void test() { - int buf[100][100]; - buf[0][-1] = 1; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// note: requires alpha.security.taint check turned on. -void test() { - char s[] = "abc"; - int x = getchar(); - char c = s[x]; // warn: index is tainted -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(int n) { - void *p = malloc(n * sizeof(int)); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(int n) { - void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON, -1, 0); - // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to - // exploitable memory regions, which could be overwritten with malicious - // code -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -static int A[10]; - -int *test() { - int *p = A + 10; - return p; // warn -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -int test(void) { - int x; - return x; // warn: undefined or garbage returned -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char x = getchar(); // 'x' marked as tainted - system(&x); // warn: untrusted data is passed to a system call -} -</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. -// Use -Wno-format-security to suppress compiler warning. -void test() { - char s[10], buf[10]; - fscanf(stdin, "%s", s); // 's' marked as tainted - - sprintf(buf, s); // warn: untrusted data as a format string -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - size_t ts; - scanf("%zd", &ts); // 'ts' marked as tainted - int *p = (int *)malloc(ts * sizeof(int)); - // warn: untrusted data as buffer size -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- ============================= unix alpha ============================= --> -<h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> -<tbody> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void f(); - -void test() { - chroot("/usr/local"); - f(); // warn: no call of chdir("/") immediately after chroot -} -</pre></div></div></td></tr> - - -<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> -pthread_mutex_lock<br> -pthread_rwlock_rdlock<br> -pthread_rwlock_wrlock<br> -lck_mtx_lock<br> -lck_rw_lock_exclusive<br> -lck_rw_lock_shared<br> -pthread_mutex_trylock<br> -pthread_rwlock_tryrdlock<br> -pthread_rwlock_tryrwlock<br> -lck_mtx_try_lock<br> -lck_rw_try_lock_exclusive<br> -lck_rw_try_lock_shared<br> -pthread_mutex_unlock<br> -pthread_rwlock_unlock<br> -lck_mtx_unlock<br> -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); - // warn: this lock has already been acquired -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -lck_mtx_t lck1, lck2; - -void test() { - lck_mtx_lock(&lck1); - lck_mtx_lock(&lck2); - lck_mtx_unlock(&lck1); - // warn: this was not the most recently acquired lock -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -lck_mtx_t lck1, lck2; - -void test() { - if (lck_mtx_try_lock(&lck1) == 0) - return; - - lck_mtx_lock(&lck2); - lck_mtx_unlock(&lck1); - // warn: this was not the most recently acquired lock -} -</pre></div></div></td></tr> - - -<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> -fopen<br> -fclose</div>(demo checker, the subject of the demo -(<a href="https://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="https://llvm.org/devmtg/2012-11/"> -2012 LLVM Developers' Meeting).</a></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - FILE *F = fopen("myfile.txt", "w"); -} // warn: opened file is never closed -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - FILE *F = fopen("myfile.txt", "w"); - - if (F) - fclose(F); - - fclose(F); // warn: closing a previously closed file stream -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int a[4] = {0}; - memcpy(a + 2, a + 1, 8); // warn -} -</pre></div></div></td></tr> - - -<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 -to:<div class=functions> -strlen<br> -strnlen<br> -strcpy<br> -strncpy<br> -strcat<br> -strncat</div></div></div></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int y = strlen((char *)&test); // warn -} -</pre></div></div></a></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(char *y) { - char x[4]; - if (strlen(y) == 4) - strncpy(x, y, 5); // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== nondeterminism alpha =========================== --> -<h3 id="nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<tr><td><a id="alpha.nondeterminism.PointerIteration"><div class="namedescr expandable"><span class="name"> -alpha.nondeterminism.PointerIteration</span><span class="lang"> -(C++)</span><div class="descr"> -Check for non-determinism caused by iterating unordered containers of pointers.</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C++ -void test() { - int a = 1, b = 2; - std::unordered_set<int *> UnorderedPtrSet = {&a, &b}; - - for (auto i : UnorderedPtrSet) // warn - f(i); -} -</pre></div></div></td></tr> -<tr><td><a id="alpha.nondeterminism.PointerSorting"><div class="namedescr expandable"><span class="name"> -alpha.nondeterminism.PointerSorting</span><span class="lang"> -(C++)</span><div class="descr"> -Check for non-determinism caused by sorting of pointers.</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C++ -void test() { - int a = 1, b = 2; - std::vector<int *> V = {&a, &b}; - std::sort(V.begin(), V.end()); // warn -} -</pre></div></div></td></tr> -</tbody></table> +For the up to date list of all <em>alpha</em> checkers, see <a href="https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers">Experimental Checkers</a>. </div> <!-- page --> </div> <!-- content --> diff --git a/clang/www/analyzer/available_checks.html b/clang/www/analyzer/available_checks.html index c23865e57e87d..18d0badac5323 100644 --- a/clang/www/analyzer/available_checks.html +++ b/clang/www/analyzer/available_checks.html @@ -17,1742 +17,8 @@ <!--#include virtual="menu.html.incl"--> <div id="content"> -<h1>Available Checkers</h1> -The analyzer performs checks that are categorized into families or "checkers". The -default set of checkers covers a variety of checks targeted at finding security -and API usage bugs, dead code, and other logic errors. See the -<a href = "#default_checkers">Default Checkers</a> list below. In addition to -these, the analyzer contains a number of <a href = "alpha_checks.html"> -Experimental (Alpha) Checkers</a>. -<h3>Writeups with examples of some of the bugs that the analyzer finds</h3> -<ul> -<li><a href="http://www.mobileorchard.com/bug-finding-with-clang-5-resources-to-get-you-started/">Bug Finding With Clang: 5 Resources To Get You Started</a></li> -<li><a href="https://fruitstandsoftware.mrrooni.com/blog/blog/2008/08/04/finding-memory-leaks-with-the-llvmclang-static-analyzer/">Finding Memory Leaks With The LLVM/Clang Static Analyzer</a></li> -<li><a href="https://weblog.rogueamoeba.com/2008/07/14/the-clang-static-analyzer/">Under the Microscope - The Clang Static Analyzer</a></li> -<li><a href="https://www.mikeash.com/pyblog/friday-qa-2009-03-06-using-the-clang-static-analyzer.html">Mike Ash - Using the Clang Static Analyzer</a></li> -</ul> - -<h2 id="default_checkers">Default Checkers</h2> -<ul> -<li><a href="#core_checkers">Core Checkers</a> model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.</li> -<li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li> -<li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li> -<li><a href="#nullability_checkers">Nullability Checkers</a> </li> -<li><a href="#optin_checkers">Optin Checkers</a> </li> -<li><a href="#osx_checkers">OS X Checkers</a> perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)</li> -<li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li> -<li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li> -</ul> - -<!-- =========================== core =========================== --> -<h3 id="core_checkers">Core Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C -struct S { - int x; -}; - -void f(struct S s); - -void test() { - struct S s; - f(s); // warn: passed-by-value arg contain uninitialized data -} -</pre></div> -<div class="example"><pre> -// C -void test() { - void (*foo)(void); - foo(); // warn: function pointer is uninitialized -} -</pre></div> -<div class="example"><pre> -// C -void test() { - void (*foo)(void); - foo = 0; - foo(); // warn: function pointer is null -} -</pre></div> -<div class="example"><pre> -// C++ -class C { -public: - void f(); -}; - -void test() { - C *pc; - pc->f(); // warn: object pointer is uninitialized -} -</pre></div> -<div class="example"><pre> -// C++ -class C { -public: - void f(); -}; - -void test() { - C *pc = 0; - pc->f(); // warn: object pointer is null -} -</pre></div> -<div class="example"><pre> -// Objective-C -@interface MyClass : NSObject -@property (readwrite,assign) id x; -- (long double)longDoubleM; -@end - -void test() { - MyClass *obj1; - long double ld1 = [obj1 longDoubleM]; - // warn: receiver is uninitialized -} -</pre></div> -<div class="example"><pre> -// Objective-C -@interface MyClass : NSObject -@property (readwrite,assign) id x; -- (long double)longDoubleM; -@end - -void test() { - MyClass *obj1; - id i = obj1.x; // warn: uninitialized object pointer -} -</pre></div> -<div class="example"><pre> -// Objective-C -@interface Subscriptable : NSObject -- (id)objectAtIndexedSubscript:(unsigned int)index; -@end - -@interface MyClass : Subscriptable -@property (readwrite,assign) id x; -- (long double)longDoubleM; -@end - -void test() { - MyClass *obj1; - id i = obj1[0]; // warn: uninitialized object pointer -} -</pre></div></div></td></tr> - - -<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></a>co</td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(int z) { - if (z == 0) - int x = 1 / z; // warn -} -</pre></div> -<div class="example"><pre> -void test() { - int x = 1; - int y = x % 0; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -int f(int *p) __attribute__((nonnull)); - -void test(int *p) { - if (!p) - f(p); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C -void test(int *p) { - if (p) - return; - - int x = p[0]; // warn -} -</pre></div> -<div class="example"><pre> -// C -void test(int *p) { - if (!p) - *p = 0; // warn -} -</pre></div> -<div class="example"><pre> -// C++ -class C { -public: - int x; -}; - -void test() { - C *pc = 0; - int k = pc->x; // warn -} -</pre></div> -<div class="example"><pre> -// Objective-C -@interface MyClass { -@public - int x; -} -@end - -void test() { - MyClass *obj = 0; - obj->x = 1; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -char const *p; - -void test() { - char const str[] = "string"; - p = str; // warn -} -</pre></div> -<div class="example"><pre> -void* test() { - return __builtin_alloca(12); // warn -} -</pre></div> -<div class="example"><pre> -void test() { - static int *x; - int y; - x = &y; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - int y = x + 1; // warn: left operand is garbage -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - int vla1[x]; // warn: garbage as size -} -</pre></div> -<div class="example"><pre> -void test() { - int x = 0; - int vla2[x]; // warn: zero size -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int i, a[10]; - int x = a[i]; // warn: array subscript is undefined -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - x |= 1; // warn: left expression is uninitialized -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - if (x) // warn - return; -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - ^{ int y = x; }(); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -int test() { - int x; - return x; // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== C++ =========================== --> -<h3 id="cplusplus_checkers">C++ Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> - -<tr><td><a id="cplusplus.ArrayDelete"><div class="namedescr expandable"><span class="name"> -cplusplus.ArrayDelete</span><span class="lang"> -(C++)</span><div class="descr"> -Reports destructions of arrays of polymorphic objects that are destructed as -their base class. If the type of an array-pointer is different from the type of -its underlying objects, calling <code>delete[]</code> is undefined. -</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -class Base { -public: - virtual ~Base() {} -}; -class Derived : public Base {}; - -Base *create() { - Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here - return x; -} - -void sink(Base *x) { - delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' undefined -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void f(int *p); - -void testUseMiddleArgAfterDelete(int *p) { - delete p; - f(p); // warn: use after free -} -</pre></div> -<div class="example"><pre> -class SomeClass { -public: - void f(); -}; - -void test() { - SomeClass *c = new SomeClass; - delete c; - c->f(); // warn: use after free -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = (int *)__builtin_alloca(sizeof(int)); - delete p; // warn: deleting memory allocated by alloca -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = new int; - delete p; - delete p; // warn: attempt to free released -} -</pre></div> -<div class="example"><pre> -void test() { - int i; - delete &i; // warn: delete address of local -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = new int[1]; - delete[] (++p); - // warn: argument to 'delete[]' is offset by 4 bytes - // from the start of memory allocated by 'new[]' -} -</pre></div></div></td></tr> - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int *p = new int; -} // warn -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== dead code =========================== --> -<h3 id="deadcode_checkers">Dead Code Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x; - x = 1; // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== nullability =========================== --> -<h3 id="nullability_checkers">Nullability Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -if (name != nil) - return; -// Warning: nil passed to a callee that requires a non-null 1st parameter -NSString *greeting = [@"Hello " stringByAppendingString:name]; -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -- (nonnull id)firstChild { - id result = nil; - if ([_children count] > 0) - result = _children[0]; - - // Warning: nil returned from a method that is expected - // to return a non-null value - return result; -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -struct LinkedList { - int data; - struct LinkedList *next; -}; - -struct LinkedList * _Nullable getNext(struct LinkedList *l); - -void updateNextData(struct LinkedList *list, int newData) { - struct LinkedList *next = getNext(list); - // Warning: Nullable pointer is dereferenced - next->data = 7; -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -typedef struct Dummy { int val; } Dummy; -Dummy *_Nullable returnsNullable(); -void takesNonnull(Dummy *_Nonnull); - -void test() { - Dummy *p = returnsNullable(); - takesNonnull(p); // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== optin =========================== --> -<h3 id="optin_checkers">Optin Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tr><td><a id="cplusplus.UninitializedObject"><div class="namedescr expandable"><span class="name"> -cplusplus.UninitializedObject</span><span class="lang"> -(C++)</span><div class="descr"> -This checker reports uninitialized fields in objects created after a constructor -call. It doesn't only find direct uninitialized fields, but rather makes a deep -inspection of the object, analyzing all of it's fields subfields. <br> -The checker regards inherited fields as direct fields, so one will recieve -warnings for uninitialized inherited data members as well. <br> -<br> -It has several options: -<ul> - <li> - "<code>Pedantic</code>" (boolean). If its not set or is set to false, the - checker won't emit warnings for objects that don't have at least one - initialized field. This may be set with <br> - <code>-analyzer-config cplusplus.UninitializedObject:Pedantic=true</code>. - </li> - <li> - "<code>NotesAsWarnings</code>" (boolean). If set to true, the checker will - emit a warning for each uninitalized field, as opposed to emitting one - warning per constructor call, and listing the uninitialized fields that - belongs to it in notes. Defaults to false. <br> - <code>-analyzer-config cplusplus.UninitializedObject:NotesAsWarnings=true</code>. - </li> - <li> - "<code>CheckPointeeInitialization</code>" (boolean). If set to false, the - checker will not analyze the pointee of pointer/reference fields, and will - only check whether the object itself is initialized. Defaults to false. <br> - <code>-analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true</code>. - </li> - <li> - "<code>IgnoreRecordsWithField</code>" (string). If supplied, the checker - will not analyze structures that have a field with a name or type name that - matches the given pattern. Defaults to <code>""</code>. - - <code>-analyzer-config cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"</code>. - </li> -</ul></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// With Pedantic and CheckPointeeInitialization set to true - -struct A { - struct B { - int x; // note: uninitialized field 'this->b.x' - // note: uninitialized field 'this->bptr->x' - int y; // note: uninitialized field 'this->b.y' - // note: uninitialized field 'this->bptr->y' - }; - int *iptr; // note: uninitialized pointer 'this->iptr' - B b; - B *bptr; - char *cptr; // note: uninitialized pointee 'this->cptr' - - A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} -}; - -void f() { - A::B b; - char c; - A a(&b, &c); // warning: 6 uninitialized fields - // after the constructor call -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// With Pedantic set to false and -// CheckPointeeInitialization set to true -// (every field is uninitialized) - -struct A { - struct B { - int x; - int y; - }; - int *iptr; - B b; - B *bptr; - char *cptr; - - A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} -}; - -void f() { - A::B b; - char c; - A a(&b, &c); // no warning -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -// With Pedantic and CheckPointeeInitialization set to false -// (pointees are regarded as initialized) - -struct A { - struct B { - int x; // note: uninitialized field 'this->b.x' - int y; // note: uninitialized field 'this->b.y' - }; - int *iptr; // note: uninitialized pointer 'this->iptr' - B b; - B *bptr; - char *cptr; - - A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {} -}; - -void f() { - A::B b; - char c; - A a(&b, &c); // warning: 3 uninitialized fields - // after the constructor call -} -</pre></div></div></td></tr> - - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -class A { -public: - A() { - f(); // warn - } - virtual void f(); -}; -</pre></div><div class="separator"></div> -<div class="example"><pre> -class A { -public: - ~A() { - this->f(); // warn - } - virtual void f(); -}; -</pre></div></div></td></tr> - - -<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></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, - 0, MPI_COMM_WORLD, &sendReq1); -} // warn: request 'sendReq1' has no matching wait. -</pre></div><div class="separator"></div> -<div class="example"><pre> -void test() { - double buf = 0; - MPI_Request sendReq; - MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); - MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn - MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn - MPI_Wait(&sendReq, MPI_STATUS_IGNORE); -} -</pre></div><div class="separator"></div> -<div class="example"><pre> -void missingNonBlocking() { - int rank = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Request sendReq1[10][10][10]; - MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -- (void)test { - NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn - NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn - NSString *string3 = NSLocalizedStringWithDefaultValue( - @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -NSString *alarmText = - NSLocalizedString(@"Enabled", @"Indicates alarm is turned on"); -if (!isEnabled) { - alarmText = @"Disabled"; -} -UILabel *alarmStateLabel = [[UILabel alloc] init]; - -// Warning: User-facing text should use localized string macro -[alarmStateLabel setText:alarmText]; -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== OS X =========================== --> -<h3 id="osx_checkers">OS X Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - dispatch_once_t pred = 0; - dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"]; -// Warning: Comparing a pointer value of type 'NSNumber *' -// to a scalar integer value -if (photoCount > 0) { - [self displayPhotos]; -} -</pre></div></div></td></tr> - - -<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> -SecKeychainItemCopyContent<br> -SecKeychainFindGenericPassword<br> -SecKeychainFindInternetPassword<br> -SecKeychainItemFreeContent<br> -SecKeychainItemCopyAttributesAndData<br> -SecKeychainItemFreeAttributesAndData</div></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - unsigned int *ptr = 0; - UInt32 length; - - SecKeychainItemFreeContent(ptr, &length); - // warn: trying to free data which has not been allocated -} -</pre></div> -<div class="example"><pre> -void test() { - unsigned int *ptr = 0; - UInt32 *length = 0; - void *outData; - - OSStatus st = - SecKeychainItemCopyContent(2, ptr, ptr, length, outData); - // warn: data is not released -} -</pre></div> -<div class="example"><pre> -void test() { - unsigned int *ptr = 0; - UInt32 *length = 0; - void *outData; - - OSStatus st = - SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); - - SecKeychainItemFreeContent(ptr, outData); - // warn: only call free if a non-NULL buffer was returned -} -</pre></div> -<div class="example"><pre> -void test() { - unsigned int *ptr = 0; - UInt32 *length = 0; - void *outData; - - OSStatus st = - SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); - - st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData); - // warn: release data before another call to the allocator - - if (st == noErr) - SecKeychainItemFreeContent(ptr, outData); -} -</pre></div> -<div class="example"><pre> -void test() { - SecKeychainItemRef itemRef = 0; - SecKeychainAttributeInfo *info = 0; - SecItemClass *itemClass = 0; - SecKeychainAttributeList *attrList = 0; - UInt32 *length = 0; - void *outData = 0; - - OSStatus st = - SecKeychainItemCopyAttributesAndData(itemRef, info, - itemClass, &attrList, - length, &outData); - - SecKeychainItemFreeContent(attrList, outData); - // warn: deallocator doesn't match the allocator -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(id x) { - if (!x) - @synchronized(x) {} // warn: nil value used as mutex -} -</pre></div> -<div class="example"><pre> -void test() { - id y; - @synchronized(y) {} // warn: uninitialized value used as mutex -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyClass : NSObject -@end - -void test(void) { - [MyClass release]; // warn -} -</pre></div></div></td></tr> - - -<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 -of <code>-dealloc</code>. -</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyObject : NSObject { - id _myproperty; -} -@end - -@implementation MyObject // warn: lacks 'dealloc' -@end -</pre></div><div class="separator"></div> -<div class="example"><pre> -@interface MyObject : NSObject {} -@property(assign) id myproperty; -@end - -@implementation MyObject // warn: does not send 'dealloc' to super -- (void)dealloc { - self.myproperty = 0; -} -@end -</pre></div><div class="separator"></div> -<div class="example"><pre> -@interface MyObject : NSObject { - id _myproperty; -} -@property(retain) id myproperty; -@end - -@implementation MyObject -@synthesize myproperty = _myproperty; - // warn: var was retained but wasn't released -- (void)dealloc { - [super dealloc]; -} -@end -</pre></div><div class="separator"></div> -<div class="example"><pre> -@interface MyObject : NSObject { - id _myproperty; -} -@property(assign) id myproperty; -@end - -@implementation MyObject -@synthesize myproperty = _myproperty; - // warn: var wasn't retained but was released -- (void)dealloc { - [_myproperty release]; - [super dealloc]; -} -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyClass1 : NSObject -- (int)foo; -@end - -@implementation MyClass1 -- (int)foo { return 1; } -@end - -@interface MyClass2 : MyClass1 -- (float)foo; -@end - -@implementation MyClass2 -- (float)foo { return 1.0; } // warn -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="example"><pre> -@interface Test : UIViewController -@end -@implementation test -- (void)viewDidLoad {} // warn -@end -</pre></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [pool release]; // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface A : NSObject -- (void)foo:(NSError **)error; -@end - -@implementation A -- (void)foo:(NSError **)error { - // warn: method accepting NSError** should have a non-void - // return value -} -@end -</pre></div> -<div class="example"><pre> -@interface A : NSObject -- (BOOL)foo:(NSError **)error; -@end - -@implementation A -- (BOOL)foo:(NSError **)error { - *error = 0; // warn: potential null dereference - return 0; -} -@end -</pre></div></div></td></tr> - - -<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> -- caseInsensitiveCompare:<br> -- compare:<br> -- compare:options:<br> -- compare:options:range:<br> -- compare:options:range:locale:<br> -- componentsSeparatedByCharactersInSet:<br> -- initWithFormat:</div></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -NSComparisonResult test(NSString *s) { - NSString *aString = nil; - return [s caseInsensitiveCompare:aString]; - // warn: argument to 'NSString' method - // 'caseInsensitiveCompare:' cannot be nil -} -</pre></div></div></td></tr> - - -<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></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 *' -// to incompatible type 'NSString *' -[birthDates addObject: [NSDate date]]; -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - NSString *s = [[NSString alloc] init]; // warn -} -</pre></div> -<div class="example"><pre> -CFStringRef test(char *bytes) { - return CFStringCreateWithCStringNoCopy( - 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyObj : NSObject { - id x; -} -- (id)init; -@end - -@implementation MyObj -- (id)init { - [super init]; - x = 0; // warn: instance variable used while 'self' is not - // initialized - return 0; -} -@end -</pre></div> -<div class="example"><pre> -@interface MyObj : NSObject -- (id)init; -@end - -@implementation MyObj -- (id)init { - [super init]; - return self; // warn: returning uninitialized 'self' -} -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface SuperDeallocThenReleaseIvarClass : NSObject { - NSObject *_ivar; -} -@end - -@implementation SuperDeallocThenReleaseIvarClass -- (void)dealloc { - [super dealloc]; - [_ivar release]; // warn -} -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -@interface MyObj : NSObject { -@private - id x; // warn -} -@end - -@implementation MyObj -@end -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - [NSSet setWithObjects:@"Foo", "Bar", nil]; - // warn: argument should be an ObjC pointer type, not 'char *' -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(CFErrorRef *error) { - // warn: function accepting CFErrorRef* should have a - // non-void return -} -</pre></div> -<div class="example"><pre> -int foo(CFErrorRef *error) { - *error = 0; // warn: potential null dereference - return 0; -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -CFNumberRef test(unsigned char x) { - return CFNumberCreate(0, kCFNumberSInt16Type, &x); - // warn: 8 bit integer is used to initialize a 16 bit integer -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(CFTypeRef p) { - if (!p) - CFRetain(p); // warn -} -</pre></div> -<div class="example"><pre> -void test(int x, CFTypeRef p) { - if (p) - return; - - CFRelease(p); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks); - CFArrayGetValueAtIndex(A, 0); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int x[] = { 1 }; - CFArrayRef A = CFArrayCreate(0, (const void **)x, 1, - &kCFTypeArrayCallBacks); // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== security =========================== --> -<h3 id="security_checkers">Security Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn -} -</pre></div></div></td></tr> - - -<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> -setuid<br> -setgid<br> -seteuid<br> -setegid<br> -setreuid<br> -setregid</div></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - setuid(1); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - bcmp(ptr0, ptr1, n); // warn -} -</pre></div></div></td></tr> - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - bcopy(src, dst, n); // warn -} -</pre></div></div></td></tr> - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - bzero(ptr, n); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char buff[1024]; - getpw(2, buff); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char buff[1024]; - gets(buff); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - mkstemp("XX"); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp -} -</pre></div></div></td></tr> - - -<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> -function is available):<div class=functions> -drand48<br> -erand48<br> -jrand48<br> -lcong48<br> -lrand48<br> -mrand48<br> -nrand48<br> -random<br> -rand_r</div></div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - random(); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char x[4]; - char *y = "abcd"; - - strcpy(x, y); // warn -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - vfork(); // warn -} -</pre></div></div></td></tr> - - -<tr><td><a id="security.insecureAPI.decodeValueOfObjCType"><div class="namedescr expandable"><span class="name"> -security.insecureAPI.decodeValueOfObjCType</span><span class="lang"> -(ObjC)</span><div class="descr"> -Warn on uses of the <code>-[NSCoder decodeValueOfObjCType:at:]</code> method. -The safe alternative is <code>-[NSCoder decodeValueOfObjCType:at:size:]</code>.</div></div></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test(NSCoder *decoder) { - // This would be a vulnerability on 64-bit platforms - // but not on 32-bit platforms. - NSUInteger x; - [decoder decodeValueOfObjCType:"I" at:&x]; // warn -} -</pre></div></div></td></tr> - -</tbody></table> - -<!-- =========================== unix =========================== --> -<h3 id="unix_checkers">Unix Checkers</h3> -<table class="checkers"> -<colgroup><col class="namedescr"><col class="example"></colgroup> -<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> - -<tbody> -<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> -open<br> -pthread_once<br> -calloc<br> -malloc<br> -realloc<br> -alloca<br></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// Currently the check is performed for apple targets only. -void test(const char *path) { - int fd = open(path, O_CREAT); - // warn: call to 'open' requires a third argument when the - // 'O_CREAT' flag is set -} -</pre></div> -<div class="example"><pre> -void f(); - -void test() { - pthread_once_t pred = {0x30B1BCBA, {0}}; - pthread_once(&pred, f); - // warn: call to 'pthread_once' uses the local variable -} -</pre></div> -<div class="example"><pre> -void test() { - void *p = malloc(0); // warn: allocation size of 0 bytes -} -</pre></div> -<div class="example"><pre> -void test() { - void *p = calloc(0, 42); // warn: allocation size of 0 bytes -} -</pre></div> -<div class="example"><pre> -void test() { - void *p = malloc(1); - p = realloc(p, 0); // warn: allocation size of 0 bytes -} -</pre></div> -<div class="example"><pre> -void test() { - void *p = alloca(0); // warn: allocation size of 0 bytes -} -</pre></div> -<div class="example"><pre> -void test() { - void *p = valloc(0); // warn: allocation size of 0 bytes -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - int *p = malloc(1); - free(p); - free(p); // warn: attempt to free released memory -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = malloc(sizeof(int)); - free(p); - *p = 1; // warn: use after free -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = malloc(1); - if (p) - return; // warn: memory is never released -} -</pre></div> -<div class="example"><pre> -void test() { - int a[] = { 1 }; - free(a); // warn: argument is not allocated by malloc -} -</pre></div> -<div class="example"><pre> -void test() { - int *p = malloc(sizeof(char)); - p = p - 1; - free(p); // warn: argument to free() is offset by -4 bytes -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - long *p = malloc(sizeof(short)); - // warn: result is converted to 'long *', which is - // incompatible with operand type 'short' - free(p); -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -// C, C++ -void test() { - int *p = (int *)malloc(sizeof(int)); - delete p; // warn -} -</pre></div> -<div class="example"><pre> -// C, C++ -void __attribute((ownership_returns(malloc))) *user_malloc(size_t); - -void test() { - int *p = (int *)user_malloc(sizeof(int)); - delete p; // warn -} -</pre></div> -<div class="example"><pre> -// C, C++ -void test() { - int *p = new int; - free(p); // warn -} -</pre></div> -<div class="example"><pre> -// C, C++ -void test() { - int *p = new int[1]; - realloc(p, sizeof(long)); // warn -} -</pre></div> -<div class="example"><pre> -// C, C++ -template <typename T> -struct SimpleSmartPointer { - T *ptr; - - explicit SimpleSmartPointer(T *p = 0) : ptr(p) {} - ~SimpleSmartPointer() { - delete ptr; // warn - } -}; - -void test() { - SimpleSmartPointer<int> a((int *)malloc(4)); -} -</pre></div> -<div class="example"><pre> -// C++ -void test() { - int *p = (int *)operator new(0); - delete[] p; // warn -} -</pre></div> -<div class="example"><pre> -// Objective-C, C++ -void test(NSUInteger dataLength) { - int *p = new int; - NSData *d = [NSData dataWithBytesNoCopy:p - length:sizeof(int) freeWhenDone:1]; - // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take - // ownership of memory allocated by 'new' -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -int test(int x) { - pid_t pid = vfork(); // warn - if (pid != 0) - return 0; - - switch (x) { - case 0: - pid = 1; - execl("", "", 0); - _exit(1); - break; - case 1: - x = 0; // warn: this assignment is prohibited - break; - case 2: - foo(); // warn: this function call is prohibited - break; - default: - return 0; // warn: return is prohibited - } - - while(1); -} -</pre></div></div></td></tr> - - -<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></a></td> -<td><div class="exampleContainer expandable"> -<div class="example"><pre> -void test() { - char dest[3]; - strncat(dest, "***", sizeof(dest)); - // warn: potential buffer overflow -} -</pre></div></div></td></tr> - - -<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> -strlen<br> -strnlen<br> -strcpy<br> -strncpy<br> -strcat<br> -strncat<br> -strcmp<br> -strncmp<br> -strcasecmp<br> -strncasecmp</div></div></div></a></td> -<td><div class="example"><pre> -int test() { - return strlen(0); // warn -} -</pre></div></td></tr> - -</tbody></table> +For the up to date list of all checkers, see <a href="https://clang.llvm.org/docs/analyzer/checkers.html#available-checkers">Available Checkers</a>. </div> <!-- page --> </div> <!-- content --> From a4fd02a187ba3d2fd00f82e232b0760e117de9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fu...@sigmatechnology.com> Date: Thu, 4 Jul 2024 14:44:39 +0200 Subject: [PATCH 2/2] add redirect and deprecation warning to pages --- clang/www/analyzer/alpha_checks.html | 9 +++++++-- clang/www/analyzer/available_checks.html | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/www/analyzer/alpha_checks.html b/clang/www/analyzer/alpha_checks.html index 80a3ebe4c6166..1ee44c7d355ba 100644 --- a/clang/www/analyzer/alpha_checks.html +++ b/clang/www/analyzer/alpha_checks.html @@ -2,7 +2,9 @@ "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> - <title>Alpha Checks</title> + <title>Alpha Checkers documentation has moved to clang.llvm.org</title> + <link rel="canonical" href="https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers"/> + <meta http-equiv="refresh" content="0;url=https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers" /> <link type="text/css" rel="stylesheet" href="menu.css"> <link type="text/css" rel="stylesheet" href="content.css"> <script type="text/javascript" src="scripts/menu.js"></script> @@ -18,7 +20,10 @@ <div id="content"> -For the up to date list of all <em>alpha</em> checkers, see <a href="https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers">Experimental Checkers</a>. +<h1>The clangd documentation has moved to clang.llvm.org</h1> +<p style="color:red; font-size:200%">This page is deprecated and will be removed in release 21.0</p> +<a href="https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers">The new site<a> +<script>window.location='https://clang.llvm.org/docs/analyzer/checkers.html#experimental-checkers'</script> </div> <!-- page --> </div> <!-- content --> diff --git a/clang/www/analyzer/available_checks.html b/clang/www/analyzer/available_checks.html index 18d0badac5323..7be155a5854e8 100644 --- a/clang/www/analyzer/available_checks.html +++ b/clang/www/analyzer/available_checks.html @@ -2,7 +2,9 @@ "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> - <title>Available Checkers</title> + <title>Available Checkers documentation has moved to clang.llvm.org</title> + <link rel="canonical" href="https://clang.llvm.org/docs/analyzer/checkers.html"/> + <meta http-equiv="refresh" content="0;url=https://clang.llvm.org/docs/analyzer/checkers.html" /> <link type="text/css" rel="stylesheet" href="menu.css"> <link type="text/css" rel="stylesheet" href="content.css"> <script type="text/javascript" src="scripts/menu.js"></script> @@ -18,7 +20,10 @@ <div id="content"> -For the up to date list of all checkers, see <a href="https://clang.llvm.org/docs/analyzer/checkers.html#available-checkers">Available Checkers</a>. +<h1>The clangd documentation has moved to clang.llvm.org</h1> +<p style="color:red; font-size:200%">This page is deprecated and will be removed in release 21.0</p> +<a href="https://clang.llvm.org/docs/analyzer/checkers.html">The new site<a> +<script>window.location='https://clang.llvm.org/docs/analyzer/checkers.html'</script> </div> <!-- page --> </div> <!-- content --> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits