From 934eefd4f067514eb08294d65a51f844e42b76d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 3 Oct 2025 12:59:21 +0300 Subject: [PATCH 1/2] [clang] [test] Verify that intrinsic headers don't use unreserved names This mirrors a similar test that libcxx does, to make sure that the libcxx headers don't use any unreserved symbols. The header for polluting with defines is based very far on the libcxx one; some parts of it could possibly be omitted, but I included most of it for completeness here. --- clang/test/Headers/arm-acle-header.c | 2 + clang/test/Headers/arm-cde-header.c | 2 + clang/test/Headers/arm-cmse-header.c | 2 + clang/test/Headers/arm-fp16-header.c | 2 + clang/test/Headers/arm-neon-header.c | 2 + clang/test/Headers/system_reserved_names.h | 161 ++++++++++++++++++ .../Headers/x86-intrinsics-headers-clean.cpp | 2 + clang/test/Headers/x86-intrinsics-headers.c | 2 + 8 files changed, 175 insertions(+) create mode 100644 clang/test/Headers/system_reserved_names.h diff --git a/clang/test/Headers/arm-acle-header.c b/clang/test/Headers/arm-acle-header.c index fea8472183c87..58fcc6648bdec 100644 --- a/clang/test/Headers/arm-acle-header.c +++ b/clang/test/Headers/arm-acle-header.c @@ -10,6 +10,8 @@ // RUN: %clang_cc1 -x c++ -triple arm64ec-windows -target-cpu cortex-a53 -fsyntax-only -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=19.11 %s // expected-no-diagnostics +#include "system_reserved_names.h" + #include #ifdef _MSC_VER #include diff --git a/clang/test/Headers/arm-cde-header.c b/clang/test/Headers/arm-cde-header.c index 1f60368ee9033..526202ab4f280 100644 --- a/clang/test/Headers/arm-cde-header.c +++ b/clang/test/Headers/arm-cde-header.c @@ -9,5 +9,7 @@ // Check that the headers don't conflict with each other +#include "system_reserved_names.h" + #include #include diff --git a/clang/test/Headers/arm-cmse-header.c b/clang/test/Headers/arm-cmse-header.c index 862572d8adcd9..c21c1ff595b4f 100644 --- a/clang/test/Headers/arm-cmse-header.c +++ b/clang/test/Headers/arm-cmse-header.c @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -triple thumbv8m.base-eabi -fsyntax-only -ffreestanding -x c++ %s -verify -mcmse // expected-no-diagnostics +#include "system_reserved_names.h" + #include typedef void (*callback_t)(void); diff --git a/clang/test/Headers/arm-fp16-header.c b/clang/test/Headers/arm-fp16-header.c index b1a87faebfe0b..e472654af24bd 100644 --- a/clang/test/Headers/arm-fp16-header.c +++ b/clang/test/Headers/arm-fp16-header.c @@ -18,4 +18,6 @@ // REQUIRES: aarch64-registered-target || arm-registered-target +#include "system_reserved_names.h" + #include diff --git a/clang/test/Headers/arm-neon-header.c b/clang/test/Headers/arm-neon-header.c index 89bd5aaa25420..43b1b355d99f4 100644 --- a/clang/test/Headers/arm-neon-header.c +++ b/clang/test/Headers/arm-neon-header.c @@ -26,4 +26,6 @@ // REQUIRES: aarch64-registered-target || arm-registered-target +#include "system_reserved_names.h" + #include diff --git a/clang/test/Headers/system_reserved_names.h b/clang/test/Headers/system_reserved_names.h new file mode 100644 index 0000000000000..2783b2e5e4ae8 --- /dev/null +++ b/clang/test/Headers/system_reserved_names.h @@ -0,0 +1,161 @@ +// Test that headers are not tripped up by the surrounding code defining various +// alphabetic macros. Also ensure that we don't swallow the definition of user +// provided macros (in other words, ensure that we push/pop correctly everywhere). + +#define SYSTEM_RESERVED_NAME This name should not be used in Clang headers + +// libc++ does not use single-letter names as a matter of principle. +// But Windows' own , , and use many of these +// (at least C,E,F,I,M,N,P,S,X,Y,Z) as uglified function parameter names, +// so don't define these on Windows. +// +#ifndef _WIN32 +#define _A SYSTEM_RESERVED_NAME +#define _B SYSTEM_RESERVED_NAME +#define _C SYSTEM_RESERVED_NAME +#define _D SYSTEM_RESERVED_NAME +#define _E SYSTEM_RESERVED_NAME +#define _F SYSTEM_RESERVED_NAME +#define _G SYSTEM_RESERVED_NAME +#define _H SYSTEM_RESERVED_NAME +#define _I SYSTEM_RESERVED_NAME +#define _J SYSTEM_RESERVED_NAME +#define _K SYSTEM_RESERVED_NAME +#define _L SYSTEM_RESERVED_NAME +#define _M SYSTEM_RESERVED_NAME +#define _N SYSTEM_RESERVED_NAME +#define _O SYSTEM_RESERVED_NAME +#define _P SYSTEM_RESERVED_NAME +#define _Q SYSTEM_RESERVED_NAME +#define _R SYSTEM_RESERVED_NAME +#define _S SYSTEM_RESERVED_NAME +#define _T SYSTEM_RESERVED_NAME +#define _U SYSTEM_RESERVED_NAME +#define _V SYSTEM_RESERVED_NAME +#define _W SYSTEM_RESERVED_NAME +#define _X SYSTEM_RESERVED_NAME +#define _Y SYSTEM_RESERVED_NAME +#define _Z SYSTEM_RESERVED_NAME +#endif + +// FreeBSD's uses _M +// +#ifdef __FreeBSD__ +# undef _M +#endif + +// Test that libc++ doesn't use names that collide with FreeBSD system macros. +// newlib and picolibc also define these macros +#if !defined(__FreeBSD__) && !defined(_NEWLIB_VERSION) +# define __null_sentinel SYSTEM_RESERVED_NAME +# define __generic SYSTEM_RESERVED_NAME +#endif + +// tchar.h defines these macros on Windows +#ifndef _WIN32 +# define _UI SYSTEM_RESERVED_NAME +# define _PUC SYSTEM_RESERVED_NAME +# define _CPUC SYSTEM_RESERVED_NAME +# define _PC SYSTEM_RESERVED_NAME +# define _CRPC SYSTEM_RESERVED_NAME +# define _CPC SYSTEM_RESERVED_NAME +#endif + +// yvals.h on MINGW defines this macro +#ifndef _WIN32 +# define _C2 SYSTEM_RESERVED_NAME +#endif + +// Test that libc++ doesn't use names that collide with Win32 API macros. +// Obviously we can only define these on non-Windows platforms. +#ifndef _WIN32 +# define __allocator SYSTEM_RESERVED_NAME +# define __bound SYSTEM_RESERVED_NAME +# define __deallocate SYSTEM_RESERVED_NAME +# define __deref SYSTEM_RESERVED_NAME +# define __format_string SYSTEM_RESERVED_NAME +# define __full SYSTEM_RESERVED_NAME +# define __in SYSTEM_RESERVED_NAME +# define __inout SYSTEM_RESERVED_NAME +# define __nz SYSTEM_RESERVED_NAME +# define __out SYSTEM_RESERVED_NAME +# define __part SYSTEM_RESERVED_NAME +# define __post SYSTEM_RESERVED_NAME +# define __pre SYSTEM_RESERVED_NAME +#endif + +// Newlib & picolibc use __input as a parameter name of a64l & l64a +#ifndef _NEWLIB_VERSION +# define __input SYSTEM_RESERVED_NAME +#endif +#define __output SYSTEM_RESERVED_NAME + +#define __acquire SYSTEM_RESERVED_NAME +#define __release SYSTEM_RESERVED_NAME + +// Android and FreeBSD use this for __attribute__((__unused__)) +#if !defined(__FreeBSD__) && !defined(__ANDROID__) +#define __unused SYSTEM_RESERVED_NAME +#endif + +// These names are not reserved, so the user can macro-define them. +// These are intended to find improperly _Uglified template parameters. +#define A SYSTEM_RESERVED_NAME +#define Arg SYSTEM_RESERVED_NAME +#define Args SYSTEM_RESERVED_NAME +#define As SYSTEM_RESERVED_NAME +#define B SYSTEM_RESERVED_NAME +#define Bs SYSTEM_RESERVED_NAME +#define C SYSTEM_RESERVED_NAME +#define Cp SYSTEM_RESERVED_NAME +#define Cs SYSTEM_RESERVED_NAME +// Windows setjmp.h contains a struct member named 'D' on ARM/AArch64. +#ifndef _WIN32 +# define D SYSTEM_RESERVED_NAME +#endif +#define Dp SYSTEM_RESERVED_NAME +#define Ds SYSTEM_RESERVED_NAME +#define E SYSTEM_RESERVED_NAME +#define Ep SYSTEM_RESERVED_NAME +#define Es SYSTEM_RESERVED_NAME +#define N SYSTEM_RESERVED_NAME +#define Np SYSTEM_RESERVED_NAME +#define Ns SYSTEM_RESERVED_NAME +#define R SYSTEM_RESERVED_NAME +#define Rp SYSTEM_RESERVED_NAME +#define Rs SYSTEM_RESERVED_NAME +#define T SYSTEM_RESERVED_NAME +#define Tp SYSTEM_RESERVED_NAME +#define Ts SYSTEM_RESERVED_NAME +#define Type SYSTEM_RESERVED_NAME +#define Types SYSTEM_RESERVED_NAME +#define U SYSTEM_RESERVED_NAME +#define Up SYSTEM_RESERVED_NAME +#define Us SYSTEM_RESERVED_NAME +#define V SYSTEM_RESERVED_NAME +#define Vp SYSTEM_RESERVED_NAME +#define Vs SYSTEM_RESERVED_NAME +#define X SYSTEM_RESERVED_NAME +#define Xp SYSTEM_RESERVED_NAME +#define Xs SYSTEM_RESERVED_NAME + +// The classic Windows min/max macros +#define min SYSTEM_RESERVED_NAME +#define max SYSTEM_RESERVED_NAME + +// Test to make sure curses has no conflicting macros with the standard library +#define move SYSTEM_RESERVED_NAME +#define erase SYSTEM_RESERVED_NAME +#define refresh SYSTEM_RESERVED_NAME + +// Dinkumware libc ctype.h uses these definitions +#define _XA SYSTEM_RESERVED_NAME +#define _XS SYSTEM_RESERVED_NAME +#define _BB SYSTEM_RESERVED_NAME +#define _CN SYSTEM_RESERVED_NAME +#define _DI SYSTEM_RESERVED_NAME +#define _LO SYSTEM_RESERVED_NAME +#define _PU SYSTEM_RESERVED_NAME +#define _SP SYSTEM_RESERVED_NAME +#define _UP SYSTEM_RESERVED_NAME +#define _XD SYSTEM_RESERVED_NAME diff --git a/clang/test/Headers/x86-intrinsics-headers-clean.cpp b/clang/test/Headers/x86-intrinsics-headers-clean.cpp index a19207f34ead8..0a04bcebfaece 100644 --- a/clang/test/Headers/x86-intrinsics-headers-clean.cpp +++ b/clang/test/Headers/x86-intrinsics-headers-clean.cpp @@ -10,4 +10,6 @@ // expected-no-diagnostics +#include "system_reserved_names.h" + #include diff --git a/clang/test/Headers/x86-intrinsics-headers.c b/clang/test/Headers/x86-intrinsics-headers.c index dc06cbde0f587..89a7d4dc21508 100644 --- a/clang/test/Headers/x86-intrinsics-headers.c +++ b/clang/test/Headers/x86-intrinsics-headers.c @@ -5,6 +5,8 @@ // XFAIL: target=arm64ec-pc-windows-msvc // These intrinsics are not yet implemented for Arm64EC. +#include "system_reserved_names.h" + #if defined(i386) || defined(__x86_64__) #ifdef __SSE4_2__ From 80a68510ea3daf91fa103dc4f992dbe1f0b2b97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 3 Oct 2025 22:45:28 +0300 Subject: [PATCH 2/2] Add a comment about the relationship with the corresponding libc++ test file --- clang/test/Headers/system_reserved_names.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/test/Headers/system_reserved_names.h b/clang/test/Headers/system_reserved_names.h index 2783b2e5e4ae8..1a53f4fa8c1ff 100644 --- a/clang/test/Headers/system_reserved_names.h +++ b/clang/test/Headers/system_reserved_names.h @@ -1,6 +1,10 @@ // Test that headers are not tripped up by the surrounding code defining various // alphabetic macros. Also ensure that we don't swallow the definition of user // provided macros (in other words, ensure that we push/pop correctly everywhere). +// +// The contents of this header is a lightly trimmed version of +// libcxx/test/libcxx/system_reserved_names.gen.py; additions to that testcase +// can be synced into this header as well. #define SYSTEM_RESERVED_NAME This name should not be used in Clang headers