usaxena95 created this revision. Herald added a project: All. usaxena95 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Access to members in a non-dependent context would always yield an invalid expression. When it appears in a requires-expression, then this is a hard error as this would always result in a substitution failure. https://eel.is/c++draft/expr.prim.req#general-note-1 Note 1: If a requires-expression contains invalid types or expressions in its requirements, and it does not appear within the declaration of a templated entity, then the program is ill-formed. — end note] If the substitution of template arguments into a requirement would always result in a substitution failure, the program is ill-formed; no diagnostic required. Fixes: https://github.com/llvm/llvm-project/issues/53334 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D140876 Files: clang/lib/Parse/ParseExprCXX.cpp clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp =================================================================== --- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp +++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp @@ -155,3 +155,28 @@ static_assert(!A<1>::faz()); static_assert(A<0>::faz()); } + +namespace non_dependent_access_check_hard_errors { +// Dependent access does not cause hard errors. +template<int N> class A; + +template <> class A<0> { + static void f() {} +}; +template<int N> +concept C1 = requires() { A<N>::f(); }; +static_assert(!C1<0>); + +template <> class A<1> { +public: + static void f() {} +}; +static_assert(C1<1>); + +// Non-dependent access to private member is a hard error. +class B{ + static void f() {} // expected-note {{implicitly declared private here}} +}; +template<class T> +concept C2 = requires() { B::f(); }; // expected-error {{'f' is a private member}} +} Index: clang/lib/Parse/ParseExprCXX.cpp =================================================================== --- clang/lib/Parse/ParseExprCXX.cpp +++ clang/lib/Parse/ParseExprCXX.cpp @@ -3507,6 +3507,7 @@ // Expressions appearing within a requirement-body are unevaluated operands. EnterExpressionEvaluationContext Ctx( Actions, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII SaveContext(Actions, Actions.CurContext); ParseScope BodyScope(this, Scope::DeclScope); RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(
Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp =================================================================== --- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp +++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp @@ -155,3 +155,28 @@ static_assert(!A<1>::faz()); static_assert(A<0>::faz()); } + +namespace non_dependent_access_check_hard_errors { +// Dependent access does not cause hard errors. +template<int N> class A; + +template <> class A<0> { + static void f() {} +}; +template<int N> +concept C1 = requires() { A<N>::f(); }; +static_assert(!C1<0>); + +template <> class A<1> { +public: + static void f() {} +}; +static_assert(C1<1>); + +// Non-dependent access to private member is a hard error. +class B{ + static void f() {} // expected-note {{implicitly declared private here}} +}; +template<class T> +concept C2 = requires() { B::f(); }; // expected-error {{'f' is a private member}} +} Index: clang/lib/Parse/ParseExprCXX.cpp =================================================================== --- clang/lib/Parse/ParseExprCXX.cpp +++ clang/lib/Parse/ParseExprCXX.cpp @@ -3507,6 +3507,7 @@ // Expressions appearing within a requirement-body are unevaluated operands. EnterExpressionEvaluationContext Ctx( Actions, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::ContextRAII SaveContext(Actions, Actions.CurContext); ParseScope BodyScope(this, Scope::DeclScope); RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits