Skip to content
Snippets Groups Projects
Unverified Commit d75a1bcf authored by Brent Huisman's avatar Brent Huisman Committed by GitHub
Browse files

Fix portability issues with long double in modcc. (#1246)

Change from long double to double for storing floating point values in modcc.

WSL, and Windows generally, treats long double differently than Linux, which leads to inconsistencies in literal numeric values in code generated by modcc on the two platforms.

Fixes #1245
parent 9233b784
No related branches found
No related tags found
No related merge requests found
...@@ -330,11 +330,11 @@ public: ...@@ -330,11 +330,11 @@ public:
: Expression(loc), value_(std::stold(value)) : Expression(loc), value_(std::stold(value))
{} {}
NumberExpression(Location loc, long double value) NumberExpression(Location loc, double value)
: Expression(loc), value_(value) : Expression(loc), value_(value)
{} {}
virtual long double value() const {return value_;}; virtual double value() const {return value_;};
std::string to_string() const override { std::string to_string() const override {
return purple(pprintf("%", value_)); return purple(pprintf("%", value_));
...@@ -350,7 +350,7 @@ public: ...@@ -350,7 +350,7 @@ public:
void accept(Visitor *v) override; void accept(Visitor *v) override;
private: private:
long double value_; double value_;
}; };
// an integral number // an integral number
...@@ -361,7 +361,7 @@ public: ...@@ -361,7 +361,7 @@ public:
{} {}
IntegerExpression(Location loc, long long integer) IntegerExpression(Location loc, long long integer)
: NumberExpression(loc, static_cast<long double>(integer)), integer_(integer) : NumberExpression(loc, static_cast<double>(integer)), integer_(integer)
{} {}
long long integer_value() const {return integer_;} long long integer_value() const {return integer_;}
......
...@@ -262,7 +262,7 @@ private: ...@@ -262,7 +262,7 @@ private:
std::string id_; std::string id_;
}; };
long double expr_value(Expression* e) { double expr_value(Expression* e) {
return e && e->is_number()? e->is_number()->value(): NAN; return e && e->is_number()? e->is_number()->value(): NAN;
} }
...@@ -273,7 +273,7 @@ private: ...@@ -273,7 +273,7 @@ private:
static bool is_number(Expression* e) { return e && e->is_number(); } static bool is_number(Expression* e) { return e && e->is_number(); }
static bool is_number(const expression_ptr& e) { return is_number(e.get()); } static bool is_number(const expression_ptr& e) { return is_number(e.get()); }
void as_number(Location loc, long double v) { void as_number(Location loc, double v) {
result_ = make_expression<NumberExpression>(loc, v); result_ = make_expression<NumberExpression>(loc, v);
} }
...@@ -293,7 +293,7 @@ public: ...@@ -293,7 +293,7 @@ public:
result_ = nullptr; result_ = nullptr;
} }
long double value() const { return expr_value(result_); } double value() const { return expr_value(result_); }
bool is_number() const { return is_number(result_); } bool is_number() const { return is_number(result_); }
......
...@@ -25,7 +25,7 @@ bool involves_identifier(Expression* e, const identifier_set& ids); ...@@ -25,7 +25,7 @@ bool involves_identifier(Expression* e, const identifier_set& ids);
expression_ptr constant_simplify(Expression* e); expression_ptr constant_simplify(Expression* e);
// Extract value of expression that is a NumberExpression, or else return NAN. // Extract value of expression that is a NumberExpression, or else return NAN.
long double expr_value(Expression* e); double expr_value(Expression* e);
// Test if expression is a NumberExpression with value zero. // Test if expression is a NumberExpression with value zero.
inline bool is_zero(Expression* e) { inline bool is_zero(Expression* e) {
...@@ -57,11 +57,11 @@ inline expression_ptr constant_simplify(const expression_ptr& e) { ...@@ -57,11 +57,11 @@ inline expression_ptr constant_simplify(const expression_ptr& e) {
return constant_simplify(e.get()); return constant_simplify(e.get());
} }
inline long double expr_value(const expression_ptr& e) { inline double expr_value(const expression_ptr& e) {
return expr_value(e.get()); return expr_value(e.get());
} }
inline long double is_zero(const expression_ptr& e) { inline double is_zero(const expression_ptr& e) {
return is_zero(e.get()); return is_zero(e.get());
} }
......
...@@ -580,7 +580,7 @@ TEST(Parser, parse_conserve) { ...@@ -580,7 +580,7 @@ TEST(Parser, parse_conserve) {
} }
} }
long double eval(Expression *e) { double eval(Expression *e) {
if (auto n = e->is_number()) { if (auto n = e->is_number()) {
return n->value(); return n->value();
} }
...@@ -606,7 +606,7 @@ long double eval(Expression *e) { ...@@ -606,7 +606,7 @@ long double eval(Expression *e) {
default:; default:;
} }
} }
return std::numeric_limits<long double>::quiet_NaN(); return std::numeric_limits<double>::quiet_NaN();
} }
// test parsing of expressions for correctness // test parsing of expressions for correctness
...@@ -654,12 +654,6 @@ TEST(Parser, parse_binop) { ...@@ -654,12 +654,6 @@ TEST(Parser, parse_binop) {
for (const auto& test_case: tests) { for (const auto& test_case: tests) {
std::unique_ptr<Expression> e; std::unique_ptr<Expression> e;
EXPECT_TRUE(check_parse(e, &Parser::parse_expression, test_case.first)); EXPECT_TRUE(check_parse(e, &Parser::parse_expression, test_case.first));
// A loose tolerance of 1e-10 is required here because the eval()
// function uses long double for intermediate results (like constant
// folding in modparser). For expressions with transcendental
// operations this can see relatively large divergence between the
// double and long double results.
EXPECT_NEAR(eval(e.get()), test_case.second, 1e-10); EXPECT_NEAR(eval(e.get()), test_case.second, 1e-10);
} }
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment