Author: Chuanqi Xu
Date: 2026-01-07T07:24:13Z
New Revision: b4ed102b1ebf92759786d750798b76bba6f1867c

URL: 
https://github.com/llvm/llvm-project/commit/b4ed102b1ebf92759786d750798b76bba6f1867c
DIFF: 
https://github.com/llvm/llvm-project/commit/b4ed102b1ebf92759786d750798b76bba6f1867c.diff

LOG: [C++20] [Modules] Avoid infinite loop when checking TU local exposures 
(#174704)

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

The root cause of the problem is that the recursion in the code pattern
triggers infinite loop in the checking process for TU local exposure.

Added: 
    clang/test/Modules/pr174543.cppm

Modified: 
    clang/lib/Sema/SemaModule.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index cbe37cd47793b..24275b97b7462 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -18,6 +18,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/SemaInternal.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
 
 using namespace clang;
@@ -1140,6 +1141,7 @@ class ExposureChecker {
 private:
   llvm::DenseSet<const NamedDecl *> ExposureSet;
   llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;
+  llvm::DenseSet<const NamedDecl *> CheckingDecls;
 };
 
 bool ExposureChecker::isTULocal(QualType Ty) {
@@ -1226,6 +1228,12 @@ bool ExposureChecker::isTULocal(const NamedDecl *D) {
     }
   }
 
+  // Avoid recursions.
+  if (CheckingDecls.count(D))
+    return false;
+  CheckingDecls.insert(D);
+  llvm::scope_exit RemoveCheckingDecls([&] { CheckingDecls.erase(D); });
+
   // [basic.link]p15.5
   // - a specialization of a template whose (possibly instantiated) declaration
   // is an exposure.

diff  --git a/clang/test/Modules/pr174543.cppm 
b/clang/test/Modules/pr174543.cppm
new file mode 100644
index 0000000000000..39dc57f791ff6
--- /dev/null
+++ b/clang/test/Modules/pr174543.cppm
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+// expected-no-diagnostics
+export module m;
+template < typename T >
+void fun(T)
+{
+    fun(9);
+}


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

Reply via email to