aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhikai Zeng <backlight.zzk@gmail.com>2024-06-22 15:31:03 +0800
committerGitHub <noreply@github.com>2024-06-22 15:31:03 +0800
commita091bfe71fdde4358dbfc73926f875cb05121c00 (patch)
tree0ee6adf20ce3f6623764497510cd1efb1aaed93d
parenta89669cb6ba7d0fbda0785650f03390b55a7650f (diff)
downloadllvm-a091bfe71fdde4358dbfc73926f875cb05121c00.zip
llvm-a091bfe71fdde4358dbfc73926f875cb05121c00.tar.gz
llvm-a091bfe71fdde4358dbfc73926f875cb05121c00.tar.bz2
[Clang] fix access checking inside return-type-requirement of compound requirements (#95651)
fixes https://github.com/llvm/llvm-project/issues/93788 .
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp2
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp36
3 files changed, 38 insertions, 1 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7ac0fa0..9c8f8c4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
- Clang now diagnoses explicit specializations with storage class specifiers in all contexts.
- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a
forward-declared class. (#GH93512).
+- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 863cc53..1fe1fe9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2735,7 +2735,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
if (TPLInst.isInvalid())
return nullptr;
TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);
- if (!TPL)
+ if (!TPL || Trap.hasErrorOccurred())
TransRetReq.emplace(createSubstDiag(SemaRef, Info,
[&] (llvm::raw_ostream& OS) {
RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
index b736620..dc0e842 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
@@ -189,3 +189,39 @@ namespace std_example {
template<C5 T> struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}}
using c5 = C5_check<short>; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}}
}
+
+namespace access_checks {
+namespace in_return_type_requirement {
+
+// https://github.com/llvm/llvm-project/issues/93788
+template <typename From, typename To>
+concept is_assignable = requires(From from, To to) {
+ from = to;
+};
+
+template <typename T>
+class trait {
+ public:
+ using public_type = int;
+ private:
+ using private_type = int;
+};
+
+template <typename T>
+concept has_field = requires(T t) {
+ { t.field } -> is_assignable<typename trait<T>::private_type>; // expected-note {{'private_type' is a private member}}
+};
+template <typename T>
+concept has_field2 = requires(T t) {
+ { t.field } -> is_assignable<typename trait<T>::public_type>;
+};
+
+struct A {
+ int field;
+};
+static_assert(has_field<A>); // expected-error {{static assertion failed}} \
+ // expected-note {{because 'A' does not satisfy 'has_field'}}
+static_assert(has_field2<A>);
+
+} // namespace access_checks
+} // namespace in_return_type_requirement