llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.05k stars 11.58k forks source link

[regression] ICE: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed. #50170

Open chengniansun opened 3 years ago

chengniansun commented 3 years ago
Bugzilla Link 50826
Version trunk
OS All
CC @DougGregor,@zygoloid

Extended Description

This is a regression. clang-10 does not crash.

$ clang-trunk -v clang version 13.0.0 (https://github.com/llvm/llvm-project.git 5c8659801a4976ef2b327f4071d98086efd42a36) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /home/cnsun/usr/bin Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Candidate multilib: x32;@mx32 Selected multilib: .;@m64

$ cat mutant.c void attribute((interrupt)) fn(void()) {}

$ clang-trunk mutant.c mutant.c:1:41: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] void attribute((interrupt)) fn(void()) {} ^ clang-13: /tmp/tmp.FIfHBNID2p-clang-builder/llvm-project/llvm/include/llvm/Support/Casting.h:255: std::enable_if_t<(! llvm::is_simple_type::value), typename llvm::cast_retty<X, const Y>::ret_type> llvm::cast(const Y&) [with X = clang::PointerType; Y = clang::QualType; std::enable_if_t<(! llvm::is_simple_type::value), typename llvm::cast_retty<X, const Y>::ret_type> = const clang::PointerType*]: Assertion `isa(Val) && "cast() argument of incompatible type!"' failed. PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump:

  1. Program arguments: /scratch/software/clang-trunk/bin/clang-13 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all --mrelax-relocations -disable-free -main-file-name mutant.c -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/scratch/cnsun/workspace/perses-fuzzer/default_c_finding_folder/crash_20210623_060659_00ee/delta/perses_result -resource-dir /scratch/software/clang-trunk/lib/clang/13.0.0 -c-isystem . -c-isystem /usr/local/include/cmsith -internal-isystem /scratch/software/clang-trunk/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/scratch/cnsun/workspace/perses-fuzzer/default_c_finding_folder/crash_20210623_060659_00ee/delta/perses_result -ferror-limit 19 -fgnuc-version=4.2.1 -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/mutant-2d7065.o -x c mutant.c
  2. parser at end of file
  3. mutant.c:1:33: LLVM IR generation of declaration 'fn'
  4. mutant.c:1:33: Generating code for declaration 'fn'

    ​0 0x000055c27649ec64 PrintStackTraceSignalHandler(void*) Signals.cpp:0:0

    ​1 0x000055c27649c41e SignalHandler(int) Signals.cpp:0:0

    ​2 0x00007fc2070a23c0 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x153c0)

    ​3 0x00007fc206b4118b raise /build/glibc-ZN95T4/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1

    ​4 0x00007fc206b20859 abort /build/glibc-ZN95T4/glibc-2.31/stdlib/abort.c:81:7

    ​5 0x00007fc206b20729 get_sysdep_segment_value /build/glibc-ZN95T4/glibc-2.31/intl/loadmsgcat.c:509:8

    ​6 0x00007fc206b20729 _nl_load_domain /build/glibc-ZN95T4/glibc-2.31/intl/loadmsgcat.c:970:34

    ​7 0x00007fc206b31f36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)

    ​8 0x000055c276989e6c addX86InterruptAttrs(clang::FunctionDecl const, llvm::GlobalValue, clang::CodeGen::CodeGenModule&) TargetInfo.cpp:0:0

    ​9 0x000055c2768ce58b clang::CodeGen::CodeGenModule::setNonAliasAttributes(clang::GlobalDecl, llvm::GlobalObject*) (/scratch/software/clang-trunk/bin/clang-13+0x3d7e58b)

    ​10 0x000055c2768f6421 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/scratch/software/clang-trunk/bin/clang-13+0x3da6421)

    ​11 0x000055c2768f1fa5 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/scratch/software/clang-trunk/bin/clang-13+0x3da1fa5)

    ​12 0x000055c2768f240b clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/scratch/software/clang-trunk/bin/clang-13+0x3da240b)

    ​13 0x000055c2768fae72 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) CodeGenModule.cpp:0:0

    ​14 0x000055c2775fd4f9 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0

    ​15 0x000055c2775ef6e0 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/scratch/software/clang-trunk/bin/clang-13+0x4a9f6e0)

    ​16 0x000055c2786b2fe4 clang::ParseAST(clang::Sema&, bool, bool) (/scratch/software/clang-trunk/bin/clang-13+0x5b62fe4)

    ​17 0x000055c2775fa678 clang::CodeGenAction::ExecuteAction() (/scratch/software/clang-trunk/bin/clang-13+0x4aaa678)

    ​18 0x000055c276eaa029 clang::FrontendAction::Execute() (/scratch/software/clang-trunk/bin/clang-13+0x435a029)

    ​19 0x000055c276e3d1e6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/scratch/software/clang-trunk/bin/clang-13+0x42ed1e6)

    ​20 0x000055c276f87eb0 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/scratch/software/clang-trunk/bin/clang-13+0x4437eb0)

    ​21 0x000055c273db06f6 cc1_main(llvm::ArrayRef<char const>, char const, void*) (/scratch/software/clang-trunk/bin/clang-13+0x12606f6)

    ​22 0x000055c273daca38 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0

    ​23 0x000055c273cda0a6 main (/scratch/software/clang-trunk/bin/clang-13+0x118a0a6)

    ​24 0x00007fc206b220b3 __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:342:3

    ​25 0x000055c273dac5ae _start (/scratch/software/clang-trunk/bin/clang-13+0x125c5ae)

    clang-13: error: unable to execute command: Aborted (core dumped) clang-13: error: clang frontend command failed due to signal (use -v to see invocation) clang version 13.0.0 (https://github.com/llvm/llvm-project.git 5c8659801a4976ef2b327f4071d98086efd42a36) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /home/cnsun/usr/bin clang-13: note: diagnostic msg:


PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: Preprocessed source(s) and associated run script(s) are located at: clang-13: note: diagnostic msg: /tmp/mutant-a7b765.c clang-13: note: diagnostic msg: /tmp/mutant-a7b765.sh clang-13: note: diagnostic msg:


AaronBallman commented 2 years ago

There are a few issues here -- this particular assertion comes from https://github.com/llvm/llvm-project/commit/ef4da3c2ba8a812a695361d786e3de8a8b2cd482 (CC @arsenm) and happens because addX86InterruptAttrs() is assuming the type of the first argument is PointerType when it could also be a DecayedType. So you can hit this assertion using:

void __attribute__((interrupt)) fn1(void fp(void)) {}
void __attribute__((interrupt)) fn2(int[]) {}

However, if you fix addX86InterruptAttrs() to properly handle decayed types, this shifts the problem to the backend if the pointee type is sizeless. From there, you'll hit fatal errors because the backend verifier doesn't like a byval sizeless type. You can hit that case already today with:

void __attribute__((interrupt)) fn1(void (*fp)(void)) {}
void __attribute__((interrupt)) fn2(struct fwd_decl *ptr) {}

I'm left with a few questions:

1) According to the GCC documentation, none of these are valid signatures because the X86 interrupt attribute requires the first parameter to be a pointer to a structure type which is compatible with the interrupt_frame structure (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#x86-Function-Attributes). Should we be rejecting anything which isn't a (possibly decayed) pointer to a structure type in SemaDeclAttr.cpp when processing the attribute? If so, there are tests explicitly added which do not use a structure type, as in https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenCXX/attr-x86-interrupt.cpp; will we be regressing behavior? CC @alexey-bataev as the original author for the X86 attribute. 2) The pointer to a forward declaration case is still problematic even if we reject things like function types because we're trying to attach information to the byval pointee type, which is sizeless. This means that the code example from GCC's documentation will cause a crash. Also, while it might be reasonable to assume that the pointer needs to be to a complete type to be usable in the function definition, it's still possible for the definition to forward that pointer to another interrupt function call in another TU where the type is completed.

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-codegen

alexey-bataev commented 2 years ago
  1. According to the GCC documentation, none of these are valid signatures because the X86 interrupt attribute requires the first parameter to be a pointer to a structure type which is compatible with the interrupt_frame structure (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#x86-Function-Attributes). Should we be rejecting anything which isn't a (possibly decayed) pointer to a structure type in SemaDeclAttr.cpp when processing the attribute? If so, there are tests explicitly added which do not use a structure type, as in https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenCXX/attr-x86-interrupt.cpp; will we be regressing behavior? CC @alexey-bataev as the original author for the X86 attribute.

I followed the description I got from the original author of this feature. If something has changed, it must be adjusted here too, I believe.