This is an archive of the discontinued LLVM Phabricator instance.

[clang][Interp] Start implementing binary operators for complex types
ClosedPublic

Authored by tbaeder on Jul 18 2023, 3:16 AM.

Diff Detail

Event Timeline

tbaeder created this revision.Jul 18 2023, 3:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 18 2023, 3:16 AM
tbaeder requested review of this revision.Jul 18 2023, 3:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 18 2023, 3:16 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Is this intended to not handle all the binary operators in this patch? And also, is this intended to only impact initializers?

clang/lib/AST/Interp/ByteCodeExprGen.cpp
570–571

Should we be getting the canonical type because of the assertion below? I'm wondering specifically about a case where the LHS is a complex type and the RHS is a typedef to a complex type, that kind of thing.

Is this intended to not handle all the binary operators in this patch?

Yes, just a subset for now.

And also, is this intended to only impact initializers?

Yes, due to problems with (non-)initializers. This should work after https://reviews.llvm.org/D156027 though.

Is this intended to not handle all the binary operators in this patch?

Yes, just a subset for now.

And also, is this intended to only impact initializers?

Yes, due to problems with (non-)initializers. This should work after https://reviews.llvm.org/D156027 though.

Okay, thanks for confirmation! The only outstanding thing is adding coverage for typedef types:

using Frobble = float;
using Bobble = _Complex float;
using Gobble = _Complex Frobble;

constexpr _Complex Frobble A = { 13.0, 2.0 };
constexpr Bobble B = { 2.0, 1.0  };
constexpr Gobble C = { 3.0, 5.0 };
constexpr _Complex float D = A - B;
constexpr _Complex float E = C - B;
static_assert(__real(D) == 11.0, "");
static_assert(__imag(D) == 1.0, "");
static_assert(__real(E) == 1.0, "");
static_assert(__imag(E) == 4.0, "");

Is this intended to not handle all the binary operators in this patch?

Yes, just a subset for now.

And also, is this intended to only impact initializers?

Yes, due to problems with (non-)initializers. This should work after https://reviews.llvm.org/D156027 though.

Okay, thanks for confirmation! The only outstanding thing is adding coverage for typedef types:

using Frobble = float;
using Bobble = _Complex float;
using Gobble = _Complex Frobble;

constexpr _Complex Frobble A = { 13.0, 2.0 };
constexpr Bobble B = { 2.0, 1.0  };
constexpr Gobble C = { 3.0, 5.0 };
constexpr _Complex float D = A - B;
constexpr _Complex float E = C - B;
static_assert(__real(D) == 11.0, "");
static_assert(__imag(D) == 1.0, "");
static_assert(__real(E) == 1.0, "");
static_assert(__imag(E) == 4.0, "");

https://godbolt.org/z/59c8Y4sqz - Is that even supposed to work?

Is this intended to not handle all the binary operators in this patch?

Yes, just a subset for now.

And also, is this intended to only impact initializers?

Yes, due to problems with (non-)initializers. This should work after https://reviews.llvm.org/D156027 though.

Okay, thanks for confirmation! The only outstanding thing is adding coverage for typedef types:

using Frobble = float;
using Bobble = _Complex float;
using Gobble = _Complex Frobble;

constexpr _Complex Frobble A = { 13.0, 2.0 };
constexpr Bobble B = { 2.0, 1.0  };
constexpr Gobble C = { 3.0, 5.0 };
constexpr _Complex float D = A - B;
constexpr _Complex float E = C - B;
static_assert(__real(D) == 11.0, "");
static_assert(__imag(D) == 1.0, "");
static_assert(__real(E) == 1.0, "");
static_assert(__imag(E) == 4.0, "");

https://godbolt.org/z/59c8Y4sqz - Is that even supposed to work?

Hmmm, I think the answer is "no"... and "maybe." _Complex can only be followed by float, double, or long double specifically per the C standard. However, we also support _Complex int (and others) as an extension, which starts to make _Complex look more like _Atomic in that it augments an existing type, and so typedefs seem quite reasonable.

But that's not your issue to worry about. Instead, let's go with this test:

using Bobble = _Complex float;

constexpr _Complex float A = { 13.0, 2.0 };
constexpr Bobble B = { 2.0, 1.0  };
constexpr _Complex float D = A - B;
static_assert(__real(D) == 11.0, "");
static_assert(__imag(D) == 1.0, "");

https://godbolt.org/z/Mrxfjzrnz

Hmmm, I think the answer is "no"... and "maybe." _Complex can only be followed by float, double, or long double specifically per the C standard. However, we also support _Complex int (and others) as an extension, which starts to make _Complex look more like _Atomic in that it augments an existing type, and so typedefs seem quite reasonable.

I know that much, I guess I was confused by the diagnostics:

../clang/test/AST/Interp/complex.cpp:121:18: warning: plain '_Complex' requires a type specifier; assuming '_Complex double'
  121 |   using Gobble = _Complex Frobble;
      |                  ^
      |                           double
tbaeder updated this revision to Diff 556825.Sep 14 2023, 9:54 PM
aaron.ballman accepted this revision.Sep 28 2023, 9:30 AM

Hmmm, I think the answer is "no"... and "maybe." _Complex can only be followed by float, double, or long double specifically per the C standard. However, we also support _Complex int (and others) as an extension, which starts to make _Complex look more like _Atomic in that it augments an existing type, and so typedefs seem quite reasonable.

I know that much, I guess I was confused by the diagnostics:

../clang/test/AST/Interp/complex.cpp:121:18: warning: plain '_Complex' requires a type specifier; assuming '_Complex double'
  121 |   using Gobble = _Complex Frobble;
      |                  ^
      |                           double

Yeah, that diagnostic could stand to be improved; but is orthogonal to your patch.

LGTM though there's a comment on the test cases you should peek at.

clang/test/AST/Interp/complex.cpp
119–124

Should this be under the Sub namespace instead of hanging out by itself?

This revision is now accepted and ready to land.Sep 28 2023, 9:30 AM
tbaeder added inline comments.Sep 29 2023, 1:15 AM
clang/test/AST/Interp/complex.cpp
119–124

Yeah I guess it should.

This revision was landed with ongoing or failed builds.Thu, Dec 14, 5:57 PM
This revision was automatically updated to reflect the committed changes.