https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/141207

>From c63f3f82d6e4c576051532b2272abf4ac0055d7f Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Fri, 23 May 2025 15:29:49 +0800
Subject: [PATCH 1/2] [Clang] Fix the access checking for non-aggregates in
 default arguments

We check the accessibility of constructors when initializing a default
argument whose type is not an aggregate.

Make sure the check is performed within the correct DeclContext.
Otherwise, it will be delayed until the end of the declaration,
at which point the context is mismatched.
---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/Sema/SemaTemplateInstantiate.cpp    | 14 ++++++------
 clang/test/SemaTemplate/default-arguments.cpp | 22 +++++++++++++++++++
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 573ae97bff710..45c96af809505 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -767,6 +767,7 @@ Bug Fixes to C++ Support
 - Clang could incorrectly instantiate functions in discarded contexts 
(#GH140449)
 - Fix instantiation of default-initialized variable template specialization. 
(#GH140632) (#GH140622)
 - Clang modules now allow a module and its user to differ on 
TrivialAutoVarInit*
+- Fixed a C++20 access checking bug when initializing non-aggregates in 
default arguments (#GH83608)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index d028eea4f8f3e..cd20dfb4fe093 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3340,13 +3340,13 @@ bool Sema::SubstDefaultArgument(
   }
 
   ExprResult Result;
+  // C++ [dcl.fct.default]p5:
+  //   The names in the [default argument] expression are bound, and
+  //   the semantic constraints are checked, at the point where the
+  //   default argument expression appears.
+  ContextRAII SavedContext(*this, FD);
   {
-    // C++ [dcl.fct.default]p5:
-    //   The names in the [default argument] expression are bound, and
-    //   the semantic constraints are checked, at the point where the
-    //   default argument expression appears.
-    ContextRAII SavedContext(*this, FD);
-    std::unique_ptr<LocalInstantiationScope> LIS;
+    std::optional<LocalInstantiationScope> LIS;
 
     if (ForCallExpr) {
       // When instantiating a default argument due to use in a call expression,
@@ -3354,7 +3354,7 @@ bool Sema::SubstDefaultArgument(
       // required to satisfy references from the default argument. For example:
       //   template<typename T> void f(T a, int = decltype(a)());
       //   void g() { f(0); }
-      LIS = std::make_unique<LocalInstantiationScope>(*this);
+      LIS.emplace(*this);
       FunctionDecl *PatternFD = FD->getTemplateInstantiationPattern(
           /*ForDefinition*/ false);
       if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
diff --git a/clang/test/SemaTemplate/default-arguments.cpp 
b/clang/test/SemaTemplate/default-arguments.cpp
index 5ea34c0254ec1..e9d781bfe5712 100644
--- a/clang/test/SemaTemplate/default-arguments.cpp
+++ b/clang/test/SemaTemplate/default-arguments.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 template<typename T, int N = 2> struct X; // expected-note{{template is 
declared here}}
 
 X<int, 1> *x1;
@@ -282,4 +283,25 @@ static_assert(S<short *>().SizeOfT<char>() == sizeof(short 
*), "");
 
 } // namespace GH68490
 
+namespace GH83608 {
+
+class single;
+
+class check_constructible {
+  // This makes it a non-aggregate in C++20+.
+  check_constructible() = default;
+
+  friend class single;
+};
+
+struct single {
+  template <class T> single(T u, check_constructible = {}) {}
+};
+
+// We perform access checking when substituting into the default argument.
+// Make sure it runs within class single.
+single x(0);
+
+}
+
 #endif

>From 7b15ebae62f0c2e492164dcbabcdb04f60b628ac Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Fri, 23 May 2025 19:45:18 +0800
Subject: [PATCH 2/2] feedback

---
 clang/docs/ReleaseNotes.rst                   |  2 +-
 clang/test/SemaCXX/access-control-check.cpp   | 46 +++++++++++++++++++
 clang/test/SemaTemplate/default-arguments.cpp | 22 ---------
 3 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 45c96af809505..400d447518c73 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -767,7 +767,7 @@ Bug Fixes to C++ Support
 - Clang could incorrectly instantiate functions in discarded contexts 
(#GH140449)
 - Fix instantiation of default-initialized variable template specialization. 
(#GH140632) (#GH140622)
 - Clang modules now allow a module and its user to differ on 
TrivialAutoVarInit*
-- Fixed a C++20 access checking bug when initializing non-aggregates in 
default arguments (#GH83608)
+- Fixed an access checking bug when initializing non-aggregates in default 
arguments (#GH62444), (#GH83608)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/test/SemaCXX/access-control-check.cpp 
b/clang/test/SemaCXX/access-control-check.cpp
index 4540e99d8a337..76d27ce3e55cb 100644
--- a/clang/test/SemaCXX/access-control-check.cpp
+++ b/clang/test/SemaCXX/access-control-check.cpp
@@ -13,3 +13,49 @@ class N : M,P {
   N() {}
   int PR() { return iP + PPR(); } // expected-error 2 {{private member of 'P'}}
 };
+
+namespace GH83608 {
+
+class single;
+
+class check_constructible {
+  // This makes the class a non-aggregate, which enforces us to check
+  // the constructor when initializing.
+  check_constructible() {}
+
+  friend class single;
+};
+
+struct single {
+  template <class T> single(T u, check_constructible = {}) {}
+};
+
+// We perform access checking when substituting into the default argument.
+// Make sure it runs within the context of 'single'.
+single x(0);
+
+}
+
+namespace GH62444 {
+
+struct B {
+  friend struct A;
+private:
+  B(int); // #B
+};
+
+template<class T>
+int f(T = 0); // #Decl
+
+struct A {
+  A() {
+    int i = f<B>();
+    // expected-error@#Decl {{calling a private constructor}}
+    // expected-note@-2 {{in instantiation of default function argument}}
+    // expected-note@#B {{declared private}}
+  }
+};
+
+int i = f<B>();
+
+}
diff --git a/clang/test/SemaTemplate/default-arguments.cpp 
b/clang/test/SemaTemplate/default-arguments.cpp
index e9d781bfe5712..5ea34c0254ec1 100644
--- a/clang/test/SemaTemplate/default-arguments.cpp
+++ b/clang/test/SemaTemplate/default-arguments.cpp
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
 template<typename T, int N = 2> struct X; // expected-note{{template is 
declared here}}
 
 X<int, 1> *x1;
@@ -283,25 +282,4 @@ static_assert(S<short *>().SizeOfT<char>() == sizeof(short 
*), "");
 
 } // namespace GH68490
 
-namespace GH83608 {
-
-class single;
-
-class check_constructible {
-  // This makes it a non-aggregate in C++20+.
-  check_constructible() = default;
-
-  friend class single;
-};
-
-struct single {
-  template <class T> single(T u, check_constructible = {}) {}
-};
-
-// We perform access checking when substituting into the default argument.
-// Make sure it runs within class single.
-single x(0);
-
-}
-
 #endif

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to