diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index aeedd6b1691..88059e94667 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3326,7 +3326,52 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Expr *Res; - if (Literal.isFloatingLiteral()) { + if (Literal.isFixedPointLiteral()) { + QualType Ty; + + if (Literal.isAccum) { + if (Literal.isHalf) { + Ty = Context.ShortAccumTy; + } else if (Literal.isLong) { + Ty = Context.LongAccumTy; + } else { + Ty = Context.AccumTy; + } + } else if (Literal.isFract) { + if (Literal.isHalf) { + Ty = Context.ShortFractTy; + } else if (Literal.isLong) { + Ty = Context.LongFractTy; + } else { + Ty = Context.FractTy; + } + } + + if (Literal.isUnsigned) Ty = Context.getCorrespondingUnsignedType(Ty); + + bool isSigned = !Literal.isUnsigned; + unsigned scale = Context.getFixedPointScale(Ty); + unsigned ibits = Context.getFixedPointIBits(Ty); + unsigned bit_width = Context.getTypeInfo(Ty).Width; + + llvm::APInt Val(bit_width, 0, isSigned); + bool Overflowed = Literal.GetFixedPointValue(Val, scale); + + // Do not use bit_width since some types may have padding like _Fract or + // unsigned _Accums if SameFBits is set. + auto MaxVal = llvm::APInt::getMaxValue(ibits + scale).zextOrSelf(bit_width); + if (Literal.isFract && Val == MaxVal + 1) + // Clause 6.4.4 - The value of a constant shall be in the range of + // representable values for its type, with exception for constants of a + // fract type with a value of exactly 1; such a constant shall denote + // the maximal value for the type. + --Val; + else if (Val.ugt(MaxVal) || Overflowed) + Diag(Tok.getLocation(), diag::err_too_large_for_fixed_point); + + Res = FixedPointLiteral::CreateFromRawInt(Context, Val, Ty, + Tok.getLocation(), scale); + } else if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isHalf){ if (getOpenCLOptions().isEnabled("cl_khr_fp16")) @@ -13122,7 +13167,7 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, CondExpr = CondICE.get(); CondIsTrue = condEval.getZExtValue(); - // If the condition is > zero, then the AST type is the same as the LSHExpr. + // If the condition is > zero, then the AST type is the same as the LHSExpr. Expr *ActiveExpr = CondIsTrue ? LHSExpr : RHSExpr; resType = ActiveExpr->getType(); |