@@ -162,6 +162,15 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
162162 const CallExpr *CE);
163163bool CheckLiteralType (InterpState &S, CodePtr OpPC, const Type *T);
164164
165+ template <typename T>
166+ static bool handleOverflow (InterpState &S, CodePtr OpPC, const T &SrcValue) {
167+ const Expr *E = S.Current ->getExpr (OpPC);
168+ S.CCEDiag (E, diag::note_constexpr_overflow) << SrcValue << E->getType ();
169+ return S.noteUndefinedBehavior ();
170+ }
171+ bool handleFixedPointOverflow (InterpState &S, CodePtr OpPC,
172+ const FixedPoint &FP);
173+
165174enum class ShiftDir { Left, Right };
166175
167176// / Checks if the shift operation is legal.
@@ -385,13 +394,10 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS,
385394 << Trunc << Type << E->getSourceRange ();
386395 }
387396
388- S.CCEDiag (E, diag::note_constexpr_overflow) << Value << Type;
389-
390- if (!S.noteUndefinedBehavior ()) {
397+ if (!handleOverflow (S, OpPC, Value)) {
391398 S.Stk .pop <T>();
392399 return false ;
393400 }
394-
395401 return true ;
396402}
397403
@@ -741,8 +747,7 @@ bool Neg(InterpState &S, CodePtr OpPC) {
741747 return true ;
742748 }
743749
744- S.CCEDiag (E, diag::note_constexpr_overflow) << NegatedValue << Type;
745- return S.noteUndefinedBehavior ();
750+ return handleOverflow (S, OpPC, NegatedValue);
746751}
747752
748753enum class PushVal : bool {
@@ -804,8 +809,7 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
804809 return true ;
805810 }
806811
807- S.CCEDiag (E, diag::note_constexpr_overflow) << APResult << Type;
808- return S.noteUndefinedBehavior ();
812+ return handleOverflow (S, OpPC, APResult);
809813}
810814
811815// / 1) Pops a pointer from the stack
@@ -2170,18 +2174,8 @@ inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) {
21702174 bool Overflow;
21712175 FixedPoint Result = Source.toSemantics (TargetSemantics, &Overflow);
21722176
2173- if (Overflow) {
2174- const Expr *E = S.Current ->getExpr (OpPC);
2175- if (S.checkingForUndefinedBehavior ()) {
2176- S.getASTContext ().getDiagnostics ().Report (
2177- E->getExprLoc (), diag::warn_fixedpoint_constant_overflow)
2178- << Result.toDiagnosticString (S.getASTContext ()) << E->getType ();
2179- }
2180- S.CCEDiag (E, diag::note_constexpr_overflow)
2181- << Result.toDiagnosticString (S.getASTContext ()) << E->getType ();
2182- if (!S.noteUndefinedBehavior ())
2183- return false ;
2184- }
2177+ if (Overflow && !handleFixedPointOverflow (S, OpPC, Result))
2178+ return false ;
21852179
21862180 S.Stk .push <FixedPoint>(Result);
21872181 return true ;
@@ -2257,13 +2251,8 @@ static inline bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC,
22572251 auto Status = F.convertToInteger (Result);
22582252
22592253 // Float-to-Integral overflow check.
2260- if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite ()) {
2261- const Expr *E = S.Current ->getExpr (OpPC);
2262- QualType Type = E->getType ();
2263-
2264- S.CCEDiag (E, diag::note_constexpr_overflow) << F.getAPFloat () << Type;
2265- return S.noteUndefinedBehavior ();
2266- }
2254+ if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite ())
2255+ return handleOverflow (S, OpPC, F.getAPFloat ());
22672256
22682257 FPOptions FPO = FPOptions::getFromOpaqueInt (FPOI);
22692258 S.Stk .push <IntegralAP<true >>(IntegralAP<true >(Result));
@@ -2278,13 +2267,8 @@ static inline bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC,
22782267 auto Status = F.convertToInteger (Result);
22792268
22802269 // Float-to-Integral overflow check.
2281- if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite ()) {
2282- const Expr *E = S.Current ->getExpr (OpPC);
2283- QualType Type = E->getType ();
2284-
2285- S.CCEDiag (E, diag::note_constexpr_overflow) << F.getAPFloat () << Type;
2286- return S.noteUndefinedBehavior ();
2287- }
2270+ if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite ())
2271+ return handleOverflow (S, OpPC, F.getAPFloat ());
22882272
22892273 FPOptions FPO = FPOptions::getFromOpaqueInt (FPOI);
22902274 S.Stk .push <IntegralAP<true >>(IntegralAP<true >(Result));
@@ -2347,20 +2331,10 @@ static inline bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC,
23472331 std::memcpy (&Sem, &FPS, sizeof (Sem));
23482332
23492333 bool Overflow;
2350- llvm::APFixedPoint Result =
2351- llvm::APFixedPoint::getFromIntValue (Int.toAPSInt (), Sem, &Overflow);
2334+ FixedPoint Result = FixedPoint::from (Int.toAPSInt (), Sem, &Overflow);
23522335
2353- if (Overflow) {
2354- const Expr *E = S.Current ->getExpr (OpPC);
2355- if (S.checkingForUndefinedBehavior ()) {
2356- S.getASTContext ().getDiagnostics ().Report (
2357- E->getExprLoc (), diag::warn_fixedpoint_constant_overflow)
2358- << Result.toString () << E->getType ();
2359- }
2360- S.CCEDiag (E, diag::note_constexpr_overflow) << Result << E->getType ();
2361- if (!S.noteUndefinedBehavior ())
2362- return false ;
2363- }
2336+ if (Overflow && !handleFixedPointOverflow (S, OpPC, Result))
2337+ return false ;
23642338
23652339 S.Stk .push <FixedPoint>(Result);
23662340 return true ;
@@ -2374,20 +2348,10 @@ static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC,
23742348 std::memcpy (&Sem, &FPS, sizeof (Sem));
23752349
23762350 bool Overflow;
2377- llvm::APFixedPoint Result =
2378- llvm::APFixedPoint::getFromFloatValue (Float.getAPFloat (), Sem, &Overflow);
2351+ FixedPoint Result = FixedPoint::from (Float.getAPFloat (), Sem, &Overflow);
23792352
2380- if (Overflow) {
2381- const Expr *E = S.Current ->getExpr (OpPC);
2382- if (S.checkingForUndefinedBehavior ()) {
2383- S.getASTContext ().getDiagnostics ().Report (
2384- E->getExprLoc (), diag::warn_fixedpoint_constant_overflow)
2385- << Result.toString () << E->getType ();
2386- }
2387- S.CCEDiag (E, diag::note_constexpr_overflow) << Result << E->getType ();
2388- if (!S.noteUndefinedBehavior ())
2389- return false ;
2390- }
2353+ if (Overflow && !handleFixedPointOverflow (S, OpPC, Result))
2354+ return false ;
23912355
23922356 S.Stk .push <FixedPoint>(Result);
23932357 return true ;
@@ -2401,6 +2365,20 @@ static inline bool CastFixedPointFloating(InterpState &S, CodePtr OpPC,
24012365 return true ;
24022366}
24032367
2368+ template <PrimType Name, class T = typename PrimConv<Name>::T>
2369+ static inline bool CastFixedPointIntegral (InterpState &S, CodePtr OpPC) {
2370+ const auto &Fixed = S.Stk .pop <FixedPoint>();
2371+
2372+ bool Overflow;
2373+ APSInt Int = Fixed.toInt (T::bitWidth (), T::isSigned (), &Overflow);
2374+
2375+ if (Overflow && !handleOverflow (S, OpPC, Int))
2376+ return false ;
2377+
2378+ S.Stk .push <T>(Int);
2379+ return true ;
2380+ }
2381+
24042382static inline bool PtrPtrCast (InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
24052383 const auto &Ptr = S.Stk .peek <Pointer>();
24062384
0 commit comments