1 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -Wno-unused -triple x86_64-gnu-linux
2 
3 typedef _ExtInt(31) EI31;
4 
5 void Ternary(_ExtInt(30) s30, EI31 s31a, _ExtInt(31) s31b,
6              _ExtInt(32) s32, int b) {
7   b ? s30 : s31a;
8   b ? s31a : s30;
9   b ? s32 : 0;
10   (void)(b ? s31a : s31b);
11   (void)(s30 ? s31a : s31b);
12 }
13 
14 struct CursedBitField {
15   _ExtInt(4) A : 8; // expected-error {{width of bit-field 'A' (8 bits) exceeds the width of its type (4 bits)}}
16 };
17 
18 #define EXPR_HAS_TYPE(EXPR, TYPE) _Generic((EXPR), default : 0, TYPE : 1)
19 
Ops(void)20 void Ops(void) {
21   _ExtInt(4) x4_s = 1;
22   _ExtInt(32) x32_s = 1;
23   _ExtInt(43) x43_s = 1;
24   unsigned _ExtInt(4) x4_u = 1;
25   unsigned _ExtInt(43) x43_u = 1;
26   unsigned _ExtInt(32) x32_u = 1;
27   int x_int = 1;
28   unsigned x_uint = 1;
29 
30   // Same size/sign ops don't change type.
31   _Static_assert(EXPR_HAS_TYPE(x43_s + x43_s, _ExtInt(43)), "");
32   _Static_assert(EXPR_HAS_TYPE(x4_s - x4_s, _ExtInt(4)), "");
33   _Static_assert(EXPR_HAS_TYPE(x43_u * x43_u, unsigned _ExtInt(43)), "");
34   _Static_assert(EXPR_HAS_TYPE(x4_u / x4_u, unsigned _ExtInt(4)), "");
35 
36   // Unary ops shouldn't go through integer promotions.
37   _Static_assert(EXPR_HAS_TYPE(x4_s++, _ExtInt(4)), "");
38   _Static_assert(EXPR_HAS_TYPE(++x4_s, _ExtInt(4)), "");
39   _Static_assert(EXPR_HAS_TYPE(x4_u++, unsigned _ExtInt(4)), "");
40   _Static_assert(EXPR_HAS_TYPE(++x4_u, unsigned _ExtInt(4)), "");
41   _Static_assert(EXPR_HAS_TYPE(+x4_s, _ExtInt(4)), "");
42   _Static_assert(EXPR_HAS_TYPE(-x4_s, _ExtInt(4)), "");
43   _Static_assert(EXPR_HAS_TYPE(~x4_u, unsigned _ExtInt(4)), "");
44 
45   // This one really does convert to a different result type though.
46   _Static_assert(EXPR_HAS_TYPE(!x4_u, int), "");
47 
48   // Test binary ops pick the correct common type.
49   _Static_assert(EXPR_HAS_TYPE(x43_s + x_int, _ExtInt(43)), "");
50   _Static_assert(EXPR_HAS_TYPE(x43_u + x_int, unsigned _ExtInt(43)), "");
51   _Static_assert(EXPR_HAS_TYPE(x32_s + x_int, int), "");
52   _Static_assert(EXPR_HAS_TYPE(x32_u + x_int, unsigned int), "");
53   _Static_assert(EXPR_HAS_TYPE(x32_s + x_uint, unsigned int), "");
54   _Static_assert(EXPR_HAS_TYPE(x32_u + x_uint, unsigned int), "");
55   _Static_assert(EXPR_HAS_TYPE(x4_s + x_int, int), "");
56   _Static_assert(EXPR_HAS_TYPE(x4_u + x_int, int), "");
57   _Static_assert(EXPR_HAS_TYPE(x4_s + x_uint, unsigned int), "");
58   _Static_assert(EXPR_HAS_TYPE(x4_u + x_uint, unsigned int), "");
59 }
60 
FromPaper1(void)61 void FromPaper1(void) {
62   // Test the examples of conversion and promotion rules from C2x 6.3.1.8.
63   _ExtInt(2) a2 = 1;
64   _ExtInt(3) a3 = 2;
65   _ExtInt(33) a33 = 1;
66   char c = 3;
67 
68   _Static_assert(EXPR_HAS_TYPE(a2 * a3, _ExtInt(3)), "");
69   _Static_assert(EXPR_HAS_TYPE(a2 * c, int), "");
70   _Static_assert(EXPR_HAS_TYPE(a33 * c, _ExtInt(33)), "");
71 }
72 
73 void FromPaper2(_ExtInt(8) a1, _ExtInt(24) a2) {
74   _Static_assert(EXPR_HAS_TYPE(a1 * (_ExtInt(32))a2, _ExtInt(32)), "");
75 }
76