usaxena95 updated this revision to Diff 485726. usaxena95 added a comment. Improved comment and added comment.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140547/new/ https://reviews.llvm.org/D140547 Files: clang/lib/Sema/SemaTemplateInstantiate.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 @@ -104,3 +104,54 @@ constexpr bool b = requires (X &x) { static_cast<int(*)[(typeid(x), 0)]>(nullptr); }; // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}} // expected-note@-2{{'x' declared here}} + +namespace access_checks { +template<auto> +struct A { + static constexpr bool foo(); + static constexpr bool bar(); + static constexpr bool baz(); + static constexpr bool faz(); +}; + +class C{}; + +class B { + void p() {} + bool data_member = true; + static const bool static_member = true; + friend struct A<0>; +}; + +template<auto x> +constexpr bool A<x>::foo() { + return requires(B b) { b.p(); }; +} +static_assert(!A<1>::foo()); +static_assert(A<0>::foo()); + +template<auto x> +constexpr bool A<x>::bar() { + return requires() { B::static_member; }; +} +static_assert(!A<1>::bar()); +static_assert(A<0>::bar()); + +template<auto x> +constexpr bool A<x>::baz() { + return requires(B b) { b.data_member; }; +} +static_assert(!A<1>::baz()); +static_assert(A<0>::baz()); + +template<auto x> +constexpr bool A<x>::faz() { + return requires(B a, B b) { + a.p(); + b.data_member; + B::static_member; + }; +} +static_assert(!A<1>::faz()); +static_assert(A<0>::faz()); +} Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -15,6 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/ASTMutationListener.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprConcepts.h" @@ -1362,6 +1363,14 @@ } ExprResult TransformRequiresExpr(RequiresExpr *E) { + if (E->getBody()->isDependentContext()) { + Sema::SFINAETrap Trap(SemaRef); + // We recreate the RequiresExpr body, but not by instantiating it. + // Produce pending diagnostics for dependent access check. + SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs); + if (Trap.hasErrorOccurred()) + return ExprError(); + } LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); return inherited::TransformRequiresExpr(E); }
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 @@ -104,3 +104,54 @@ constexpr bool b = requires (X &x) { static_cast<int(*)[(typeid(x), 0)]>(nullptr); }; // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}} // expected-note@-2{{'x' declared here}} + +namespace access_checks { +template<auto> +struct A { + static constexpr bool foo(); + static constexpr bool bar(); + static constexpr bool baz(); + static constexpr bool faz(); +}; + +class C{}; + +class B { + void p() {} + bool data_member = true; + static const bool static_member = true; + friend struct A<0>; +}; + +template<auto x> +constexpr bool A<x>::foo() { + return requires(B b) { b.p(); }; +} +static_assert(!A<1>::foo()); +static_assert(A<0>::foo()); + +template<auto x> +constexpr bool A<x>::bar() { + return requires() { B::static_member; }; +} +static_assert(!A<1>::bar()); +static_assert(A<0>::bar()); + +template<auto x> +constexpr bool A<x>::baz() { + return requires(B b) { b.data_member; }; +} +static_assert(!A<1>::baz()); +static_assert(A<0>::baz()); + +template<auto x> +constexpr bool A<x>::faz() { + return requires(B a, B b) { + a.p(); + b.data_member; + B::static_member; + }; +} +static_assert(!A<1>::faz()); +static_assert(A<0>::faz()); +} Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -15,6 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/ASTMutationListener.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprConcepts.h" @@ -1362,6 +1363,14 @@ } ExprResult TransformRequiresExpr(RequiresExpr *E) { + if (E->getBody()->isDependentContext()) { + Sema::SFINAETrap Trap(SemaRef); + // We recreate the RequiresExpr body, but not by instantiating it. + // Produce pending diagnostics for dependent access check. + SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs); + if (Trap.hasErrorOccurred()) + return ExprError(); + } LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); return inherited::TransformRequiresExpr(E); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits