diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 573ae97bff710..400d447518c73 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 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 LIS; + std::optional 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 void f(T a, int = decltype(a)()); // void g() { f(0); } - LIS = std::make_unique(*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 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 +int f(T = 0); // #Decl + +struct A { + A() { + int i = f(); + // expected-error@#Decl {{calling a private constructor}} + // expected-note@-2 {{in instantiation of default function argument}} + // expected-note@#B {{declared private}} + } +}; + +int i = f(); + +}