-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Improve clarity of the implicit declaration diagnostic #149314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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 llvm#146924
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) ChangesThe previous text was "implicitly declaring library function 'exp' with The new message calls out the library functions which come from a Fixes #146924 Full diff: https://github.com/llvm/llvm-project/pull/149314.diff 10 Files Affected:
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'}}
}
|
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Aaron Ballman (AaronBallman) ChangesThe previous text was "implicitly declaring library function 'exp' with The new message calls out the library functions which come from a Fixes #146924 Full diff: https://github.com/llvm/llvm-project/pull/149314.diff 10 Files Affected:
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'}}
}
|
@@ -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 *,}} \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, there's another type in the parameter list, but it's size_t which resolves to different types on different systems, so it's dropped here for the same reason it was dropped before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target tripple is pinned in the test. We could spell it out if we wanted.
But it's also fine if we rtrim it after ... 'memcpy'
.
No action expected here. I just left this if you find this useful.
@@ -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'}} \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing happening here as above.
- 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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you double check this is aligned as it should?
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; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we modify the HEADER macro in BuiltinHeaders.def to generate that automatically?
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A way to simplify (ie, get rid of isDeclaredInStandardHeader
)
would be to say " will assume it exists with type %1 as if header <%2>" had been included"
(where %2 is Context.BuiltinInfo.getName(ID)
)
WDYT?
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