Skip to content

undeduced type in IR-generation UNREACHABLE executed at llvm/clang/lib/CodeGen/CodeGenFunction.cpp:233! #60085

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
davidstone opened this issue Jan 16, 2023 · 4 comments
Assignees
Labels
clang:modules C++20 modules and Clang Header Modules crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@davidstone
Copy link
Contributor

davidstone commented Jan 16, 2023

Given the following four files:

export module d;

export template<typename>
struct integer {
	using type = int;
	
	static constexpr auto value() {
		return 0;
	}
	
	friend constexpr void f(integer const x) {
		x.value();
	}
};

export constexpr void ddd(auto const value) {
	f(value);
}


template<typename T>
constexpr auto dd = T();

export template<typename T>
constexpr auto d() {
	dd<T>;
}
export module c;

import d;

template<typename T>
auto cc = T();

auto c() {
	cc<integer<int>>;
	integer<int>().value();
}
export module b;

import d;

auto b() {
	integer<int>::type;
}
export module a;

import b;
import c;
import d;


constexpr void aa() {
	d<integer<unsigned>>();
	ddd(integer<int>());
}

void a() {
	aa();
}

clang crashes with an assertion failure while compiling a.cpp:

In module 'b':
crashes/d.cpp:26:2: warning: expression result unused [-Wunused-value]
        dd<T>;
        ^~~~~
crashes/a.cpp:9:2: note: in instantiation of function template specialization 'd<integer<unsigned int>>' requested here
        d<integer<unsigned>>();
        ^
1 warning generated.
undeduced type in IR-generation
UNREACHABLE executed at llvm/clang/lib/CodeGen/CodeGenFunction.cpp:233!
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: llvm/build/bin/clang-16 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -main-file-name a.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb -fcoverage-compilation-dir=build -resource-dir llvm/build/lib/clang/16 -std=c++2b -fdebug-compilation-dir=build -ferror-limit 19 -ftemplate-backtrace-limit 0 -fgnuc-version=4.2.1 -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o dependencies/bounded-integer/CMakeFiles/crashes.dir/source/crashes/a.cpp.o -x pcm dependencies/bounded-integer/CMakeFiles/crashes.dir/a.pcm
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      crashes/d.cpp:11:24: Generating code for declaration 'f'
 #0 0x0000564f0e297c7b llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (llvm/build/bin/clang-16+0x4146c7b)
 #1 0x0000564f0e295b3e llvm::sys::RunSignalHandlers() (llvm/build/bin/clang-16+0x4144b3e)
 #2 0x0000564f0e298506 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fc4e2851a00 (/usr/lib/libc.so.6+0x38a00)
 #4 0x00007fc4e28a164c (/usr/lib/libc.so.6+0x8864c)
 #5 0x00007fc4e2851958 raise (/usr/lib/libc.so.6+0x38958)
 #6 0x00007fc4e283b53d abort (/usr/lib/libc.so.6+0x2253d)
 #7 0x0000564f0e2147e1 (llvm/build/bin/clang-16+0x40c37e1)
 #8 0x0000564f0e6d4b2e clang::CodeGen::CodeGenFunction::getEvaluationKind(clang::QualType) (llvm/build/bin/clang-16+0x4583b2e)
 #9 0x0000564f0ecca13a (anonymous namespace)::X86_64ABIInfo::getIndirectReturnResult(clang::QualType) const TargetInfo.cpp:0:0
