CFGElement to CFGStmt

Hi,

I am trying to cast CFGElement* to CFGStmt*. I remember using the following
code a while back:
CFGStmt *cs = bit->getAs<CFGStmt>() where bit is a const_iterator (I am
iterating through the elements of a CFG block). I get the following error
"error: cannot convert ‘llvm::Optional<clang::CFGStmt>’ to ‘const
clang::CFGStmt*’ in initialization". I remember the above code used to work
fine a while back. Is there a work around and why the change?
Thanks!

Hi,

I am trying to cast CFGElement* to CFGStmt*. I remember using the following
code a while back:
CFGStmt *cs = bit->getAs<CFGStmt>()

The code looked more like this, I believe:

- if (CFGStmt CS = E.getAs<CFGStmt>()) {
- const Stmt *S = CS.getStmt();
+ if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
+ const Stmt *S = CS->getStmt();

Notice in the old code you didn't convert to a pointer, you converted
to a concrete CFGStmt value.

where bit is a const_iterator (I am
iterating through the elements of a CFG block). I get the following error
"error: cannot convert ‘llvm::Optional<clang::CFGStmt>’ to ‘const
clang::CFGStmt*’ in initialization". I remember the above code used to work
fine a while back. Is there a work around and why the change?

r1759328

There were several issues that lead to this:

1) the llvm::cast machinery was being abused for value conversions
rather than pointer/reference conversions - this created undefined
behavior (casting pointers/references to base objects to derived types
& then calling derived copy ctors with those base objects)
2) CFG* types were boolean testable to check for the "invalid" state.
It was better to enshrine this invalid state in the type system
explicitly through the use of Optional<T> rather than to let every
CFG* object be potentially invalid

Thanks! That worked.

Hi David,

I am trying to do the same anikau31 was trying to do, using your code:

+ if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
+ const Stmt *S = CS->getStmt();

but I'm getting following error on second line:

" error: cannot convert 'clang::CFGStmt::getStmt' from type 'const
clang::Stmt* (clang::CFGStmt::)()const' to type 'const clang::Stmt*' "

Thank you in advance,

Hi David,

I am trying to do the same anikau31 was trying to do, using your code:

+ if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
+ const Stmt *S = CS->getStmt();

but I'm getting following error on second line:

" error: cannot convert 'clang::CFGStmt::getStmt' from type 'const
clang::Stmt* (clang::CFGStmt::)()const' to type 'const clang::Stmt*' "

Looks like you wrote:

const Stmt *S = CS->getStmt;

And forgot the '()' where you should've written:

const Stmt *S = CS->getStmt();

Hi David,

I am trying to do the same anikau31 was trying to do, using your code:

+ if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
+ const Stmt *S = CS->getStmt();

but I'm getting following error on second line:

" error: cannot convert 'clang::CFGStmt::getStmt' from type 'const
clang::Stmt* (clang::CFGStmt::)()const' to type 'const clang::Stmt*' "

Looks like you wrote:

const Stmt *S = CS->getStmt;

And forgot the '()' where you should've written:

const Stmt *S = CS->getStmt();

(& might I suggest self-hosting Clang as your compiler, in part
because it has better error messages for this particular case (&
others), if my guess is correct & the above is the problem. For
example:

call.cpp:7:24: error: reference to non-static member function must be
called; did you mean to call it with no arguments?
  const foo *f = bar().f;
                 ~~~~~~^
                        ()

Hi David,

I am trying to do the same anikau31 was trying to do, using your code:

+ if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
+ const Stmt *S = CS->getStmt();

but I'm getting following error on second line:

" error: cannot convert 'clang::CFGStmt::getStmt' from type 'const
clang::Stmt* (clang::CFGStmt::)()const' to type 'const clang::Stmt*' "

Looks like you wrote:

const Stmt *S = CS->getStmt;

And forgot the '()' where you should've written:

const Stmt *S = CS->getStmt();

Oh, thanks it was real reason.

(& might I suggest self-hosting Clang as your compiler, in part
because it has better error messages for this particular case (&
others), if my guess is correct & the above is the problem. For
example:

call.cpp:7:24: error: reference to non-static member function must be
called; did you mean to call it with no arguments?
const foo *f = bar().f;
                ~~~~~~^
                       ()

You see I am building with ninja, which was noted to be preferable way
building plugins, checkers, tools for clang, and it has been noted there to
change cmake compiler to clang(++) what I actually did due to lack of
experience in catching my own bug, and previously clang showed me reasons
for all of them.

Hi David,

I am trying to do the same anikau31 was trying to do, using your code:

  • if (Optional CS = E.getAs()) {
  • const Stmt *S = CS->getStmt();

but I’m getting following error on second line:

" error: cannot convert ‘clang::CFGStmt::getStmt’ from type ‘const
clang::Stmt* (clang::CFGStmt::)()const’ to type ‘const clang::Stmt*’ "

Looks like you wrote:

const Stmt *S = CS->getStmt;

And forgot the ‘()’ where you should’ve written:

const Stmt *S = CS->getStmt();

Oh, thanks it was real reason.

(& might I suggest self-hosting Clang as your compiler, in part
because it has better error messages for this particular case (&
others), if my guess is correct & the above is the problem. For
example:

call.cpp:7:24: error: reference to non-static member function must be
called; did you mean to call it with no arguments?
const foo *f = bar().f;

()

You see I am building with ninja, which was noted to be preferable way
building plugins, checkers, tools for clang, and it has been noted there to
change cmake compiler to clang(++) what I actually did due to lack of
experience in catching my own bug, and previously clang showed me reasons
for all of them.

So you are using clang as your compiler? And you still got that less helpful error message? Perhaps you’re using an old/out of date version.