From: Steve Naroff Date: Wed, 16 Jan 2008 15:01:34 +0000 (+0000) Subject: Sema::MergeFunctionDecl()...make sure diagnostic is accurate (wrt function declaratio... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=837618c0945e1f67ec1e39000c568a1fa857a5a9;p=clang Sema::MergeFunctionDecl()...make sure diagnostic is accurate (wrt function declarations/definitions). Patch by Carl Lewis! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46070 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index ddfde8f44d..9e6dbfe333 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -251,11 +251,16 @@ FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, ScopedDecl *OldD) { if (Context.functionTypesAreCompatible(OldQType, NewQType)) return New; + // A function that has already been declared has been redeclared or defined + // with a different type- show appropriate diagnostic + diag::kind PrevDiag = Old->getBody() ? diag::err_previous_definition : + diag::err_previous_declaration; + // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope. // TODO: This is totally simplistic. It should handle merging functions // together etc, merging extern int X; int X; ... - Diag(New->getLocation(), diag::err_redefinition, New->getName()); - Diag(Old->getLocation(), diag::err_previous_definition); + Diag(New->getLocation(), diag::err_conflicting_types, New->getName()); + Diag(Old->getLocation(), PrevDiag); return New; } diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index ea6da368cd..50815ec216 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -598,6 +598,8 @@ DIAG(err_redefinition, ERROR, "redefinition of '%0'") DIAG(err_redefinition_different_kind, ERROR, "redefinition of '%0' as different kind of symbol") +DIAG(err_conflicting_types, ERROR, + "conflicting types for '%0'") DIAG(err_nested_redefinition, ERROR, "nested redefinition of '%0'") DIAG(err_use_with_wrong_tag, ERROR, diff --git a/test/Sema/merge-decls.c b/test/Sema/merge-decls.c index 22026e7f25..50ce478769 100644 --- a/test/Sema/merge-decls.c +++ b/test/Sema/merge-decls.c @@ -3,9 +3,9 @@ void foo(void); void foo(void) {} void foo(void); -void foo(void); // expected-error{{previous definition is here}} +void foo(void); // expected-error{{previous declaration is here}} -void foo(int); // expected-error {{redefinition of 'foo'}} +void foo(int); // expected-error {{conflicting types for 'foo'}} int funcdef() { diff --git a/test/Sema/predefined-function.c b/test/Sema/predefined-function.c index d554b8faa8..1dcd1d38a2 100644 --- a/test/Sema/predefined-function.c +++ b/test/Sema/predefined-function.c @@ -4,13 +4,13 @@ char *funk(int format); enum Test {A=-1}; char *funk(enum Test x); -int eli(float b); // expected-error {{previous definition is here}} +int eli(float b); // expected-error {{previous declaration is here}} int b(int c) {return 1;} int foo(); int foo() { - int eli(int (int)); // expected-error {{redefinition of 'eli'}} + int eli(int (int)); // expected-error {{conflicting types for 'eli'}} eli(b); return 0; } @@ -20,19 +20,19 @@ int bar(int i) // expected-error {{previous definition is here}} { return 0; } -int bar() // expected-error {{redefinition of 'bar'}} +int bar() // expected-error {{redefinition of 'bar'}} expected-error {{conflicting types for 'bar'}} { return 0; } -int foobar(int); // expected-error {{previous definition is here}} -int foobar() // expected-error {{redefinition of 'foobar'}} +int foobar(int); // expected-error {{previous declaration is here}} +int foobar() // expected-error {{conflicting types for 'foobar'}} { return 0; } -int wibble(); // expected-error {{previous definition is here}} -float wibble() // expected-error {{redefinition of 'wibble'}} +int wibble(); // expected-error {{previous declaration is here}} +float wibble() // expected-error {{conflicting types for 'wibble'}} { return 0.0f; }