[analyzer][UninitializedObjectChecker] Added documentation to the checker list

Differential Revision: https://reviews.llvm.org/D50904


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340266 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kristof Umann 2018-08-21 10:47:19 +00:00
parent 01b8a31de3
commit 1bdc37d05e
2 changed files with 112 additions and 12 deletions

View File

@ -286,18 +286,6 @@ bool FindUninitializedFields::isNonUnionUninit(const TypedValueRegion *R,
}
// 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;

View File

@ -323,6 +323,118 @@ public:
};
</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>