File: n3035.c

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (51 lines) | stat: -rw-r--r-- 2,422 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// RUN: %clang_cc1 -triple x86_64 -ffreestanding -verify -std=c2x %s

/* WG14 N3035: yes
 * _BitInt Fixes
 */

#include <stdint.h>

/* intmax_t and uintmax_t don't need to be able to represent all of the values
 * of a bit-precise integer type. We test this by using a bit-precise integer
 * suffix on some huge values used within the preprocessor.
 */
#if 0x1'FFFF'FFFF'FFFF'FFFFwb == 0 /* expected-error {{integer literal is too large to be represented in any integer type}} */
#endif

/* Yet we can use that value as an initializer... */
_BitInt(66) Val = 0x1'FFFF'FFFF'FFFF'FFFFwb;

/* ...so long as the type is wide enough. */
intmax_t WrongVal = 0x1'FFFF'FFFF'FFFF'FFFFwb; /* expected-warning-re {{implicit conversion from '_BitInt(66)' to 'intmax_t' (aka '{{.*}}') changes value from 36893488147419103231 to -1}} */

/* None of the types in stdint.h may be defined in terms of a bit-precise
 * integer type. This macro presumes that if the type is not one of the builtin
 * scalar integer types, the type must be a bit-precise type. We're using this
 * because C does not have a particularly straightforward way to use _Generic
 * with arbitrary bit-precise integer types.
 */
#define IS_NOT_BIT_PRECISE(TYPE) _Generic((TYPE){ 0 },                          \
                                   short : 1, int : 1, long : 1, long long : 1, \
                                   unsigned short : 1, unsigned int : 1,        \
                                   unsigned long : 1, unsigned long long : 1,   \
                                   char : 1, signed char : 1, unsigned char : 1,\
                                   default : 0)
static_assert(IS_NOT_BIT_PRECISE(int8_t));
static_assert(IS_NOT_BIT_PRECISE(uint8_t));
static_assert(IS_NOT_BIT_PRECISE(int16_t));
static_assert(IS_NOT_BIT_PRECISE(uint16_t));
static_assert(IS_NOT_BIT_PRECISE(int32_t));
static_assert(IS_NOT_BIT_PRECISE(uint32_t));
static_assert(IS_NOT_BIT_PRECISE(int64_t));
static_assert(IS_NOT_BIT_PRECISE(uint64_t));
static_assert(IS_NOT_BIT_PRECISE(intmax_t));
static_assert(IS_NOT_BIT_PRECISE(uintmax_t));
static_assert(IS_NOT_BIT_PRECISE(intptr_t));
static_assert(IS_NOT_BIT_PRECISE(uintptr_t));

/* FIXME: N3035 also added wording disallowing using a bit-precise integer type
 * as the compatible type for an enumerated type. However, we don't have a
 * direct way to test that, so we're claiming conformance without test
 * coverage.
 */