[cfe-dev] Constructors vs Copy Constructors in Clang
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Sep 17 11:37:01 PDT 2010
On Sep 17, 2010, at 6:22 PM, Jim Goodnow II wrote:
> At 08:04 AM 9/17/2010, Douglas Gregor wrote:
>
>> On Sep 17, 2010, at 2:30 AM, Jim Goodnow II wrote:
>>
>>> Hi,
>>>
>>> One of the things that I'm seeing in several places is where
>>> VarDecl::getInit() is returning an Expr that is CXXConstructExpr when
>>> a class variable is declared. However, the logic that follows the
>>> getInit() call usually assumes that if a non-NULL value is returned,
>>> there is a value being assigned. In the case of a constructor, that's
>>> sort of true but not completely unless it is a copy constructor.
>>
>> It need not always be a copy constructor. Any constructor could
>> occur there. A CXXConstructExpr occurs anywhere that we're
>> performing initialization by constructor.
>
> Yes, I am aware of that. The problem is distinguishing between:
>
> foo f;
> foo f1 = f;
>
> Both declarations will return a CXXConstructExpr from getInit(), but
> the code I am finding is assuming that there is an assignment
> happening which is not the case in the first declaration.
>
>
>>> So,
>>> a question of philosophy:
>>>
>>> Should getInit() return NULL when the constructor is not a copy
>>> constructor to support the logic in most cases? This might break or
>>> require a rework of things that do handle getInit() correctly like
>>> CodeGen and require a different call to get a non-copy
>> constructor initializer.
>>>
>>> Or should the calls to getInit() be qualified by an additional call
>>> to an 'isCopyConstructor()' function where appropriate?
>>
>>
>> Why do you consider copy constructors to be special? They are
>> elidable in some cases (and CXXConstructExpr tells us when the
>> construction can be elided), but they aren't the only kinds of
>> constructors that are elidable (C++0x allows move constructors to be
>> elided, too). Static analysis need not treat them as special, unless
>> for some reason that improves results.
>>
>> - Doug
>
> Again, I'm looking at code in the static analyzer and other places
> that is assuming an assignment is taking place because getInit() is
> not returning a NULL. My question is how to distinguish between the
> two examples I gave before?
See VarDecl's hasCXXDirectInitializer():
/// hasCXXDirectInitializer - If true, the initializer was a direct
/// initializer, e.g: "int x(1);". The Init expression will be the expression
/// inside the parens or a "ClassType(a,b,c)" class constructor expression for
/// class types. Clients can distinguish between "int x(1);" and "int x=1;"
/// by checking hasCXXDirectInitializer.
-Argiris
> One way is to check the result for a
> constructor and then look at the constructor and see if it is a copy
> constructor or not. So,
>
> if (Expr *Init = D->getInit()) {
>
> becomes
>
> Expr *Init = D->getInit();
> if (Init && (!isa<CXXConstructExpr>(Init) ||
> dyn_cast<CXXConstructExpr>(Init)->getConstructor()->isCopyConstructor()))
> {
>
> - jim
>
> _______________________________________________
> 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/20100917/5e59f71c/attachment.html>
More information about the cfe-dev
mailing list