diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fcd3887ec7a09..dbbe1ce4b3d09 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -716,6 +716,10 @@ Improvements to Clang's diagnostics Added a new warning in this group for the case where the attribute is missing/implicit on an override of a virtual method. + - Reworded the ``-Wimplicit-function-declaration`` diagnostic to make it more + clear that the type selected for the implicit declaration is based on the + signature of a standard (C, C++, POSIX) library function. (#GH146924) + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 3a5e31de2bc50..4bb860e537b8a 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -376,6 +376,33 @@ class Context { return getInfo(ID).Header.getName(); } + /// Returns true if a library function is declared within a C or C++ standard + /// header (like stdio.h) or POSIX header (like malloc.h), false if the + /// function is not declared within a header or is declared in a non-standard + /// header (like Microsoft or Objective-C headers). + bool isDeclaredInStandardHeader(unsigned ID) const { + switch (getInfo(ID).Header.ID) { + default: + return false; + case HeaderDesc::COMPLEX_H: // C99 + case HeaderDesc::CTYPE_H: // C89 + case HeaderDesc::MATH_H: // C89 + case HeaderDesc::MALLOC_H: // POSIX + case HeaderDesc::MEMORY: // C++98 + case HeaderDesc::PTHREAD_H: // POSIX + case HeaderDesc::SETJMP_H: // C89 + case HeaderDesc::STDARG_H: // C89 + case HeaderDesc::STDIO_H: // C89 + case HeaderDesc::STDLIB_H: // C89 + case HeaderDesc::STRING_H: // C89 + case HeaderDesc::STRINGS_H: // POSIX + case HeaderDesc::UNISTD_H: // POSIX + case HeaderDesc::UTILITY: // C++98 + case HeaderDesc::WCHAR_H: // C99 + return true; + } + } + /// Determine whether this builtin is like printf in its /// formatting rules and, if so, set the index to the format string /// argument and whether this function as a va_list argument. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b2ea65ae111be..abb916a66984c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -816,11 +816,12 @@ def warn_unreachable_association : Warning< /// Built-in functions. def ext_implicit_lib_function_decl : ExtWarn< - "implicitly declaring library function '%0' with type %1">, - InGroup; + "implicitly declaring library function '%0' with%select{| standards-mandated}2 " + "type %1">, InGroup; def ext_implicit_lib_function_decl_c99 : ExtWarn< - "call to undeclared library function '%0' with type %1; ISO C99 and later " - "do not support implicit function declarations">, + "call to undeclared library function '%0', will assume it exists with" + "%select{| standards-mandated}2 type %1; ISO C99 and later do not support " + "implicit function declarations">, InGroup, DefaultError; def note_include_header_or_declare : Note< "include the header <%0> or explicitly provide a declaration for '%1'">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 14403e65e8f42..8824ce69c17cc 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2380,9 +2380,11 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, if (!ForRedeclaration && (Context.BuiltinInfo.isPredefinedLibFunction(ID) || Context.BuiltinInfo.isHeaderDependentFunction(ID))) { + bool IsStandardsMandated = + Context.BuiltinInfo.isDeclaredInStandardHeader(ID); Diag(Loc, LangOpts.C99 ? diag::ext_implicit_lib_function_decl_c99 : diag::ext_implicit_lib_function_decl) - << Context.BuiltinInfo.getName(ID) << R; + << Context.BuiltinInfo.getName(ID) << R << IsStandardsMandated; if (const char *Header = Context.BuiltinInfo.getHeaderName(ID)) Diag(Loc, diag::note_include_header_or_declare) << Header << Context.BuiltinInfo.getName(ID); diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index 21d97a364e190..2de884b56ca7f 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -22,7 +22,7 @@ void_typedef f2_helper(void); static void f2(void *buf) { F12_typedef* x; x = f2_helper(); - memcpy((&x[1]), (buf), 1); // expected-warning{{call to undeclared library function 'memcpy' with type 'void *(void *, const void *}} \ + memcpy((&x[1]), (buf), 1); // expected-warning{{call to undeclared library function 'memcpy', will assume it exists with standards-mandated type 'void *(void *, const void *,}} \ // expected-note{{include the header or explicitly provide a declaration for 'memcpy'}} } diff --git a/clang/test/Driver/implicit-function-as-error.c b/clang/test/Driver/implicit-function-as-error.c index a7f815c8ed69b..f2db881a3eb2e 100644 --- a/clang/test/Driver/implicit-function-as-error.c +++ b/clang/test/Driver/implicit-function-as-error.c @@ -6,6 +6,6 @@ // to an error. void radar_10894044(void) { - printf("Hi\n"); // expected-error {{call to undeclared library function 'printf' with type 'int (const char *, ...)'}} expected-note {{include the header or explicitly provide a declaration for 'printf'}} + printf("Hi\n"); // expected-error {{call to undeclared library function 'printf', will assume it exists with standards-mandated type 'int (const char *, ...)'; ISO C99 and later do not support implicit function declarations}} expected-note {{include the header or explicitly provide a declaration for 'printf'}} radar_10894044_not_declared(); // expected-error {{call to undeclared function 'radar_10894044_not_declared'; ISO C99 and later do not support implicit function declarations}} } diff --git a/clang/test/Sema/builtin-setjmp.c b/clang/test/Sema/builtin-setjmp.c index a71f87162612d..61ebf8012cdba 100644 --- a/clang/test/Sema/builtin-setjmp.c +++ b/clang/test/Sema/builtin-setjmp.c @@ -38,7 +38,7 @@ void use(void) { // c-error@-3 {{call to undeclared function 'setjmp'; ISO C99 and later do not support implicit function declarations}} #elif ONLY_JMP_BUF // cxx-error@-5 {{undeclared identifier 'setjmp'}} - // c-error@-6 {{call to undeclared library function 'setjmp' with type 'int (jmp_buf)' (aka 'int (int *)'); ISO C99 and later do not support implicit function declarations}} + // c-error@-6 {{call to undeclared library function 'setjmp', will assume it exists with standards-mandated type 'int (jmp_buf)' (aka 'int (int *)'); ISO C99 and later do not support implicit function declarations}} // c-note@-7 {{include the header or explicitly provide a declaration for 'setjmp'}} #else // cxx-no-diagnostics diff --git a/clang/test/Sema/implicit-builtin-decl.c b/clang/test/Sema/implicit-builtin-decl.c index 055ba7e70eb12..a36263a27d14c 100644 --- a/clang/test/Sema/implicit-builtin-decl.c +++ b/clang/test/Sema/implicit-builtin-decl.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -Wno-strict-prototypes -verify %s void f() { - int *ptr = malloc(sizeof(int) * 10); // expected-error{{call to undeclared library function 'malloc' with type}} \ + int *ptr = malloc(sizeof(int) * 10); // expected-error{{call to undeclared library function 'malloc'}} \ // expected-note{{include the header or explicitly provide a declaration for 'malloc'}} \ // expected-note{{'malloc' is a builtin with type 'void *}} } diff --git a/clang/test/SemaObjC/builtin_objc_lib_functions.m b/clang/test/SemaObjC/builtin_objc_lib_functions.m index a98abdf6039cb..449ae5edfb34e 100644 --- a/clang/test/SemaObjC/builtin_objc_lib_functions.m +++ b/clang/test/SemaObjC/builtin_objc_lib_functions.m @@ -1,27 +1,27 @@ // RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify -Class f0(void) { return objc_getClass("a"); } // expected-error {{call to undeclared library function 'objc_getClass' with type 'id (const char *)'}} \ +Class f0(void) { return objc_getClass("a"); } // expected-error {{call to undeclared library function 'objc_getClass', will assume it exists with type 'id (const char *)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_getClass'}} -Class f1(void) { return objc_getMetaClass("a"); } // expected-error {{call to undeclared library function 'objc_getMetaClass' with type 'id (const char *)'}} \ +Class f1(void) { return objc_getMetaClass("a"); } // expected-error {{call to undeclared library function 'objc_getMetaClass', will assume it exists with type 'id (const char *)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_getMetaClass'}} -void f2(id val) { objc_enumerationMutation(val); } // expected-error {{call to undeclared library function 'objc_enumerationMutation' with type 'void (id)'}} \ +void f2(id val) { objc_enumerationMutation(val); } // expected-error {{call to undeclared library function 'objc_enumerationMutation', will assume it exists with type 'void (id)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_enumerationMutation'}} -long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expected-error {{call to undeclared library function 'objc_msgSend_fpret' with type 'long double (id, SEL, ...)'}} \ +long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expected-error {{call to undeclared library function 'objc_msgSend_fpret', will assume it exists with type 'long double (id, SEL, ...)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_msgSend_fpret'}} id f4(struct objc_super *super, SEL op) { // expected-warning {{declaration of 'struct objc_super' will not be visible outside of this function}} - return objc_msgSendSuper(super, op); // expected-error {{call to undeclared library function 'objc_msgSendSuper' with type 'id (struct objc_super *, SEL, ...)'}} \ + return objc_msgSendSuper(super, op); // expected-error {{call to undeclared library function 'objc_msgSendSuper', will assume it exists with type 'id (struct objc_super *, SEL, ...)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_msgSendSuper'}} } id f5(id val, id *dest) { - return objc_assign_strongCast(val, dest); // expected-error {{call to undeclared library function 'objc_assign_strongCast' with type 'id (id, id *)'}} \ + return objc_assign_strongCast(val, dest); // expected-error {{call to undeclared library function 'objc_assign_strongCast', will assume it exists with type 'id (id, id *)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_assign_strongCast'}} } int f6(Class exceptionClass, id exception) { - return objc_exception_match(exceptionClass, exception); // expected-error {{call to undeclared library function 'objc_exception_match' with type 'int (id, id)'}} \ + return objc_exception_match(exceptionClass, exception); // expected-error {{call to undeclared library function 'objc_exception_match', will assume it exists with type 'int (id, id)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'objc_exception_match'}} } diff --git a/clang/test/SemaObjC/builtin_objc_nslog.m b/clang/test/SemaObjC/builtin_objc_nslog.m index 3c35a02d9b8a3..855d861516f72 100644 --- a/clang/test/SemaObjC/builtin_objc_nslog.m +++ b/clang/test/SemaObjC/builtin_objc_nslog.m @@ -3,11 +3,11 @@ #include void f1(id arg) { - NSLog(@"%@", arg); // expected-error {{call to undeclared library function 'NSLog' with type 'void (id, ...)'}} \ + NSLog(@"%@", arg); // expected-error {{call to undeclared library function 'NSLog', will assume it exists with type 'void (id, ...)'; ISO C99 and later do not support implicit function declaration}} \ // expected-note {{include the header or explicitly provide a declaration for 'NSLog'}} } void f2(id str, va_list args) { - NSLogv(@"%@", args); // expected-error {{call to undeclared library function 'NSLogv' with type }} \ + NSLogv(@"%@", args); // expected-error {{call to undeclared library function 'NSLogv', will assume it exists with type 'void (id, __builtin_va_list)'; ISO C99 and later do not support implicit function declarations}} \ // expected-note {{include the header or explicitly provide a declaration for 'NSLogv'}} }