brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 48a72cc Raw
123 lines · c
1// RUN: %clang_cc1 -verify -std=c99 %s2 3/* WG14 N620, N638, N657, N694, N809: Partial4 * Complex and imaginary support in <complex.h>5 *6 * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is7 * required outside of freestanding, but _Imaginary support is fully optional.8 * In C11, both are made fully optional.9 *10 * NB: _Complex support requires an underlying support library such as11 * compiler-rt to provide functions like __divsc3. Compiler-rt is not supported12 * on Windows.13 *14 * Because the functionality is so intertwined between the various papers,15 * we're testing all of the functionality in one file.16 */17 18// Demonstrate that we support spelling complex floating-point objects.19float _Complex f1;20_Complex float f2;21 22double _Complex d1;23_Complex double d2;24 25long double _Complex ld1;26_Complex long double ld2;27 28// Show that we don't support spelling imaginary types.29float _Imaginary fi1; // expected-error {{imaginary types are not supported}}30_Imaginary float fi2; // expected-error {{imaginary types are not supported}}31 32double _Imaginary di1; // expected-error {{imaginary types are not supported}}33_Imaginary double di2; // expected-error {{imaginary types are not supported}}34 35long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}}36_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}}37 38// Each complex type has the same representation and alignment as an array39// containing two elements of the corresponding real type. Note, it is not40// mandatory that the alignment of a structure containing an array of two41// elements has the same alignment as an array of two elements outside of a42// 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]; }), "");45 46_Static_assert(sizeof(double _Complex) == sizeof(struct { double mem[2]; }), "");47_Static_assert(_Alignof(double _Complex) == _Alignof(struct { double mem[2]; }), "");48 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]; }), "");51 52// The first element corresponds to the real part and the second element53// 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, "");56 57_Static_assert(__real((double _Complex){ 1.0, 2.0 }) == 1.0, "");58_Static_assert(__imag((double _Complex){ 1.0, 2.0 }) == 2.0, "");59 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, "");62 63// When a real value is converted to a complex value, the real part follows the64// 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, "");67 68_Static_assert(__real((double _Complex)1.0f) == 1.0, "");69_Static_assert(__imag((double _Complex)1.0f) == 0.0, "");70 71_Static_assert(__real((long double _Complex)1.0f) == 1.0L, "");72_Static_assert(__imag((long double _Complex)1.0f) == 0.0L, "");73 74// When a complex value is converted to a real value, the real part follows the75// 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, "");79 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 }, "");84 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 }, "");88 89// You cannot use relational operator on complex values.90int i1 = (float _Complex){ 1.0f, 2.0f } < 10;        // expected-error {{invalid operands to binary expression}}91int i2 = (double _Complex){ 1.0f, 2.0f } > 10;       // expected-error {{invalid operands to binary expression}}92int i3 = (long double _Complex){ 1.0f, 2.0f } <= 10; // expected-error {{invalid operands to binary expression}}93int i4 = (float _Complex){ 1.0f, 2.0f } >= 10;       // expected-error {{invalid operands to binary expression}}94 95// As a type specifier, _Complex cannot appear alone; however, we support it as96// 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 to99// 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}}103 104void func(void) {105#pragma clang diagnostic push106#pragma clang diagnostic warning "-Wpedantic"107  // Increment and decrement operators have a constraint that their operand be108  // a real type; Clang supports this as an extension on complex types as well.109  _Complex float cf = 0.0f;110 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}}113 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}}116 117  // However, unary + and - are fine, as is += 1.118  (void)-cf;119  (void)+cf;120  cf += 1;121#pragma clang diagnostic pop122}123