Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

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 crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Jan 16, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 16, 2023

@llvm/issue-subscribers-clang-codegen

@llvmbot
Copy link
Collaborator

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.

@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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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