[cfe-dev] CFG and CXXDefaultInitExpr

Enrico P epertoso at google.com
Tue Oct 22 10:17:54 PDT 2013


Yes, the presence of a CXXDefaultInitExpr is enough to consider a field
initialized.

I forgot to mention that I'm trying to use
clang::runUninitializedVariablesAnalysis() to detect the use of an
uninitialized field in the constructor's body.

In the following case:

1:  struct A {
2:   int a;
3:   int b = a;
4:   int c, d;
5:   A() : c(d) {
6:     a = d;
7:   }
8:  };

A()'s constructor initializers will be (in order): a CXXCtorInitializer
constructed with the FieldDecl of 'b' and a CXXDefaultInitExpr, and one
with the FieldDecl of 'y' and an ImplicitCastExpr.

If UninitializedValues.cpp is modified to also track uninitialized uses of
fields, it will issue a warning about 'd' on line 5 and one on line 6.
It will not warn about 'a' on line 3 because the expression wrapped by
CXXDefaultInitExpr doesn't appear in the CFG. Hence my initial question.

Sema::ActOnMemInitializers (calling 'DiagnoseUnitializedFields' defined in
SemaDeclCXX.cpp) will correctly warn about 'a' on line 3 and 'd' on line 5,
but of course not on line 6.

As we've established that the expression for which a CXXDefaultInitExpr
acts as a placeholder should not be appended to the CFG, the easiest way to
warn on lines 3, 5, and 6 is to use
both SemaDeclCXX.cpp's DiagnoseUnitializedFields and
clang::runUninitializedVariablesAnalysis, but care must be taken so that
only one warning is generated for line 5.

I'm sorry to have caused confusion.
Enrico


On Tue, Oct 22, 2013 at 5:59 PM, Jordan Rose <jordan_rose at apple.com> wrote:

> CXXDefaultInitExprs only appear if the field has an in-class initializer,
> so just the presence of the expr should be enough to consider the field
> initialized. Or am I misunderstanding something?
>
> Jordan
>
>
> On Oct 21, 2013, at 10:10 , Enrico P <epertoso at google.com> wrote:
>
> Right, I can see the CXXDefaultInitExpr appearing multiple times when
> initializing (C++14) aggregates with braces.
>
> Verifying that a field has an in-class initializer (or that the
> constructor has a CXXCtorInitializer for that field) is what I'm currently
> doing.
>
> Sema::ActOnMemInitializers already takes care of the initialization order.
> If the fields appearing in the constructor body aren't ignored until all of
> the CXXCtorInitializers have been visited, duplicate warnings may be
> issued, hence I was wondering whether the analysis could be done in just
> one place.
>
> I guess that for now it would be better to just visit the CFG of a
> constructor starting from the statement that follows the last
> CFGInitializer, and let Sema::ActOnMemInitializers take care of the rest.
>
> Thanks for the answer!
> Enrico
>
> On Fri, Oct 18, 2013 at 6:40 PM, Jordan Rose <jordan_rose at apple.com>wrote:
>
>> Unfortunately yes: a CXXDefaultInitExpr is a placeholder for whichever
>> expression was written as the initial value of the member you've left out,
>> and that expression doesn't belong to the current context. If you used list
>> initialization (braces) to initialize two different objects, you'd end up
>> including the initializer expression twice, and the CFG doesn't work right
>> if the same Stmt* appears more than once.
>>
>> That said, I would think that the presence of a CXXDefaultInitExpr would
>> be enough to prove that a member variable is initialized. If you're worried
>> about initialization order problems, you could either traverse the
>> CXXDefaultInitExpr manually or just make a non-flow-sensitive check that
>> the initializer expression doesn't reference any member variables defined
>> later in the class.
>>
>> Does that help?
>> Jordan
>>
>>
>> On Oct 18, 2013, at 9:19 , Enrico P <epertoso at google.com> wrote:
>>
>> > Hello,
>> >
>> > I'm doing some work on -Wuninitialized to make it detect the use of
>> uninitialized fields within C++ constructor bodies.
>> >
>> > When the CFGBuilder visits a CXXDefaultInitExpr, it won't visit its
>> children because CXXDefaultInitExpr::children() returns an empty
>> child_range.
>> >
>> > Is there any reason for this (maybe related to the comment at line 1108
>> of CFG.cpp?), or is it safe to have it return a non-empty child_range?
>> >
>> > Thanks,
>> > Enrico
>> > _______________________________________________
>> > cfe-dev mailing list
>> > cfe-dev at cs.uiuc.edu
>> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131022/014eb6a0/attachment.html>


More information about the cfe-dev mailing list