@@ -38,6 +38,7 @@ namespace clang {
3838namespace interp {
3939
4040using APSInt = llvm::APSInt;
41+ using FixedPointSemantics = llvm::FixedPointSemantics;
4142
4243// / Convert a value to an APValue.
4344template <typename T>
@@ -2311,6 +2312,34 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
23112312 return true ;
23122313}
23132314
2315+ template <PrimType Name, class T = typename PrimConv<Name>::T>
2316+ static inline bool CastIntegralFixedPoint (InterpState &S, CodePtr OpPC,
2317+ uint32_t FPS) {
2318+ const T &Int = S.Stk .pop <T>();
2319+
2320+ FixedPointSemantics Sem (0 , 0 , false , false , false );
2321+ std::memcpy (&Sem, &FPS, sizeof (Sem));
2322+
2323+ bool Overflow;
2324+ llvm::APFixedPoint IntResult =
2325+ llvm::APFixedPoint::getFromIntValue (Int.toAPSInt (), Sem, &Overflow);
2326+
2327+ if (Overflow) {
2328+ const Expr *E = S.Current ->getExpr (OpPC);
2329+ if (S.checkingForUndefinedBehavior ()) {
2330+ S.getASTContext ().getDiagnostics ().Report (
2331+ E->getExprLoc (), diag::warn_fixedpoint_constant_overflow)
2332+ << IntResult.toString () << E->getType ();
2333+ }
2334+ S.CCEDiag (E, diag::note_constexpr_overflow) << IntResult << E->getType ();
2335+ if (!S.noteUndefinedBehavior ())
2336+ return false ;
2337+ }
2338+
2339+ S.Stk .push <FixedPoint>(IntResult);
2340+ return true ;
2341+ }
2342+
23142343static inline bool PtrPtrCast (InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
23152344 const auto &Ptr = S.Stk .peek <Pointer>();
23162345
0 commit comments