#10 0x0000564f0ecc485f (anonymous namespace)::X86_64ABIInfo::computeInfo(clang::CodeGen::CGFunctionInfo&) const TargetInfo.cpp:0:0
#11 0x0000564f0e66ee7c clang::CodeGen::CodeGenTypes::arrangeLLVMFunctionInfo(clang::CanQual<clang::Type>, bool, bool, llvm::ArrayRef<clang::CanQual<clang::Type>>, clang::FunctionType::ExtInfo, llvm::ArrayRef<clang::FunctionType::ExtParameterInfo>, clang::CodeGen::RequiredArgs) (llvm/build/bin/clang-16+0x451de7c)
#12 0x0000564f0e66f3a1 arrangeLLVMFunctionInfo(clang::CodeGen::CodeGenTypes&, bool, llvm::SmallVectorImpl<clang::CanQual<clang::Type>>&, clang::CanQual<clang::FunctionProtoType>) CGCall.cpp:0:0
#13 0x0000564f0e66f250 clang::CodeGen::CodeGenTypes::arrangeFreeFunctionType(clang::CanQual<clang::FunctionProtoType>) (llvm/build/bin/clang-16+0x451e250)
#14 0x0000564f0e695f23 clang::CodeGen::CodeGenTypes::ConvertFunctionTypeInternal(clang::QualType) (llvm/build/bin/clang-16+0x4544f23)
#15 0x0000564f0e693f3e clang::CodeGen::CodeGenTypes::ConvertType(clang::QualType) (llvm/build/bin/clang-16+0x4542f3e)
#16 0x0000564f0e60edfd clang::CodeGen::CodeGenModule::GetAddrOfFunction(clang::GlobalDecl, llvm::Type*, bool, bool, clang::CodeGen::ForDefinition_t) (llvm/build/bin/clang-16+0x44bddfd)
#17 0x0000564f0e6d1e22 EmitFunctionDeclPointer(clang::CodeGen::CodeGenModule&, clang::GlobalDecl) CGExpr.cpp:0:0
#18 0x0000564f0e6d0583 EmitDirectCallee(clang::CodeGen::CodeGenFunction&, clang::GlobalDecl) CGExpr.cpp:0:0
#19 0x0000564f0e6cea4d clang::CodeGen::CodeGenFunction::EmitCallee(clang::Expr const*) (llvm/build/bin/clang-16+0x457da4d)
#20 0x0000564f0e6ce75d clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot) (llvm/build/bin/clang-16+0x457d75d)
#21 0x0000564f0e7d1bc6 (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) CGExprScalar.cpp:0:0
#22 0x0000564f0e7bff4d clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (llvm/build/bin/clang-16+0x466ef4d)
#23 0x0000564f0e6ad121 clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) (llvm/build/bin/clang-16+0x455c121)
#24 0x0000564f0e6ad090 clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) (llvm/build/bin/clang-16+0x455c090)
#25 0x0000564f0e6eea50 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (llvm/build/bin/clang-16+0x459da50)
#26 0x0000564f0e6fc951 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (llvm/build/bin/clang-16+0x45ab951)
#27 0x0000564f0e6ddb9b clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (llvm/build/bin/clang-16+0x458cb9b)
#28 0x0000564f0e60ce09 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (llvm/build/bin/clang-16+0x44bbe09)
#29 0x0000564f0e604c17 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (llvm/build/bin/clang-16+0x44b3c17)
#30 0x0000564f0e5f3cb0 clang::CodeGen::CodeGenModule::EmitDeferred() (llvm/build/bin/clang-16+0x44a2cb0)
#31 0x0000564f0e5f3cdc clang::CodeGen::CodeGenModule::EmitDeferred() (llvm/build/bin/clang-16+0x44a2cdc)
#32 0x0000564f0e5f3cdc clang::CodeGen::CodeGenModule::EmitDeferred() (llvm/build/bin/clang-16+0x44a2cdc)
#33 0x0000564f0e5f169f clang::CodeGen::CodeGenModule::Release() (llvm/build/bin/clang-16+0x44a069f)
#34 0x0000564f0f04dac4 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
#35 0x0000564f0f04ae38 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) CodeGenAction.cpp:0:0
#36 0x0000564f1075f2ca clang::ParseAST(clang::Sema&, bool, bool) (llvm/build/bin/clang-16+0x660e2ca)
#37 0x0000564f0f049494 clang::CodeGenAction::ExecuteAction() (llvm/build/bin/clang-16+0x4ef8494)
#38 0x0000564f0ef59cfe clang::FrontendAction::Execute() (llvm/build/bin/clang-16+0x4e08cfe)
#39 0x0000564f0eec04df clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (llvm/build/bin/clang-16+0x4d6f4df)
#40 0x0000564f0f043e77 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (llvm/build/bin/clang-16+0x4ef2e77)
#41 0x0000564f0ce10684 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (llvm/build/bin/clang-16+0x2cbf684)
#42 0x0000564f0ce0cb9b ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
#43 0x0000564f0ce0bdf4 clang_main(int, char**) (llvm/build/bin/clang-16+0x2cbadf4)
#44 0x00007fc4e283c290 (/usr/lib/libc.so.6+0x23290)
#45 0x00007fc4e283c34a __libc_start_main (/usr/lib/libc.so.6+0x2334a)
#46 0x0000564f0ce08be5 _start /build/glibc/src/glibc/csu/../sysdeps/x86_64/start.S:117:0
clang-16: error: unable to execute command: Aborted (core dumped)
clang-16: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 16.0.0 (git@github.com:mathstuf/llvm-project.git 073ab80a546cdb407dd242c0017269af014b3590)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: llvm/build/bin
clang-16: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-16: note: diagnostic msg: /tmp/a-9ab9b4.cppm
clang-16: note: diagnostic msg: /tmp/a-9ab9b4.sh
clang-16: note: diagnostic msg: 

********************

Where my clang build is https://github.com/mathstuf/llvm-project/tree/p1689r5-csd rebased on 396ad40, so it should still reproduce on main.

@EugeneZelenko EugeneZelenko added clang:codegen IR generation bugs: mangling, exceptions, etc. crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Jan 16, 2023
@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2023

@llvm/issue-subscribers-clang-codegen

@llvmbot
Copy link
Member

llvmbot commented Jan 25, 2023

@llvm/issue-subscribers-clang-modules

@ChuanqiXu9 ChuanqiXu9 self-assigned this Jan 31, 2023
@ChuanqiXu9
Copy link
Member

Update for developers: When I compile a.pcm, I found the following AST in CodeGenTypes::arrangeCXXMethodType:

