Skip to content

Commit 6abe19a

Browse files
[clang] Predefine _CRT_USE_BUILTIN_OFFSETOF in MS-compatible modes (#127568)
This patch makes Clang predefine `_CRT_USE_BUILTIN_OFFSETOF` in MS-compatible modes. The macro can make the `offsetof` provided by MS UCRT's `<stddef.h>` to select the `__builtin_offsetof` version, so with it Clang (Clang-cl) can directly consume UCRT's `offsetof`. MSVC predefines the macro as `1` since at least VS 2017 19.14, but I think it's also OK to define it in "older" compatible modes. Fixes #59689.
1 parent 5d5f162 commit 6abe19a

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ Android Support
358358
Windows Support
359359
^^^^^^^^^^^^^^^
360360

361+
- Clang now defines ``_CRT_USE_BUILTIN_OFFSETOF`` macro in MSVC-compatible mode,
362+
which makes ``offsetof`` provided by Microsoft's ``<stddef.h>`` to be defined
363+
correctly. (#GH59689)
364+
361365
LoongArch Support
362366
^^^^^^^^^^^^^^^^^
363367

clang/lib/Basic/Targets/OSTargets.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
220220
Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
221221
// FIXME We cannot encode the revision information into 32-bits
222222
Builder.defineMacro("_MSC_BUILD", Twine(1));
223+
// Exposed by MSVC, used in their stddef.h.
224+
Builder.defineMacro("_CRT_USE_BUILTIN_OFFSETOF", Twine(1));
223225

224226
if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
225227
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));

clang/test/Sema/offsetof-ucrt.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -verify -fms-compatibility
2+
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -verify
3+
// expected-no-diagnostics
4+
5+
typedef __typeof__(sizeof(0)) size_t;
6+
7+
#ifdef _MSC_VER
8+
#ifndef _CRT_USE_BUILTIN_OFFSETOF
9+
#error _CRT_USE_BUILTIN_OFFSETOF should be predefined in MSVC-compatible modes.
10+
#endif
11+
#else
12+
#ifdef _CRT_USE_BUILTIN_OFFSETOF
13+
#error _CRT_USE_BUILTIN_OFFSETOF should not be predefined in non-MSVC-compatible modes.
14+
#endif
15+
#endif
16+
17+
#if defined _MSC_VER && !defined _CRT_USE_BUILTIN_OFFSETOF
18+
#ifdef __cplusplus
19+
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
20+
#else
21+
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
22+
#endif
23+
#else
24+
#define offsetof(s,m) __builtin_offsetof(s,m)
25+
#endif
26+
27+
struct S { int a; };
28+
_Static_assert(offsetof(struct S, a) == 0, "");

clang/test/SemaCXX/offsetof-ucrt.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -verify -fms-compatibility
2+
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -verify
3+
// expected-no-diagnostics
4+
5+
typedef __typeof__(sizeof(0)) size_t;
6+
7+
#ifdef _MSC_VER
8+
#ifndef _CRT_USE_BUILTIN_OFFSETOF
9+
#error _CRT_USE_BUILTIN_OFFSETOF should be predefined in MSVC-compatible modes.
10+
#endif
11+
#else
12+
#ifdef _CRT_USE_BUILTIN_OFFSETOF
13+
#error _CRT_USE_BUILTIN_OFFSETOF should not be predefined in non-MSVC-compatible modes.
14+
#endif
15+
#endif
16+
17+
#if defined _MSC_VER && !defined _CRT_USE_BUILTIN_OFFSETOF
18+
#ifdef __cplusplus
19+
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
20+
#else
21+
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
22+
#endif
23+
#else
24+
#define offsetof(s,m) __builtin_offsetof(s,m)
25+
#endif
26+
27+
struct S { int a; };
28+
_Static_assert(offsetof(S, a) == 0, "");

0 commit comments

Comments
 (0)