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. 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?
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.
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.
> 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,
> 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
The AST for the first will be a CXXConstructExpr that calls the default constructor.
The AST for the second will be a CXXConstructExpr calls the copy constructor, with f as its argument.
> 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,
Why are you trying to treat the copy constructor as special here? In both cases the static analyzer needs to model a call to the constructor. If you're planning to treat a call to the copy constructor as a "copy" (in some semantic sense), then you'll want to recognize any CXXConstructExpr/CXXTemporaryObjectExpr expressions that calls the copy constructor as being a "copy", not just ones that show up when initializing variables.
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.