llvm / llvm-project

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

After dcd74716f9d, Assertion failed: (getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"), function setIncomingValue #54831

Open DimitryAndric opened 2 years ago

DimitryAndric commented 2 years ago

After dcd74716f9d ("[clang] p0388 conversion to incomplete array", by @urnathan, reviewed by @AaronBallman), compiling the FreeBSD editors/imhex port (see https://github.com/WerWolv/ImHex), which uses C++20, results in assertion failures:

Assertion failed: (getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"), function setIncomingValue, file /poudriere/jails/mainamd64PR261742/usr/src/contrib/llvm-project/llvm/include/llvm/IR/Instructions.h, line 2756.

Minimized test case (mostly parts of std::format):

// clang -cc1 -triple x86_64-- -S -std=c++20 imhex-min.cpp
template <typename Visitor, typename Context>
void visit_format_arg(Visitor vis, Context) {
  vis(1);
}
template <typename = void> struct basic_data {
  static constexpr char hex_digits[] = "";
};
template <int, typename It, typename UInt> void format_uint(It, UInt upper) {
  { upper ? "" : basic_data<>::hex_digits; }
}
template <typename Char, typename OutputIt, typename UIntPtr>
void write_ptr(OutputIt, UIntPtr, Char) {
  auto write = [](OutputIt) { format_uint<1>(1, 1); };
  write(1);
}
template <typename OutputIt, typename T> void write(OutputIt, T) {
  write_ptr(1, 1, 1);
}
struct default_arg_formatter {
  void operator()(int) { write(1, 1); }
};
void vformat_to() { visit_format_arg(default_arg_formatter{}, 1); }

Backtrace:

clang: /home/dim/src/llvm/llvm-project/llvm/include/llvm/IR/Instructions.h:2755: void llvm::PHINode::setIncomingValue(unsigned int, llvm::Value *): Assertion `getType() == V->getType() && "All operands to PHI node must be the same type as the PHI node!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: /home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang -cc1 -triple x86_64-- -S -std=c++20 imhex-min.cpp
1.  <eof> parser at end of file
2.  Per-file LLVM IR generation
3.  imhex-min.cpp:9:49: Generating code for declaration 'format_uint'
4.  imhex-min.cpp:10:3: LLVM IR generation of compound statement ('{}')
 #0 0x00005575e44e8813 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x1ff7813)
 #1 0x00005575e44e65ee llvm::sys::RunSignalHandlers() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x1ff55ee)
 #2 0x00005575e44e8cda SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fcd087d6520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007fcd0882aa7c __pthread_kill_implementation ./nptl/./nptl/pthread_kill.c:44:76
 #5 0x00007fcd0882aa7c __pthread_kill_internal ./nptl/./nptl/pthread_kill.c:78:10
 #6 0x00007fcd0882aa7c pthread_kill ./nptl/./nptl/pthread_kill.c:89:10
 #7 0x00007fcd087d6476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007fcd087bc7f3 abort ./stdlib/./stdlib/abort.c:81:7
 #9 0x00007fcd087bc71b _nl_load_domain ./intl/./intl/loadmsgcat.c:1177:9
#10 0x00007fcd087cde96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00005575e32116ed llvm::PHINode::setIncomingValue(unsigned int, llvm::Value*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0xd206ed)
#12 0x00005575e32220e8 llvm::PHINode::addIncoming(llvm::Value*, llvm::BasicBlock*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0xd310e8)
#13 0x00005575e4b2feb0 clang::CodeGen::CodeGenFunction::EmitConditionalOperatorLValue(clang::AbstractConditionalOperator const*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x263eeb0)
#14 0x00005575e4b1dedf clang::CodeGen::CodeGenFunction::EmitLValue(clang::Expr const*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x262cedf)
#15 0x00005575e4b1dbd1 clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x262cbd1)
#16 0x00005575e48743d0 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23833d0)
#17 0x00005575e4874fe1 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x2383fe1)
#18 0x00005575e48742f1 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23832f1)
#19 0x00005575e4881a90 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x2390a90)
#20 0x00005575e48e2ee7 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23f1ee7)
#21 0x00005575e49065d5 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x24155d5)
#22 0x00005575e48feaa2 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x240daa2)
#23 0x00005575e48f0ce0 clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffce0)
#24 0x00005575e48f0d0c clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffd0c)
#25 0x00005575e48f0d0c clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffd0c)
#26 0x00005575e48f0d0c clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffd0c)
#27 0x00005575e48f0d0c clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffd0c)
#28 0x00005575e48f0d0c clang::CodeGen::CodeGenModule::EmitDeferred() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23ffd0c)
#29 0x00005575e48ef229 clang::CodeGen::CodeGenModule::Release() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x23fe229)
#30 0x00005575e54b7724 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
#31 0x00005575e54b415e clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x2fc315e)
#32 0x00005575e614ab24 clang::ParseAST(clang::Sema&, bool, bool) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x3c59b24)
#33 0x00005575e4ebecb0 clang::FrontendAction::Execute() (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x29cdcb0)
#34 0x00005575e4e3617f clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x294517f)
#35 0x00005575e4f8c983 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0x2a9b983)
#36 0x00005575e31af412 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0xcbe412)
#37 0x00005575e31ad350 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#38 0x00005575e31ad0e7 main (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0xcbc0e7)
#39 0x00007fcd087bdd90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#40 0x00007fcd087bde40 call_init ./csu/../csu/libc-start.c:128:20
#41 0x00007fcd087bde40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#42 0x00005575e31aa235 _start (/home/dim/obj/llvmorg-15-init-7191-gc807141d27e6-linux5-x86_64-ninja-clang-rel-1/bin/clang+0xcb9235)
llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-frontend

llvmbot commented 2 years ago

@llvm/issue-subscribers-c-20

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-codegen

urnathan commented 2 years ago

works without template, ICEs with template:

// clang++ -cc1 -triple x86_64-- -S -std=c++20 54831.cc

// non-template, ok
struct CLS {
  static constexpr char hex_digits[] = "";
};

void Ok(bool upper) {
  void (upper ? "" : CLS::hex_digits);
}

// ICE with template
template<typename = void>
struct TPL {
  static constexpr char hex_digits[] = "";
};

void Bad(bool upper) {
  void (upper ? "" : TPL<>::hex_digits);
}
urnathan commented 2 years ago

Updating to today's HEAD (55b6a3186cfa) fixes the ICE

DimitryAndric commented 2 years ago

@urnathan any idea which specific commit fixes it? I'd like to backport it to 14.0.1.

urnathan commented 2 years ago

I do not know. I last updated on Friday, to 26b3a1ea3483, so somewhere between those two commits? None of the [clang] fixes between those leap out (from their titles, not looked in detail). It could be the opaque pointer enablement patch: 702d5de4380b 2022-04-07 | [Clang] Enable opaque pointers by default [Nikita Popov] but if so, that smells coincidental

ETA: indeed, today adding -no-opaque-pointers is also needed to tickle the bug. so no magic happened over the weekend.

urnathan commented 2 years ago

ETA: for some reason the TPL<>::hex_chars access gets a const char [] declrefexpr, which doesn't happen in the CLS::hex_chars case: gdb) call RHSExpr->dump() DeclRefExpr 0xd28c6c0 'const char[]' lvalue Var 0xd28c600 'hex_digits' 'const char[1]'

However, I think there's also a p388-related defect in order to get to the ICE.

I suppose I own this bug now.

urnathan commented 2 years ago

yeah, we totally mess up the types of static members of template instantiations with incomplete array types:

template<typename = void> struct TPL
{
  static constexpr char CEAry[] = "abc";
  static char Ary[];
};

template<typename T> char TPL<T>::Ary[] = {0, 0};

void Use (const void *);
void Bob ()
{
  Use(&typeid(TPL<>::CEAry)); // unbounded
  Use(&typeid(TPL<>::Ary)); // unbounded
  (void)(TPL<>::CEAry[0] + TPL<>::Ary[0]);
  Use(&typeid(TPL<>::CEAry)); // bound[4]
  Use(&typeid(TPL<>::Ary)); // unbounded!
}

The intializer should only be instantiated if the variable is used in such a way that it's needed. But we appear to be forgetting that the initializer can complete the array type. Excitingly the VarDecl's type is mutated after creation, depending no how it is used, that's never a good thing.

DimitryAndric commented 2 years ago

Ah yes, it looks like 702d5de4380b1e1554e5b90863093c3a57f76f70 papered over this bug, as the test case didn't assert anymore after that. However, if you run it with -no-opaque-pointers, it still asserts in the same fashion.