usaxena95 updated this revision to Diff 485725. usaxena95 added a comment. Perform access-dependent checks after transforming requires clause. This is more generic and less invasive than the previous version which changed `RebuildMemberExpr` and also produced duplicate diagnostics.
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()); +} \ No newline at end of file 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" @@ -1363,7 +1364,19 @@ ExprResult TransformRequiresExpr(RequiresExpr *E) { LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); - return inherited::TransformRequiresExpr(E); + ExprResult TransReq = inherited::TransformRequiresExpr(E); + { + if (TransReq.isInvalid() || !E->getBody()->isDependentContext()) + return TransReq; + Sema::SFINAETrap Trap(SemaRef); + // We recreated parameters, but not by instantiating them. There may be + // pending access-dependent diagnostics to produce. + // RequiresExpr Body serves as the DeclContext for the parameters. + SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs); + if (Trap.hasErrorOccurred()) + return ExprError(); + } + return TransReq; } bool TransformRequiresExprRequirements(
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()); +} \ No newline at end of file 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" @@ -1363,7 +1364,19 @@ ExprResult TransformRequiresExpr(RequiresExpr *E) { LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); - return inherited::TransformRequiresExpr(E); + ExprResult TransReq = inherited::TransformRequiresExpr(E); + { + if (TransReq.isInvalid() || !E->getBody()->isDependentContext()) + return TransReq; + Sema::SFINAETrap Trap(SemaRef); + // We recreated parameters, but not by instantiating them. There may be + // pending access-dependent diagnostics to produce. + // RequiresExpr Body serves as the DeclContext for the parameters. + SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs); + if (Trap.hasErrorOccurred()) + return ExprError(); + } + return TransReq; } bool TransformRequiresExprRequirements(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits