Skip to content

Commit a9884a9

Browse files
Backl1ghtAlexisPerry
authored andcommitted
[Clang] fix access checking inside return-type-requirement of compound requirements (llvm#95651)
fixes llvm#93788 .
1 parent 0c4ed4b commit a9884a9

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ Bug Fixes to C++ Support
914914
- Clang now diagnoses explicit specializations with storage class specifiers in all contexts.
915915
- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a
916916
forward-declared class. (#GH93512).
917+
- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
917918

918919
Bug Fixes to AST Handling
919920
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2735,7 +2735,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
27352735
if (TPLInst.isInvalid())
27362736
return nullptr;
27372737
TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);
2738-
if (!TPL)
2738+
if (!TPL || Trap.hasErrorOccurred())
27392739
TransRetReq.emplace(createSubstDiag(SemaRef, Info,
27402740
[&] (llvm::raw_ostream& OS) {
27412741
RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()

clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,39 @@ namespace std_example {
189189
template<C5 T> struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}}
190190
using c5 = C5_check<short>; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}}
191191
}
192+
193+
namespace access_checks {
194+
namespace in_return_type_requirement {
195+
196+
// https://github.com/llvm/llvm-project/issues/93788
197+
template <typename From, typename To>
198+
concept is_assignable = requires(From from, To to) {
199+
from = to;
200+
};
201+
202+
template <typename T>
203+
class trait {
204+
public:
205+
using public_type = int;
206+
private:
207+
using private_type = int;
208+
};
209+
210+
template <typename T>
211+
concept has_field = requires(T t) {
212+
{ t.field } -> is_assignable<typename trait<T>::private_type>; // expected-note {{'private_type' is a private member}}
213+
};
214+
template <typename T>
215+
concept has_field2 = requires(T t) {
216+
{ t.field } -> is_assignable<typename trait<T>::public_type>;
217+
};
218+
219+
struct A {
220+
int field;
221+
};
222+
static_assert(has_field<A>); // expected-error {{static assertion failed}} \
223+
// expected-note {{because 'A' does not satisfy 'has_field'}}
224+
static_assert(has_field2<A>);
225+
226+
} // namespace access_checks
227+
} // namespace in_return_type_requirement

0 commit comments

Comments
 (0)