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 | 7c019177b002f679194ca340e0bef1573ad24543 (patch) | |
tree | bc8c2337d4c16b5e33ada9d7b30ad1b4cf1ad538 /clang/lib/Sema/SemaDecl.cpp | |
parent | 33c364b12b73c0710bbea96969e70417cd13e80c (diff) | |
download | bcm5719-llvm-7c019177b002f679194ca340e0bef1573ad24543.tar.gz bcm5719-llvm-7c019177b002f679194ca340e0bef1573ad24543.zip |
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
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 64a67d9a64d..796d2a2bb3f 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<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) { |