diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e9e20b222d5d3..d9389e7b00331 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1665,9 +1665,9 @@ bool ByteCodeExprGen::visitZeroInitializer(PrimType T, QualType QT, case PT_Uint64: return this->emitZeroUint64(E); case PT_IntAP: + return this->emitZeroIntAP(Ctx.getBitWidth(QT), E); case PT_IntAPS: - assert(false); - return false; + return this->emitZeroIntAPS(Ctx.getBitWidth(QT), E); case PT_Ptr: return this->emitNullPtr(E); case PT_FnPtr: diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index fd120944a2504..ebf362238ba09 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -78,7 +78,8 @@ template class IntegralAP final { template static IntegralAP from(T Value, unsigned NumBits = 0) { assert(NumBits > 0); - APSInt Copy = APSInt(APInt(NumBits, static_cast(Value), Signed), !Signed); + APSInt Copy = + APSInt(APInt(NumBits, static_cast(Value), Signed), !Signed); return IntegralAP(Copy); } @@ -97,16 +98,16 @@ template class IntegralAP final { template static IntegralAP from(Integral I, unsigned BitWidth) { APSInt Copy = - APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed); + APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed); Copy.setIsSigned(Signed); assert(Copy.isSigned() == Signed); return IntegralAP(Copy); } - static IntegralAP zero() { - assert(false); - return IntegralAP(0); + static IntegralAP zero(int32_t BitWidth) { + APSInt V = APSInt(APInt(BitWidth, 0LL, Signed), !Signed); + return IntegralAP(V); } constexpr unsigned bitWidth() const { return V.getBitWidth(); } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 3d226a40f9cf6..4b081301655cf 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1688,6 +1688,16 @@ bool Zero(InterpState &S, CodePtr OpPC) { return true; } +static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { + S.Stk.push>(IntegralAP::zero(BitWidth)); + return true; +} + +static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { + S.Stk.push>(IntegralAP::zero(BitWidth)); + return true; +} + template ::T> inline bool Null(InterpState &S, CodePtr OpPC) { S.Stk.push(); diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 9d390fed15241..e1e7e5e2efbb0 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -72,6 +72,11 @@ def IntegerTypeClass : TypeClass { Uint32, Sint64, Uint64, IntAP, IntAPS]; } +def FixedSizeIntegralTypeClass : TypeClass { + let Types = [Sint8, Uint8, Sint16, Uint16, Sint32, + Uint32, Sint64, Uint64, Bool]; +} + def NumberTypeClass : TypeClass { let Types = !listconcat(IntegerTypeClass.Types, [Float]); } @@ -243,10 +248,18 @@ def ConstBool : ConstOpcode; // [] -> [Integer] def Zero : Opcode { - let Types = [AluTypeClass]; + let Types = [FixedSizeIntegralTypeClass]; let HasGroup = 1; } +def ZeroIntAP : Opcode { + let Args = [ArgUint32]; +} + +def ZeroIntAPS : Opcode { + let Args = [ArgUint32]; +} + // [] -> [Pointer] def Null : Opcode { let Types = [PtrTypeClass]; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index ef7a0d4f0dfda..27fae1b904351 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -17,6 +17,16 @@ constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; static_assert(B_ == 1, ""); +constexpr MaxBitInt BitIntZero{}; +static_assert(BitIntZero == 0, ""); +constexpr unsigned _BitInt(128) UBitIntZero{}; +static_assert(UBitIntZero == 0, ""); + +constexpr _BitInt(2) BitIntZero2{}; +static_assert(BitIntZero2 == 0, ""); +constexpr unsigned _BitInt(1) UBitIntZero1{}; +static_assert(UBitIntZero1 == 0, ""); + #ifdef __SIZEOF_INT128__ namespace i128 { @@ -49,6 +59,11 @@ namespace i128 { constexpr uint128_t AllOnes = ~static_cast(0); static_assert(AllOnes == UINT128_MAX, ""); + constexpr uint128_t i128Zero{}; + static_assert(i128Zero == 0, ""); + constexpr uint128_t ui128Zero{}; + static_assert(ui128Zero == 0, ""); + #if __cplusplus >= 201402L template constexpr T CastFrom(__int128_t A) {