diff options
author | Kaelyn Uhrain <rikka@google.com> | 2012-04-03 18:20:11 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2012-04-03 18:20:11 +0000 |
commit | 6d858d96ea294baecdf3e7ad3f3c5395c00dec8e (patch) | |
tree | 66841fb215eefc47865e390f1f0f203ce53af5a7 | |
parent | b3f904f79bbe55f3e088d7174d64d20d186914a1 (diff) |
Replace the workaround from r153445 with a proper fix.
Infinite recursion was happening when DiagnoseInvalidRedeclaration
called ActOnFunctionDeclarator to check if a typo correction works when
the correction was just to the nested-name-specifier because the wrong
DeclContext was being passed in. Unlike a number of functions
surrounding typo correction, the DeclContext passed in for a function is
the context of the function name after applying any nested name
specifiers, not the lexical DeclContext where the
function+nested-name-specifier appears.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153962 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Sema/TypoCorrection.h | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 2 | ||||
-rw-r--r-- | test/FixIt/typo-crash.cpp | 4 |
4 files changed, 10 insertions, 22 deletions
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index a333c8182b..a8f6e1178b 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -205,7 +205,7 @@ class CorrectionCandidateCallback { : WantTypeSpecifiers(true), WantExpressionKeywords(true), WantCXXNamedCasts(true), WantRemainingKeywords(true), WantObjCSuper(false), - IsObjCIvarLookup(false), AllowAddedQualifier(true) {} + IsObjCIvarLookup(false) {} virtual ~CorrectionCandidateCallback() {} @@ -239,10 +239,6 @@ class CorrectionCandidateCallback { // Temporary hack for the one case where a CorrectTypoContext enum is used // when looking up results. bool IsObjCIvarLookup; - - /// \brief Whether to allow this typo correction to add a - /// nested-name-specifier. - bool AllowAddedQualifier; }; /// @brief Simple template class for restricting typo correction candidates diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cc75f3f4aa..12b9a63025 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4500,14 +4500,7 @@ namespace { class DifferentNameValidatorCCC : public CorrectionCandidateCallback { public: DifferentNameValidatorCCC(CXXRecordDecl *Parent) - : ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) { - // Don't allow any additional qualification. - // FIXME: It would be nice to perform this additional qualification. - // However, DiagnoseInvalidRedeclaration is unable to handle the - // qualification, because it doesn't know how to pass the corrected - // nested-name-specifier through to ActOnFunctionDeclarator. - AllowAddedQualifier = false; - } + : ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {} virtual bool ValidateCandidate(const TypoCorrection &candidate) { if (candidate.getEditDistance() == 0) @@ -4596,12 +4589,11 @@ static NamedDecl* DiagnoseInvalidRedeclaration( // TODO: Refactor ActOnFunctionDeclarator so that we can call only the // pieces need to verify the typo-corrected C++ declaraction and hopefully // eliminate the need for the parameter pack ExtraArgs. - Result = SemaRef.ActOnFunctionDeclarator(ExtraArgs.S, ExtraArgs.D, - NewFD->getDeclContext(), - NewFD->getTypeSourceInfo(), - Previous, - ExtraArgs.TemplateParamLists, - ExtraArgs.AddToScope); + Result = SemaRef.ActOnFunctionDeclarator( + ExtraArgs.S, ExtraArgs.D, + Correction.getCorrectionDecl()->getDeclContext(), + NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, + ExtraArgs.AddToScope); if (Trap.hasErrorOccurred()) { // Pretend the typo correction never occurred ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index a8d7b1e971..adbfedc641 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -3815,7 +3815,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, // Determine whether we are going to search in the various namespaces for // corrections. bool SearchNamespaces - = getLangOpts().CPlusPlus && CCC.AllowAddedQualifier && + = getLangOpts().CPlusPlus && (IsUnqualifiedLookup || (QualifiedDC && QualifiedDC->isNamespace())); if (IsUnqualifiedLookup || SearchNamespaces) { diff --git a/test/FixIt/typo-crash.cpp b/test/FixIt/typo-crash.cpp index 2e6f34a2a0..c154e3baba 100644 --- a/test/FixIt/typo-crash.cpp +++ b/test/FixIt/typo-crash.cpp @@ -19,11 +19,11 @@ namespace PR12297 { namespace B { typedef short T; - T global(); + T global(); // expected-note {{'A::B::global' declared here}} } } using namespace A::B; - T A::global(); // expected-error{{out-of-line definition of 'global' does not match any declaration in namespace 'PR12297::A'}} + T A::global(); // expected-error {{out-of-line definition of 'global' does not match any declaration in namespace 'PR12297::A'; did you mean 'A::B::global'?}} } |