From: Kaelyn Uhrain Date: Fri, 21 Mar 2014 21:54:25 +0000 (+0000) Subject: Be a bit smarter about what nested name qualifiers to allow when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42b6eb5513cf168066ea782f2befda373b9c4b9e;p=clang Be a bit smarter about what nested name qualifiers to allow when performing typo correction on very short (1 or 2 char) identifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204525 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 0dd0260a5b..020fafa8f5 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -4209,13 +4209,17 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, IEnd = DI->second.end(); I != IEnd; /* Increment in loop. */) { // If we only want nested name specifier corrections, ignore potential - // corrections that have a different base identifier from the typo. - if (AllowOnlyNNSChanges && - I->second.front().getCorrectionAsIdentifierInfo() != Typo) { - TypoCorrectionConsumer::result_iterator Prev = I; - ++I; - DI->second.erase(Prev); - continue; + // corrections that have a different base identifier from the typo or + // which have a normalized edit distance longer than the typo itself. + if (AllowOnlyNNSChanges) { + TypoCorrection &TC = I->second.front(); + if (TC.getCorrectionAsIdentifierInfo() != Typo || + TC.getEditDistance(true) > TypoLen) { + TypoCorrectionConsumer::result_iterator Prev = I; + ++I; + DI->second.erase(Prev); + continue; + } } // If the item already has been looked up or is a keyword, keep it. diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp index 619bc61f25..96bed074db 100644 --- a/test/SemaCXX/missing-members.cpp +++ b/test/SemaCXX/missing-members.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s namespace A { namespace B { - class C { }; // expected-note 2 {{'A::B::C' declared here}} + class C { }; // expected-note {{'A::B::C' declared here}} struct S { }; union U { }; } @@ -18,13 +18,12 @@ namespace B { } void g() { - A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}} + A::B::D::E; // expected-error-re {{no member named 'D' in namespace 'A::B'{{$}}}} // FIXME: The typo corrections below should be suppressed since A::B::C // doesn't have a member named D. B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \ - // expected-error {{no member named 'D' in 'A::B::C'}} - ::C::D; // expected-error {{no member named 'C' in the global namespace; did you mean 'A::B::C'?}}\ - // expected-error {{no member named 'D' in 'A::B::C'}} + // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}} + ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}} } int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}} diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp index e39a24bd09..9943dd21f5 100644 --- a/test/SemaCXX/typo-correction-pt2.cpp +++ b/test/SemaCXX/typo-correction-pt2.cpp @@ -243,3 +243,16 @@ void func() { bar(); // expected-error-re {{use of undeclared identifier 'bar'{{$}}}} } } + +namespace std { +class bernoulli_distribution { + public: + double p() const; +}; +} +void test() { + // Make sure that typo correction doesn't suggest changing 'p' to + // 'std::bernoulli_distribution::p' as that is most likely wrong. + if (p) // expected-error-re {{use of undeclared identifier 'p'{{$}}}} + return; +}