llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Aaron Ballman (AaronBallman) <details> <summary>Changes</summary> The previous text was "implicitly declaring library function 'exp' with type 'double (double)'" which helpfully mentioned the type. However, it was also confusing because an implicit function declaration in C89 was 'int()', so when we'd implicitly declare a library function that isn't present in the specified language mode, the type information was a bit confusing. The new message calls out the library functions which come from a particular standard (C, C++, or POSIX) to mention that the type selected is because the standard mandates that type. That makes it a little more clear why the type is not 'int()'. Fixes #<!-- -->146924 --- Full diff: https://github.com/llvm/llvm-project/pull/149314.diff 10 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/include/clang/Basic/Builtins.h (+27) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+5-4) - (modified) clang/lib/Sema/SemaDecl.cpp (+3-1) - (modified) clang/test/Analysis/exercise-ps.c (+1-1) - (modified) clang/test/Driver/implicit-function-as-error.c (+1-1) - (modified) clang/test/Sema/builtin-setjmp.c (+1-1) - (modified) clang/test/Sema/implicit-builtin-decl.c (+1-1) - (modified) clang/test/SemaObjC/builtin_objc_lib_functions.m (+7-7) - (modified) clang/test/SemaObjC/builtin_objc_nslog.m (+2-2) ``````````diff 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<ImplicitFunctionDeclare>; + "implicitly declaring library function '%0' with%select{| standards-mandated}2 " + "type %1">, InGroup<ImplicitFunctionDeclare>; 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<ImplicitFunctionDeclare>, 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 <string.h> 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 <stdio.h> 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 <stdio.h> 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 <setjmp.h> 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 <stdlib.h> 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 <objc/runtime.h> 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 <objc/runtime.h> 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 <objc/runtime.h> 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 <objc/message.h> 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 <objc/message.h> 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 <objc/objc-auto.h> 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 <objc/objc-exception.h> 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 <stdarg.h> 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 <Foundation/NSObjCRuntime.h> 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 <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}} } `````````` </details> https://github.com/llvm/llvm-project/pull/149314 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits