1 // RUN: %clang_cc1 -std=c2x -fsyntax-only -verify -Wno-unused %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused -x c++ -std=c++17 %s
4 // Test that the semantic behavior of the extension allowing the user to pass a
5 // type as the first argument to _Generic.
7 // Test that we match on basic types.
8 static_assert(_Generic(int, int : 1, default : 0) == 1);
9 static_assert(_Generic(_BitInt(12), int : 1, _BitInt(10) : 2, _BitInt(12) : 3) == 3);
11 // Test that we correctly fall back to the default association appropriately.
12 static_assert(_Generic(int, long : 1, default : 0) == 0);
14 // Ensure we correctly match constant arrays by their extent.
15 static_assert(_Generic(int[12], int[0] : 0, int * : 0, int[12] : 1, default : 0) == 1);
17 // Ensure we correctly match function types by their signature.
18 static_assert(_Generic(int(int), void(void) : 0, int(void) : 0, void(int) : 0, int(int) : 1, default : 0) == 1);
20 // Test that we still diagnose when no associations match and that the
21 // diagnostic includes qualifiers.
22 static_assert(_Generic(const int, long : 1)); // expected-error {{controlling expression type 'const int' not compatible with any generic association type}}
24 // Test that qualifiers work as expected and do not issue a diagnostic when
25 // using the type form.
26 static_assert(_Generic(const int, int : 0, const int : 1) == 1);
27 static_assert(_Generic(int volatile _Atomic
const, int : 0, const int : 0, volatile int : 0, _Atomic
int : 0, _Atomic
const volatile int : 1) == 1);
29 // Test that inferred qualifiers also work as expected.
31 static_assert(_Generic(__typeof__(ci
), int : 0, const int : 1) == 1);
32 // And that the expression form still complains about qualified associations
33 // and matches the correct association.
34 static_assert(_Generic(ci
, int : 1, const int : 0) == 1); // expected-warning {{due to lvalue conversion of the controlling expression, association of type 'const int' will never be selected because it is qualified}}
36 // The type operand form of _Generic allows incomplete and non-object types,
37 // but the expression operand form still rejects them.
38 static_assert(_Generic(struct incomplete
, struct incomplete
: 1, default : 0) == 1);
39 static_assert(_Generic(struct another_incomplete
, struct incomplete
: 1, default : 0) == 0);
40 static_assert(_Generic(1, struct also_incomplete
: 1, default : 0) == 0); // expected-error {{type 'struct also_incomplete' in generic association incomplete}}
43 static_assert(_Generic(__typeof__(foo
), void(int) : 1, default : 0) == 1);
44 static_assert(_Generic(foo
, void(int) : 1, default : 0) == 0); // expected-error {{type 'void (int)' in generic association not an object type}}
46 // Ensure we still get a diagnostic for duplicated associations for the type
47 // form, even when using qualified type, and that the diagnostic includes
49 static_assert(_Generic(const int,
50 const int : 1, // expected-note {{compatible type 'const int' specified here}}
52 const int : 3 // expected-error {{type 'const int' in generic association compatible with previously specified type 'const int'}}
55 // Verify that we are matching using the canonical type of the type operand...
57 typedef const Int CInt
;
58 typedef CInt OtherCInt
;
59 static_assert(_Generic(volatile CInt
, const volatile int : 1, default : 0) == 1);
60 static_assert(_Generic(const int, CInt
: 1, default : 0) == 1);
62 // ...and that duplicate associations are doing so as well.
63 static_assert(_Generic(const int,
64 CInt
: 1, // expected-note {{compatible type 'CInt' (aka 'const int') specified here}}
65 const volatile int : 2,
66 OtherCInt
: 3 // expected-error {{type 'OtherCInt' (aka 'const int') in generic association compatible with previously specified type 'CInt' (aka 'const int')}}
69 // Also test that duplicate array or function types are caught.
70 static_assert(_Generic(const int,
71 int[12] : 0, // expected-note {{compatible type 'int[12]' specified here}}
72 int[12] : 0, // expected-error {{type 'int[12]' in generic association compatible with previously specified type 'int[12]'}}
73 int(int) : 0, // expected-note {{compatible type 'int (int)' specified here}}
74 int(int) : 0, // expected-error {{type 'int (int)' in generic association compatible with previously specified type 'int (int)'}}
79 // Tests that only make sense for C++:
81 // Ensure that _Generic works within a template argument list.
82 template <typename Ty
, int N
= _Generic(Ty
, int : 0, default : 1)>
83 constexpr Ty
bar() { return N
; }
85 static_assert(bar
<int>() == 0);
86 static_assert(bar
<float>() == 1);
88 // Or that it can be used as a non-type template argument.
89 static_assert(bar
<int, _Generic(int, int : 1, default : 0)>() == 1);
91 // Ensure that a dependent type works as expected.
92 template <typename Ty
>
94 // If we checked the type early, this would fail to compile without any
95 // instantiation. Instead, it only fails with the bad instantiation.
96 static_assert(_Generic(Ty
, int : 1)); // expected-error {{controlling expression type 'double' not compatible with any generic association type}} \
97 expected
-note@
#BadInstantiation {{in instantiation of template class 'Dependent<double>' requested here}}
100 template struct Dependent
<int>; // Good instantiation
101 template struct Dependent
<double>; // #BadInstantiation
103 // Another template instantiation test, this time for a variable template with
104 // a type-dependent initializer.
105 template <typename Ty
>
106 constexpr auto Val
= _Generic(Ty
, Ty
: Ty
{});
108 static_assert(Val
<int> == 0);
109 static_assert(__is_same(decltype(Val
<Dependent
<int>>), const Dependent
<int>));
111 // Ensure that pack types also work as expected.
112 template <unsigned Arg
, unsigned... Args
> struct Or
{
113 enum { result
= Arg
| Or
<Args
...>::result
};
116 template <unsigned Arg
> struct Or
<Arg
> {
117 enum { result
= Arg
};
120 template <class... Args
> struct TypeMask
{
122 result
= Or
<_Generic(Args
, int: 1, long: 2, short: 4, float: 8)...>::result
126 static_assert(TypeMask
<int, long, short>::result
== 7, "fail");
127 static_assert(TypeMask
<float, short>::result
== 12, "fail");
128 static_assert(TypeMask
<int, float, float>::result
== 9, "fail");
130 template <typename
... T
>
132 // Because _Generic only accepts a single type argument, it does not make
133 // sense for it to accept a pack, so a pack is rejected while parsing.
134 _Generic(T
..., int : 1); // expected-error {{expected ','}}
136 #endif // __cplusplus