From e7228062b2bb87abf762abcb77668452a1ed35d4 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 13 Jan 2021 17:22:45 -0800 Subject: [PATCH] [libc] Use #undef isascii in specific header Standard C allows all standard headers to declare macros for all their functions. So after possibly including any standard header like , it's perfectly normal for any and all of the functions it declares to be defined as macros. Standard C requires explicit `#undef` before using that identifier in a way that is not compatible with function-like macro definitions. The C standard's rules for this are extended to POSIX as well for the interfaces it defines, and it's the expected norm for nonstandard extensions declared by standard C library headers too. So far the only place this has come up for llvm-libc's code is with the isascii function in Fuchsia's libc. But other cases can arise for any standard (or common extension) function names that source code in llvm-libc is using in nonstandard ways, i.e. as C++ identifiers. The only correct and robust way to handle the possible inclusion of standard C library headers when building llvm-libc source code is to use `#undef` explicitly for each identifier before using it. The easy and obvious place to do that is in the per-function header. This requires that all code, such as test code, that might include any standard C library headers, e.g. via utils/UnitTest/Test.h, make sure to include those *first* before the per-function header. This change does that for isascii and its test. But it should be done uniformly for all the code and documented as a consistent convention so new implementation files are sure to get this right. Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D94642 --- libc/src/ctype/isascii.h | 2 ++ libc/test/src/ctype/isascii_test.cpp | 4 ++-- libc/utils/UnitTest/FuchsiaTest.h | 6 ------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libc/src/ctype/isascii.h b/libc/src/ctype/isascii.h index 8ec304489b37..7e31b3c6ca4d 100644 --- a/libc/src/ctype/isascii.h +++ b/libc/src/ctype/isascii.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_SRC_CTYPE_ISASCII_H #define LLVM_LIBC_SRC_CTYPE_ISASCII_H +#undef isascii + namespace __llvm_libc { int isascii(int c); diff --git a/libc/test/src/ctype/isascii_test.cpp b/libc/test/src/ctype/isascii_test.cpp index b5f66d7aef57..e0a15a0a5a29 100644 --- a/libc/test/src/ctype/isascii_test.cpp +++ b/libc/test/src/ctype/isascii_test.cpp @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "src/ctype/isascii.h" - #include "utils/UnitTest/Test.h" +#include "src/ctype/isascii.h" + TEST(IsAscii, DefaultLocale) { // Loops through all characters, verifying that ascii characters // (which are all 7 bit unsigned integers) diff --git a/libc/utils/UnitTest/FuchsiaTest.h b/libc/utils/UnitTest/FuchsiaTest.h index 0a19a986fb5a..b7b5b48538b8 100644 --- a/libc/utils/UnitTest/FuchsiaTest.h +++ b/libc/utils/UnitTest/FuchsiaTest.h @@ -10,11 +10,5 @@ #define LLVM_LIBC_UTILS_UNITTEST_FUCHSIATEST_H #include -// isascii is being undef'd because Fuchsia's headers define a macro for -// isascii. that macro causes errors when isascii_test.cpp references -// __llvm_libc::isascii since the macro is applied first. -#ifdef isascii -#undef isascii -#endif #endif // LLVM_LIBC_UTILS_UNITTEST_FUCHSIATEST_H