Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -213,6 +213,8 @@ return Discard(this->emitMul(*T, BO)); case BO_Rem: return Discard(this->emitRem(*T, BO)); + case BO_Div: + return Discard(this->emitDiv(*T, BO)); case BO_Assign: if (!this->emitStore(*T, BO)) return false; Index: clang/lib/AST/Interp/Integral.h =================================================================== --- clang/lib/AST/Interp/Integral.h +++ clang/lib/AST/Interp/Integral.h @@ -215,6 +215,11 @@ return false; } + static bool div(Integral A, Integral B, unsigned OpBits, Integral *R) { + *R = Integral(A.V / B.V); + return false; + } + static bool neg(Integral A, Integral *R) { *R = -A; return false; Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -175,6 +175,25 @@ return false; } +template ::T> +bool Div(InterpState &S, CodePtr OpPC) { + const T &RHS = S.Stk.pop(); + const T &LHS = S.Stk.pop(); + + if (RHS.isZero()) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_expr_divide_by_zero); + return false; + } + const unsigned Bits = RHS.bitWidth() * 2; + T Result; + if (!T::div(LHS, RHS, Bits, &Result)) { + S.Stk.push(Result); + return true; + } + return false; +} + //===----------------------------------------------------------------------===// // Inv //===----------------------------------------------------------------------===// Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -401,7 +401,10 @@ let Types = [NumberTypeClass]; let HasGroup = 1; } - +def Div : Opcode { + let Types = [NumberTypeClass]; + let HasGroup = 1; +} //===----------------------------------------------------------------------===// // Unary operators. Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -167,3 +167,19 @@ // expected-error {{not an integral constant expression}} \ // expected-note {{division by zero}} }; + +namespace div { + constexpr int zero() { return 0; } + static_assert(12 / 3 == 4, ""); + static_assert(12 / 0 == 12, ""); // ref-error {{not an integral constant expression}} \ + // ref-note {{division by zero}} \ + // expected-error {{not an integral constant expression}} \ + // expected-note {{division by zero}} + static_assert(12 / -3 == -4, ""); + static_assert(-12 / 3 == -4, ""); + + + constexpr int LHS = 12; + constexpr long unsigned RHS = 3; + static_assert(LHS / RHS == 4, ""); +};