return this->emitConst(E, E->getValue());
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
+ const CompoundAssignOperator *E) {
+ const Expr *LHS = E->getLHS();
+ const Expr *RHS = E->getRHS();
+ Optional<PrimType> LT = classify(E->getLHS()->getType());
+ Optional<PrimType> RT = classify(E->getRHS()->getType());
+
+ if (!LT || !RT)
+ return false;
+
+ assert(!E->getType()->isPointerType() &&
+ "Support pointer arithmethic in compound assignment operators");
+
+ // Get LHS pointer, load its value and get RHS value.
+ if (!visit(LHS))
+ return false;
+ if (!this->emitLoad(*LT, E))
+ return false;
+ if (!visit(RHS))
+ return false;
+
+ // Perform operation.
+ switch (E->getOpcode()) {
+ case BO_AddAssign:
+ if (!this->emitAdd(*LT, E))
+ return false;
+ break;
+ case BO_SubAssign:
+ if (!this->emitSub(*LT, E))
+ return false;
+ break;
+
+ case BO_MulAssign:
+ case BO_DivAssign:
+ case BO_RemAssign:
+ case BO_ShlAssign:
+ case BO_ShrAssign:
+ case BO_AndAssign:
+ case BO_XorAssign:
+ case BO_OrAssign:
+ default:
+ llvm_unreachable("Unimplemented compound assign operator");
+ }
+
+ // And store the result in LHS.
+ if (DiscardResult)
+ return this->emitStorePop(*LT, E);
+ return this->emitStore(*LT, E);
+}
+
template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true);
return this->Visit(E);
// expected-note {{in call to 'UnderFlow()'}} \
// ref-error {{not an integral constant expression}} \
// ref-note {{in call to 'UnderFlow()'}}
+
+ constexpr int getTwo() {
+ int i = 1;
+ return (i += 1);
+ }
+ static_assert(getTwo() == 2, "");
+
+ constexpr int sub(int a) {
+ return (a -= 2);
+ }
+ static_assert(sub(7) == 5, "");
+
+ constexpr int add(int a, int b) {
+ a += b; // expected-note {{is outside the range of representable values}} \
+ // ref-note {{is outside the range of representable values}}
+ return a;
+ }
+ static_assert(add(1, 2) == 3, "");
+ static_assert(add(INT_MAX, 1) == 0, ""); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'add}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'add}}
+
+ constexpr int sub(int a, int b) {
+ a -= b; // expected-note {{is outside the range of representable values}} \
+ // ref-note {{is outside the range of representable values}}
+ return a;
+ }
+ static_assert(sub(10, 20) == -10, "");
+ static_assert(sub(INT_MIN, 1) == 0, ""); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'sub}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'sub}}
+
+ constexpr int subAll(int a) {
+ return (a -= a);
+ }
+ static_assert(subAll(213) == 0, "");
};
#endif