[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