diff --git a/lib/Translation/ForthToMLIR/ForthToMLIR.cpp b/lib/Translation/ForthToMLIR/ForthToMLIR.cpp index 808e421..a31e661 100644 --- a/lib/Translation/ForthToMLIR/ForthToMLIR.cpp +++ b/lib/Translation/ForthToMLIR/ForthToMLIR.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h" #include +#include using namespace mlir; using namespace mlir::forth; @@ -958,7 +959,11 @@ LogicalResult ForthParser::parseBody(Value &stack) { if (currentToken.kind == Token::Kind::Number) { Location tokenLoc = getLoc(); - int64_t value = std::stoll(currentToken.text); + StringRef text = currentToken.text; + text.consume_front("+"); + int64_t value; + if (text.getAsInteger(10, value)) + return emitError("integer literal out of range for i64"); stack = builder .create(tokenLoc, stackType, stack, builder.getI64IntegerAttr(value)) @@ -966,7 +971,9 @@ LogicalResult ForthParser::parseBody(Value &stack) { consume(); } else if (currentToken.kind == Token::Kind::Float) { Location tokenLoc = getLoc(); - double value = std::stod(currentToken.text); + double value; + if (!llvm::to_float(currentToken.text, value) || std::isinf(value)) + return emitError("float literal out of range for f64"); stack = builder .create(tokenLoc, stackType, stack, builder.getF64FloatAttr(value)) diff --git a/test/Translation/Forth/basic-literals.forth b/test/Translation/Forth/basic-literals.forth index e739e93..829487a 100644 --- a/test/Translation/Forth/basic-literals.forth +++ b/test/Translation/Forth/basic-literals.forth @@ -4,5 +4,8 @@ \ CHECK-NEXT: forth.constant %{{.*}}(42 : i64) \ CHECK-NEXT: forth.constant %{{.*}}(-7 : i64) \ CHECK-NEXT: forth.constant %{{.*}}(0 : i64) +\ CHECK-NEXT: forth.constant %{{.*}}(5 : i64) +\ CHECK-NEXT: forth.constant %{{.*}}(9223372036854775807 : i64) +\ CHECK-NEXT: forth.constant %{{.*}}(-9223372036854775808 : i64) \! kernel main -42 -7 0 +42 -7 0 +5 9223372036854775807 -9223372036854775808 diff --git a/test/Translation/Forth/float-literal-overflow-error.forth b/test/Translation/Forth/float-literal-overflow-error.forth new file mode 100644 index 0000000..cf2df0f --- /dev/null +++ b/test/Translation/Forth/float-literal-overflow-error.forth @@ -0,0 +1,4 @@ +\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s +\ CHECK: {{.*}}float-literal-overflow-error.forth:4:5: error: float literal out of range for f64 +\! kernel main +1.0 -1e999 diff --git a/test/Translation/Forth/float-literals.forth b/test/Translation/Forth/float-literals.forth index 26b4c8b..e52b23f 100644 --- a/test/Translation/Forth/float-literals.forth +++ b/test/Translation/Forth/float-literals.forth @@ -11,5 +11,7 @@ \ CHECK-NEXT: forth.constant %{{.*}}(5.000000e+00 : f64) \ CHECK-NEXT: forth.constant %{{.*}}(1.500000e+00 : f64) \ CHECK-NEXT: forth.constant %{{.*}}(2.500000e+02 : f64) +\ CHECK-NEXT: forth.constant %{{.*}}(1.7976931348623157E+308 : f64) +\ CHECK-NEXT: forth.constant %{{.*}}(0.000000e+00 : f64) \! kernel main -3.14 -2.0 1.0e-5 1e3 1E3 .5 -.5 5. +1.5 2.5e+2 +3.14 -2.0 1.0e-5 1e3 1E3 .5 -.5 5. +1.5 2.5e+2 1.7976931348623157e308 1e-400 diff --git a/test/Translation/Forth/integer-literal-overflow-error.forth b/test/Translation/Forth/integer-literal-overflow-error.forth new file mode 100644 index 0000000..99d7665 --- /dev/null +++ b/test/Translation/Forth/integer-literal-overflow-error.forth @@ -0,0 +1,4 @@ +\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s +\ CHECK: {{.*}}integer-literal-overflow-error.forth:4:3: error: integer literal out of range for i64 +\! kernel main +1 9223372036854775808 diff --git a/test/Translation/Forth/integer-literal-underflow-error.forth b/test/Translation/Forth/integer-literal-underflow-error.forth new file mode 100644 index 0000000..fc16000 --- /dev/null +++ b/test/Translation/Forth/integer-literal-underflow-error.forth @@ -0,0 +1,4 @@ +\ RUN: %not %warpforth-translate --forth-to-mlir %s 2>&1 | %FileCheck %s +\ CHECK: {{.*}}integer-literal-underflow-error.forth:4:3: error: integer literal out of range for i64 +\! kernel main +1 -9223372036854775809