Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -10750,7 +10750,8 @@ // functions, including those from argument-dependent lookup. AddOverloadedCallCandidates(ULE, Args, *CandidateSet); - if (getLangOpts().MSVCCompat && CurContext->isDependentContext() && + if (getLangOpts().MSVCCompat && + CurContext->isDependentContext() && !isSFINAEContext() && (isa(CurContext) || isa(CurContext))) { OverloadCandidateSet::iterator Best; Index: test/SemaTemplate/ms-lookup-template-base-classes.cpp =================================================================== --- test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -563,3 +563,13 @@ x.member(); // expected-note{{requested here}} }; } + +namespace PR23823 { +// Don't delay lookup in SFINAE context. +template decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}} +decltype(check()) x; // expected-error{{no matching function for call to 'check'}} + +void h(); +template decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}} +decltype(check2()) y; // expected-error{{no matching function for call to 'check2'}} +}