diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 5304bd77f2c0..ea96e21ea944 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -96,10 +96,21 @@ static void pushInteger(InterpState &S, T Val, QualType QT) { QT); } -static void assignInteger(const Pointer &Dest, PrimType ValueT, +static void assignInteger(InterpState &S, const Pointer &Dest, PrimType ValueT, const APSInt &Value) { - INT_TYPE_SWITCH_NO_BOOL( - ValueT, { Dest.deref() = T::from(static_cast(Value)); }); + + if (ValueT == PT_IntAPS) { + Dest.deref>() = + S.allocAP>(Value.getBitWidth()); + Dest.deref>().copy(Value); + } else if (ValueT == PT_IntAP) { + Dest.deref>() = + S.allocAP>(Value.getBitWidth()); + Dest.deref>().copy(Value); + } else { + INT_TYPE_SWITCH_NO_BOOL( + ValueT, { Dest.deref() = T::from(static_cast(Value)); }); + } } static QualType getElemType(const Pointer &P) { @@ -849,7 +860,7 @@ static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, } // Write Result to ResultPtr and put Overflow on the stack. - assignInteger(ResultPtr, ResultT, Result); + assignInteger(S, ResultPtr, ResultT, Result); ResultPtr.initialize(); assert(Call->getDirectCallee()->getReturnType()->isBooleanType()); S.Stk.push(Overflow); @@ -902,7 +913,7 @@ static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); PrimType CarryOutT = *S.getContext().classify(CarryOutType); - assignInteger(CarryOutPtr, CarryOutT, CarryOut); + assignInteger(S, CarryOutPtr, CarryOutT, CarryOut); CarryOutPtr.initialize(); assert(Call->getType() == Call->getArg(0)->getType()); @@ -1414,7 +1425,7 @@ static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); PrimType CarryOutT = *S.getContext().classify(CarryOutType); - assignInteger(CarryOutPtr, CarryOutT, APSInt(Result, true)); + assignInteger(S, CarryOutPtr, CarryOutT, APSInt(Result, true)); pushInteger(S, CarryOut, Call->getType()); diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 174c1ffa79a4..3b95a8ea4859 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1739,4 +1739,18 @@ namespace WithinLifetime { // both-warning {{expression result unused}} } } + +#ifdef __SIZEOF_INT128__ +namespace I128Mul { + constexpr int mul() { + __int128 A = 10; + __int128 B = 10; + __int128 R; + __builtin_mul_overflow(A, B, &R); + return 1; + } + static_assert(mul() == 1); +} +#endif + #endif