[clang] 902140d - [clang][Interp] Re-apply "Implement missing compound assign operators"
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 25 01:25:20 PST 2023
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
More information about the cfe-commits
mailing list