CXXMethodDecl 0x83d7bc0 </home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/60085/d.cppm:7:2, line:9:2> line:7:7 imported in d hidden used value 'int ()'
ClassTemplateSpecializationDecl 0x83d55e8 </home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/60085/d.cppm:3:8, line:10:1> line:4:8 imported in d hidden <undeserialized declarations> struct integer definition
|-also in d
|-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
| |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr
| |-CopyConstructor simple trivial has_const_param implicit_has_const_param
| |-MoveConstructor exists simple trivial
| |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial constexpr
`-TemplateArgument type 'int'
  `-BuiltinType 0x832e610 'int'
FunctionProtoType 0x83d7d20 'auto (void)' imported cdecl
`-AutoType 0x83cc680 'auto' undeduced

And the correct one should be:

CXXMethodDecl 0x83d7a10 </home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/60085/d.cppm:7:2, line:9:2> line:7:7 imported in d hidden used value 'int ()'
`-CompoundStmt 0x83d7dc0 <col:15, line:9:2>
  `-ReturnStmt 0x83d7db0 <line:8:3, col:11>
    `-UnaryOperator 0x83d7d98 <col:10, col:11> 'int' prefix '-'
      `-IntegerLiteral 0x83d7d78 <col:11> 'int' 1
ClassTemplateSpecializationDecl 0x83d5438 </home/chuanqi.xcq/workspace.xuchuanqi/llvm-project-for-work/build/60085/d.cppm:3:8, line:10:1> line:4:8 imported in d hidden <undeserialized declarations> struct integer definition
|-also in d
|-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
| |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr
| |-CopyConstructor simple trivial has_const_param implicit_has_const_param
| |-MoveConstructor exists simple trivial
| |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
| |-MoveAssignment exists simple trivial needs_implicit
| `-Destructor simple irrelevant trivial constexpr
`-TemplateArgument type 'int'
  `-BuiltinType 0x832e610 'int'
FunctionProtoType 0x83d7d20 'int (void)' cdecl
`-BuiltinType 0x832e610 'int'

So the problem looks like when we instantiate integer<int>::value() in a.cppm, we saw the previous instantiation in formal modules ( b and c) and something goes wrong. Then we didn't instantiate integer<int>::value() actually. So we can find the instantiated CXXMethodDecl doesn't have a body. Then the direct problem happens when FunctionProtoType doesn't change after we don't want to instantiate integer<int>::value() in a.cppm. So here is the undeduced type.

@EugeneZelenko EugeneZelenko added test-suite and removed clang:codegen IR generation bugs: mangling, exceptions, etc. labels Mar 8, 2023
@ChuanqiXu9
Copy link
Member

When I looked again into the tests, I find the way it introduce module files is deprecated (we don't like to introduce modules via -fmodule-file=<module-file-name> flag), and when I want to make it properly:

// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/d.cppm \
// RUN:     -emit-module-interface -o %t/d.pcm
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/c.cppm \
// RUN:     -emit-module-interface -o %t/c.pcm -fmodule-file=d=%t/d.pcm
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cppm \
// RUN:     -emit-module-interface -o %t/b.pcm -fmodule-file=d=%t/d.pcm
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm \
// RUN:     -emit-module-interface -o %t/a.pcm -fmodule-file=d=%t/d.pcm \
// RUN:     -fmodule-file=c=%t/c.pcm -fmodule-file=b=%t/b.pcm 
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.pcm \
// RUN:     -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/a.cppm

//--- d.cppm
export module d;

export template<typename>
struct integer {
	using type = int;
	
	static constexpr auto value() {
		return 0;
	}
	
	friend constexpr void f(integer const x) {
		x.value();
	}
};

export constexpr void ddd(auto const value) {
	f(value);
}


template<typename T>
constexpr auto dd = T();

export template<typename T>
constexpr auto d() {
	dd<T>;
}

//--- c.cppm
export module c;

import d;

template<typename T>
auto cc = T();

auto c() {
	cc<integer<int>>;
	integer<int>().value();
}

//--- b.cppm
export module b;

import d;

auto b() {
	integer<int>::type;
}

//--- a.cppm
export module a;

import b;
import c;
import d;

constexpr void aa() {
	d<integer<unsigned>>();
	ddd(integer<int>());
}

export extern "C" void a() {
	aa();
}

// Checks that we emit the IR successfully.
// CHECK: define{{.*}}@a(

Boom! I met the same problem before. So I am going to reopen the issue and look into it again. BTW, previously when I committed the test , I wanted to test it with the form -fmodule-file=<module-name>=<module-file>. But it shows I made a simple overlook that I didn't add it actually... so here is the problem.

@ChuanqiXu9 ChuanqiXu9 reopened this Jan 5, 2024
ChuanqiXu9 added a commit that referenced this issue Jan 5, 2024
See #60085 for the complete
story.

Previously I thought the problem got fixed surprisingly. But it is not
true. I just tested it with a deprecated method. My bad. Then the
deprecated style should be removed and the proper style can't work. So
I'll remove the test and reopen that issue to look into it.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
clang:modules C++20 modules and Clang Header Modules crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

No branches or pull requests

5 participants