diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.h')
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.h | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 7ba6e21..9012442 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -468,10 +468,10 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) { const Pointer &Result = S.Stk.peek<Pointer>(); if constexpr (std::is_same_v<T, Floating>) { - APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat(); - APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat(); - APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat(); - APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat(); + APFloat A = LHS.elem<Floating>(0).getAPFloat(); + APFloat B = LHS.elem<Floating>(1).getAPFloat(); + APFloat C = RHS.elem<Floating>(0).getAPFloat(); + APFloat D = RHS.elem<Floating>(1).getAPFloat(); APFloat ResR(A.getSemantics()); APFloat ResI(A.getSemantics()); @@ -480,20 +480,20 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) { // Copy into the result. Floating RA = S.allocFloat(A.getSemantics()); RA.copy(ResR); - Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR); + Result.elem<Floating>(0) = RA; // Floating(ResR); Result.atIndex(0).initialize(); Floating RI = S.allocFloat(A.getSemantics()); RI.copy(ResI); - Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI); + Result.elem<Floating>(1) = RI; // Floating(ResI); Result.atIndex(1).initialize(); Result.initialize(); } else { // Integer element type. - const T &LHSR = LHS.atIndex(0).deref<T>(); - const T &LHSI = LHS.atIndex(1).deref<T>(); - const T &RHSR = RHS.atIndex(0).deref<T>(); - const T &RHSI = RHS.atIndex(1).deref<T>(); + const T &LHSR = LHS.elem<T>(0); + const T &LHSI = LHS.elem<T>(1); + const T &RHSR = RHS.elem<T>(0); + const T &RHSI = RHS.elem<T>(1); unsigned Bits = LHSR.bitWidth(); // real(Result) = (real(LHS) * real(RHS)) - (imag(LHS) * imag(RHS)) @@ -503,7 +503,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) { T B; if (T::mul(LHSI, RHSI, Bits, &B)) return false; - if (T::sub(A, B, Bits, &Result.atIndex(0).deref<T>())) + if (T::sub(A, B, Bits, &Result.elem<T>(0))) return false; Result.atIndex(0).initialize(); @@ -512,7 +512,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) { return false; if (T::mul(LHSI, RHSR, Bits, &B)) return false; - if (T::add(A, B, Bits, &Result.atIndex(1).deref<T>())) + if (T::add(A, B, Bits, &Result.elem<T>(1))) return false; Result.atIndex(1).initialize(); Result.initialize(); @@ -528,10 +528,10 @@ inline bool Divc(InterpState &S, CodePtr OpPC) { const Pointer &Result = S.Stk.peek<Pointer>(); if constexpr (std::is_same_v<T, Floating>) { - APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat(); - APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat(); - APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat(); - APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat(); + APFloat A = LHS.elem<Floating>(0).getAPFloat(); + APFloat B = LHS.elem<Floating>(1).getAPFloat(); + APFloat C = RHS.elem<Floating>(0).getAPFloat(); + APFloat D = RHS.elem<Floating>(1).getAPFloat(); APFloat ResR(A.getSemantics()); APFloat ResI(A.getSemantics()); @@ -540,21 +540,21 @@ inline bool Divc(InterpState &S, CodePtr OpPC) { // Copy into the result. Floating RA = S.allocFloat(A.getSemantics()); RA.copy(ResR); - Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR); + Result.elem<Floating>(0) = RA; // Floating(ResR); Result.atIndex(0).initialize(); Floating RI = S.allocFloat(A.getSemantics()); RI.copy(ResI); - Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI); + Result.elem<Floating>(1) = RI; // Floating(ResI); Result.atIndex(1).initialize(); Result.initialize(); } else { // Integer element type. - const T &LHSR = LHS.atIndex(0).deref<T>(); - const T &LHSI = LHS.atIndex(1).deref<T>(); - const T &RHSR = RHS.atIndex(0).deref<T>(); - const T &RHSI = RHS.atIndex(1).deref<T>(); + const T &LHSR = LHS.elem<T>(0); + const T &LHSI = LHS.elem<T>(1); + const T &RHSR = RHS.elem<T>(0); + const T &RHSI = RHS.elem<T>(1); unsigned Bits = LHSR.bitWidth(); const T Zero = T::from(0, Bits); @@ -581,8 +581,8 @@ inline bool Divc(InterpState &S, CodePtr OpPC) { } // real(Result) = ((real(LHS) * real(RHS)) + (imag(LHS) * imag(RHS))) / Den - T &ResultR = Result.atIndex(0).deref<T>(); - T &ResultI = Result.atIndex(1).deref<T>(); + T &ResultR = Result.elem<T>(0); + T &ResultI = Result.elem<T>(1); if (T::mul(LHSR, RHSR, Bits, &A) || T::mul(LHSI, RHSI, Bits, &B)) return false; @@ -1983,6 +1983,16 @@ static inline bool Activate(InterpState &S, CodePtr OpPC) { return true; } +static inline bool ActivateThisField(InterpState &S, CodePtr OpPC, uint32_t I) { + if (S.checkingPotentialConstantExpression()) + return false; + + const Pointer &Ptr = S.Current->getThis(); + assert(Ptr.atField(I).canBeInitialized()); + Ptr.atField(I).activate(); + return true; +} + template <PrimType Name, class T = typename PrimConv<Name>::T> bool StoreActivate(InterpState &S, CodePtr OpPC) { const T &Value = S.Stk.pop<T>(); @@ -3103,7 +3113,7 @@ inline bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index) { return false; assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name); - S.Stk.push<T>(Ptr.atIndex(Index).deref<T>()); + S.Stk.push<T>(Ptr.elem<T>(Index)); return true; } @@ -3115,7 +3125,7 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) { return false; assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name); - S.Stk.push<T>(Ptr.atIndex(Index).deref<T>()); + S.Stk.push<T>(Ptr.elem<T>(Index)); return true; } @@ -3557,12 +3567,22 @@ inline bool BitCastPrim(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte, Floating Result = S.allocFloat(*Sem); Floating::bitcastFromMemory(Buff.data(), *Sem, &Result); S.Stk.push<Floating>(Result); - - // S.Stk.push<Floating>(T::bitcastFromMemory(Buff.data(), *Sem)); } else if constexpr (needsAlloc<T>()) { T Result = S.allocAP<T>(ResultBitWidth); T::bitcastFromMemory(Buff.data(), ResultBitWidth, &Result); S.Stk.push<T>(Result); + } else if constexpr (std::is_same_v<T, Boolean>) { + // Only allow to cast single-byte integers to bool if they are either 0 + // or 1. + assert(FullBitWidth.getQuantity() == 8); + auto Val = static_cast<unsigned int>(Buff[0]); + if (Val > 1) { + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_bit_cast_unrepresentable_value) + << S.getASTContext().BoolTy << Val; + return false; + } + S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth)); } else { assert(!Sem); S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth)); |