Szelethus updated this revision to Diff 161262. Szelethus added a comment. Removed a TODO from the checker file.
https://reviews.llvm.org/D50904 Files: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp www/analyzer/alpha_checks.html
Index: www/analyzer/alpha_checks.html =================================================================== --- www/analyzer/alpha_checks.html +++ www/analyzer/alpha_checks.html @@ -323,6 +323,118 @@ }; </pre></div></div></td></tr> +<tbody> +<tr><td><div class="namedescr expandable"><span class="name"> +alpha.cplusplus.UninitializedObject</span><span class="lang"> +(C++)</span><div class="descr"> +This checker reports uninitialized fields in objects created +after a constructor 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 alpha.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 alpha.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 alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true</code>. + </li> +</ul></div></div></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 +} +<div class="example"><pre> + + +</pre></div></div></td></tr> + </tbody></table> Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -285,18 +285,6 @@ } // Checking bases. - // FIXME: As of now, because of `willObjectBeAnalyzedLater`, objects whose - // type is a descendant of another type will emit warnings for uninitalized - // inherited members. - // This is not the only way to analyze bases of an object -- if we didn't - // filter them out, and didn't analyze the bases, this checker would run for - // each base of the object in order of base initailization and in theory would - // find every uninitalized field. This approach could also make handling - // diamond inheritances more easily. - // - // This rule (that a descendant type's cunstructor is responsible for - // initializing inherited data members) is not obvious, and should it should - // be. const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); if (!CXXRD) return ContainsUninitField;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits