https://github.com/fogsong233 updated 
https://github.com/llvm/llvm-project/pull/178842

>From 5f802f4aabd807e9821228ef3a6382145687f8e0 Mon Sep 17 00:00:00 2001
From: fogsong233 <[email protected]>
Date: Tue, 10 Feb 2026 21:17:57 +0800
Subject: [PATCH] [clang-repl] Fix private type aliases. Fixes #164885. Fixes
 #169272. See also jank-lang/jank#609.

This patch fixes a bug in clang-repl where out-of-line member function
definitions were incorrectly identified as statements when involved private
type aliases.

The issue occurred because `isCXXDeclarationStatement` would trigger
immediate access checks during tentative parsing. Since the context of
an out-of-line definition isn't fully established during this phase,
Sema would incorrectly flag private members as inaccessible, causing
the parser to fail the declaration check and fall back to statement parsing.

Changes:
- In `isCXXDeclarationStatement`, use `TentativeParsingAction` with
  `TentativeParsingAction` to ensure the token stream is
  fully restored.
- Use `SuppressAccessChecks` during the tentative disambiguation phase
  to prevent premature access errors.
- Ensure that formal access verification still occurs during the
  actual parsing phase in `ParseDeclarationOrFunctionDefinition`.
- Add tests.
- Resolve a FIXME in clang/test/Interpreter/disambiguate-decl-stmt.cpp
---
 clang/lib/Parse/ParseTentative.cpp            | 19 +++++++++++++++++++
 clang/test/Interpreter/access.cpp             | 15 +++++++++++++++
 .../Interpreter/disambiguate-decl-stmt.cpp    |  5 ++---
 3 files changed, 36 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Interpreter/access.cpp

diff --git a/clang/lib/Parse/ParseTentative.cpp 
b/clang/lib/Parse/ParseTentative.cpp
index 9622a00687ca5..0047e3ea3749b 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -12,6 +12,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "clang/Parse/Parser.h"
+#include "clang/Parse/RAIIObjectsForParser.h"
 #include "clang/Sema/ParsedTemplate.h"
 using namespace clang;
 
@@ -78,6 +79,21 @@ bool Parser::isCXXDeclarationStatement(
     [[fallthrough]];
     // simple-declaration
   default:
+
+    if (DisambiguatingWithExpression) {
+      TentativeParsingAction TPA(*this, /*Unannotated=*/true);
+      // Skip early access checks to support edge cases like extern 
declarations
+      // involving private types. Tokens are unannotated by reverting so that
+      // access integrity is verified during the subsequent type-lookup phase.
+      SuppressAccessChecks AccessExporter(*this, /*activate=*/true);
+      if (isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false)) {
+        // Do not annotate the tokens, otherwise access will be neglected 
later.
+        TPA.Revert();
+        return true;
+      }
+      TPA.Commit();
+      return false;
+    }
     return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
   }
 }
@@ -574,6 +590,9 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, 
bool &isAmbiguous) {
     } else if (Context == TentativeCXXTypeIdContext::InTrailingReturnType) {
       TPR = TPResult::True;
       isAmbiguous = true;
+    } else if (Context == TentativeCXXTypeIdContext::AsReflectionOperand) {
+      TPR = TPResult::True;
+      isAmbiguous = true;
     } else
       TPR = TPResult::False;
   }
diff --git a/clang/test/Interpreter/access.cpp 
b/clang/test/Interpreter/access.cpp
new file mode 100644
index 0000000000000..c6b535bc1db92
--- /dev/null
+++ b/clang/test/Interpreter/access.cpp
@@ -0,0 +1,15 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+
+struct A { };
+
+class B { using u = A; const static int p = 1; public: u *foo(); };
+
+B::u* foo() { return nullptr; } 
+// CHECK: error: 'u' is a private member of 'B'
+
+B::u * B::foo() { return nullptr; }
+// CHECK-NOT: error: 'u' is a private member of 'B'
+
+int p = B::p; 
+// CHECK: error: 'p' is a private member of 'B'
diff --git a/clang/test/Interpreter/disambiguate-decl-stmt.cpp 
b/clang/test/Interpreter/disambiguate-decl-stmt.cpp
index 1f4d5e267288b..24902cee8ed1f 100644
--- a/clang/test/Interpreter/disambiguate-decl-stmt.cpp
+++ b/clang/test/Interpreter/disambiguate-decl-stmt.cpp
@@ -70,11 +70,10 @@ class PrivateUsingFriendVar { static PrivateUsingFriend::T 
i; };
 PrivateUsingFriend::T PrivateUsingFriendVar::i = 42;
 
 // The following should still diagnose (inspired by PR13642)
-// FIXME: Should not be diagnosed twice!
 class PR13642 { class Inner { public: static int i; }; };
-// expected-note@-1 2 {{implicitly declared private here}}
+// expected-note@-1 {{implicitly declared private here}}
 PR13642::Inner::i = 5;
-// expected-error@-1 2 {{'Inner' is a private member of 'PR13642'}}
+// expected-error@-1 {{'Inner' is a private member of 'PR13642'}}
 
 // Deduction guide
 template<typename T> struct A { A(); A(T); };

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

Reply via email to