Skip to content

Commit 5eab514

Browse files
author
git apple-llvm automerger
committed
Merge commit '52ccec45bb33' from swift/release/5.9 into stable/20221013
2 parents e39b922 + 52ccec4 commit 5eab514

File tree

5 files changed

+80
-8
lines changed

5 files changed

+80
-8
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5346,11 +5346,22 @@ class Sema final {
53465346
// Expression Parsing Callbacks: SemaExpr.cpp.
53475347

53485348
bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid);
5349+
// A version of DiagnoseUseOfDecl that should be used if overload resolution
5350+
// has been used to find this declaration, which means we don't have to bother
5351+
// checking the trailing requires clause.
5352+
bool DiagnoseUseOfOverloadedDecl(NamedDecl *D, SourceLocation Loc) {
5353+
return DiagnoseUseOfDecl(
5354+
D, Loc, /*UnknownObjCClass=*/nullptr, /*ObjCPropertyAccess=*/false,
5355+
/*AvoidPartialAvailabilityChecks=*/false, /*ClassReceiver=*/nullptr,
5356+
/*SkipTrailingRequiresClause=*/true);
5357+
}
5358+
53495359
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
53505360
const ObjCInterfaceDecl *UnknownObjCClass = nullptr,
53515361
bool ObjCPropertyAccess = false,
53525362
bool AvoidPartialAvailabilityChecks = false,
5353-
ObjCInterfaceDecl *ClassReciever = nullptr);
5363+
ObjCInterfaceDecl *ClassReciever = nullptr,
5364+
bool SkipTrailingRequiresClause = false);
53545365
void NoteDeletedFunction(FunctionDecl *FD);
53555366
void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD);
53565367
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15592,7 +15592,10 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
1559215592
SourceRange ParenRange) {
1559315593
if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl)) {
1559415594
Constructor = findInheritingConstructor(ConstructLoc, Constructor, Shadow);
15595-
if (DiagnoseUseOfDecl(Constructor, ConstructLoc))
15595+
// The only way to get here is if we did overlaod resolution to find the
15596+
// shadow decl, so we don't need to worry about re-checking the trailing
15597+
// requires clause.
15598+
if (DiagnoseUseOfOverloadedDecl(Constructor, ConstructLoc))
1559615599
return ExprError();
1559715600
}
1559815601

clang/lib/Sema/SemaExpr.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
222222
const ObjCInterfaceDecl *UnknownObjCClass,
223223
bool ObjCPropertyAccess,
224224
bool AvoidPartialAvailabilityChecks,
225-
ObjCInterfaceDecl *ClassReceiver) {
225+
ObjCInterfaceDecl *ClassReceiver,
226+
bool SkipTrailingRequiresClause) {
226227
SourceLocation Loc = Locs.front();
227228
if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
228229
// If there were any diagnostics suppressed by template argument deduction,
@@ -281,7 +282,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
281282
// See if this is a function with constraints that need to be satisfied.
282283
// Check this before deducing the return type, as it might instantiate the
283284
// definition.
284-
if (FD->getTrailingRequiresClause()) {
285+
if (!SkipTrailingRequiresClause && FD->getTrailingRequiresClause()) {
285286
ConstraintSatisfaction Satisfaction;
286287
if (CheckFunctionConstraints(FD, Satisfaction, Loc,
287288
/*ForOverloadResolution*/ true))
@@ -6776,8 +6777,8 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
67766777
nullptr, DRE->isNonOdrUse());
67776778
}
67786779
}
6779-
} else if (isa<MemberExpr>(NakedFn))
6780-
NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl();
6780+
} else if (auto *ME = dyn_cast<MemberExpr>(NakedFn))
6781+
NDecl = ME->getMemberDecl();
67816782

67826783
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(NDecl)) {
67836784
if (CallingNDeclIndirectly && !checkAddressOfFunctionIsAvailable(

clang/lib/Sema/SemaOverload.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14694,7 +14694,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
1469414694
Method = cast<CXXMethodDecl>(Best->Function);
1469514695
FoundDecl = Best->FoundDecl;
1469614696
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
14697-
if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
14697+
if (DiagnoseUseOfOverloadedDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
1469814698
break;
1469914699
// If FoundDecl is different from Method (such as if one is a template
1470014700
// and the other a specialization), make sure DiagnoseUseOfDecl is
@@ -14703,7 +14703,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
1470314703
// DiagnoseUseOfDecl to accept both the FoundDecl and the decl
1470414704
// being used.
1470514705
if (Method != FoundDecl.getDecl() &&
14706-
DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc()))
14706+
DiagnoseUseOfOverloadedDecl(Method, UnresExpr->getNameLoc()))
1470714707
break;
1470814708
Succeeded = true;
1470914709
break;

clang/test/SemaTemplate/concepts.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,60 @@ Container<5>::var_templ<int> inst_fail;
708708
// expected-note@#CMVT_REQ{{because 'sizeof(int) == arity' (4 == 5) evaluated to false}}
709709
} // namespace ConstrainedMemberVarTemplate
710710

711+
// These should not diagnose, where we were unintentionally doing so before by
712+
// checking trailing requires clause twice, yet not having the ability to the
713+
// 2nd time, since it was no longer a dependent variant.
714+
namespace InheritedFromPartialSpec {
715+
template<class C>
716+
constexpr bool Check = true;
717+
718+
template<typename T>
719+
struct Foo {
720+
template<typename U>
721+
Foo(U&&) requires (Check<U>){}
722+
template<typename U>
723+
void MemFunc(U&&) requires (Check<U>){}
724+
template<typename U>
725+
static void StaticMemFunc(U&&) requires (Check<U>){}
726+
~Foo() requires (Check<T>){}
727+
};
728+
729+
template<>
730+
struct Foo<void> : Foo<int> {
731+
using Foo<int>::Foo;
732+
using Foo<int>::MemFunc;
733+
using Foo<int>::StaticMemFunc;
734+
};
735+
736+
void use() {
737+
Foo<void> F {1.1};
738+
F.MemFunc(1.1);
739+
Foo<void>::StaticMemFunc(1.1);
740+
}
741+
742+
template<typename T>
743+
struct counted_iterator {
744+
constexpr auto operator->() const noexcept requires false {
745+
return T::Invalid;
746+
};
747+
};
748+
749+
template<class _Ip>
750+
concept __has_member_pointer = requires { typename _Ip::pointer; };
751+
752+
template<class>
753+
struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; };
754+
template<__has_member_pointer _Ip>
755+
struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; };
756+
757+
template<class _Ip>
758+
requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
759+
struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
760+
using type = decltype(declval<_Ip&>().operator->());
761+
};
762+
763+
764+
void use2() {
765+
__iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f;
766+
}
767+
}// namespace InheritedFromPartialSpec

0 commit comments

Comments
 (0)