Index: docs/analyzer/checkers.rst =================================================================== --- docs/analyzer/checkers.rst +++ docs/analyzer/checkers.rst @@ -242,6 +242,110 @@ """""""""""""""""""""""""""""" Checks C++ copy and move assignment operators for self assignment. +cplusplus.UninitializedObject (C++) +""""""""""""""""""""""""""""""""""" + +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. +The checker regards inherited fields as direct fields, so one will recieve +warnings for uninitialized inherited data members as well. + +.. code-block:: cpp + + // 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 + } + + // 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 + } + + // With Pedantic set to true 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 + } + + +**Options** + +This checker has several options which can be set from command line (e.g. +``-analyzer-config cplusplus.UninitializedObject:Pedantic=true``): + +* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for + objects that don't have at least one initialized field. Defaults to false. + +* ``NotesAsWarnings`` (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*. + +* ``CheckPointeeInitialization`` (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*. + +* ``IgnoreRecordsWithField`` (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 ""*. + .. _deadcode-checkers: deadcode @@ -1372,101 +1476,6 @@ a.foo(); // warn: method call on a 'moved-from' object 'a' } -alpha.cplusplus.UninitializedObject (C++) -""""""""""""""""""""""""""""""""""""""""" - -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. -The checker regards inherited fields as direct fields, so one will -recieve warnings for uninitialized inherited data members as well. - -.. code-block:: cpp - - // 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 - } - - // 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 - } - - // With Pedantic set to true 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 - } - - -**Options** - -This checker has several options which can be set from command line (e.g. ``-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true``): - -* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for objects that don't have at least one initialized field. Defaults to false. - -* ``NotesAsWarnings`` (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.*. - -* ``CheckPointeeInitialization`` (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.*. - -* ``IgnoreRecordsWithField`` (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 ""*. Can be set with ``-analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"``. - alpha.deadcode ^^^^^^^^^^^^^^ Index: include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- include/clang/StaticAnalyzer/Checkers/Checkers.td +++ include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -448,6 +448,10 @@ HelpText<"Find use-after-move bugs in C++">, Documentation; +def UninitializedObjectChecker: Checker<"UninitializedObject">, + HelpText<"Reports uninitialized fields after object construction">, + Documentation; + } // end: "cplusplus" let ParentPackage = CplusplusOptIn in { @@ -489,10 +493,6 @@ Dependencies<[IteratorModeling]>, Documentation; -def UninitializedObjectChecker: Checker<"UninitializedObject">, - HelpText<"Reports uninitialized fields after object construction">, - Documentation; - } // end: "alpha.cplusplus" Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h @@ -17,7 +17,7 @@ // won't emit warnings for objects that don't have at least one initialized // field. This may be set with // -// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`. +// `-analyzer-config cplusplus.UninitializedObject:Pedantic=true`. // // - "NotesAsWarnings" (boolean). If set to true, the checker will emit a // warning for each uninitialized field, as opposed to emitting one warning @@ -25,14 +25,14 @@ // to it in notes. Defaults to false. // // `-analyzer-config \ -// alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`. +// cplusplus.UninitializedObject:NotesAsWarnings=true`. // // - "CheckPointeeInitialization" (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. // // `-analyzer-config \ -// alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`. +// cplusplus.UninitializedObject:CheckPointeeInitialization=true`. // // TODO: With some clever heuristics, some pointers should be dereferenced // by default. For example, if the pointee is constructed within the @@ -45,14 +45,14 @@ // matches the given pattern. Defaults to "". // // `-analyzer-config \ -// alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`. +// cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`. // // - "IgnoreGuardedFields" (boolean). If set to true, the checker will analyze // _syntactically_ whether the found uninitialized object is used without a // preceding assert call. Defaults to false. // // `-analyzer-config \ -// alpha.cplusplus.UninitializedObject:IgnoreGuardedFields=true`. +// cplusplus.UninitializedObject:IgnoreGuardedFields=true`. // // Most of the following methods as well as the checker itself is defined in // UninitializedObjectChecker.cpp. Index: test/Analysis/cxx-uninitialized-object-inheritance.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-inheritance.cpp +++ test/Analysis/cxx-uninitialized-object-inheritance.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// Index: test/Analysis/cxx-uninitialized-object-no-dereference.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-no-dereference.cpp +++ test/Analysis/cxx-uninitialized-object-no-dereference.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ // RUN: -std=c++11 -DPEDANTIC -verify %s class UninitPointerTest { Index: test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp +++ test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:NotesAsWarnings=true \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++11 -verify %s class NotesAsWarningsTest { Index: test/Analysis/cxx-uninitialized-object-ptr-ref.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++11 -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// Index: test/Analysis/cxx-uninitialized-object-unguarded-access.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-unguarded-access.cpp +++ test/Analysis/cxx-uninitialized-object-unguarded-access.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreGuardedFields=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config cplusplus.UninitializedObject:IgnoreGuardedFields=true \ // RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// Index: test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp +++ test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ // RUN: -std=c++11 -verify %s // expected-no-diagnostics Index: test/Analysis/cxx-uninitialized-object.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object.cpp +++ test/Analysis/cxx-uninitialized-object.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++14 -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ -// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject \ +// RUN: -analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++14 -verify %s //===----------------------------------------------------------------------===// Index: test/Analysis/objcpp-uninitialized-object.mm =================================================================== --- test/Analysis/objcpp-uninitialized-object.mm +++ test/Analysis/objcpp-uninitialized-object.mm @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -std=c++11 -fblocks -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.UninitializedObject -std=c++11 -fblocks -verify %s typedef void (^myBlock) (); Index: www/analyzer/alpha_checks.html =================================================================== --- www/analyzer/alpha_checks.html +++ www/analyzer/alpha_checks.html @@ -444,120 +444,6 @@ - - - - Index: www/analyzer/available_checks.html =================================================================== --- www/analyzer/available_checks.html +++ www/analyzer/available_checks.html @@ -435,6 +435,121 @@ } // warn + + + + +