[llvm-bugs] [Bug 45472] New: [C++] Illegal address space conversions for non-capturing lambdas

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Apr 8 02:36:21 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45472

            Bug ID: 45472
           Summary: [C++] Illegal address space conversions for
                    non-capturing lambdas
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: OpenCL
          Assignee: unassignedclangbugs at nondot.org
          Reporter: mariya.podchishchaeva at intel.com
                CC: anastasia.stulova at arm.com, llvm-bugs at lists.llvm.org

I found this bug in a bit other way, but consider the following example:

int a;
auto priv4 = +[](int a) __global { a++; };
priv4(a);

This example crashes with an assertion instead of giving diagnostics:

clang -cc1 -triple spir64 -O0 address-space-lambda.cl -cl-std=clc++ -emit-llvm
clang: llvm-project/llvm/lib/IR/Constants.cpp:1661: static llvm::Constant*
llvm::ConstantExpr::getCast(unsigned int, llvm::Constant*, llvm::Type*, bool):
Assertion `CastInst::castIsV
alid(opc, C, Ty) && "Invalid constantexpr cast!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash
backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: clang -cc1 -triple spir64 -O0
address-space-lambda.cl -cl-std=clc++ -emit-llvm
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      address-space-lambda.cl:38:17: Generating code for declaration
'test_qual()::(anonymous class)::__invoke'
 #0 0x000055fa7cd69b3f llvm::sys::PrintStackTrace(llvm::raw_ostream&)
llvm-project/llvm/lib/Support/Unix/Signals.inc:564:0
 #1 0x000055fa7cd69bd2 PrintStackTraceSignalHandler(void*)
llvm-project/llvm/lib/Support/Unix/Signals.inc:625:0
 #2 0x000055fa7cd67963 llvm::sys::RunSignalHandlers()
llvm-project/llvm/lib/Support/Signals.cpp:68:0
 #3 0x000055fa7cd694bc SignalHandler(int)
llvm-project/llvm/lib/Support/Unix/Signals.inc:406:0
 #4 0x00007fe8a557e890 __restore_rt
(/lib/x86_64-linux-gnu/libpthread.so.0+0x12890)
 #5 0x00007fe8a422fe97 raise
/build/glibc-OTsEL5/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
 #6 0x00007fe8a4231801 abort /build/glibc-OTsEL5/glibc-2.27/stdlib/abort.c:81:0
 #7 0x00007fe8a422139a __assert_fail_base
/build/glibc-OTsEL5/glibc-2.27/assert/assert.c:89:0
 #8 0x00007fe8a4221412 (/lib/x86_64-linux-gnu/libc.so.6+0x30412)
 #9 0x000055fa7c375565 llvm::ConstantExpr::getCast(unsigned int,
llvm::Constant*, llvm::Type*, bool)
llvm-project/llvm/lib/IR/Constants.cpp:1661:0
#10 0x000055fa7c454d92
llvm::ConstantFolder::CreateCast(llvm::Instruction::CastOps, llvm::Constant*,
llvm::Type*) const llvm-project/llvm/include/llvm/IR/ConstantFolder.h:191:0
#11 0x000055fa7b622172
llvm::IRBuilderBase::CreateCast(llvm::Instruction::CastOps, llvm::Value*,
llvm::Type*, llvm::Twine const&)
llvm-project/llvm/include/llvm/IR/IRBuilder.h:2210:$
#12 0x000055fa7b6220e6 llvm::IRBuilderBase::CreateBitCast(llvm::Value*,
llvm::Type*, llvm::Twine const&)
llvm-project/llvm/include/llvm/IR/IRBuilder.h:2171:0
#13 0x000055fa7d4eb5fd
clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo
const&, clang::CodeGen::CGCallee const&, clang::CodeGen::ReturnValueSlot,
clang::CodeGen::CallArgList const&, llvm$
:CallBase**, clang::SourceLocation)
llvm-project/clang/lib/CodeGen/CGCall.cpp:4283:0
#14 0x000055fa7d1defe7
clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo
const&, clang::CodeGen::CGCallee const&, clang::CodeGen::ReturnValueSlot,
clang::CodeGen::CallArgList const&, llvm$
:CallBase**) llvm-project/clang/lib/CodeGen/CodeGenFunction.h:3733:0
#15 0x000055fa7d50d3df
clang::CodeGen::CodeGenFunction::EmitForwardingCallToLambda(clang::CXXMethodDecl
const*, clang::CodeGen::CallArgList&) llvm-project/clang/lib/CodeGen/CGClass.$
pp:2882:0
#16 0x000055fa7d50daad
clang::CodeGen::CodeGenFunction::EmitLambdaDelegatingInvokeBody(clang::CXXMethodDecl
const*) llvm-project/clang/lib/CodeGen/CGClass.cpp:2928:0
#17 0x000055fa7d50db2f
clang::CodeGen::CodeGenFunction::EmitLambdaStaticInvokeBody(clang::CXXMethodDecl
const*) llvm-project/clang/lib/CodeGen/CGClass.cpp:2963:0
#18 0x000055fa7d1edafe
clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl,
llvm::Function*, clang::CodeGen::CGFunctionInfo const&)
llvm-project/clang/lib/CodeGen/CodeGe$
Function.cpp:1339:0
#19 0x000055fa7d216bbd
clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl,
llvm::GlobalValue*) llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:4499:0
#20 0x000055fa7d20f63e
clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl,
llvm::GlobalValue*) llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:2854:0
#21 0x000055fa7d20c607 clang::CodeGen::CodeGenModule::EmitDeferred()
llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:2210:0
#22 0x000055fa7d20c655 clang::CodeGen::CodeGenModule::EmitDeferred()
llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:2212:0
#23 0x000055fa7d2031df clang::CodeGen::CodeGenModule::Release()
llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:407:0
#24 0x000055fa7e1bd8f5 (anonymous
namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&)
llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp:271:0
#25 0x000055fa7e1b717d
clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&)
llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:285:0
#26 0x000055fa7f870f8a clang::ParseAST(clang::Sema&, bool, bool)
llvm-project/clang/lib/Parse/ParseAST.cpp:178:0
#27 0x000055fa7d8cc6c3 clang::ASTFrontendAction::ExecuteAction()
llvm-project/clang/lib/Frontend/FrontendAction.cpp:1047:0
#28 0x000055fa7e1b4a1a clang::CodeGenAction::ExecuteAction()
llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:1180:0
#29 0x000055fa7d8cc024 clang::FrontendAction::Execute()
llvm-project/clang/lib/Frontend/FrontendAction.cpp:944:0
#30 0x000055fa7d86151c
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
llvm-project/clang/lib/Frontend/CompilerInstance.cpp:973:0
#31 0x000055fa7da3dd95
clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:282:0
#32 0x000055fa7b5a2d57 cc1_main(llvm::ArrayRef<char const*>, char const*,
void*) llvm-project/clang/tools/driver/cc1_main.cpp:240:0
#33 0x000055fa7b59805c ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&)
llvm-project/clang/tools/driver/driver.cpp:330:0
#34 0x000055fa7b59882e main llvm-project/clang/tools/driver/driver.cpp:407:0
#35 0x00007fe8a4212b97 __libc_start_main
/build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:344:0
#36 0x000055fa7b5966da _start (llvm-project/debug-build/bin/clang+0x22f16da)
Aborted (core dumped)

What is happening here?
First, I don't think that function pointers are allowed in classic OpenCL C,
but C++ for OpenCL allowed me to use them in described way. 
Second, following classic C++ rules:
The closure type for a lambda-expression with no lambda-capture has a public
non-virtual non-explicit const conversion function to pointer to function
having the same parameter and return types as the closure type’s function call
operator. 
So, the `priv4` variable is a such function pointer. Trying to call a function
using this pointer leads to crash because the compiler attempts to create
invalid address space cast. This is happening because I've marked the lambda
with `__global` qualifier, so, such lambda can be called only if lambda object
itself was created with __global address space (I'd add some AST dumps, but
they are pretty ugly in preview here, so some AST dumps are available here
https://github.com/intel/llvm/pull/1039/files#r402905578)
>From AST dump I can see this conversion operator converts this lambda to a
pointer to a function without address space qualifiers at all, i,e, everything
what this function accepts can be in *Default* address space. That is why the
crash is here, I suppose.
I think, if the philosophy of OpenCL address spaces is qualify ALL types with
address space qualifier and if C++ for OpenCL should work like regular C++ for
language features like lambdas, I think conversion from lambda object to
function pointer must convert to a pointer to a function with the same address
space qualifiers as operator () has.
And the compiler definitely shouldn't crash.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200408/59495c61/attachment-0001.html>


More information about the llvm-bugs mailing list