aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorKaelyn Uhrain <rikka@google.com>2012-02-16 22:40:59 +0000
committerKaelyn Uhrain <rikka@google.com>2012-02-16 22:40:59 +0000
commit3336353578a02eb7dc35926c2440577993196e36 (patch)
treee02b41d04d084323bf1b8e569ab7fd46e3bdefb9 /lib/Sema/SemaDecl.cpp
parentad901a6cf3c57d7dd3d7b400835440992e99cff8 (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.cpp20
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) {