Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -4310,15 +4310,38 @@ std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts()); for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end(); RI != RIEnd; ++RI) { - // If the Correction refers to a decl already in the result list, - // replace the existing result if the string representation of Correction - // comes before the current result alphabetically, then stop as there is - // nothing more to be done to add Correction to the candidate set. - if (RI->getCorrectionDecl() == NewND) { - if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts())) - *RI = Correction; + if (RI->getCorrectionDecl() != NewND) + continue; + + // The Correction refers to a decl already in the list. No insertion is + // necessary and all further cases will return. + + auto IsDeprecated = [](Decl *decl) { + while (decl) { + if (decl->isDeprecated()) + return true; + decl = llvm::dyn_cast_or_null(decl->getDeclContext()); + } + return false; + }; + + // If the Correction in the result list is deprecated and the new one + // isn't always replace it with the new Correction. + // Additionally, don't allow a new deprecated Correction to overwrite + // an old not-deprecated one. + auto newIsDeprecated = IsDeprecated(Correction.getFoundDecl()); + auto oldIsDeprecated = IsDeprecated(RI->getFoundDecl()); + if (oldIsDeprecated && !newIsDeprecated) { + *RI = Correction; return; } + if (newIsDeprecated && !oldIsDeprecated) + return; + + // Otherwise, simply sort them alphabetically. + if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts())) + *RI = Correction; + return; } } if (CList.empty() || Correction.isResolved()) Index: clang/test/SemaCXX/typo-correction.cpp =================================================================== --- clang/test/SemaCXX/typo-correction.cpp +++ clang/test/SemaCXX/typo-correction.cpp @@ -757,3 +757,17 @@ b = g_volatile_uchar // expected-error {{did you mean 'g_volatile_char'}} }; } + + +namespace PR47272 +{ +namespace Views { +int Take(); // expected-note{{'Views::Take' declared here}} +} +namespace [[deprecated("use Views instead")]] View { +using Views::Take; +} +void function() { + int x = ::Take(); // expected-error{{no member named 'Take' in the global namespace; did you mean 'Views::Take'?}} +} +}