Method returns null pointer when compiling with optimizations (-O2)

Hi all,

I have the following code to try to get functionDecl from a given statement:

const clang::Decl* llvm_convertert::get_DeclContext_from_Stmt(

const clang::Stmt& stmt)

{

auto it = ASTContext->getParents(stmt).begin();

if(it == ASTContext->getParents(stmt).end())

return nullptr;

const clang::Decl *aDecl = it->getclang::Decl();

if(aDecl)

return aDecl;

const clang::Stmt *aStmt = it->getclang::Stmt();

if(aStmt)

return get_DeclContext_from_Stmt(*aStmt);

return nullptr;

}

const clang::FunctionDecl* llvm_convertert::get_top_FunctionDecl_from_Stmt(

const clang::Stmt& stmt)

{

const clang::Decl *decl = get_DeclContext_from_Stmt(stmt);

if(decl)

return static_cast<const clang::FunctionDecl*>(decl->getNonClosureContext());

return nullptr;

}

Right now, I only call the method for a return statement:

const clang::ReturnStmt &ret =

static_cast<const clang::ReturnStmt&>(stmt);

const clang::FunctionDecl *fd = get_top_FunctionDecl_from_Stmt(ret);

The code works fine when I compile it with O0 but stops working when compiling with O2.

Here is the assembly generated with -O0:

000000000000c29e <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)>:
c29e: 55 push %rbp
c29f: 48 89 e5 mov %rsp,%rbp
c2a2: 48 83 ec 20 sub $0x20,%rsp
c2a6: 48 89 7d e8 mov %rdi,-0x18(%rbp)
c2aa: 48 89 75 e0 mov %rsi,-0x20(%rbp)
c2ae: 48 8b 55 e0 mov -0x20(%rbp),%rdx
c2b2: 48 8b 45 e8 mov -0x18(%rbp),%rax
c2b6: 48 89 d6 mov %rdx,%rsi
c2b9: 48 89 c7 mov %rax,%rdi
c2bc: e8 00 00 00 00 callq c2c1 <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x23>
c2c1: 48 89 45 f8 mov %rax,-0x8(%rbp)
c2c5: 48 83 7d f8 00 cmpq $0x0,-0x8(%rbp)
c2ca: 74 0e je c2da <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x3c>
c2cc: 48 8b 45 f8 mov -0x8(%rbp),%rax
c2d0: 48 89 c7 mov %rax,%rdi
c2d3: e8 00 00 00 00 callq c2d8 <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x3a>
c2d8: eb 05 jmp c2df <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x41>
c2da: b8 00 00 00 00 mov $0x0,%eax
c2df: c9 leaveq
c2e0: c3 retq
c2e1: 90 nop

and the assembly generated with -O2:

0000000000002160 <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)>:
2160: 48 83 ec 08 sub $0x8,%rsp
2164: e8 00 00 00 00 callq 2169 <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x9>
2169: 48 85 c0 test %rax,%rax
216c: 74 12 je 2180 <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x20>
216e: 48 89 c7 mov %rax,%rdi
2171: 48 83 c4 08 add $0x8,%rsp
2175: e9 00 00 00 00 jmpq 217a <llvm_convertert::get_top_FunctionDecl_from_Stmt(clang::Stmt const&)+0x1a>
217a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
2180: 31 c0 xor %eax,%eax
2182: 48 83 c4 08 add $0x8,%rsp
2186: c3 retq
2187: 90 nop
2188: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
218f: 00

Does anyone has any idea why this is happening and how to fix it? The whole assembly ended up being too big to be attached so I added them to dropbox.

I’m using clang 3.8 RC3 to link and building with g++ 5.3.1.

Thank you,