[PATCH] D116775: [clang][#47272] Avoid suggesting deprecated version of a declaration over another in typo correction

Markus Böck via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 6 15:55:31 PST 2022


zero9178 created this revision.
zero9178 added reviewers: Quuxplusone, aaron.ballman, rsmith.
zero9178 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Prior to this patch, clang might suggest a deprecated name of a declaration over another name as the only mechanism for resolving two typo corrections referring to the same underlying declaration has previously been an alphabetical sort.

This patch adjusts this resolve by also taking into account whether one of two declarations are deprecated. If the new one is deprecated it may not replace a previous correction with a non-deprecated correction and a previous deprecated correction always gets replaced by a non-deprecated new correction.

Fixes https://github.com/llvm/llvm-project/issues/47272


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116775

Files:
  clang/lib/Sema/SemaLookup.cpp
  clang/test/SemaCXX/typo-correction.cpp


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'?}}
+}
+}
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<NamespaceDecl>(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())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116775.398002.patch
Type: text/x-patch
Size: 2714 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220106/2d3b09a5/attachment.bin>


More information about the cfe-commits mailing list