[cfe-dev] Constructors vs Copy Constructors in Clang

Jim Goodnow II jim at thegoodnows.net
Fri Sep 17 10:22:54 PDT 2010


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? 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




More information about the cfe-dev mailing list