https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/201291
Close https://github.com/llvm/llvm-project/issues/195905 The root cause of the problem is, after decl merging, one of the destructor for `base` (see test case) is chosen, and its body is not deserialized for performance as we alreday see its body in current TU. And then, the code call FunctionDecl::isInlineDefinitionExternallyVisible from the destructor without a serialized body, but FunctionDecl::isInlineDefinitionExternallyVisible's implementation requires to see a body. Then assertion failed. Decl merging and function decl merging is common. We can't always make sure we find the definition without checking. It is much more fundamental. So the PR doesn't try to touch the decl merging mechanism or how we handle the result of lookups. We tried to fix the issue at the calling point to make sure we have a definition for isInlineDefinitionExternallyVisible. Other use of isInlineDefinitionExternallyVisible the similar thing. >From abb389950ef9a900bcf1ce1f7ff6992a90258e2a Mon Sep 17 00:00:00 2001 From: Chuanqi Xu <[email protected]> Date: Wed, 3 Jun 2026 16:04:50 +0800 Subject: [PATCH] [C++20] [Modules] Ask for definition before calling isInlineDefinitionExternallyVisible Close https://github.com/llvm/llvm-project/issues/195905 The root cause of the problem is, after decl merging, one of the destructor for `base` (see test case) is chosen, and its body is not deserialized for performance as we alreday see its body in current TU. And then, the code call FunctionDecl::isInlineDefinitionExternallyVisible from the destructor without a serialized body, but FunctionDecl::isInlineDefinitionExternallyVisible's implementation requires to see a body. Then assertion failed. Decl merging and function decl merging is common. We can't always make sure we find the definition without checking. It is much more fundamental. So the PR doesn't try to touch the decl merging mechanism or how we handle the result of lookups. We tried to fix the issue at the calling point to make sure we have a definition for isInlineDefinitionExternallyVisible. Other use of isInlineDefinitionExternallyVisible the similar thing. --- clang/lib/AST/ASTContext.cpp | 3 ++- clang/test/Modules/pr195905.cppm | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 clang/test/Modules/pr195905.cppm diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a401a7471e6fc..1e35aba7b2b19 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13064,7 +13064,8 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, // GNU or C99 inline semantics. Determine whether this symbol should be // externally visible. - if (FD->isInlineDefinitionExternallyVisible()) + if (auto *Def = FD->getDefinition(); + Def && Def->isInlineDefinitionExternallyVisible()) return External; // C99 inline semantics, where the symbol is not externally visible. diff --git a/clang/test/Modules/pr195905.cppm b/clang/test/Modules/pr195905.cppm new file mode 100644 index 0000000000000..d107549ab10ea --- /dev/null +++ b/clang/test/Modules/pr195905.cppm @@ -0,0 +1,42 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++26 %t/a.cppm \ +// RUN: -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++26 %t/b.cppm \ +// RUN: -fmodule-file=a=%t/a.pcm -emit-llvm -Og -mconstructor-aliases \ +// RUN: -o - | FileCheck %t/b.cppm + +//--- base.hpp +struct base { + [[__gnu__::__gnu_inline__]] inline ~base() {} +}; + +//--- a.cppm +module; + +#include "base.hpp" + +export module a; + +export using ::base; + +//--- b.cppm +module; + +#include "base.hpp" + +export module b; + +import a; + +struct derived : base { +}; + +void f() { + derived x; +} + +// fine enough to check it won't crash +// CHECK: define {{.*}}@_ZGIW1b _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
