Add additional compiler macro checks for checking float and double data formats conform to IEEE 754
Bug: 351170734
Change-Id: I2aab09a611136727d3662d1ec4a17562ef0c1bcc
diff --git a/include/cppbor/cppbor.h b/include/cppbor/cppbor.h
index acce184..271e0e6 100644
--- a/include/cppbor/cppbor.h
+++ b/include/cppbor/cppbor.h
@@ -943,7 +943,7 @@
std::unique_ptr<Item> clone() const override { return std::make_unique<Null>(); }
};
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
/**
* Float is a concrete type that implements CBOR major type 7, with additional item value for
* FLOAT.
@@ -977,7 +977,9 @@
private:
float mValue;
};
+#endif // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
/**
* Double is a concrete type that implements CBOR major type 7, with additional item value for
* DOUBLE.
@@ -1011,7 +1013,7 @@
private:
double mValue;
};
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
/**
* Returns pretty-printed CBOR for |item|
diff --git a/src/cppbor.cpp b/src/cppbor.cpp
index fbb71c6..bdb5559 100644
--- a/src/cppbor.cpp
+++ b/src/cppbor.cpp
@@ -245,23 +245,28 @@
case NULL_T:
out.append("null");
break;
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
case FLOAT:
snprintf(buf, sizeof(buf), "%f", item->asSimple()->asFloat()->value());
out.append(buf);
break;
+#ifndef __TRUSTY__
+ LOG(ERROR) << "float not supported for this platform.";
+#endif // __TRUSTY__
+ return false;
+#endif // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
case DOUBLE:
snprintf(buf, sizeof(buf), "%f", item->asSimple()->asDouble()->value());
out.append(buf);
break;
#else
- case FLOAT:
case DOUBLE:
#ifndef __TRUSTY__
- LOG(ERROR) << "float/double not supported for this platform.";
+ LOG(ERROR) << "double not supported for this platform.";
#endif // __TRUSTY__
return false;
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
default:
#ifndef __TRUSTY__
LOG(ERROR) << "Only boolean/null/float/double is implemented for SIMPLE";
@@ -391,12 +396,14 @@
return *asBool() == *(other.asBool());
case NULL_T:
return true;
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
case FLOAT:
return *asFloat() == *(other.asFloat());
+#endif // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
case DOUBLE:
return *asDouble() == *(other.asDouble());
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
default:
CHECK(false); // Impossible to get here.
return false;
diff --git a/src/cppbor_parse.cpp b/src/cppbor_parse.cpp
index ddcc44b..de724db 100644
--- a/src/cppbor_parse.cpp
+++ b/src/cppbor_parse.cpp
@@ -104,7 +104,7 @@
parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
}
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
std::tuple<const uint8_t*, ParseClient*> handleFloat(uint32_t value, const uint8_t* hdrBegin,
const uint8_t* hdrEnd,
ParseClient* parseClient) {
@@ -114,7 +114,9 @@
return {hdrEnd,
parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
}
+#endif // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
std::tuple<const uint8_t*, ParseClient*> handleDouble(uint64_t value, const uint8_t* hdrBegin,
const uint8_t* hdrEnd,
ParseClient* parseClient) {
@@ -124,7 +126,7 @@
return {hdrEnd,
parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
}
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
template <typename T>
std::tuple<const uint8_t*, ParseClient*> handleString(uint64_t length, const uint8_t* hdrBegin,
@@ -471,17 +473,22 @@
case TRUE:
case FALSE:
return handleBool(*addlData, begin, pos, parseClient);
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
case FLOAT_V:
return handleFloat(*addlData, begin, pos, parseClient);
+#else
+ case FLOAT_V:
+ parseClient->error(begin, "Value float is not supported for platform.");
+ return {begin, nullptr};
+#endif // __STDC_IEC_559__ || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
case DOUBLE_V:
return handleDouble(*addlData, begin, pos, parseClient);
#else
- case FLOAT_V:
case DOUBLE_V:
- parseClient->error(begin, "Unsupported floating-point value for platform.");
+ parseClient->error(begin, "Value double is not supported for platform.");
return {begin, nullptr};
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
case NULL_V:
return handleNull(begin, pos, parseClient);
default:
diff --git a/tests/cppbor_test.cpp b/tests/cppbor_test.cpp
index 7274a08..700c038 100644
--- a/tests/cppbor_test.cpp
+++ b/tests/cppbor_test.cpp
@@ -2022,7 +2022,7 @@
EXPECT_EQ("Unsupported half-floating-point or simple value.", message);
}
-#ifdef __STDC_IEC_559__
+#if defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
TEST(FullParserTest, FloatingPointValue) {
vector<uint8_t> floatingPointValue = {0xFA, 0x12, 0x75, 0x34, 0x37};
float f_val = 7.737272847557572e-28;
@@ -2094,7 +2094,9 @@
Float f(f_val);
EXPECT_EQ(f.encode(), floatingPointValue);
}
+#endif // defined(__STDC_IEC_559__) || FLT_MANT_DIG == 24 || __FLT_MANT_DIG__ == 24
+#if defined(__STDC_IEC_559__) || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
TEST(FullParserTest, DoubleValue) {
vector<uint8_t> doubleValue = {0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A};
double d_val = 3.1415926000000001;
@@ -2166,7 +2168,7 @@
Double d(d_val);
EXPECT_EQ(d.encode(), doubleValue);
}
-#endif // __STDC_IEC_559__
+#endif // __STDC_IEC_559__ || DBL_MANT_DIG == 53 || __DBL_MANT_DIG__ == 53
TEST(MapGetValueByKeyTest, Map) {
Array compoundItem(1, 2, 3, 4, 5, Map(4, 5, "a", "b"));