From: Kaelyn Uhrain Date: Thu, 16 Feb 2012 22:40:59 +0000 (+0000) Subject: Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3336353578a02eb7dc35926c2440577993196e36;p=clang Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration. Don't try to typo-correct a method redeclaration to declarations not in the current record as it could lead to infinite recursion if CorrectTypo finds more than one correction candidate in a parent record. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150735 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 64a67d9a64..796d2a2bb3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4439,11 +4439,26 @@ namespace { namespace { // Callback to only accept typo corrections that have a non-zero edit distance. +// Also only accept corrections that have the same parent decl. class DifferentNameValidatorCCC : public CorrectionCandidateCallback { public: + DifferentNameValidatorCCC(CXXRecordDecl *Parent) + : ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {} + virtual bool ValidateCandidate(const TypoCorrection &candidate) { - return candidate.getEditDistance() > 0; + if (candidate.getEditDistance() == 0) + return false; + + if (CXXMethodDecl *MD = candidate.getCorrectionDeclAs()) { + CXXRecordDecl *Parent = MD->getParent(); + return Parent && Parent->getCanonicalDecl() == ExpectedParent; + } + + return !ExpectedParent; } + + private: + CXXRecordDecl *ExpectedParent; }; } @@ -4477,7 +4492,8 @@ static NamedDecl* DiagnoseInvalidRedeclaration( SemaRef.LookupQualifiedName(Prev, NewDC); assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); - DifferentNameValidatorCCC Validator; + CXXMethodDecl *MD = dyn_cast(NewFD); + DifferentNameValidatorCCC Validator(MD ? MD->getParent() : 0); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp index 556e654a2d..55fead5c62 100644 --- a/test/SemaCXX/typo-correction.cpp +++ b/test/SemaCXX/typo-correction.cpp @@ -157,3 +157,13 @@ bool begun(R); void RangeTest() { for (auto b : R()) {} // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type}} } + +// PR 12019 - Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration +// by not trying to typo-correct a method redeclaration to declarations not +// in the current record. +class Parent { + void set_types(int index, int value); + void add_types(int value); +}; +class Child: public Parent {}; +void Child::add_types(int value) {} // expected-error{{out-of-line definition of 'add_types' does not match any declaration in 'Child'}}