1 // RUN: %clang_cc1 -verify -std=c99 %s
3 /* WG14 N620, N638, N657, N694, N809: Partial
4 * Complex and imaginary support in <complex.h>
6 * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is
7 * required outside of freestanding, but _Imaginary support is fully optional.
8 * In C11, both are made fully optional.
10 * NB: _Complex support requires an underlying support library such as
11 * compiler-rt to provide functions like __divsc3. Compiler-rt is not supported
14 * Because the functionality is so intertwined between the various papers,
15 * we're testing all of the functionality in one file.
18 // Demonstrate that we support spelling complex floating-point objects.
25 long double _Complex ld1
;
26 _Complex
long double ld2
;
28 // Show that we don't support spelling imaginary types.
29 float _Imaginary fi1
; // expected-error {{imaginary types are not supported}}
30 _Imaginary
float fi2
; // expected-error {{imaginary types are not supported}}
32 double _Imaginary di1
; // expected-error {{imaginary types are not supported}}
33 _Imaginary
double di2
; // expected-error {{imaginary types are not supported}}
35 long double _Imaginary ldi1
; // expected-error {{imaginary types are not supported}}
36 _Imaginary
long double ldi2
; // expected-error {{imaginary types are not supported}}
38 // Each complex type has the same representation and alignment as an array
39 // containing two elements of the corresponding real type. Note, it is not
40 // mandatory that the alignment of a structure containing an array of two
41 // elements has the same alignment as an array of two elements outside of a
42 // structure, but this is a property Clang supports.
43 _Static_assert(sizeof(float _Complex
) == sizeof(struct { float mem
[2]; }), "");
44 _Static_assert(_Alignof(float _Complex
) == _Alignof(struct { float mem
[2]; }), "");
46 _Static_assert(sizeof(double _Complex
) == sizeof(struct { double mem
[2]; }), "");
47 _Static_assert(_Alignof(double _Complex
) == _Alignof(struct { double mem
[2]; }), "");
49 _Static_assert(sizeof(long double _Complex
) == sizeof(struct { long double mem
[2]; }), "");
50 _Static_assert(_Alignof(long double _Complex
) == _Alignof(struct { long double mem
[2]; }), "");
52 // The first element corresponds to the real part and the second element
53 // corresponds to the imaginary part.
54 _Static_assert(__real((float _Complex
){ 1.0f
, 2.0f
}) == 1.0f
, "");
55 _Static_assert(__imag((float _Complex
){ 1.0f
, 2.0f
}) == 2.0f
, "");
57 _Static_assert(__real((double _Complex
){ 1.0, 2.0 }) == 1.0, "");
58 _Static_assert(__imag((double _Complex
){ 1.0, 2.0 }) == 2.0, "");
60 _Static_assert(__real((long double _Complex
){ 1.0L, 2.0L }) == 1.0L, "");
61 _Static_assert(__imag((long double _Complex
){ 1.0L, 2.0L }) == 2.0L, "");
63 // When a real value is converted to a complex value, the real part follows the
64 // usual conversion rules and the imaginary part should be zero.
65 _Static_assert(__real((float _Complex
)1.0f
) == 1.0f
, "");
66 _Static_assert(__imag((float _Complex
)1.0f
) == 0.0f
, "");
68 _Static_assert(__real((double _Complex
)1.0f
) == 1.0, "");
69 _Static_assert(__imag((double _Complex
)1.0f
) == 0.0, "");
71 _Static_assert(__real((long double _Complex
)1.0f
) == 1.0L, "");
72 _Static_assert(__imag((long double _Complex
)1.0f
) == 0.0L, "");
74 // When a complex value is converted to a real value, the real part follows the
75 // usual conversion rules and the imaginary part is discarded.
76 _Static_assert((float)(float _Complex
){ 1.0f
, 2.0f
} == 1.0f
, "");
77 _Static_assert((double)(float _Complex
){ 1.0f
, 2.0f
} == 1.0, "");
78 _Static_assert((long double)(float _Complex
){ 1.0f
, 2.0f
} == 1.0L, "");
80 // Complex values are only equal if both the real and imaginary parts are equal.
81 _Static_assert((float _Complex
){ 1.0f
, 2.0f
} == (float _Complex
){ 1.0f
, 2.0f
}, "");
82 _Static_assert((double _Complex
){ 1.0, 2.0 } == (double _Complex
){ 1.0, 2.0 }, "");
83 _Static_assert((long double _Complex
){ 1.0L, 2.0L } == (long double _Complex
){ 1.0L, 2.0L }, "");
85 _Static_assert((float _Complex
){ 1.0f
, 2.0f
} != (float _Complex
){ 2.0f
, 0.0f
}, "");
86 _Static_assert((double _Complex
){ 1.0, 2.0 } != (double _Complex
){ 2.0, 0.0 }, "");
87 _Static_assert((long double _Complex
){ 1.0L, 2.0L } != (long double _Complex
){ 2.0L, 0.0L }, "");
89 // You cannot use relational operator on complex values.
90 int i1
= (float _Complex
){ 1.0f
, 2.0f
} < 10; // expected-error {{invalid operands to binary expression}}
91 int i2
= (double _Complex
){ 1.0f
, 2.0f
} > 10; // expected-error {{invalid operands to binary expression}}
92 int i3
= (long double _Complex
){ 1.0f
, 2.0f
} <= 10; // expected-error {{invalid operands to binary expression}}
93 int i4
= (float _Complex
){ 1.0f
, 2.0f
} >= 10; // expected-error {{invalid operands to binary expression}}
95 // As a type specifier, _Complex cannot appear alone; however, we support it as
96 // an extension by assuming _Complex double.
97 _Complex c
= 1.0f
; // expected-warning {{plain '_Complex' requires a type specifier; assuming '_Complex double'}}
98 // Because we don't support imaginary types, we don't extend the extension to
99 // that type specifier.
100 // FIXME: the warning diagnostic here is incorrect and should not be emitted.
101 _Imaginary i
= 1.0f
; // expected-warning {{plain '_Complex' requires a type specifier; assuming '_Complex double'}} \
102 expected
-error
{{imaginary types are
not supported
}}
105 #pragma clang diagnostic push
106 #pragma clang diagnostic warning "-Wpedantic"
107 // Increment and decrement operators have a constraint that their operand be
108 // a real type; Clang supports this as an extension on complex types as well.
109 _Complex
float cf
= 0.0f
;
111 cf
++; // expected-warning {{'++' on an object of complex type is a C2y extension}}
112 ++cf
; // expected-warning {{'++' on an object of complex type is a C2y extension}}
114 cf
--; // expected-warning {{'--' on an object of complex type is a C2y extension}}
115 --cf
; // expected-warning {{'--' on an object of complex type is a C2y extension}}
117 // However, unary + and - are fine, as is += 1.
121 #pragma clang diagnostic pop