Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -1068,6 +1068,12 @@ /// same special member, we should act as if it is not yet declared. llvm::SmallSet SpecialMembersBeingDeclared; + /// The function definitions which were renamed as part of typo-correction + /// to match their respective declarations. We want to keep track of them + /// to ensure that we don't emit a "redefinition" error if we encounter a + /// correctly named definition after the renamed definition. + llvm::SmallPtrSet TypoCorrectedFunctionDefinitions; + void ReadMethodPool(Selector Sel); void updateOutOfDateSelector(Selector Sel); @@ -3117,6 +3123,8 @@ const PartialDiagnostic &PrevNote, bool ErrorRecovery = true); + void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F); + void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef Args, AssociatedNamespaceSet &AssociatedNamespaces, Index: cfe/trunk/lib/Sema/SemaDecl.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -7424,6 +7424,10 @@ } // end anonymous namespace +void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) { + TypoCorrectedFunctionDefinitions.insert(F); +} + /// \brief Generate diagnostics for an invalid function redeclaration. /// /// This routine handles generating the diagnostic messages for an invalid @@ -7521,6 +7525,8 @@ if ((*I)->getCanonicalDecl() == Canonical) Correction.setCorrectionDecl(*I); + // Let Sema know about the correction. + SemaRef.MarkTypoCorrectedFunctionDefinition(Result); SemaRef.diagnoseTypo( Correction, SemaRef.PDiag(IsLocalFriend @@ -11732,6 +11738,11 @@ if (canRedefineFunction(Definition, getLangOpts())) return; + // Don't emit an error when this is redifinition of a typo-corrected + // definition. + if (TypoCorrectedFunctionDefinitions.count(Definition)) + return; + // If we don't have a visible definition of the function, and it's inline or // a template, skip the new definition. if (SkipBody && !hasVisibleDefinition(Definition) && Index: cfe/trunk/test/SemaCXX/typo-correction.cpp =================================================================== --- cfe/trunk/test/SemaCXX/typo-correction.cpp +++ cfe/trunk/test/SemaCXX/typo-correction.cpp @@ -679,3 +679,30 @@ sizeof(c0is0)]; // expected-error {{use of undeclared identifier}} }; } + +namespace avoidRedundantRedefinitionErrors { +class Class { + void function(int pid); // expected-note {{'function' declared here}} +}; + +void Class::function2(int pid) { // expected-error {{out-of-line definition of 'function2' does not match any declaration in 'avoidRedundantRedefinitionErrors::Class'; did you mean 'function'?}} +} + +// Expected no redefinition error here. +void Class::function(int pid) { // expected-note {{previous definition is here}} +} + +void Class::function(int pid) { // expected-error {{redefinition of 'function'}} +} + +namespace ns { +void create_test(); // expected-note {{'create_test' declared here}} +} + +void ns::create_test2() { // expected-error {{out-of-line definition of 'create_test2' does not match any declaration in namespace 'avoidRedundantRedefinitionErrors::ns'; did you mean 'create_test'?}} +} + +// Expected no redefinition error here. +void ns::create_test() { +} +}