Author: Timm Baeder Date: 2023-11-16T06:18:17+01:00 New Revision: 6416b2d0a81abdce0819961b9d12609e34916098
URL: https://github.com/llvm/llvm-project/commit/6416b2d0a81abdce0819961b9d12609e34916098 DIFF: https://github.com/llvm/llvm-project/commit/6416b2d0a81abdce0819961b9d12609e34916098.diff LOG: [clang][Interp] Implement IntegralAP subtraction (#71648) Added: Modified: clang/lib/AST/Interp/IntegralAP.h clang/test/AST/Interp/intap.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 88de1f1392e6813..b8e37878ce2f848 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -191,12 +191,11 @@ template <bool Signed> class IntegralAP final { } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { - return CheckAddUB(A, B, OpBits, R); + return CheckAddSubUB<std::plus>(A, B, OpBits, R); } static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { - /// FIXME: Gotta check if the result fits into OpBits bits. - return CheckSubUB(A, B, R); + return CheckAddSubUB<std::minus>(A, B, OpBits, R); } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -264,28 +263,21 @@ template <bool Signed> class IntegralAP final { } private: - static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B, - unsigned BitWidth, IntegralAP *R) { - if (!A.isSigned()) { - R->V = A.V + B.V; + template <template <typename T> class Op> + static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B, + unsigned BitWidth, IntegralAP *R) { + if constexpr (!Signed) { + R->V = Op<APInt>{}(A.V, B.V); return false; } - const APSInt &LHS = APSInt(A.V, A.isSigned()); - const APSInt &RHS = APSInt(B.V, B.isSigned()); - - APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); + const APSInt &LHS = A.toAPSInt(); + const APSInt &RHS = B.toAPSInt(); + APSInt Value = Op<APSInt>{}(LHS.extend(BitWidth), RHS.extend(BitWidth)); APSInt Result = Value.trunc(LHS.getBitWidth()); - if (Result.extend(BitWidth) != Value) - return true; - R->V = Result; - return false; - } - static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B, - IntegralAP *R) { - R->V = A.V - B.V; - return false; // Success! + + return Result.extend(BitWidth) != Value; } }; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 34c8d0565082994..c3cae9a64780d5c 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -11,7 +11,12 @@ constexpr _BitInt(2) B = A + 1; constexpr _BitInt(2) C = B + 1; // expected-warning {{from 2 to -2}} \ // ref-warning {{from 2 to -2}} static_assert(C == -2, ""); +static_assert(C - B == A, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{value -3 is outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{value -3 is outside the range of representable values}} +static_assert(B - 1 == 0, ""); constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; @@ -130,6 +135,16 @@ namespace i128 { // expected-warning {{implicit conversion of out of range value}} \ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{is outside the range of representable values of type}} + + constexpr uint128_t Zero = 0; + static_assert((Zero -1) == -1, ""); + constexpr int128_t Five = 5; + static_assert(Five - Zero == Five, ""); + + constexpr int128_t Sub1 = INT128_MIN - 1; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{-170141183460469231731687303715884105729 is outside the range}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{-170141183460469231731687303715884105729 is outside the range}} } namespace AddSubOffset { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits