@@ -48,6 +48,11 @@ static void discard(InterpStack &Stk, PrimType T) {
4848 TYPE_SWITCH (T, { Stk.discard <T>(); });
4949}
5050
51+ static uint64_t popToUInt64 (const InterpState &S, const Expr *E) {
52+ INT_TYPE_SWITCH (*S.getContext ().classify (E->getType ()),
53+ return static_cast <uint64_t >(S.Stk .pop <T>()));
54+ }
55+
5156static APSInt popToAPSInt (InterpStack &Stk, PrimType T) {
5257 INT_TYPE_SWITCH (T, return Stk.pop <T>().toAPSInt ());
5358}
@@ -212,8 +217,7 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
212217 uint64_t Limit = ~static_cast <uint64_t >(0 );
213218 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
214219 ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
215- Limit = popToAPSInt (S.Stk , *S.getContext ().classify (Call->getArg (2 )))
216- .getZExtValue ();
220+ Limit = popToUInt64 (S, Call->getArg (2 ));
217221
218222 const Pointer &B = S.Stk .pop <Pointer>();
219223 const Pointer &A = S.Stk .pop <Pointer>();
@@ -991,7 +995,7 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
991995 };
992996
993997 const Pointer &Ptr = S.Stk .pop <Pointer>();
994- const APSInt & SizeVal = popToAPSInt (S, Call->getArg (0 ));
998+ uint64_t SizeVal = popToUInt64 (S, Call->getArg (0 ));
995999
9961000 // For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power
9971001 // of two less than or equal to the maximum inline atomic width, we know it
@@ -1003,7 +1007,7 @@ static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
10031007 // x86-64 processors.
10041008
10051009 // Check power-of-two.
1006- CharUnits Size = CharUnits::fromQuantity (SizeVal. getZExtValue () );
1010+ CharUnits Size = CharUnits::fromQuantity (SizeVal);
10071011 if (Size.isPowerOfTwo ()) {
10081012 // Check against inlining width.
10091013 unsigned InlineWidthBits =
@@ -1057,9 +1061,9 @@ static bool interp__builtin_c11_atomic_is_lock_free(InterpState &S,
10571061 CodePtr OpPC,
10581062 const InterpFrame *Frame,
10591063 const CallExpr *Call) {
1060- const APSInt & SizeVal = popToAPSInt (S, Call->getArg (0 ));
1064+ uint64_t SizeVal = popToUInt64 (S, Call->getArg (0 ));
10611065
1062- CharUnits Size = CharUnits::fromQuantity (SizeVal. getZExtValue () );
1066+ CharUnits Size = CharUnits::fromQuantity (SizeVal);
10631067 if (Size.isPowerOfTwo ()) {
10641068 // Check against inlining width.
10651069 unsigned InlineWidthBits =
@@ -1719,12 +1723,10 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17191723 const CallExpr *Call, unsigned ID) {
17201724 assert (Call->getNumArgs () == 3 );
17211725 const ASTContext &ASTCtx = S.getASTContext ();
1722- APSInt Size = popToAPSInt (S, Call->getArg (2 ));
1726+ uint64_t Size = popToUInt64 (S, Call->getArg (2 ));
17231727 Pointer SrcPtr = S.Stk .pop <Pointer>().expand ();
17241728 Pointer DestPtr = S.Stk .pop <Pointer>().expand ();
17251729
1726- assert (!Size.isSigned () && " memcpy and friends take an unsigned size" );
1727-
17281730 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
17291731 diagnoseNonConstexprBuiltin (S, OpPC, ID);
17301732
@@ -1736,7 +1738,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17361738 ID == Builtin::BI__builtin_wmemmove;
17371739
17381740 // If the size is zero, we treat this as always being a valid no-op.
1739- if (Size. isZero () ) {
1741+ if (Size == 0 ) {
17401742 S.Stk .push <Pointer>(DestPtr);
17411743 return true ;
17421744 }
@@ -1798,11 +1800,10 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
17981800 if (WChar) {
17991801 uint64_t WCharSize =
18001802 ASTCtx.getTypeSizeInChars (ASTCtx.getWCharType ()).getQuantity ();
1801- Size *= APSInt (APInt (Size.getBitWidth (), WCharSize, /* IsSigned=*/ false ),
1802- /* IsUnsigend=*/ true );
1803+ Size *= WCharSize;
18031804 }
18041805
1805- if (Size. urem ( DestElemSize) != 0 ) {
1806+ if (Size % DestElemSize != 0 ) {
18061807 S.FFDiag (S.Current ->getSource (OpPC),
18071808 diag::note_constexpr_memcpy_unsupported)
18081809 << Move << WChar << 0 << DestElemType << Size << DestElemSize;
@@ -1835,12 +1836,12 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18351836 // Check if we have enough elements to read from and write to.
18361837 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
18371838 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1838- if (Size. ugt ( RemainingDestBytes) || Size. ugt ( RemainingSrcBytes) ) {
1839- APInt N = Size. udiv ( DestElemSize);
1839+ if (Size > RemainingDestBytes || Size > RemainingSrcBytes) {
1840+ APInt N = APInt ( 64 , Size / DestElemSize);
18401841 S.FFDiag (S.Current ->getSource (OpPC),
18411842 diag::note_constexpr_memcpy_unsupported)
1842- << Move << WChar << (Size. ugt ( RemainingSrcBytes) ? 1 : 2 )
1843- << DestElemType << toString (N, 10 , /* Signed=*/ false );
1843+ << Move << WChar << (Size > RemainingSrcBytes ? 1 : 2 ) << DestElemType
1844+ << toString (N, 10 , /* Signed=*/ false );
18441845 return false ;
18451846 }
18461847
@@ -1857,18 +1858,17 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18571858
18581859 unsigned SrcIndex = SrcP.expand ().getIndex () * SrcP.elemSize ();
18591860 unsigned DstIndex = DestP.expand ().getIndex () * DestP.elemSize ();
1860- unsigned N = Size.getZExtValue ();
18611861
1862- if ((SrcIndex <= DstIndex && (SrcIndex + N ) > DstIndex) ||
1863- (DstIndex <= SrcIndex && (DstIndex + N ) > SrcIndex)) {
1862+ if ((SrcIndex <= DstIndex && (SrcIndex + Size ) > DstIndex) ||
1863+ (DstIndex <= SrcIndex && (DstIndex + Size ) > SrcIndex)) {
18641864 S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_memcpy_overlap)
18651865 << /* IsWChar=*/ false ;
18661866 return false ;
18671867 }
18681868 }
18691869
1870- assert (Size. getZExtValue () % DestElemSize == 0 );
1871- if (!DoMemcpy (S, OpPC, SrcPtr, DestPtr, Bytes (Size. getZExtValue () ).toBits ()))
1870+ assert (Size % DestElemSize == 0 );
1871+ if (!DoMemcpy (S, OpPC, SrcPtr, DestPtr, Bytes (Size).toBits ()))
18721872 return false ;
18731873
18741874 S.Stk .push <Pointer>(DestPtr);
@@ -1885,15 +1885,15 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
18851885 const InterpFrame *Frame,
18861886 const CallExpr *Call, unsigned ID) {
18871887 assert (Call->getNumArgs () == 3 );
1888- const APSInt & Size = popToAPSInt (S, Call->getArg (2 ));
1888+ uint64_t Size = popToUInt64 (S, Call->getArg (2 ));
18891889 const Pointer &PtrB = S.Stk .pop <Pointer>();
18901890 const Pointer &PtrA = S.Stk .pop <Pointer>();
18911891
18921892 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
18931893 ID == Builtin::BIwmemcmp)
18941894 diagnoseNonConstexprBuiltin (S, OpPC, ID);
18951895
1896- if (Size. isZero () ) {
1896+ if (Size == 0 ) {
18971897 pushInteger (S, 0 , Call->getType ());
18981898 return true ;
18991899 }
@@ -1950,7 +1950,7 @@ static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC,
19501950 ElemSize = ASTCtx.getTypeSizeInChars (ASTCtx.getWCharType ()).getQuantity ();
19511951 // The Size given for the wide variants is in wide-char units. Convert it
19521952 // to bytes.
1953- size_t ByteSize = Size. getZExtValue () * ElemSize;
1953+ size_t ByteSize = Size * ElemSize;
19541954 size_t CmpSize = std::min (MinBufferSize, ByteSize);
19551955
19561956 for (size_t I = 0 ; I != CmpSize; I += ElemSize) {
@@ -2238,7 +2238,7 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
22382238 // clear, objects are whole variables. If it is set, a closest surrounding
22392239 // subobject is considered the object a pointer points to. The second bit
22402240 // determines if maximum or minimum of remaining bytes is computed.
2241- unsigned Kind = popToAPSInt (S, Call->getArg (1 )). getZExtValue ( );
2241+ unsigned Kind = popToUInt64 (S, Call->getArg (1 ));
22422242 assert (Kind <= 3 && " unexpected kind" );
22432243 bool UseFieldDesc = (Kind & 1u );
22442244 bool ReportMinimum = (Kind & 2u );
0 commit comments