Skip to content

Commit b174a3d

Browse files
author
arphaman
committed
[Sema] Avoid an invalid redefinition error that was presented for
of a function whose previous definition was typo-corrected rdar://28550928 Differential Revision: https://reviews.llvm.org/D25113 git-svn-id: http://llvm.org/svn/llvm-project/cfe/trunk@301643 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 55b9024 commit b174a3d

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

include/clang/Sema/Sema.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,12 @@ class Sema {
10681068
/// same special member, we should act as if it is not yet declared.
10691069
llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
10701070

1071+
/// The function definitions which were renamed as part of typo-correction
1072+
/// to match their respective declarations. We want to keep track of them
1073+
/// to ensure that we don't emit a "redefinition" error if we encounter a
1074+
/// correctly named definition after the renamed definition.
1075+
llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions;
1076+
10711077
void ReadMethodPool(Selector Sel);
10721078
void updateOutOfDateSelector(Selector Sel);
10731079

@@ -3117,6 +3123,8 @@ class Sema {
31173123
const PartialDiagnostic &PrevNote,
31183124
bool ErrorRecovery = true);
31193125

3126+
void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F);
3127+
31203128
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
31213129
ArrayRef<Expr *> Args,
31223130
AssociatedNamespaceSet &AssociatedNamespaces,

lib/Sema/SemaDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7424,6 +7424,10 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
74247424

74257425
} // end anonymous namespace
74267426

7427+
void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) {
7428+
TypoCorrectedFunctionDefinitions.insert(F);
7429+
}
7430+
74277431
/// \brief Generate diagnostics for an invalid function redeclaration.
74287432
///
74297433
/// This routine handles generating the diagnostic messages for an invalid
@@ -7521,6 +7525,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
75217525
if ((*I)->getCanonicalDecl() == Canonical)
75227526
Correction.setCorrectionDecl(*I);
75237527

7528+
// Let Sema know about the correction.
7529+
SemaRef.MarkTypoCorrectedFunctionDefinition(Result);
75247530
SemaRef.diagnoseTypo(
75257531
Correction,
75267532
SemaRef.PDiag(IsLocalFriend
@@ -11732,6 +11738,11 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
1173211738
if (canRedefineFunction(Definition, getLangOpts()))
1173311739
return;
1173411740

11741+
// Don't emit an error when this is redifinition of a typo-corrected
11742+
// definition.
11743+
if (TypoCorrectedFunctionDefinitions.count(Definition))
11744+
return;
11745+
1173511746
// If we don't have a visible definition of the function, and it's inline or
1173611747
// a template, skip the new definition.
1173711748
if (SkipBody && !hasVisibleDefinition(Definition) &&

test/SemaCXX/typo-correction.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,3 +679,30 @@ int g() {
679679
sizeof(c0is0)]; // expected-error {{use of undeclared identifier}}
680680
};
681681
}
682+
683+
namespace avoidRedundantRedefinitionErrors {
684+
class Class {
685+
void function(int pid); // expected-note {{'function' declared here}}
686+
};
687+
688+
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'?}}
689+
}
690+
691+
// Expected no redefinition error here.
692+
void Class::function(int pid) { // expected-note {{previous definition is here}}
693+
}
694+
695+
void Class::function(int pid) { // expected-error {{redefinition of 'function'}}
696+
}
697+
698+
namespace ns {
699+
void create_test(); // expected-note {{'create_test' declared here}}
700+
}
701+
702+
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'?}}
703+
}
704+
705+
// Expected no redefinition error here.
706+
void ns::create_test() {
707+
}
708+
}

0 commit comments

Comments
 (0)