Skip to content

[Clang] Add predefined macros for integer constants to implement section 7.18.4 of ISO/IEC 9899:1999 in <stdint.h> in a safe way #123514

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

Merged
merged 6 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,17 @@ Non-comprehensive list of changes in this release
``__builtin_elementwise_sub_sat``, ``__builtin_reduce_min`` (For integral element type),
``__builtin_reduce_max`` (For integral element type).

- The builtin macros ``__INT8_C``, ``__INT16_C``, ``__INT32_C``, ``__INT64_C``,
``__INTMAX_C``, ``__UINT8_C``, ``__UINT16_C``, ``__UINT32_C``, ``__UINT64_C``
and ``__UINTMAX_C`` have been introduced to ease the implementaton of section
7.18.4 of ISO/IEC 9899:1999. These macros are also defined by GCC and should
be used instead of others that expand and paste the suffixes provided by
``__INT8_C_SUFFIX__``, ``__INT16_C_SUFFIX__``, ``__INT32_C_SUFFIX__``,
``__INT64_C_SUFFIX__``, ``__INTMAX_C_SUFFIX__``, ``__UINT8_C_SUFFIX__``,
``__UINT16_C_SUFFIX__``, ``__UINT32_C_SUFFIX__``, ``__UINT64_C_SUFFIX__`` and
``__UINTMAX_C_SUFFIX__``. Pasting suffixes after the expansion of their
respective macros is unsafe, as users can define the suffixes as macros.

- Clang now rejects ``_BitInt`` matrix element types if the bit width is less than ``CHAR_WIDTH`` or
not a power of two, matching preexisting behaviour for vector types.

Expand Down
14 changes: 10 additions & 4 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ static void DefineExactWidthIntType(const LangOptions &LangOpts,

StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C(c)",
ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
}

static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
Expand Down Expand Up @@ -1164,12 +1166,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI,

DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder);
Builder.defineMacro("__INTMAX_C_SUFFIX__",
TI.getTypeConstantSuffix(TI.getIntMaxType()));
StringRef ConstSuffix(TI.getTypeConstantSuffix(TI.getIntMaxType()));
Builder.defineMacro("__INTMAX_C_SUFFIX__", ConstSuffix);
Builder.defineMacro("__INTMAX_C(c)",
ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder);
Builder.defineMacro("__UINTMAX_C_SUFFIX__",
TI.getTypeConstantSuffix(TI.getUIntMaxType()));
ConstSuffix = TI.getTypeConstantSuffix(TI.getUIntMaxType());
Builder.defineMacro("__UINTMAX_C_SUFFIX__", ConstSuffix);
Builder.defineMacro("__UINTMAX_C(c)",
ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c");
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
Builder);
Expand Down
35 changes: 35 additions & 0 deletions clang/test/Preprocessor/init-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,26 +135,31 @@
// AARCH64_CXX-NEXT: #define __GLIBCXX_BITSIZE_INT_N_0 128
// AARCH64_CXX-NEXT: #define __GLIBCXX_TYPE_INT_N_0 __int128
// AARCH64-NEXT: #define __HAVE_FUNCTION_MULTI_VERSIONING 1
// AARCH64-NEXT: #define __INT16_C(c) c
// AARCH64-NEXT: #define __INT16_C_SUFFIX__
// AARCH64-NEXT: #define __INT16_FMTd__ "hd"
// AARCH64-NEXT: #define __INT16_FMTi__ "hi"
// AARCH64-NEXT: #define __INT16_MAX__ 32767
// AARCH64-NEXT: #define __INT16_TYPE__ short
// AARCH64-NEXT: #define __INT32_C(c) c
// AARCH64-NEXT: #define __INT32_C_SUFFIX__
// AARCH64-NEXT: #define __INT32_FMTd__ "d"
// AARCH64-NEXT: #define __INT32_FMTi__ "i"
// AARCH64-NEXT: #define __INT32_MAX__ 2147483647
// AARCH64-NEXT: #define __INT32_TYPE__ int
// AARCH64-NEXT: #define __INT64_C(c) c##L
// AARCH64-NEXT: #define __INT64_C_SUFFIX__ L
// AARCH64-NEXT: #define __INT64_FMTd__ "ld"
// AARCH64-NEXT: #define __INT64_FMTi__ "li"
// AARCH64-NEXT: #define __INT64_MAX__ 9223372036854775807L
// AARCH64-NEXT: #define __INT64_TYPE__ long int
// AARCH64-NEXT: #define __INT8_C(c) c
// AARCH64-NEXT: #define __INT8_C_SUFFIX__
// AARCH64-NEXT: #define __INT8_FMTd__ "hhd"
// AARCH64-NEXT: #define __INT8_FMTi__ "hhi"
// AARCH64-NEXT: #define __INT8_MAX__ 127
// AARCH64-NEXT: #define __INT8_TYPE__ signed char
// AARCH64-NEXT: #define __INTMAX_C(c) c##L
// AARCH64-NEXT: #define __INTMAX_C_SUFFIX__ L
// AARCH64-NEXT: #define __INTMAX_FMTd__ "ld"
// AARCH64-NEXT: #define __INTMAX_FMTi__ "li"
Expand Down Expand Up @@ -287,34 +292,39 @@
// AARCH64-NEXT: #define __STDC_UTF_32__ 1
// AARCH64_C: #define __STDC_VERSION__ 201710L
// AARCH64-NEXT: #define __STDC__ 1
// AARCH64-NEXT: #define __UINT16_C(c) c
// AARCH64-NEXT: #define __UINT16_C_SUFFIX__
// AARCH64-NEXT: #define __UINT16_FMTX__ "hX"
// AARCH64-NEXT: #define __UINT16_FMTo__ "ho"
// AARCH64-NEXT: #define __UINT16_FMTu__ "hu"
// AARCH64-NEXT: #define __UINT16_FMTx__ "hx"
// AARCH64-NEXT: #define __UINT16_MAX__ 65535
// AARCH64-NEXT: #define __UINT16_TYPE__ unsigned short
// AARCH64-NEXT: #define __UINT32_C(c) c##U
// AARCH64-NEXT: #define __UINT32_C_SUFFIX__ U
// AARCH64-NEXT: #define __UINT32_FMTX__ "X"
// AARCH64-NEXT: #define __UINT32_FMTo__ "o"
// AARCH64-NEXT: #define __UINT32_FMTu__ "u"
// AARCH64-NEXT: #define __UINT32_FMTx__ "x"
// AARCH64-NEXT: #define __UINT32_MAX__ 4294967295U
// AARCH64-NEXT: #define __UINT32_TYPE__ unsigned int
// AARCH64-NEXT: #define __UINT64_C(c) c##UL
// AARCH64-NEXT: #define __UINT64_C_SUFFIX__ UL
// AARCH64-NEXT: #define __UINT64_FMTX__ "lX"
// AARCH64-NEXT: #define __UINT64_FMTo__ "lo"
// AARCH64-NEXT: #define __UINT64_FMTu__ "lu"
// AARCH64-NEXT: #define __UINT64_FMTx__ "lx"
// AARCH64-NEXT: #define __UINT64_MAX__ 18446744073709551615UL
// AARCH64-NEXT: #define __UINT64_TYPE__ long unsigned int
// AARCH64-NEXT: #define __UINT8_C(c) c
// AARCH64-NEXT: #define __UINT8_C_SUFFIX__
// AARCH64-NEXT: #define __UINT8_FMTX__ "hhX"
// AARCH64-NEXT: #define __UINT8_FMTo__ "hho"
// AARCH64-NEXT: #define __UINT8_FMTu__ "hhu"
// AARCH64-NEXT: #define __UINT8_FMTx__ "hhx"
// AARCH64-NEXT: #define __UINT8_MAX__ 255
// AARCH64-NEXT: #define __UINT8_TYPE__ unsigned char
// AARCH64-NEXT: #define __UINTMAX_C(c) c##UL
// AARCH64-NEXT: #define __UINTMAX_C_SUFFIX__ UL
// AARCH64-NEXT: #define __UINTMAX_FMTX__ "lX"
// AARCH64-NEXT: #define __UINTMAX_FMTo__ "lo"
Expand Down Expand Up @@ -435,26 +445,31 @@
// AARCH64-DARWIN: #define __FLT_MIN__ 1.17549435e-38F
// AARCH64-DARWIN: #define __FLT_RADIX__ 2
// AARCH64-DARWIN: #define __FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL 202430
// AARCH64-DARWIN: #define __INT16_C(c) c
// AARCH64-DARWIN: #define __INT16_C_SUFFIX__
// AARCH64-DARWIN: #define __INT16_FMTd__ "hd"
// AARCH64-DARWIN: #define __INT16_FMTi__ "hi"
// AARCH64-DARWIN: #define __INT16_MAX__ 32767
// AARCH64-DARWIN: #define __INT16_TYPE__ short
// AARCH64-DARWIN: #define __INT32_C(c) c
// AARCH64-DARWIN: #define __INT32_C_SUFFIX__
// AARCH64-DARWIN: #define __INT32_FMTd__ "d"
// AARCH64-DARWIN: #define __INT32_FMTi__ "i"
// AARCH64-DARWIN: #define __INT32_MAX__ 2147483647
// AARCH64-DARWIN: #define __INT32_TYPE__ int
// AARCH64-DARWIN: #define __INT64_C(c) c##LL
// AARCH64-DARWIN: #define __INT64_C_SUFFIX__ LL
// AARCH64-DARWIN: #define __INT64_FMTd__ "lld"
// AARCH64-DARWIN: #define __INT64_FMTi__ "lli"
// AARCH64-DARWIN: #define __INT64_MAX__ 9223372036854775807LL
// AARCH64-DARWIN: #define __INT64_TYPE__ long long int
// AARCH64-DARWIN: #define __INT8_C(c) c
// AARCH64-DARWIN: #define __INT8_C_SUFFIX__
// AARCH64-DARWIN: #define __INT8_FMTd__ "hhd"
// AARCH64-DARWIN: #define __INT8_FMTi__ "hhi"
// AARCH64-DARWIN: #define __INT8_MAX__ 127
// AARCH64-DARWIN: #define __INT8_TYPE__ signed char
// AARCH64-DARWIN: #define __INTMAX_C(c) c##L
// AARCH64-DARWIN: #define __INTMAX_C_SUFFIX__ L
// AARCH64-DARWIN: #define __INTMAX_FMTd__ "ld"
// AARCH64-DARWIN: #define __INTMAX_FMTi__ "li"
Expand Down Expand Up @@ -538,18 +553,23 @@
// AARCH64-DARWIN: #define __SIZE_MAX__ 18446744073709551615UL
// AARCH64-DARWIN: #define __SIZE_TYPE__ long unsigned int
// AARCH64-DARWIN: #define __SIZE_WIDTH__ 64
// AARCH64-DARWIN: #define __UINT16_C(c) c
// AARCH64-DARWIN: #define __UINT16_C_SUFFIX__
// AARCH64-DARWIN: #define __UINT16_MAX__ 65535
// AARCH64-DARWIN: #define __UINT16_TYPE__ unsigned short
// AARCH64-DARWIN: #define __UINT32_C(c) c##U
// AARCH64-DARWIN: #define __UINT32_C_SUFFIX__ U
// AARCH64-DARWIN: #define __UINT32_MAX__ 4294967295U
// AARCH64-DARWIN: #define __UINT32_TYPE__ unsigned int
// AARCH64-DARWIN: #define __UINT64_C(c) c##ULL
// AARCH64-DARWIN: #define __UINT64_C_SUFFIX__ ULL
// AARCH64-DARWIN: #define __UINT64_MAX__ 18446744073709551615ULL
// AARCH64-DARWIN: #define __UINT64_TYPE__ long long unsigned int
// AARCH64-DARWIN: #define __UINT8_C(c) c
// AARCH64-DARWIN: #define __UINT8_C_SUFFIX__
// AARCH64-DARWIN: #define __UINT8_MAX__ 255
// AARCH64-DARWIN: #define __UINT8_TYPE__ unsigned char
// AARCH64-DARWIN: #define __UINTMAX_C(c) c##UL
// AARCH64-DARWIN: #define __UINTMAX_C_SUFFIX__ UL
// AARCH64-DARWIN: #define __UINTMAX_MAX__ 18446744073709551615UL
// AARCH64-DARWIN: #define __UINTMAX_TYPE__ long unsigned int
Expand Down Expand Up @@ -703,18 +723,23 @@
// AARCH64-MSVC: #define __STDC_UTF_32__ 1
// AARCH64-MSVC: #define __STDC_VERSION__ 201710L
// AARCH64-MSVC: #define __STDC__ 1
// AARCH64-MSVC: #define __UINT16_C(c) c
// AARCH64-MSVC: #define __UINT16_C_SUFFIX__
// AARCH64-MSVC: #define __UINT16_MAX__ 65535
// AARCH64-MSVC: #define __UINT16_TYPE__ unsigned short
// AARCH64-MSVC: #define __UINT32_C(c) c##U
// AARCH64-MSVC: #define __UINT32_C_SUFFIX__ U
// AARCH64-MSVC: #define __UINT32_MAX__ 4294967295U
// AARCH64-MSVC: #define __UINT32_TYPE__ unsigned int
// AARCH64-MSVC: #define __UINT64_C(c) c##ULL
// AARCH64-MSVC: #define __UINT64_C_SUFFIX__ ULL
// AARCH64-MSVC: #define __UINT64_MAX__ 18446744073709551615ULL
// AARCH64-MSVC: #define __UINT64_TYPE__ long long unsigned int
// AARCH64-MSVC: #define __UINT8_C(c) c
// AARCH64-MSVC: #define __UINT8_C_SUFFIX__
// AARCH64-MSVC: #define __UINT8_MAX__ 255
// AARCH64-MSVC: #define __UINT8_TYPE__ unsigned char
// AARCH64-MSVC: #define __UINTMAX_C(c) c##ULL
// AARCH64-MSVC: #define __UINTMAX_C_SUFFIX__ ULL
// AARCH64-MSVC: #define __UINTMAX_MAX__ 18446744073709551615ULL
// AARCH64-MSVC: #define __UINTMAX_TYPE__ long long unsigned int
Expand Down Expand Up @@ -867,26 +892,31 @@
// ARM64EC-MSVC: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
// ARM64EC-MSVC: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
// ARM64EC-MSVC: #define __HAVE_FUNCTION_MULTI_VERSIONING 1
// ARM64EC-MSVC: #define __INT16_C(c) c
// ARM64EC-MSVC: #define __INT16_C_SUFFIX__
// ARM64EC-MSVC: #define __INT16_FMTd__ "hd"
// ARM64EC-MSVC: #define __INT16_FMTi__ "hi"
// ARM64EC-MSVC: #define __INT16_MAX__ 32767
// ARM64EC-MSVC: #define __INT16_TYPE__ short
// ARM64EC-MSVC: #define __INT32_C(c) c
// ARM64EC-MSVC: #define __INT32_C_SUFFIX__
// ARM64EC-MSVC: #define __INT32_FMTd__ "d"
// ARM64EC-MSVC: #define __INT32_FMTi__ "i"
// ARM64EC-MSVC: #define __INT32_MAX__ 2147483647
// ARM64EC-MSVC: #define __INT32_TYPE__ int
// ARM64EC-MSVC: #define __INT64_C(c) c##LL
// ARM64EC-MSVC: #define __INT64_C_SUFFIX__ LL
// ARM64EC-MSVC: #define __INT64_FMTd__ "lld"
// ARM64EC-MSVC: #define __INT64_FMTi__ "lli"
// ARM64EC-MSVC: #define __INT64_MAX__ 9223372036854775807LL
// ARM64EC-MSVC: #define __INT64_TYPE__ long long int
// ARM64EC-MSVC: #define __INT8_C(c) c
// ARM64EC-MSVC: #define __INT8_C_SUFFIX__
// ARM64EC-MSVC: #define __INT8_FMTd__ "hhd"
// ARM64EC-MSVC: #define __INT8_FMTi__ "hhi"
// ARM64EC-MSVC: #define __INT8_MAX__ 127
// ARM64EC-MSVC: #define __INT8_TYPE__ signed char
// ARM64EC-MSVC: #define __INTMAX_C(c) c##LL
// ARM64EC-MSVC: #define __INTMAX_C_SUFFIX__ LL
// ARM64EC-MSVC: #define __INTMAX_FMTd__ "lld"
// ARM64EC-MSVC: #define __INTMAX_FMTi__ "lli"
Expand Down Expand Up @@ -1013,34 +1043,39 @@
// ARM64EC-MSVC: #define __STDC_UTF_32__ 1
// ARM64EC-MSVC: #define __STDC_VERSION__ 201710L
// ARM64EC-MSVC: #define __STDC__ 1
// ARM64EC-MSVC: #define __UINT16_C(c) c
// ARM64EC-MSVC: #define __UINT16_C_SUFFIX__
// ARM64EC-MSVC: #define __UINT16_FMTX__ "hX"
// ARM64EC-MSVC: #define __UINT16_FMTo__ "ho"
// ARM64EC-MSVC: #define __UINT16_FMTu__ "hu"
// ARM64EC-MSVC: #define __UINT16_FMTx__ "hx"
// ARM64EC-MSVC: #define __UINT16_MAX__ 65535
// ARM64EC-MSVC: #define __UINT16_TYPE__ unsigned short
// ARM64EC-MSVC: #define __UINT32_C(c) c##U
// ARM64EC-MSVC: #define __UINT32_C_SUFFIX__ U
// ARM64EC-MSVC: #define __UINT32_FMTX__ "X"
// ARM64EC-MSVC: #define __UINT32_FMTo__ "o"
// ARM64EC-MSVC: #define __UINT32_FMTu__ "u"
// ARM64EC-MSVC: #define __UINT32_FMTx__ "x"
// ARM64EC-MSVC: #define __UINT32_MAX__ 4294967295U
// ARM64EC-MSVC: #define __UINT32_TYPE__ unsigned int
// ARM64EC-MSVC: #define __UINT64_C(c) c##ULL
// ARM64EC-MSVC: #define __UINT64_C_SUFFIX__ ULL
// ARM64EC-MSVC: #define __UINT64_FMTX__ "llX"
// ARM64EC-MSVC: #define __UINT64_FMTo__ "llo"
// ARM64EC-MSVC: #define __UINT64_FMTu__ "llu"
// ARM64EC-MSVC: #define __UINT64_FMTx__ "llx"
// ARM64EC-MSVC: #define __UINT64_MAX__ 18446744073709551615ULL
// ARM64EC-MSVC: #define __UINT64_TYPE__ long long unsigned int
// ARM64EC-MSVC: #define __UINT8_C(c) c
// ARM64EC-MSVC: #define __UINT8_C_SUFFIX__
// ARM64EC-MSVC: #define __UINT8_FMTX__ "hhX"
// ARM64EC-MSVC: #define __UINT8_FMTo__ "hho"
// ARM64EC-MSVC: #define __UINT8_FMTu__ "hhu"
// ARM64EC-MSVC: #define __UINT8_FMTx__ "hhx"
// ARM64EC-MSVC: #define __UINT8_MAX__ 255
// ARM64EC-MSVC: #define __UINT8_TYPE__ unsigned char
// ARM64EC-MSVC: #define __UINTMAX_C(c) c##ULL
// ARM64EC-MSVC: #define __UINTMAX_C_SUFFIX__ ULL
// ARM64EC-MSVC: #define __UINTMAX_FMTX__ "llX"
// ARM64EC-MSVC: #define __UINTMAX_FMTo__ "llo"
Expand Down
Loading
Loading