[clang] d4f0f43 - [Clang] Fix the access checking for non-aggregates in default arguments (#141207)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 23 05:11:25 PDT 2025
Author: Younan Zhang
Date: 2025-05-23T20:11:22+08:00
New Revision: d4f0f43506d04807e82e5c722c6362bcf112a2a0
URL: https://github.com/llvm/llvm-project/commit/d4f0f43506d04807e82e5c722c6362bcf112a2a0
DIFF: https://github.com/llvm/llvm-project/commit/d4f0f43506d04807e82e5c722c6362bcf112a2a0.diff
LOG: [Clang] Fix the access checking for non-aggregates in default arguments (#141207)
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.
Fixes #62444
Fixes https://github.com/llvm/llvm-project/issues/83608
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaCXX/access-control-check.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8a4ff6efc6860..b93fa33acc2a0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -794,6 +794,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
diff er on TrivialAutoVarInit*
+- Fixed an access checking bug when initializing non-aggregates in default arguments (#GH62444), (#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/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 at -2 {{in instantiation of default function argument}}
+ // expected-note@#B {{declared private}}
+ }
+};
+
+int i = f<B>();
+
+}
More information about the cfe-commits
mailing list