From: David Neto Date: Wed, 14 Oct 2015 15:31:51 +0000 (-0400) Subject: SPV_FAILED_MATCH error mutes DiagnosticStream. X-Git-Tag: upstream/2018.6~1511^2~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=51013d15ee86360489309ca0d9c385f8b4e9f871;p=platform%2Fupstream%2FSPIRV-Tools.git SPV_FAILED_MATCH error mutes DiagnosticStream. The DiagnosticStream will not emit the accumulated message text if the error is SPV_FAILED_MATCH. Change various interfaces to accept the intended error code instead of a boolean "is_optional". This allows us to avoid repeating the following type of logic deep inside helper methods: if (is_optional) return SPV_FAILED_MATCH; return diagnostic() << " message text "; --- diff --git a/source/diagnostic.cpp b/source/diagnostic.cpp index 74ce76b..94f5799 100644 --- a/source/diagnostic.cpp +++ b/source/diagnostic.cpp @@ -82,7 +82,7 @@ spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) { DiagnosticStream::~DiagnosticStream() { - if (pDiagnostic_) { + if (pDiagnostic_ && error_ != SPV_FAILED_MATCH) { *pDiagnostic_ = spvDiagnosticCreate(position_, stream_.str().c_str()); } } diff --git a/source/diagnostic.h b/source/diagnostic.h index 27be491..d6c77fe 100644 --- a/source/diagnostic.h +++ b/source/diagnostic.h @@ -54,7 +54,8 @@ class diagnostic_helper { // A DiagnosticStream remembers the current position of the input and an error // code, and captures diagnostic messages via the left-shift operator. -// Captured messages are emitted during the destructor. +// If the error code is not SPV_FAILED_MATCH, then captured messages are +// emitted during the destructor. // TODO(awoloszyn): This is very similar to diagnostic_helper, and hides // the data more easily. Replace diagnostic_helper elsewhere // eventually. diff --git a/source/text.cpp b/source/text.cpp index e2ccc3c..2bb0ba8 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -172,7 +172,7 @@ spv_result_t encodeImmediate(libspirv::AssemblyContext* context, assert(*text == '!'); uint32_t parse_result; if (auto error = - context->parseNumber(text + 1, false, &parse_result, + context->parseNumber(text + 1, SPV_ERROR_INVALID_TEXT, &parse_result, "Invalid immediate integer: !")) return error; context->binaryEncodeU32(parse_result, pInst); @@ -208,6 +208,12 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar, return SPV_SUCCESS; } + // Optional literal operands can fail to parse. In that case use + // SPV_FAILED_MATCH to avoid emitting a diagostic. Use the following + // for those situations. + spv_result_t error_code_for_literals = + spvOperandIsOptional(type) ? SPV_FAILED_MATCH : SPV_ERROR_INVALID_TEXT; + switch (type) { case SPV_OPERAND_TYPE_EXECUTION_SCOPE: case SPV_OPERAND_TYPE_ID: @@ -278,9 +284,9 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar, } if (auto error = context->binaryEncodeNumericLiteral( - textValue, spvOperandIsOptional(type), expected_type, pInst)) { + textValue, error_code_for_literals, expected_type, pInst)) { return error; - } + } } break; case SPV_OPERAND_TYPE_LITERAL_STRING: case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: { @@ -288,12 +294,11 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar, spv_result_t error = spvTextToLiteral(textValue, &literal); if (error != SPV_SUCCESS) { if (error == SPV_ERROR_OUT_OF_MEMORY) return error; - if (spvOperandIsOptional(type)) return SPV_FAILED_MATCH; - return context->diagnostic() << "Invalid literal string '" << textValue - << "'."; + return context->diagnostic(error_code_for_literals) + << "Invalid literal string '" << textValue << "'."; } if (literal.type != SPV_LITERAL_TYPE_STRING) { - return context->diagnostic(SPV_FAILED_MATCH) + return context->diagnostic() << "Expected literal string, found literal number '" << textValue << "'."; } diff --git a/source/text_handler.cpp b/source/text_handler.cpp index 39fe433..3b10582 100644 --- a/source/text_handler.cpp +++ b/source/text_handler.cpp @@ -347,7 +347,7 @@ spv_result_t AssemblyContext::binaryEncodeU64(const uint64_t value, } spv_result_t AssemblyContext::binaryEncodeNumericLiteral( - const char *val, bool is_optional, const IdType &type, + const char *val, spv_result_t error_code, const IdType &type, spv_instruction_t *pInst) { const bool is_bottom = type.type_class == libspirv::IdTypeClass::kBottom; const bool is_floating = libspirv::isScalarFloating(type); @@ -365,9 +365,9 @@ spv_result_t AssemblyContext::binaryEncodeNumericLiteral( // If we explicitly expect a floating-point number, we should handle that // first. if (is_floating || looks_like_float) - return binaryEncodeFloatingPointLiteral(val, is_optional, type, pInst); + return binaryEncodeFloatingPointLiteral(val, error_code, type, pInst); - return binaryEncodeIntegerLiteral(val, is_optional, type, pInst); + return binaryEncodeIntegerLiteral(val, error_code, type, pInst); } spv_result_t AssemblyContext::binaryEncodeString( @@ -445,7 +445,7 @@ spv_result_t AssemblyContext::recordTypeIdForValue(uint32_t value, } spv_result_t AssemblyContext::binaryEncodeFloatingPointLiteral( - const char *val, bool is_optional, const IdType &type, + const char *val, spv_result_t error_code, const IdType &type, spv_instruction_t *pInst) { const auto bit_width = assumedBitWidth(type); switch (bit_width) { @@ -454,14 +454,14 @@ spv_result_t AssemblyContext::binaryEncodeFloatingPointLiteral( << "Unsupported yet: 16-bit float constants."; case 32: { float fVal; - if (auto error = parseNumber(val, is_optional, &fVal, + if (auto error = parseNumber(val, error_code, &fVal, "Invalid 32-bit float literal: ")) return error; return binaryEncodeU32(BitwiseCast(fVal), pInst); } break; case 64: { double dVal; - if (auto error = parseNumber(val, is_optional, &dVal, + if (auto error = parseNumber(val, error_code, &dVal, "Invalid 64-bit float literal: ")) return error; return binaryEncodeU64(BitwiseCast(dVal), pInst); @@ -473,7 +473,7 @@ spv_result_t AssemblyContext::binaryEncodeFloatingPointLiteral( } spv_result_t AssemblyContext::binaryEncodeIntegerLiteral( - const char *val, bool is_optional, const IdType &type, + const char *val, spv_result_t error_code, const IdType &type, spv_instruction_t *pInst) { const bool is_bottom = type.type_class == libspirv::IdTypeClass::kBottom; const auto bit_width = assumedBitWidth(type); @@ -496,20 +496,20 @@ spv_result_t AssemblyContext::binaryEncodeIntegerLiteral( uint64_t decoded_bits; if (is_negative) { int64_t decoded_signed = 0; - if (auto error = parseNumber(val, is_optional, &decoded_signed, + if (auto error = parseNumber(val, error_code, &decoded_signed, "Invalid signed integer literal: ")) return error; if (auto error = checkRangeAndIfHexThenSignExtend( - decoded_signed, is_optional, type, is_hex, &decoded_signed)) + decoded_signed, error_code, type, is_hex, &decoded_signed)) return error; decoded_bits = decoded_signed; } else { // There's no leading minus sign, so parse it as an unsigned integer. - if (auto error = parseNumber(val, is_optional, &decoded_bits, + if (auto error = parseNumber(val, error_code, &decoded_bits, "Invalid unsigned integer literal: ")) return error; if (auto error = checkRangeAndIfHexThenSignExtend( - decoded_bits, is_optional, type, is_hex, &decoded_bits)) + decoded_bits, error_code, type, is_hex, &decoded_bits)) return error; } if (bit_width > 32) { @@ -521,7 +521,7 @@ spv_result_t AssemblyContext::binaryEncodeIntegerLiteral( template spv_result_t AssemblyContext::checkRangeAndIfHexThenSignExtend( - T value, bool is_optional, const IdType &type, bool is_hex, + T value, spv_result_t error_code, const IdType &type, bool is_hex, T *updated_value_for_hex) { // The encoded result has three regions of bits that are of interest, from // least to most significant: @@ -569,12 +569,10 @@ spv_result_t AssemblyContext::checkRangeAndIfHexThenSignExtend( } if (failed) { - if (is_optional) return SPV_FAILED_MATCH; - return diagnostic() << "Integer " << (is_hex ? std::hex : std::dec) - << std::showbase << value << " does not fit in a " - << std::dec << bit_width << "-bit " - << (type.isSigned ? "signed" : "unsigned") - << " integer"; + return diagnostic(error_code) + << "Integer " << (is_hex ? std::hex : std::dec) << std::showbase + << value << " does not fit in a " << std::dec << bit_width << "-bit " + << (type.isSigned ? "signed" : "unsigned") << " integer"; } // Sign extend hex the number. diff --git a/source/text_handler.h b/source/text_handler.h index 065a710..d2c0360 100644 --- a/source/text_handler.h +++ b/source/text_handler.h @@ -238,9 +238,10 @@ class AssemblyContext { // If the type is of class kBottom the value will be encoded as a // 32-bit integer. // Returns SPV_SUCCESS if the value could be correctly added to the - // instruction. + // instruction. Returns the given error code on failure, and emits + // a diagnotic if that error code is not SPV_FAILED_MATCH. spv_result_t binaryEncodeNumericLiteral(const char *numeric_literal, - bool optional, + spv_result_t error_code, const IdType &type, spv_instruction_t *pInst); @@ -268,11 +269,11 @@ class AssemblyContext { // Parses a numeric value of a given type from the given text. The number // should take up the entire string, and should be within bounds for the // target type. On success, returns SPV_SUCCESS and populates the object - // referenced by value_pointer. On failure, returns SPV_FAILED_MATCH if - // is_optional is true, and returns SPV_ERROR_INVALID_TEXT and emits a - // diagnostic otherwise. + // referenced by value_pointer. On failure, returns the given error code, + // and emits a diagnostic if that error code is not SPV_FAILED_MATCH. template - spv_result_t parseNumber(const char *text, bool is_optional, T *value_pointer, + spv_result_t parseNumber(const char *text, spv_result_t error_code, + T *value_pointer, const char *error_message_fragment) { // C++11 doesn't define std::istringstream(int8_t&), so calling this method // with a single-byte type leads to implementation-defined behaviour. @@ -303,26 +304,27 @@ class AssemblyContext { } if (ok) return SPV_SUCCESS; - if (is_optional) return SPV_FAILED_MATCH; - return diagnostic() << error_message_fragment << text; + return diagnostic(error_code) << error_message_fragment << text; } private: // Appends the given floating point literal to the given instruction. // Returns SPV_SUCCESS if the value was correctly parsed. Otherwise - // an error code is returned, and a message is emitted if is_optional - // is false. Only 32 and 64 bit floating point numbers are supported. + // returns the given error code, and emits a diagnostic if that error + // code is not SPV_FAILED_MATCH. + // Only 32 and 64 bit floating point numbers are supported. spv_result_t binaryEncodeFloatingPointLiteral(const char *numeric_literal, - bool optional, + spv_result_t error_code, const IdType& type, spv_instruction_t *pInst); // Appends the given integer literal to the given instruction. // Returns SPV_SUCCESS if the value was correctly parsed. Otherwise - // an error code is returned, and a message is emitted if is_optional - // is false. Integers up to 64 bits are supported. + // returns the given error code, and emits a diagnostic if that error + // code is not SPV_FAILED_MATCH. + // Integers up to 64 bits are supported. spv_result_t binaryEncodeIntegerLiteral(const char *numeric_literal, - bool optional, + spv_result_t error_code, const IdType &type, spv_instruction_t *pInst); @@ -332,10 +334,10 @@ class AssemblyContext { // the overflow bits should be zero. If it was hex and the target type is // signed, then return the sign-extended value through the // updated_value_for_hex pointer argument. - // On failure, if is_optional is true then return SPV_FAILED_MATCH, otherwise - // emit a diagnostic and return SPV_ERROR_INVALID_TEXT. + // On failure, return the given error code and emit a diagnostic if that error + // code is not SPV_FAILED_MATCH. template - spv_result_t checkRangeAndIfHexThenSignExtend(T value, bool is_optional, + spv_result_t checkRangeAndIfHexThenSignExtend(T value, spv_result_t error_code, const IdType &type, bool is_hex, T *updated_value_for_hex); diff --git a/test/TextLiteral.cpp b/test/TextLiteral.cpp index 02b0d96..de328bc 100644 --- a/test/TextLiteral.cpp +++ b/test/TextLiteral.cpp @@ -187,9 +187,10 @@ std::vector successfulEncode(const TextLiteralCase& test, test.is_signed, type }; - EXPECT_EQ(SPV_SUCCESS, libspirv::AssemblyContext(nullptr, &diagnostic) - .binaryEncodeNumericLiteral(test.text, false, - expected_type, &inst)) + EXPECT_EQ(SPV_SUCCESS, + libspirv::AssemblyContext(nullptr, &diagnostic) + .binaryEncodeNumericLiteral(test.text, SPV_ERROR_INVALID_TEXT, + expected_type, &inst)) << diagnostic->error; return inst.words; } @@ -203,9 +204,10 @@ std::string failedEncode(const TextLiteralCase& test, test.is_signed, type }; - EXPECT_NE(SPV_SUCCESS, libspirv::AssemblyContext(nullptr, &diagnostic) - .binaryEncodeNumericLiteral(test.text, false, - expected_type, &inst)); + EXPECT_EQ(SPV_ERROR_INVALID_TEXT, + libspirv::AssemblyContext(nullptr, &diagnostic) + .binaryEncodeNumericLiteral(test.text, SPV_ERROR_INVALID_TEXT, + expected_type, &inst)); std::string ret_val; if (diagnostic) { ret_val = diagnostic->error; diff --git a/test/TextToBinary.cpp b/test/TextToBinary.cpp index 404b0a0..c8827aa 100644 --- a/test/TextToBinary.cpp +++ b/test/TextToBinary.cpp @@ -452,153 +452,162 @@ INSTANTIATE_TEST_CASE_P( TEST(AssemblyContextParseNarrowSignedIntegers, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; int16_t i16; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &i16, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &i16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &i16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &i16, "")); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &i16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &i16, "")); EXPECT_EQ(0, i16); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("32767", true, &i16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("32767", ec, &i16, "")); EXPECT_EQ(32767, i16); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32768", true, &i16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32768", ec, &i16, "")); EXPECT_EQ(-32768, i16); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", true, &i16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", ec, &i16, "")); EXPECT_EQ(0, i16); // These are out of range, so they should return an error. // The error code depends on whether this is an optional value. - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("32768", true, &i16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("32768", ec, &i16, "")); EXPECT_EQ(SPV_ERROR_INVALID_TEXT, - context.parseNumber("65535", false, &i16, "")); + context.parseNumber("65535", SPV_ERROR_INVALID_TEXT, &i16, "")); // Check hex parsing. - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0x7fff", true, &i16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0x7fff", ec, &i16, "")); EXPECT_EQ(32767, i16); // This is out of range. - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0xffff", true, &i16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0xffff", ec, &i16, "")); } TEST(AssemblyContextParseNarrowUnsignedIntegers, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; uint16_t u16; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &u16, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &u16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &u16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &u16, "")); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &u16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &u16, "")); EXPECT_EQ(0, u16); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("65535", true, &u16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("65535", ec, &u16, "")); EXPECT_EQ(65535, u16); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("65536", true, &u16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("65536", ec, &u16, "")); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", true, &u16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", ec, &u16, "")); EXPECT_EQ(0, u16); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1", true, &u16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1", ec, &u16, "")); EXPECT_EQ(0, u16); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0xffff", true, &u16, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0xffff", ec, &u16, "")); EXPECT_EQ(0xffff, u16); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0x10000", true, &u16, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0x10000", ec, &u16, "")); } TEST(AssemblyContextParseWideSignedIntegers, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; int64_t i64; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &i64, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &i64, "")); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &i64, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &i64, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &i64, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &i64, "")); EXPECT_EQ(0, i64); EXPECT_EQ(SPV_SUCCESS, - context.parseNumber("0x7fffffffffffffff", true, &i64, "")); + context.parseNumber("0x7fffffffffffffff", ec, &i64, "")); EXPECT_EQ(0x7fffffffffffffff, i64); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", true, &i64, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", ec, &i64, "")); EXPECT_EQ(0, i64); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1", true, &i64, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1", ec, &i64, "")); EXPECT_EQ(-1, i64); } TEST(AssemblyContextParseWideUnsignedIntegers, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; uint64_t u64; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &u64, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &u64, "")); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &u64, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &u64, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &u64, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &u64, "")); EXPECT_EQ(0, u64); EXPECT_EQ(SPV_SUCCESS, - context.parseNumber("0xffffffffffffffff", true, &u64, "")); + context.parseNumber("0xffffffffffffffff", ec, &u64, "")); EXPECT_EQ(0xffffffffffffffffULL, u64); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", true, &u64, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-0", ec, &u64, "")); EXPECT_EQ(0, u64); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1", true, &u64, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1", ec, &u64, "")); } TEST(AssemblyContextParseFloat, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; float f; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &f, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &f, "")); // These values are exactly representatble. - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &f, "")); EXPECT_EQ(0.0f, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("42", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("42", ec, &f, "")); EXPECT_EQ(42.0f, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("2.5", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("2.5", ec, &f, "")); EXPECT_EQ(2.5f, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32.5", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32.5", ec, &f, "")); EXPECT_EQ(-32.5f, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e38", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e38", ec, &f, "")); EXPECT_EQ(1e38f, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e38", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e38", ec, &f, "")); EXPECT_EQ(-1e38f, f); // Out of range. - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("1e40", true, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("1e40", ec, &f, "")); } TEST(AssemblyContextParseDouble, Sample) { AssemblyContext context(AutoText(""), nullptr); + const spv_result_t ec = SPV_FAILED_MATCH; double f; - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", true, &f, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", true, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("", ec, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("0=", ec, &f, "")); // These values are exactly representatble. - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("0", ec, &f, "")); EXPECT_EQ(0.0, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("42", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("42", ec, &f, "")); EXPECT_EQ(42.0, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("2.5", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("2.5", ec, &f, "")); EXPECT_EQ(2.5, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32.5", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-32.5", ec, &f, "")); EXPECT_EQ(-32.5, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e38", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e38", ec, &f, "")); EXPECT_EQ(1e38, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e38", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e38", ec, &f, "")); EXPECT_EQ(-1e38, f); // These are out of range for 32-bit float, but in range for 64-bit float. - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e40", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("1e40", ec, &f, "")); EXPECT_EQ(1e40, f); - EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e40", true, &f, "")); + EXPECT_EQ(SPV_SUCCESS, context.parseNumber("-1e40", ec, &f, "")); EXPECT_EQ(-1e40, f); // Out of range. - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("1e400", true, &f, "")); - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1e400", true, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("1e400", ec, &f, "")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("-1e400", ec, &f, "")); } TEST(AssemblyContextParseMessages, Errors) { spv_diagnostic diag = nullptr; + const spv_result_t ec = SPV_FAILED_MATCH; AssemblyContext context(AutoText(""), &diag); int16_t i16; // No message is generated for a failure to parse an optional value. - EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("abc", true, &i16, "bad narrow int: ")); + EXPECT_EQ(SPV_FAILED_MATCH, context.parseNumber("abc", ec, &i16, "bad narrow int: ")); EXPECT_EQ(nullptr, diag); // For a required value, use the message fragment. - EXPECT_EQ(SPV_ERROR_INVALID_TEXT, context.parseNumber("abc", false, &i16, "bad narrow int: ")); + EXPECT_EQ(SPV_ERROR_INVALID_TEXT, + context.parseNumber("abc", SPV_ERROR_INVALID_TEXT, &i16, + "bad narrow int: ")); ASSERT_NE(nullptr, diag); EXPECT_EQ("bad narrow int: abc", std::string(diag->error)); // Don't leak.