[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