From 7c019177b002f679194ca340e0bef1573ad24543 Mon Sep 17 00:00:00 2001 From: Kaelyn Uhrain Date: Thu, 16 Feb 2012 22:40:59 +0000 Subject: [PATCH] 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. llvm-svn: 150735 --- clang/lib/Sema/SemaDecl.cpp | 20 ++++++++++++++++++-- clang/test/SemaCXX/typo-correction.cpp | 10 ++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 64a67d9a64d9..796d2a2bb3f4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp index 556e654a2d2c..55fead5c62ca 100644 --- a/clang/test/SemaCXX/typo-correction.cpp +++ b/clang/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'}}