[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: > I'm surprised about the "compiler-rt is not supported on windows" comment - > in our distribution, we've been building compiler-rt on windows for years, > and I don't remember significant issues. > > It's true that `__divsc3` is not available _without_ compiler-rt (i.e. just > relying on the msvc runtime libraries), but together with compiler-rt these > things are generally possible? Note that a similar > [situation](https://github.com/llvm/llvm-project/issues/54596) exists on > `osx-arm` for example - in certain situations, linking `compiler-rt` is > unavoidable. CC @petrhosek as compiler-rt CRT code owner -- is compiler-rt officially supported for Windows? The official documentation does not mention it under platform support: https://compiler-rt.llvm.org/ https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
h-vetinari wrote: I'm surprised about the "compiler-rt is not supported on windows" comment - in our distribution, we've been building compiler-rt on windows for years, and I don't remember significant issues. It's true that `__divsc3` is not available _without_ compiler-rt (i.e. just relying on the msvc runtime libraries), but together with compiler-rt these things are generally possible? Not that a similar [situation](https://github.com/llvm/llvm-project/issues/54596) exists on `osx-arm` for example - in certain situations, linking `compiler-rt` is unavoidable. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/AaronBallman closed https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/jcranmer-intel approved this pull request. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
zahiraam wrote: LGTM. Thanks. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/zahiraam approved this pull request. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/philnik777 approved this pull request. LGTM from my side. I'll leave the conformance test details to the folks who know what they're doing. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: > > > Note that > > > ```c++ > > > auto div(_Complex float lhs, _Complex float rhs) { > > > return lhs / rhs; > > > } > > > > > > int main() { > > > return __real div(1.f, 2.f); > > > } > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > will fail to link on windows due to `__divsc3` not being available. > > > Similar programs probably also fail due to other compiler-rt functions > > > not being available. > > > > > > I _think_ Clang still gets to claim conformance here because we handle the > > language side of things correctly and the user is responsible for linking > > to a runtime library with appropriate support for the platform. However, > > this sure does straddle the line in some ways, so I could see this being a > > reason to claim "partial" conformance. > > IIRC the problem is that you can't get compiler-rt on windows. If it was just > a matter of compiling compiler-rt with clang I'd be 100% with you. Partial > conformance with a note that some operations require compiler-rt functions > that aren't available on windows seems like a good compromise to me. Yeah, that seems like a reasonable compromise. I'll make updates for that, thanks! https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
philnik777 wrote: > > Note that > > ```c++ > > auto div(_Complex float lhs, _Complex float rhs) { > > return lhs / rhs; > > } > > > > int main() { > > return __real div(1.f, 2.f); > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > will fail to link on windows due to `__divsc3` not being available. Similar > > programs probably also fail due to other compiler-rt functions not being > > available. > > I _think_ Clang still gets to claim conformance here because we handle the > language side of things correctly and the user is responsible for linking to > a runtime library with appropriate support for the platform. However, this > sure does straddle the line in some ways, so I could see this being a reason > to claim "partial" conformance. IIRC the problem is that you can't get compiler-rt on windows. If it was just a matter of compiling compiler-rt with clang I'd be 100% with you. Partial conformance with a note that some operations require compiler-rt functions that aren't available on windows seems like a good compromise to me. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: > You're missing checks for type domain rules, so things like: > > * converting between `float _Complex` and `double _Complex` > > * common type of `float _Complex` and `double` > > * result of `int` and `float _Complex` > > * complex types not allowed in increment/decrement operators > > * complex types permitted in unary +, - Thanks for the suggestions, these are now being tested. > Not sure how to test this, but _Complex float not promoting to _Complex > double like float does to double is also worth slotting under complex > conformance. Also 6.7.8p10 (static-storage duration arithmetic types (which > include complex types) are initialized to 0). I'll add tests for these as well. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); AaronBallman wrote: I added a comment to clarify that. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -373,6 +355,10 @@ C99 implementation status Yes +(2): Clang supports _Complex type specifiers but +does not support _Imaginary type specifiers. Support for +_Imaginary is optional in C99 which is why Clang is fully conforming. AaronBallman wrote: Done https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); + +_Static_assert(sizeof(double _Complex) == sizeof(struct { double mem[2]; }), ""); +_Static_assert(_Alignof(double _Complex) == _Alignof(struct { double mem[2]; }), ""); + +_Static_assert(sizeof(long double _Complex) == sizeof(struct { long double mem[2]; }), ""); +_Static_assert(_Alignof(long double _Complex) == _Alignof(struct { long double mem[2]; }), ""); + +// The first element corresponds to the real part and the second element +// corresponds to the imaginary part. +_Static_assert(__real((float _Complex){ 1.0f, 2.0f }) == 1.0f, ""); +_Static_assert(__imag((float _Complex){ 1.0f, 2.0f }) == 2.0f, ""); AaronBallman wrote: The other alternative would be to use a builtin function, I can go either way. Maybe I should use one of each to show they're equivalent? https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); AaronBallman wrote: I think this is a property we want to guarantee, so it seems reasonable-ish to test it here as part of our conformance testing. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -373,6 +355,10 @@ C99 implementation status Yes +(2): Clang supports _Complex type specifiers but +does not support _Imaginary type specifiers. Support for +_Imaginary is optional in C99 which is why Clang is fully conforming. jcranmer-intel wrote: Maybe mention here something about not claiming Annex G conformance? https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); jcranmer-intel wrote: I'm not entirely certain that there's a mandatory rule in C99 (or any other version of C) that requires that `struct { float mem[2]; }` and `float mem[2];` are the same in layout (particularly alignment, see C99 6.7.2.1p12 and read it somewhat maliciously). Though I will concede that all non-malicious compilers will treat them as the same. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
@@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); + +_Static_assert(sizeof(double _Complex) == sizeof(struct { double mem[2]; }), ""); +_Static_assert(_Alignof(double _Complex) == _Alignof(struct { double mem[2]; }), ""); + +_Static_assert(sizeof(long double _Complex) == sizeof(struct { long double mem[2]; }), ""); +_Static_assert(_Alignof(long double _Complex) == _Alignof(struct { long double mem[2]; }), ""); + +// The first element corresponds to the real part and the second element +// corresponds to the imaginary part. +_Static_assert(__real((float _Complex){ 1.0f, 2.0f }) == 1.0f, ""); +_Static_assert(__imag((float _Complex){ 1.0f, 2.0f }) == 2.0f, ""); jcranmer-intel wrote: This is using an extension for complex initializers, not a standard feature, so I'm a little bit uncomfortable that it's actually testing the assertion that the first element of the array corresponds to the real. That said, I'm not sure there's any non-extension way to test that as a constant expression anyways, so... :shrug: https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/jcranmer-intel edited https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
https://github.com/jcranmer-intel commented: You're missing checks for type domain rules, so things like: - converting between `float _Complex` and `double _Complex` - common type of `float _Complex` and `double` - result of `int` and `float _Complex` - complex types not allowed in increment/decrement operators - complex types permitted in unary +, - Not sure how to test this, but _Complex float not promoting to _Complex double like float does to double is also worth slotting under complex conformance. Also 6.7.8p10 (static-storage duration arithmetic types (which include complex types) are initialized to 0). https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: > Note that > > ```c++ > auto div(_Complex float lhs, _Complex float rhs) { > return lhs / rhs; > } > > int main() { > return __real div(1.f, 2.f); > } > ``` > > will fail to link on windows due to `__divsc3` not being available. Similar > programs probably also fail due to other compiler-rt functions not being > available. I *think* Clang still gets to claim conformance here because we handle the language side of things correctly and the user is responsible for linking to a runtime library with appropriate support for the platform. However, this sure does straddle the line in some ways, so I could see this being a reason to claim "partial" conformance. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
philnik777 wrote: Note that ```c++ auto div(_Complex float lhs, _Complex float rhs) { return lhs / rhs; } int main() { return __real div(1.f, 2.f); } ``` will fail to link on windows due to `__divsc3` not being available. Similar programs probably also fail due to other compiler-rt functions not being available. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
frederick-vs-ja wrote: > But fails on Windows. This seems because of that MS UCRT's complex math functions are non-conforming. I _guess_ they could work if we write the following before including UCRT's ``. ```C #define _C_COMPLEX_T typedef double _Complex _C_double_complex; typedef float _Complex _C_float_complex; typedef long double _Complex _C_ldouble_complex; ``` https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
zahiraam wrote: > > > I'm not convinced I have sufficient tests, so I'm especially interested > > > in some help figuring out what else to test and how to go about it. I > > > don't believe we need to test library behavior here because Clang does > > > not provide any library support for complex types in freestanding mode; > > > we expect the user to link against a C standard library that has such > > > support. > > > > > > I haven't looked at it in details yet, but the test needs to run on Linux > > and Windows. > > I don't think there's anything platform-specific about our support at this > level, so the test has no triples in the RUN line (so it will be run on all > triples we test on which includes Linux and Windows). Or do you mean > something else? I guess at the IR level no. It's just that I have recently found that this test: `#include ` `#include ` `int main()` `{` `float complex b = -8.45345913e+29f + -1.23588801e+31f * I;` ` float complex a = 1.25284138e+31f + -7.91789592e+30f * I;` `float complex c = a / b;` `printf("%f %f\n", creal(c), cimag(c));` `return 0;` `}` But fails on Windows. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: > > I'm not convinced I have sufficient tests, so I'm especially interested in > > some help figuring out what else to test and how to go about it. I don't > > believe we need to test library behavior here because Clang does not > > provide any library support for complex types in freestanding mode; we > > expect the user to link against a C standard library that has such support. > > I haven't looked at it in details yet, but the test needs to run on Linux and > Windows. I don't think there's anything platform-specific about our support at this level, so the test has no triples in the RUN line (so it will be run on all triples we test on which includes Linux and Windows). Or do you mean something else? https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
zahiraam wrote: > I'm not convinced I have sufficient tests, so I'm especially interested in > some help figuring out what else to test and how to go about it. I don't > believe we need to test library behavior here because Clang does not provide > any library support for complex types in freestanding mode; we expect the > user to link against a C standard library that has such support. I haven't looked at it in details yet, but the test needs to run on Linux and Windows. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
AaronBallman wrote: I'm not convinced I have sufficient tests, so I'm especially interested in some help figuring out what else to test and how to go about it. I don't believe we need to test library behavior here because Clang does not provide any library support for complex types in freestanding mode; we expect the user to link against a C standard library that has such support. https://github.com/llvm/llvm-project/pull/88161 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C99] Claim conformance for _Complex support (PR #88161)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) Changes There's so much overlap between the cited papers so this condenses the status page into a single entry rather than trying to test conformance against multiple papers doing conflicting things. --- Full diff: https://github.com/llvm/llvm-project/pull/88161.diff 2 Files Affected: - (added) clang/test/C/C99/n809.c (+97) - (modified) clang/www/c_status.html (+8-22) ``diff diff --git a/clang/test/C/C99/n809.c b/clang/test/C/C99/n809.c new file mode 100644 index 00..8d2673eec4 --- /dev/null +++ b/clang/test/C/C99/n809.c @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c99 %s + +/* WG14 N620, N638, N657, N694, N809: Yes* + * Complex and imaginary support in + * + * NB: Clang supports _Complex but not _Imaginary. In C99, _Complex support is + * required outside of freestanding, but _Imaginary support is fully optional. + * In C11, both are made fully optional. We claim full conformance because we + * are actually conforming, but this gets an asterisk because it's also only + * partially implemented in a way and users should know about that. + * + * Because the functionality is so intertwined between the various papers, + * we're testing all of the functionality in one file. + */ + +// Demonstrate that we support spelling complex floating-point objects. +float _Complex f1; +_Complex float f2; + +double _Complex d1; +_Complex double d2; + +long double _Complex ld1; +_Complex long double ld2; + +// Show that we don't support spelling imaginary types. +float _Imaginary fi1; // expected-error {{imaginary types are not supported}} +_Imaginary float fi2; // expected-error {{imaginary types are not supported}} + +double _Imaginary di1; // expected-error {{imaginary types are not supported}} +_Imaginary double di2; // expected-error {{imaginary types are not supported}} + +long double _Imaginary ldi1; // expected-error {{imaginary types are not supported}} +_Imaginary long double ldi2; // expected-error {{imaginary types are not supported}} + +// Each complex type has the same representation and alignment as an array +// containing two elements of the corresponding real type. +_Static_assert(sizeof(float _Complex) == sizeof(struct { float mem[2]; }), ""); +_Static_assert(_Alignof(float _Complex) == _Alignof(struct { float mem[2]; }), ""); + +_Static_assert(sizeof(double _Complex) == sizeof(struct { double mem[2]; }), ""); +_Static_assert(_Alignof(double _Complex) == _Alignof(struct { double mem[2]; }), ""); + +_Static_assert(sizeof(long double _Complex) == sizeof(struct { long double mem[2]; }), ""); +_Static_assert(_Alignof(long double _Complex) == _Alignof(struct { long double mem[2]; }), ""); + +// The first element corresponds to the real part and the second element +// corresponds to the imaginary part. +_Static_assert(__real((float _Complex){ 1.0f, 2.0f }) == 1.0f, ""); +_Static_assert(__imag((float _Complex){ 1.0f, 2.0f }) == 2.0f, ""); + +_Static_assert(__real((double _Complex){ 1.0, 2.0 }) == 1.0, ""); +_Static_assert(__imag((double _Complex){ 1.0, 2.0 }) == 2.0, ""); + +_Static_assert(__real((long double _Complex){ 1.0L, 2.0L }) == 1.0L, ""); +_Static_assert(__imag((long double _Complex){ 1.0L, 2.0L }) == 2.0L, ""); + +// When a real value is converted to a complex value, the real part follows the +// usual conversion rules and the imaginary part should be zero. +_Static_assert(__real((float _Complex)1.0f) == 1.0f, ""); +_Static_assert(__imag((float _Complex)1.0f) == 0.0f, ""); + +_Static_assert(__real((double _Complex)1.0f) == 1.0, ""); +_Static_assert(__imag((double _Complex)1.0f) == 0.0, ""); + +_Static_assert(__real((long double _Complex)1.0f) == 1.0L, ""); +_Static_assert(__imag((long double _Complex)1.0f) == 0.0L, ""); + +// When a complex value is converted to a real value, the real part follows the +// usual conversion rules and the imaginary part is discarded. +_Static_assert((float)(float _Complex){ 1.0f, 2.0f } == 1.0f, ""); +_Static_assert((double)(float _Complex){ 1.0f, 2.0f } == 1.0, ""); +_Static_assert((long double)(float _Complex){ 1.0f, 2.0f } == 1.0L, ""); + +// Complex values are only equal if both the real and imaginary parts are equal. +_Static_assert((float _Complex){ 1.0f, 2.0f } == (float _Complex){ 1.0f, 2.0f }, ""); +_Static_assert((double _Complex){ 1.0, 2.0 } == (double _Complex){ 1.0, 2.0 }, ""); +_Static_assert((long double _Complex){ 1.0L, 2.0L } == (long double _Complex){ 1.0L, 2.0L }, ""); + +_Static_assert((float _Complex){ 1.0f, 2.0f } != (float _Complex){ 2.0f, 0.0f }, ""); +_Static_assert((double _Complex){ 1.0, 2.0 } != (double _Complex){ 2.0, 0.0 }, ""); +_Static_assert((long double _Complex){ 1.0L, 2.0L } != (long double _Complex){ 2.0L, 0.0L }, ""); + +// You cannot use relational operator on complex values. +int i1 = (float _Complex){ 1.0f, 2.0f } < 10;// expected-error {{invalid operands to binary expression}} +int i2