Skip to content

[C99] Fix definitions of INTn_C macros #133916

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 5 commits into from
Apr 2, 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
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ Bug Fixes in This Version
- Fixed a problematic case with recursive deserialization within ``FinishedDeserializing()`` where
``PassInterestingDeclsToConsumer()`` was called before the declarations were safe to be passed. (#GH129982)
- Fixed a modules crash where an explicit Constructor was deserialized. (#GH132794)
- Defining an integer literal suffix (e.g., ``LL``) before including
``<stdint.h>`` in a freestanding build no longer causes invalid token pasting
when using the ``INTn_C`` macros. (#GH85995)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
147 changes: 18 additions & 129 deletions clang/lib/Headers/stdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,166 +317,55 @@ typedef __UINTMAX_TYPE__ uintmax_t;
* integer width that the target implements, so corresponding macros are
* defined below, too.
*
* These macros are defined using the same successive-shrinking approach as
* the type definitions above. It is likewise important that macros are defined
* in order of decending width.
*
* Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
* claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
*/

#define __int_c_join(a, b) a ## b
#define __int_c(v, suffix) __int_c_join(v, suffix)
#define __uint_c(v, suffix) __int_c_join(v##U, suffix)


#ifdef __INT64_TYPE__
# undef __int64_c_suffix
# undef __int32_c_suffix
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT64_C_SUFFIX__
# define __int64_c_suffix __INT64_C_SUFFIX__
# define __int32_c_suffix __INT64_C_SUFFIX__
# define __int16_c_suffix __INT64_C_SUFFIX__
# define __int8_c_suffix __INT64_C_SUFFIX__
# endif /* __INT64_C_SUFFIX__ */
#endif /* __INT64_TYPE__ */

#ifdef __int_least64_t
# ifdef __int64_c_suffix
# define INT64_C(v) __int_c(v, __int64_c_suffix)
# define UINT64_C(v) __uint_c(v, __int64_c_suffix)
# else
# define INT64_C(v) v
# define UINT64_C(v) v ## U
# endif /* __int64_c_suffix */
#define INT64_C(v) __INT64_C(v)
#define UINT64_C(v) __UINT64_C(v)
#endif /* __int_least64_t */


#ifdef __INT56_TYPE__
# undef __int32_c_suffix
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT56_C_SUFFIX__
# define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__)
# define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__)
# define __int32_c_suffix __INT56_C_SUFFIX__
# define __int16_c_suffix __INT56_C_SUFFIX__
# define __int8_c_suffix __INT56_C_SUFFIX__
# else
# define INT56_C(v) v
# define UINT56_C(v) v ## U
# endif /* __INT56_C_SUFFIX__ */
#define INT56_C(v) __INT56_C(v)
#define UINT56_C(v) __UINT56_C(v)
#endif /* __INT56_TYPE__ */


#ifdef __INT48_TYPE__
# undef __int32_c_suffix
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT48_C_SUFFIX__
# define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__)
# define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__)
# define __int32_c_suffix __INT48_C_SUFFIX__
# define __int16_c_suffix __INT48_C_SUFFIX__
# define __int8_c_suffix __INT48_C_SUFFIX__
# else
# define INT48_C(v) v
# define UINT48_C(v) v ## U
# endif /* __INT48_C_SUFFIX__ */
#define INT48_C(v) __INT48_C(v)
#define UINT48_C(v) __UINT48_C(v)
#endif /* __INT48_TYPE__ */


#ifdef __INT40_TYPE__
# undef __int32_c_suffix
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT40_C_SUFFIX__
# define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__)
# define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__)
# define __int32_c_suffix __INT40_C_SUFFIX__
# define __int16_c_suffix __INT40_C_SUFFIX__
# define __int8_c_suffix __INT40_C_SUFFIX__
# else
# define INT40_C(v) v
# define UINT40_C(v) v ## U
# endif /* __INT40_C_SUFFIX__ */
#define INT40_C(v) __INT40_C(v)
#define UINT40_C(v) __UINT40_C(v)
#endif /* __INT40_TYPE__ */


#ifdef __INT32_TYPE__
# undef __int32_c_suffix
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT32_C_SUFFIX__
# define __int32_c_suffix __INT32_C_SUFFIX__
# define __int16_c_suffix __INT32_C_SUFFIX__
# define __int8_c_suffix __INT32_C_SUFFIX__
# endif /* __INT32_C_SUFFIX__ */
#endif /* __INT32_TYPE__ */

#ifdef __int_least32_t
# ifdef __int32_c_suffix
# define INT32_C(v) __int_c(v, __int32_c_suffix)
# define UINT32_C(v) __uint_c(v, __int32_c_suffix)
# else
# define INT32_C(v) v
# define UINT32_C(v) v ## U
# endif /* __int32_c_suffix */
#define INT32_C(v) __INT32_C(v)
#define UINT32_C(v) __UINT32_C(v)
#endif /* __int_least32_t */


#ifdef __INT24_TYPE__
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT24_C_SUFFIX__
# define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__)
# define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__)
# define __int16_c_suffix __INT24_C_SUFFIX__
# define __int8_c_suffix __INT24_C_SUFFIX__
# else
# define INT24_C(v) v
# define UINT24_C(v) v ## U
# endif /* __INT24_C_SUFFIX__ */
#define INT24_C(v) __INT24_C(v)
#define UINT24_C(v) __UINT24_C(v)
#endif /* __INT24_TYPE__ */


#ifdef __INT16_TYPE__
# undef __int16_c_suffix
# undef __int8_c_suffix
# ifdef __INT16_C_SUFFIX__
# define __int16_c_suffix __INT16_C_SUFFIX__
# define __int8_c_suffix __INT16_C_SUFFIX__
# endif /* __INT16_C_SUFFIX__ */
#endif /* __INT16_TYPE__ */

#ifdef __int_least16_t
# ifdef __int16_c_suffix
# define INT16_C(v) __int_c(v, __int16_c_suffix)
# define UINT16_C(v) __uint_c(v, __int16_c_suffix)
# else
# define INT16_C(v) v
# define UINT16_C(v) v ## U
# endif /* __int16_c_suffix */
#define INT16_C(v) __INT16_C(v)
#define UINT16_C(v) __UINT16_C(v)
#endif /* __int_least16_t */


#ifdef __INT8_TYPE__
# undef __int8_c_suffix
# ifdef __INT8_C_SUFFIX__
# define __int8_c_suffix __INT8_C_SUFFIX__
# endif /* __INT8_C_SUFFIX__ */
#endif /* __INT8_TYPE__ */

#ifdef __int_least8_t
# ifdef __int8_c_suffix
# define INT8_C(v) __int_c(v, __int8_c_suffix)
# define UINT8_C(v) __uint_c(v, __int8_c_suffix)
# else
# define INT8_C(v) v
# define UINT8_C(v) v ## U
# endif /* __int8_c_suffix */
#define INT8_C(v) __INT8_C(v)
#define UINT8_C(v) __UINT8_C(v)
#endif /* __int_least8_t */


Expand Down Expand Up @@ -938,8 +827,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#endif

/* 7.18.4.2 Macros for greatest-width integer constants. */
#define INTMAX_C(v) __int_c(v, __INTMAX_C_SUFFIX__)
#define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__)
#define INTMAX_C(v) __INTMAX_C(v)
#define UINTMAX_C(v) __UINTMAX_C(v)

/* C23 7.22.3.x Width of other integer types. */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
Expand Down
6 changes: 2 additions & 4 deletions clang/test/C/drs/dr209.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
RUN: %clang_cc1 -std=c17 -ffreestanding -fsyntax-only -verify -pedantic %s
RUN: %clang_cc1 -std=c2x -ffreestanding -fsyntax-only -verify -pedantic %s
*/
// expected-no-diagnostics

/* WG14 DR209: partial
* Problem implementing INTN_C macros
Expand Down Expand Up @@ -33,8 +34,7 @@ void dr209(void) {
(void)_Generic(INT16_C(0), __typeof__(+(int_least16_t){0}) : 1);
(void)_Generic(INT32_C(0), __typeof__(+(int_least32_t){0}) : 1);
(void)_Generic(INT64_C(0), __typeof__(+(int_least64_t){0}) : 1);
// FIXME: This is not the expected behavior; the type of the expanded value
// in both of these cases should be 'int',
// The type of the expanded value in both of these cases should be 'int',
//
// C99 7.18.4p3: The type of the expression shall have the same type as would
// an expression of the corresponding type converted according to the integer
Expand All @@ -53,8 +53,6 @@ void dr209(void) {
//
(void)_Generic(UINT8_C(0), __typeof__(+(uint_least8_t){0}) : 1);
(void)_Generic(UINT16_C(0), __typeof__(+(uint_least16_t){0}) : 1);
// expected-error@-2 {{controlling expression type 'unsigned int' not compatible with any generic association type}}
// expected-error@-2 {{controlling expression type 'unsigned int' not compatible with any generic association type}}
(void)_Generic(UINT32_C(0), __typeof__(+(uint_least32_t){0}) : 1);
(void)_Generic(UINT64_C(0), __typeof__(+(uint_least64_t){0}) : 1);
}
Expand Down
Loading
Loading