diff options
author | Kaelyn Uhrain <rikka@google.com> | 2012-02-16 22:40:59 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2012-02-16 22:40:59 +0000 |
commit | 3336353578a02eb7dc35926c2440577993196e36 (patch) | |
tree | e02b41d04d084323bf1b8e569ab7fd46e3bdefb9 /lib/Sema/SemaDecl.cpp | |
parent | ad901a6cf3c57d7dd3d7b400835440992e99cff8 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
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<CXXMethodDecl>()) { + 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<CXXMethodDecl>(NewFD); + DifferentNameValidatorCCC Validator(MD ? MD->getParent() : 0); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { |