Author: Timm Bäder Date: 2023-01-25T10:24:50+01:00 New Revision: 902140dd3877b63bb749fce64e22d0d39e3a9ec2
URL: https://github.com/llvm/llvm-project/commit/902140dd3877b63bb749fce64e22d0d39e3a9ec2 DIFF: https://github.com/llvm/llvm-project/commit/902140dd3877b63bb749fce64e22d0d39e3a9ec2.diff LOG: [clang][Interp] Re-apply "Implement missing compound assign operators" Implement mul, div, rem, etc. compound assign operators. Differential Revision: https://reviews.llvm.org/D137071 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/literals.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a777768061c4..fa2c74c4e1a5 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -534,11 +534,18 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator( if (!this->emitSub(*LHSComputationT, E)) return false; break; - case BO_MulAssign: + if (!this->emitMul(*LHSComputationT, E)) + return false; + break; case BO_DivAssign: + if (!this->emitDiv(*LHSComputationT, E)) + return false; + break; case BO_RemAssign: - + if (!this->emitRem(*LHSComputationT, E)) + return false; + break; case BO_ShlAssign: if (!this->emitShl(*LHSComputationT, *RT, E)) return false; @@ -548,8 +555,17 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator( return false; break; case BO_AndAssign: + if (!this->emitBitAnd(*LHSComputationT, E)) + return false; + break; case BO_XorAssign: + if (!this->emitBitXor(*LHSComputationT, E)) + return false; + break; case BO_OrAssign: + if (!this->emitBitOr(*LHSComputationT, E)) + return false; + break; default: llvm_unreachable("Unimplemented compound assign operator"); } diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index cd5c9da9bda5..4fc9489941e5 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -469,5 +469,160 @@ namespace IncDec { return (a -= a); } static_assert(subAll(213) == 0, ""); + + constexpr bool BoolOr(bool b1, bool b2) { + bool a; + a = b1; + a |= b2; + return a; + } + static_assert(BoolOr(true, true), ""); + static_assert(BoolOr(true, false), ""); + static_assert(BoolOr(false, true), ""); + static_assert(!BoolOr(false, false), ""); + + constexpr int IntOr(unsigned a, unsigned b) { + unsigned r; + r = a; + r |= b; + return r; + } + static_assert(IntOr(10, 1) == 11, ""); + static_assert(IntOr(1337, -1) == -1, ""); + static_assert(IntOr(0, 12) == 12, ""); + + constexpr bool BoolAnd(bool b1, bool b2) { + bool a; + a = b1; + a &= b2; + return a; + } + static_assert(BoolAnd(true, true), ""); + static_assert(!BoolAnd(true, false), ""); + static_assert(!BoolAnd(false, true), ""); + static_assert(!BoolAnd(false, false), ""); + + constexpr int IntAnd(unsigned a, unsigned b) { + unsigned r; + r = a; + r &= b; + return r; + } + static_assert(IntAnd(10, 1) == 0, ""); + static_assert(IntAnd(1337, -1) == 1337, ""); + static_assert(IntAnd(0, 12) == 0, ""); + + constexpr bool BoolXor(bool b1, bool b2) { + bool a; + a = b1; + a ^= b2; + return a; + } + static_assert(!BoolXor(true, true), ""); + static_assert(BoolXor(true, false), ""); + static_assert(BoolXor(false, true), ""); + static_assert(!BoolXor(false, false), ""); + + constexpr int IntXor(unsigned a, unsigned b) { + unsigned r; + r = a; + r ^= b; + return r; + } + static_assert(IntXor(10, 1) == 11, ""); + static_assert(IntXor(10, 10) == 0, ""); + static_assert(IntXor(12, true) == 13, ""); + + constexpr bool BoolRem(bool b1, bool b2) { + bool a; + a = b1; + a %= b2; + return a; + } + static_assert(!BoolRem(true, true), ""); + static_assert(!BoolRem(false, true), ""); + + constexpr int IntRem(int a, int b) { + int r; + r = a; + r %= b; // expected-note {{division by zero}} \ + // ref-note {{division by zero}} \ + // expected-note {{outside the range of representable values}} \ + // ref-note {{outside the range of representable values}} + return r; + } + static_assert(IntRem(2, 2) == 0, ""); + static_assert(IntRem(2, 1) == 0, ""); + static_assert(IntRem(9, 7) == 2, ""); + static_assert(IntRem(5, 0) == 0, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'IntRem(5, 0)'}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'IntRem(5, 0)'}} + + static_assert(IntRem(INT_MIN, -1) == 0, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'IntRem}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'IntRem}} + + + + constexpr bool BoolDiv(bool b1, bool b2) { + bool a; + a = b1; + a /= b2; + return a; + } + static_assert(BoolDiv(true, true), ""); + static_assert(!BoolDiv(false, true), ""); + + constexpr int IntDiv(int a, int b) { + int r; + r = a; + r /= b; // expected-note {{division by zero}} \ + // ref-note {{division by zero}} \ + // expected-note {{outside the range of representable values}} \ + // ref-note {{outside the range of representable values}} + return r; + } + static_assert(IntDiv(2, 2) == 1, ""); + static_assert(IntDiv(12, 20) == 0, ""); + static_assert(IntDiv(2, 1) == 2, ""); + static_assert(IntDiv(9, 7) == 1, ""); + static_assert(IntDiv(5, 0) == 0, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'IntDiv(5, 0)'}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'IntDiv(5, 0)'}} + + static_assert(IntDiv(INT_MIN, -1) == 0, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'IntDiv}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'IntDiv}} + + constexpr bool BoolMul(bool b1, bool b2) { + bool a; + a = b1; + a *= b2; + return a; + } + static_assert(BoolMul(true, true), ""); + static_assert(!BoolMul(true, false), ""); + static_assert(!BoolMul(false, true), ""); + static_assert(!BoolMul(false, false), ""); + + constexpr int IntMul(int a, int b) { + int r; + r = a; + r *= b; // expected-note {{is outside the range of representable values of type 'int'}} \ + // ref-note {{is outside the range of representable values of type 'int'}} + return r; + } + static_assert(IntMul(2, 2) == 4, ""); + static_assert(IntMul(12, 20) == 240, ""); + static_assert(IntMul(2, 1) == 2, ""); + static_assert(IntMul(9, 7) == 63, ""); + static_assert(IntMul(INT_MAX, 2) == 0, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'IntMul}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'IntMul}} }; #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits