[clang] ea15e8b - [C++20] [Modules] Avoid use-but-not-defined error
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 5 03:13:03 PST 2025
Author: Chuanqi Xu
Date: 2025-03-05T19:05:49+08:00
New Revision: ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516
URL: https://github.com/llvm/llvm-project/commit/ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516
DIFF: https://github.com/llvm/llvm-project/commit/ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516.diff
LOG: [C++20] [Modules] Avoid use-but-not-defined error
See the attached test for example.
Added:
clang/test/Modules/external-but-not-type-external.cppm
Modified:
clang/lib/Serialization/ASTWriterDecl.cpp
Removed:
################################################################################
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index a1810003f5425..88dd212259085 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -330,6 +330,12 @@ namespace clang {
}
bool clang::CanElideDeclDef(const Decl *D) {
+ bool isExternalWithNoLinkageType = false;
+ if (auto *VD = dyn_cast<ValueDecl>(D))
+ if (VD->hasExternalFormalLinkage() &&
+ !isExternalFormalLinkage(VD->getType()->getLinkage()))
+ isExternalWithNoLinkageType = true;
+
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->isInlined() || FD->isConstexpr())
return false;
@@ -339,6 +345,9 @@ bool clang::CanElideDeclDef(const Decl *D) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return false;
+
+ if (isExternalWithNoLinkageType && !FD->isExternC())
+ return false;
}
if (auto *VD = dyn_cast<VarDecl>(D)) {
@@ -352,6 +361,9 @@ bool clang::CanElideDeclDef(const Decl *D) {
if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return false;
+
+ if (isExternalWithNoLinkageType && !VD->isExternC())
+ return false;
}
return true;
diff --git a/clang/test/Modules/external-but-not-type-external.cppm b/clang/test/Modules/external-but-not-type-external.cppm
new file mode 100644
index 0000000000000..37a0d29104c5d
--- /dev/null
+++ b/clang/test/Modules/external-but-not-type-external.cppm
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/use.cc -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
+
+//--- a.cppm
+export module a;
+namespace {
+struct Local {};
+}
+
+export class A {
+public:
+ void *external_but_not_type_external(Local *) {
+ return nullptr;
+ }
+};
+
+//--- use.cc
+// expected-no-diagnostics
+import a;
+void *use() {
+ A a;
+ return a.external_but_not_type_external(nullptr);
+}
More information about the cfe-commits
mailing list