]> granicus.if.org Git - clang/commitdiff
Fix a typo correction crash when resolving ambiguous corrections.
authorKaelyn Takata <rikka@google.com>
Thu, 25 Jun 2015 23:47:39 +0000 (23:47 +0000)
committerKaelyn Takata <rikka@google.com>
Thu, 25 Jun 2015 23:47:39 +0000 (23:47 +0000)
In certain cases, the tree transform would introduce new TypoExprs while
trying one of the corrections, invalidating the unique_ptr in the state
reference, and also causing a TypoExpr to exist that will never be
corrected since it doesn't exist in the final corrected expression. The
simple solution to both problems is to temporarily disable typo
correction while handling potentially ambiguous typo corrections.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240734 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/typo-correction-cxx11.cpp

index 6c839f356fdc26cf4d815adab035766893923ba3..6608d7c1f061a108892697d615146c9c193471e6 100644 (file)
@@ -6506,6 +6506,11 @@ public:
     // with the same edit length that pass all the checks and filters.
     // TODO: Properly handle various permutations of possible corrections when
     // there is more than one potentially ambiguous typo correction.
+    // Also, disable typo correction while attempting the transform when
+    // handling potentially ambiguous typo corrections as any new TypoExprs will
+    // have been introduced by the application of one of the correction
+    // candidates and add little to no value if corrected.
+    SemaRef.DisableTypoCorrection = true;
     while (!AmbiguousTypoExprs.empty()) {
       auto TE  = AmbiguousTypoExprs.back();
       auto Cached = TransformCache[TE];
@@ -6522,6 +6527,7 @@ public:
       State.Consumer->restoreSavedPosition();
       TransformCache[TE] = Cached;
     }
+    SemaRef.DisableTypoCorrection = false;
 
     // Ensure that all of the TypoExprs within the current Expr have been found.
     if (!Res.isUsable())
index 99cb1662b7a045e847cf93d56c6d49b99dc95ae2..8c588203cc1283b73059f02d5d4459a48b30554e 100644 (file)
@@ -32,3 +32,29 @@ void f() {
   }
 }
 }
+
+namespace NewTypoExprFromResolvingTypoAmbiguity {
+struct A {
+  void Swap(A *other);
+};
+
+struct pair {
+  int first;
+  A *second;
+};
+
+struct map {
+public:
+  void swap(map &x);
+  pair find(int x);
+};
+
+void run(A *annotations) {
+  map new_annotations;
+
+  auto &annotation = *annotations;
+  auto new_it = new_annotations.find(5);
+  auto &new_anotation = new_it.second;  // expected-note {{'new_anotation' declared here}}
+  new_annotation->Swap(&annotation);  // expected-error {{use of undeclared identifier 'new_annotation'; did you mean 'new_anotation'?}}
+}
+}