diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-22 00:40:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-22 00:40:25 +0000 |
commit | d84aac17180075e0ede53d7762b73d3bd079b52f (patch) | |
tree | e075e1f085260a5469d9a42c58165a674ff570f8 | |
parent | ce056bcaa1c97b89a4b2de2112c62d060863be2b (diff) |
Add 'previous declaration is here' note for param redefinition
errors, e.g.:
t.c:1:21: error: redefinition of parameter 'x'
int test(int x, int x);
^
t.c:1:14: note: previous declaration is here
int test(int x, int x);
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96769 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | test/Sema/arg-duplicate.c | 3 | ||||
-rw-r--r-- | test/Sema/block-args.c | 3 | ||||
-rw-r--r-- | test/SemaCXX/default2.cpp | 3 |
5 files changed, 9 insertions, 8 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 682f20348d..7c75f2fc7b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -492,8 +492,7 @@ def err_implicit_object_parameter_init : Error< def note_field_decl : Note<"member is declared here">; def note_bitfield_decl : Note<"bit-field is declared here">; -def note_previous_decl : Note< - "%0 declared here">; +def note_previous_decl : Note<"%0 declared here">; def note_member_synthesized_at : Note< "implicit default %select{constructor|copy constructor|" "copy assignment operator|destructor}0 for %1 first required here">; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2a9885c6a3..c59e8bad66 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3878,9 +3878,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { << Context.getTypeDeclType(OwnedDecl); } - // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope. - // Can this happen for params? We already checked that they don't conflict - // among each other. Here they can only shadow globals, which is ok. + // Check for redeclaration of parameters, e.g. int foo(int x, int x); IdentifierInfo *II = D.getIdentifier(); if (II) { if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) { @@ -3891,6 +3889,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { PrevDecl = 0; } else if (S->isDeclScope(DeclPtrTy::make(PrevDecl))) { Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II; + Diag(PrevDecl->getLocation(), diag::note_previous_declaration); // Recover by removing the name II = 0; diff --git a/test/Sema/arg-duplicate.c b/test/Sema/arg-duplicate.c index ca091eb309..feeb458a3f 100644 --- a/test/Sema/arg-duplicate.c +++ b/test/Sema/arg-duplicate.c @@ -2,7 +2,8 @@ int f3(y, x, x) // expected-error {{redefinition of parameter}} - int y, x, + int y, + x, // expected-note {{previous declaration is here}} x; // expected-error {{redefinition of parameter}} { return x + y; diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c index a07c82e75a..970c60d51d 100644 --- a/test/Sema/block-args.c +++ b/test/Sema/block-args.c @@ -6,7 +6,8 @@ void test() { take(^(int x){}); take(^(int x, int y){}); take(^(int x, int y){}); - take(^(int x, int x){}); // expected-error {{redefinition of parameter 'x'}} + take(^(int x, // expected-note {{previous declaration is here}} + int x){}); // expected-error {{redefinition of parameter 'x'}} take(^(int x) { return x+1; }); diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index d2c44bd998..e674260680 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -16,7 +16,8 @@ void i() } -int f1(int i, int i, int j) { // expected-error {{redefinition of parameter 'i'}} +int f1(int i, // expected-note {{previous declaration is here}} + int i, int j) { // expected-error {{redefinition of parameter 'i'}} i = 17; return j; } |