https://github.com/ChuanqiXu9 created 
https://github.com/llvm/llvm-project/pull/238239

Close https://github.com/llvm/llvm-project/issues/237418

The root cause of the issue is, when clang tries to judge if a function's 
definition is acceptable or not, the body of the function is removed in reduced 
BMI.

The solution here is to judge the acceptability of the function itself instead.

>From 74c26b7f355738ceb1ab8a22b7bd28a0140d7e75 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <[email protected]>
Date: Tue, 3 Nov 2026 15:09:32 +0800
Subject: [PATCH] [C++20] [Modules] Don't judge the accetability of a function
 for whose definition is reduced

Close https://github.com/llvm/llvm-project/issues/237418

The root cause of the issue is, when clang tries to judge if a
function's definition is acceptable or not, the body of the function
is removed in reduced BMI.

The solution here is to judge the acceptability of the function
itself instead.
---
 clang/lib/Sema/SemaLookup.cpp                 |  4 ++
 .../test/Modules/reduced-bmi-local-type.cppm  | 62 +++++++++++++++++++
 2 files changed, 66 insertions(+)
 create mode 100644 clang/test/Modules/reduced-bmi-local-type.cppm

diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 75cad0bb433f89..66465979792c29 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1907,6 +1907,10 @@ bool LookupResult::isAcceptableSlow(Sema &SemaRef, 
NamedDecl *D,
         }
         DC = DC->getLexicalParent();
       } while (!IsEffectivelyFileContext(DC));
+    } else if (auto *FD = dyn_cast<FunctionDecl>(DC);
+               FD && !FD->getDefinition()) {
+      // This is possible as the definition are removed in reduced BMI.
+      AcceptableWithinParent = isAcceptable(SemaRef, FD, Kind);
     } else {
       AcceptableWithinParent =
           SemaRef.hasAcceptableDefinition(cast<NamedDecl>(DC), Kind);
diff --git a/clang/test/Modules/reduced-bmi-local-type.cppm 
b/clang/test/Modules/reduced-bmi-local-type.cppm
new file mode 100644
index 00000000000000..b891898f6ea634
--- /dev/null
+++ b/clang/test/Modules/reduced-bmi-local-type.cppm
@@ -0,0 +1,62 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/view.cppm -emit-reduced-module-interface -o 
%t/view.pcm
+// RUN: %clang_cc1 -std=c++20 %t/wrapper.cppm -emit-reduced-module-interface \
+// RUN:   -fprebuilt-module-path=%t -o %t/wrapper.pcm
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t 
-fsyntax-only -verify
+//
+// RUN: %clang_cc1 -std=c++20 %t/view.cppm -emit-module-interface -o 
%t/view.pcm
+// RUN: %clang_cc1 -std=c++20 %t/wrapper.cppm -emit-module-interface \
+// RUN:   -fprebuilt-module-path=%t -o %t/wrapper.pcm
+// RUN: %clang_cc1 -std=c++20 %t/use.cpp -fprebuilt-module-path=%t 
-fsyntax-only -verify
+
+//--- global.h
+auto global_local() {
+  struct S {};
+  return S{};
+}
+
+//--- view.cppm
+module;
+#include "global.h"
+export module view;
+
+export using global_local_type = decltype(global_local());
+
+export auto local() {
+  struct S {};
+  return S{};
+}
+
+export namespace associated {
+struct Base {};
+template <class T> constexpr bool g(T *) { return true; }
+}
+
+export auto local_derived() {
+  struct S : associated::Base {};
+  return S{};
+}
+
+//--- wrapper.cppm
+export module wrapper;
+import view;
+
+export template <class T> struct W {};
+export using local_wrapper = W<decltype(local())>;
+export using derived_wrapper = W<decltype(local_derived())>;
+export using global_wrapper = W<global_local_type>;
+
+//--- use.cpp
+// expected-no-diagnostics
+import wrapper;
+
+void g(...);
+
+void test(local_wrapper *p, global_wrapper *q) {
+  g(p);
+  g(q);
+}
+
+static_assert(g(static_cast<derived_wrapper *>(nullptr)));

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to