Implement inverting and negating values
Details
Diff Detail
Event Timeline
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
134–148 | Implementing the IntegralToBoolean cast is not necessary for this change, but makes more tests possible. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
142 | Nevermind, I get it, you are emitting a 0 and then doing a not equal to zero to determine the result. I feel like a comment explaining what is going on would be helpful for anyone not familiar with the code. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
632 | This code path is not just for boolean values though. | |
clang/lib/AST/Interp/Interp.h | ||
183 | Haha, yes. I already found this bug once before locally but now imported the broken version in my main branch. Thanks for catching that. | |
clang/test/AST/Interp/literals.cpp | ||
2–15 | That works as well but is also fixed after https://reviews.llvm.org/D132136 |
When changing the test to use -verify=test, I noticed that static_assert(-false) did not assert.
I had to implement integral casts (only from sint32 to bool for now) in this patch as well to make it work.
clang/lib/AST/Interp/Integral.h | ||
---|---|---|
175 | I'm a bit out of my element with the template magic here. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
129–130 | ||
632 | All the more reason to be worried about ~ being marked as unreachable (I mostly worry because people often try to make bit fiddling operations constant expressions when possible, so this seems pretty likely to be hit). Perhaps make it into an assert(false && "operation not supported yet"); or something more loud? | |
clang/lib/AST/Interp/Integral.h | ||
175 | It mostly looks correct to me, but the part I'm struggling with is static_cast<Integral::T>; can you explain what you're trying to do there? |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
632 | How is that different? It's just a marker for me so I know later in development that this is not implemented yet. And now that I'm writing this, I guess I see what you mean. Yes, it's not unreachable, but it shouldn't be reached when testing what is currently implemented. | |
clang/lib/AST/Interp/Integral.h | ||
175 | I was trying to implement creating an Integral from a Boolean; the static_cast casts to Integral::T (which in my case is int). It might not be needed. |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
632 | Aaron: we tend to NEVER use 'assert(false...' and instead use llvm_unreachable for 'not implemented yet' quite often in clang. I don't see the semantic difference here? |
clang/lib/AST/Interp/ByteCodeExprGen.cpp | ||
---|---|---|
632 | Aaron clarified offline: the problem is that llvm_unreachable inserts optimization hints in non-asserts builds, so the result is optimizer-caused-UB here. The preference for 'assert(false', though it causing an odd state, at least doesn't allow the optimizer to go hog wild. So I agree with Aaron here. We DO do this wrong in some places, which is unfortunate, but should be considered mistakes, not precedent. |
clang/lib/AST/Interp/Integral.h | ||
---|---|---|
175 | Oh!!! I see now why there's so much confusion. You have template <typename T> and I was wondering why you were trying to use that here. I see now that there's Integral::T as a private member. Can we please rename Integral::T to be something mildly descriptive? (I'm fine if that's done in a follow-up as an NFC change.) |
clang/lib/AST/Interp/Integral.h | ||
---|---|---|
175 | As Aaron said separately, the 'T' name of the integral member is bonkers and confusing! So it appears the intent here is to take a non-integral 'Value', cast it to the underlying representation, and then call the version of this on 159. From a 'style' perspective, I'd prefer this live right next to that version (since it is the inverse SFINAE). In fact, I'd probably prefer you switch this to an 'if constexpr' instead: template <typename ValTy> static Integral from (ValTy Value) { if constexpr (std::is_integral_v<T>) { return Integral(Value); } else { return Integral(static_cast<Integral::RepTy>(Value)); } } } |
clang/lib/AST/Interp/Integral.h | ||
---|---|---|
175 | That's a cool solution, thanks! And yes I'll push a renaming patch. |