]> granicus.if.org Git - clang/commitdiff
Do not use typo correction that is unaccessible.
authorSerge Pavlov <sepavloff@gmail.com>
Mon, 14 Oct 2013 14:05:48 +0000 (14:05 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Mon, 14 Oct 2013 14:05:48 +0000 (14:05 +0000)
This patch fixes PR17019. When doing typo correction, Sema::CorrectTypo uses
correction already seen for the same typo. This causes problems if that
correction is from another scope and cannot be accessed in the current.

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

lib/Sema/SemaLookup.cpp
test/SemaCXX/typo-correction-pt2.cpp
test/SemaObjC/bad-property-synthesis-crash.m
test/SemaObjC/error-outof-scope-property-use.m

index 2b80b97728134513f24b64abfa43def03eb35292..6ffb78776878e81f812338d30d7e5f7d3dabe7bb 100644 (file)
@@ -4167,8 +4167,15 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
       // keyword case, we'll end up adding the keyword below.
       if (Cached->second) {
         if (!Cached->second.isKeyword() &&
-            isCandidateViable(CCC, Cached->second))
-          Consumer.addCorrection(Cached->second);
+            isCandidateViable(CCC, Cached->second)) {
+          // Do not use correction that is unaccessible in the given scope.
+          NamedDecl* CorrectionDecl = Cached->second.getCorrectionDecl();
+          DeclarationNameInfo NameInfo(CorrectionDecl->getDeclName(),
+                                       CorrectionDecl->getLocation());
+          LookupResult R(*this, NameInfo, LookupOrdinaryName);
+          if (LookupName(R, S))
+            Consumer.addCorrection(Cached->second);
+        }
       } else {
         // Only honor no-correction cache hits when a callback that will validate
         // correction candidates is not being used.
index f360649cccda68cde373591e066e18144521da46..d22a8e92e0ddd956cec93dc739dab1998704484d 100644 (file)
@@ -151,3 +151,20 @@ struct S {
   void f() { my_menber = 1; }  // expected-error {{use of undeclared identifier 'my_menber'; did you mean 'my_member'?}}
 };
 }
+
+namespace PR17019 {
+  template<class F>
+  struct evil {
+    evil(F de) {  // expected-note {{'de' declared here}}
+      de_;  // expected-error {{use of undeclared identifier 'de_'; did you mean 'de'?}} \
+            // expected-warning {{expression result unused}}
+    }
+    ~evil() {
+      de_->bar()  // expected-error {{use of undeclared identifier 'de_'}}
+    }
+  };
+
+  void meow() {
+    evil<int> Q(0); // expected-note {{in instantiation of member function}}
+  }
+}
index ea4e0045dc4b34090acd5a95ce8acb8185d7c800..94c680489d916f8e291c3d06577beed0237b56f7 100644 (file)
@@ -13,7 +13,7 @@
   __what; // expected-error {{use of undeclared identifier}} \
           // expected-warning {{expression result unused}}
 }
-@synthesize what; // expected-note {{'what' declared here}}
+@synthesize what; // expected-note {{'what' declared here}}
 @end
 
 @implementation Bar // expected-warning {{cannot find interface declaration for}}
index 8767dc0b856ecb8917b95612e280d5aa21b90872..c480e2df0b7ee6dea1a669857461aa8e81d2c721 100644 (file)
@@ -6,7 +6,7 @@
 
 @interface LaunchdJobs 
 
-@property (nonatomic,retain) NSMutableDictionary *uuids_jobs; // expected-note {{'_uuids_jobs' declared here}}
+@property (nonatomic,retain) NSMutableDictionary *uuids_jobs; // expected-note {{'_uuids_jobs' declared here}}
 
 @end