]> granicus.if.org Git - clang/commitdiff
Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration.
authorKaelyn Uhrain <rikka@google.com>
Thu, 16 Feb 2012 22:40:59 +0000 (22:40 +0000)
committerKaelyn Uhrain <rikka@google.com>
Thu, 16 Feb 2012 22:40:59 +0000 (22:40 +0000)
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

lib/Sema/SemaDecl.cpp
test/SemaCXX/typo-correction.cpp

index 64a67d9a64d996fcb348f7cc6afcbdd6b1f0472a..796d2a2bb3f4561aea6a93af598924108df6dbc8 100644 (file)
@@ -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) {
index 556e654a2d2ca53e8ece1d52d33010da4697e6ef..55fead5c62ca6cb94865f25be098ba9f4de13a52 100644 (file)
@@ -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'}}