================ @@ -821,22 +873,115 @@ std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() { PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo(), PP.getDiagnostics()); if (Literal.hadError) - return true; // Error has already been reported so just return + return std::nullopt; // Error has already been reported so just return - assert(Literal.isIntegerLiteral() && "IsNumberChar will only support digits"); + assert(Literal.isIntegerLiteral() && + "NumSpelling can only consist of digits"); - llvm::APSInt Val = llvm::APSInt(32, false); + llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true); if (Literal.GetIntegerValue(Val)) { // Report that the value has overflowed PP.getDiagnostics().Report(CurToken.TokLoc, diag::err_hlsl_number_literal_overflow) - << 0 << CurToken.NumSpelling; + << /*integer type*/ 0 << /*is signed*/ 0; return std::nullopt; } return Val.getExtValue(); } +std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) { + // Parse the numeric value and do semantic checks on its specification + clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc, + PP.getSourceManager(), PP.getLangOpts(), + PP.getTargetInfo(), PP.getDiagnostics()); + if (Literal.hadError) + return std::nullopt; // Error has already been reported so just return + + assert(Literal.isIntegerLiteral() && + "NumSpelling can only consist of digits"); + + llvm::APSInt Val = llvm::APSInt(32, /*IsUnsigned=*/true); + // GetIntegerValue will overwrite Val from the parsed Literal and return + // true if it overflows as a 32-bit unsigned int. Then check that it also + // doesn't overflow as a signed 32-bit int. + int64_t MaxMagnitude = + -static_cast<int64_t>(std::numeric_limits<int32_t>::min()); + if (Literal.GetIntegerValue(Val) || MaxMagnitude < Val.getExtValue()) { + // Report that the value has overflowed + PP.getDiagnostics().Report(CurToken.TokLoc, + diag::err_hlsl_number_literal_overflow) + << /*integer type*/ 0 << /*is signed*/ 1; + return std::nullopt; + } + + if (Negated) + Val = -Val; + + return static_cast<int32_t>(Val.getExtValue()); +} + +std::optional<float> RootSignatureParser::handleFloatLiteral(bool Negated) { + // Parse the numeric value and do semantic checks on its specification + clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc, + PP.getSourceManager(), PP.getLangOpts(), + PP.getTargetInfo(), PP.getDiagnostics()); + if (Literal.hadError) + return std::nullopt; // Error has already been reported so just return + + assert(Literal.isFloatingLiteral() && + "NumSpelling consists only of [0-9.ef+-]. Any malformed NumSpelling " + "will be caught and reported by NumericLiteralParser."); + + // DXC used `strtod` to convert the token string to a float which corresponds + // to: + auto DXCSemantics = llvm::APFloat::Semantics::S_IEEEdouble; + auto DXCRoundingMode = llvm::RoundingMode::NearestTiesToEven; + + llvm::APFloat Val = + llvm::APFloat(llvm::APFloat::EnumToSemantics(DXCSemantics)); + llvm::APFloat::opStatus Status = Literal.GetFloatValue(Val, DXCRoundingMode); + + // Note: we do not error when opStatus::opInexact by itself as this just + // denotes that rounding occured but not that it is invalid + assert(!(Status & llvm::APFloat::opStatus::opInvalidOp) && + "NumSpelling consists only of [0-9.ef+-]. Any malformed NumSpelling " + "will be caught and reported by NumericLiteralParser."); + + assert(!(Status & llvm::APFloat::opStatus::opDivByZero) && + "It is not possible for a division to be performed when " + "constructing an APFloat from a string"); + + if (Status & llvm::APFloat::opStatus::opUnderflow) { + // Report that the value has underflowed + PP.getDiagnostics().Report(CurToken.TokLoc, + diag::err_hlsl_number_literal_underflow); + return std::nullopt; + } + + if (Status & llvm::APFloat::opStatus::opOverflow) { + // Report that the value has overflowed + PP.getDiagnostics().Report(CurToken.TokLoc, + diag::err_hlsl_number_literal_overflow) + << /*float type*/ 1; + return std::nullopt; + } + + if (Negated) + Val = -Val; + + double DoubleVal = Val.convertToDouble(); + if (FLT_MAX < DoubleVal || DoubleVal < -FLT_MAX) { ---------------- bogner wrote:
Aha, this is what `float.h` was for. Please use `std::numeric_limits` instead, as you do elsewhere. https://github.com/llvm/llvm-project/pull/140181 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits