[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