diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9865e1d0a3eb..699c3db7b835 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -98,7 +98,7 @@ def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; def err_implicit_decl_requires_stdio : Error< "implicit declaration of '%0' requires inclusion of the header ">; def warn_redecl_library_builtin : Warning< - "incompatible redeclaration of library function %0 will be ignored">; + "incompatible redeclaration of library function %0">; def err_builtin_definition : Error<"definition of builtin function %0">; /// parser diagnostics diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 89375d7066e7..bcb21c33ce9b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -747,11 +747,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) { // The function the user is redeclaring is a library-defined // function like 'malloc' or 'printf'. Warn about the - // redeclaration, then ignore it. + // redeclaration, then pretend that we don't know about this + // library built-in. Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New; Diag(Old->getLocation(), diag::note_previous_builtin_declaration) << Old << Old->getType(); - return true; + New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); + Old->setInvalidDecl(); + return false; } PrevDiag = diag::note_previous_builtin_declaration; diff --git a/clang/test/Sema/implicit-builtin-decl.c b/clang/test/Sema/implicit-builtin-decl.c index e1f24e35f3b2..6477a5723ffa 100644 --- a/clang/test/Sema/implicit-builtin-decl.c +++ b/clang/test/Sema/implicit-builtin-decl.c @@ -7,7 +7,7 @@ void f() { void *alloca(__SIZE_TYPE__); // redeclaration okay -int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-warning{{incompatible redeclaration of library function 'calloc' will be ignored}} \ +int *calloc(__SIZE_TYPE__, __SIZE_TYPE__); // expected-warning{{incompatible redeclaration of library function 'calloc'}} \ // expected-note{{'calloc' is a builtin with type 'void *}} @@ -16,8 +16,8 @@ void g(int malloc) { // okay: these aren't functions } void h() { - int malloc(int); // expected-warning{{incompatible redeclaration of library function 'malloc' will be ignored}} - int strcpy(int); // expected-warning{{incompatible redeclaration of library function 'strcpy' will be ignored}} \ + int malloc(int); // expected-warning{{incompatible redeclaration of library function 'malloc'}} + int strcpy(int); // expected-warning{{incompatible redeclaration of library function 'strcpy'}} \ // expected-note{{'strcpy' is a builtin with type 'char *(char *, char const *)'}} } @@ -35,7 +35,19 @@ int f0() { return __builtin_object_size(&a); // expected-error {{too few arguments to function}} } -void * realloc(void *p, int size) { // expected-warning{{incompatible redeclaration of library function 'realloc' will be ignored}} \ +void * realloc(void *p, int size) { // expected-warning{{incompatible redeclaration of library function 'realloc'}} \ // expected-note{{'realloc' is a builtin with type 'void *(void *,}} return p; } + +// PR3855 +void snprintf(); // expected-warning{{incompatible redeclaration of library function 'snprintf'}} \ + // expected-note{{'snprintf' is a builtin with type 'int (char *, unsigned long, char const *, ...)'}} + +int +main(int argc, char *argv[]) +{ + snprintf(); +} + +void snprintf() { } diff --git a/clang/test/Sema/implicit-builtin-redecl.c b/clang/test/Sema/implicit-builtin-redecl.c index c9b38558b3e2..2ad35185b252 100644 --- a/clang/test/Sema/implicit-builtin-redecl.c +++ b/clang/test/Sema/implicit-builtin-redecl.c @@ -10,5 +10,5 @@ void *calloc(int, int, int); // expected-warning{{incompatible redeclaration of // expected-note{{'calloc' is a builtin with type 'void *}} void f1(void) { - return calloc(0, 0, 0); // expected-error{{too many arguments to function call}} + calloc(0, 0, 0); }