Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn on suffix-less integer literals outside Int64's range #12427

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/compiler/interpreter/primitives_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ describe Crystal::Repl::Interpreter do
assert_overflows 1_i16 + 32767
assert_overflows 1_u32 + 4294967295
assert_overflows 1_i32 + 2147483647
assert_overflows 1_u64 + 18446744073709551615
assert_overflows 1_u64 + 18446744073709551615u64
assert_overflows 1_i64 + 9223372036854775807
end

Expand All @@ -328,7 +328,7 @@ describe Crystal::Repl::Interpreter do
assert_overflows 1_u32 - 2
assert_overflows 1_i32 - 2147483650
assert_overflows 1_u64 - 2
assert_overflows 1_i64 - 9223372036854775810
assert_overflows 1_i64 - 9223372036854775810u64
end

context "*" do
Expand Down
4 changes: 4 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2949,6 +2949,10 @@ module Crystal
assert_macro %({{parse_type :Foo }}), %(nil)
end
end

it "exposes syntax warnings" do
assert_warning %({% parse_type "Foo(0x8000_0000_0000_0000)" %}), "Warning: 0x8000_0000_0000_0000 doesn't fit in an Int64, try using the suffix u64 or i128"
end
end

describe "printing" do
Expand Down
30 changes: 30 additions & 0 deletions spec/compiler/parser/warnings_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "../../support/syntax"

private def assert_parser_warning(source, message, *, file = __FILE__, line = __LINE__)
parser = Parser.new(source)
parser.filename = "/foo/bar/baz.cr"
node = parser.parse

warnings = parser.warnings.infos
warnings.size.should eq(1), file: file, line: line
warnings[0].should contain(message), file: file, line: line
end

describe "Parser warnings" do
it "warns on suffix-less UInt64 literals > Int64::MAX" do
values = [
"9223372036854775808", # Int64::MAX + 1
"9999999999999999999",
"10000000000000000000",
"18446744073709551615", # UInt64::MAX
"0x8000_0000_0000_0000",
"0xFFFF_FFFF_FFFF_FFFF",
]

values.each do |value|
assert_parser_warning value, "Warning: #{value} doesn't fit in an Int64, try using the suffix u64 or i128"
assert_parser_warning "Foo(#{value})", "Warning: #{value} doesn't fit in an Int64, try using the suffix u64 or i128"
assert_parser_warning "{{ #{value} }}", "Warning: #{value} doesn't fit in an Int64, try using the suffix u64 or i128"
end
end
end
8 changes: 8 additions & 0 deletions spec/compiler/semantic/warnings_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -729,4 +729,12 @@ describe "Semantic: warnings" do
end
end
end

it "exposes syntax warnings" do
assert_warning UInt64::MAX.to_s, "Warning: #{UInt64::MAX} doesn't fit in an Int64, try using the suffix u64 or i128"
end

it "exposes syntax warnings after macro interpolation" do
assert_warning "{% begin %}0x8000_0000_0000_000{{ 0 }}{% end %}", "Warning: 0x8000_0000_0000_0000 doesn't fit in an Int64, try using the suffix u64 or i128"
end
end
10 changes: 6 additions & 4 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ def assert_type(str, *, inject_primitives = false, flags = nil, file = __FILE__,
end

def semantic(code : String, wants_doc = false, inject_primitives = false, flags = nil, filename = nil)
node = parse(code, wants_doc: wants_doc, filename: filename)
warnings = WarningCollection.new
node = parse(code, wants_doc: wants_doc, filename: filename, warnings: warnings)
node = inject_primitives(node) if inject_primitives
semantic node, wants_doc: wants_doc, flags: flags
semantic node, warnings: warnings, wants_doc: wants_doc, flags: flags
end

private def inject_primitives(node : ASTNode)
Expand All @@ -66,8 +67,9 @@ private def inject_primitives(node : ASTNode)
end
end

def semantic(node : ASTNode, wants_doc = false, flags = nil)
def semantic(node : ASTNode, *, warnings = nil, wants_doc = false, flags = nil)
program = new_program
program.warnings = warnings if warnings
program.flags.concat(flags.split) if flags
program.wants_doc = wants_doc
node = program.normalize node
Expand Down Expand Up @@ -123,7 +125,7 @@ end
def assert_warning(code, message, *, file = __FILE__, line = __LINE__)
warning_failures = warnings_result(code)
warning_failures.size.should eq(1), file: file, line: line
warning_failures[0].should start_with(message), file: file, line: line
warning_failures[0].should contain(message), file: file, line: line
end

def assert_macro(macro_body, expected, args = nil, *, expected_pragmas = nil, flags = nil, file = __FILE__, line = __LINE__)
Expand Down
14 changes: 7 additions & 7 deletions spec/std/big/big_int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,12 @@ describe "BigInt" do
big = BigInt.new("9" * 32)
expect_raises(OverflowError) { big.to_i64 }
expect_raises(OverflowError) { big.to_u64 }
big.to_i64!.should eq(-8814407033341083649) # 99999999999999999999999999999999 - 5421010862428*(2**64)
big.to_u64!.should eq(9632337040368467967) # 99999999999999999999999999999999 - 5421010862427*(2**64)
big.to_i64!.should eq(-8814407033341083649) # 99999999999999999999999999999999 - 5421010862428*(2**64)
big.to_u64!.should eq(9632337040368467967u64) # 99999999999999999999999999999999 - 5421010862427*(2**64)
end

it "between 63 and 64 bits" do
big = BigInt.new(i = 9999999999999999999)
big = BigInt.new(i = 9999999999999999999u64)
expect_raises(OverflowError) { big.to_i64 }
big.to_u64.should eq(i)
big.to_i64!.should eq(-8446744073709551617) # 9999999999999999999 - 2**64
Expand All @@ -529,15 +529,15 @@ describe "BigInt" do
big.to_i64.should eq(i)
expect_raises(OverflowError) { big.to_u64 }
big.to_i64!.should eq(i)
big.to_u64!.should eq(18446744073709541617) # -9999 + 2**64
big.to_u64!.should eq(18446744073709541617u64) # -9999 + 2**64
end

it "negative between 32 and 63 bits" do
big = BigInt.new(i = -9999999999999)
big.to_i64.should eq(i)
expect_raises(OverflowError) { big.to_u64 }
big.to_i64!.should eq(i)
big.to_u64!.should eq(18446734073709551617) # -9999999999999 + 2**64
big.to_u64!.should eq(18446734073709551617u64) # -9999999999999 + 2**64
end

it "negative between 63 and 64 bits" do
Expand All @@ -552,8 +552,8 @@ describe "BigInt" do
big = BigInt.new("-" + "9" * 20)
expect_raises(OverflowError) { big.to_i64 }
expect_raises(OverflowError) { big.to_u64 }
big.to_i64!.should eq(-7766279631452241919) # -9999999999999999999 + 5*(2**64)
big.to_u64!.should eq(10680464442257309697) # -9999999999999999999 + 6*(2**64)
big.to_i64!.should eq(-7766279631452241919) # -9999999999999999999 + 5*(2**64)
big.to_u64!.should eq(10680464442257309697u64) # -9999999999999999999 + 6*(2**64)

big = BigInt.new("-" + "9" * 32)
expect_raises(OverflowError) { big.to_i64 }
Expand Down
72 changes: 36 additions & 36 deletions spec/std/crystal/compiler_rt/ashlti3_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,40 @@ require "./spec_helper"
# Ported from https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/ashlti3_test.c

it ".__ashlti3" do
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 0).should eq make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 1).should eq make_ti(0xFDB97530ECA8642B, 0xFDB97530ECA8642A)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 2).should eq make_ti(0xFB72EA61D950C857, 0xFB72EA61D950C854)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 3).should eq make_ti(0xF6E5D4C3B2A190AF, 0xF6E5D4C3B2A190A8)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 4).should eq make_ti(0xEDCBA9876543215F, 0xEDCBA98765432150)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 28).should eq make_ti(0x876543215FEDCBA9, 0x8765432150000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 29).should eq make_ti(0x0ECA8642BFDB9753, 0x0ECA8642A0000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 30).should eq make_ti(0x1D950C857FB72EA6, 0x1D950C8540000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 31).should eq make_ti(0x3B2A190AFF6E5D4C, 0x3B2A190A80000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 32).should eq make_ti(0x76543215FEDCBA98, 0x7654321500000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 33).should eq make_ti(0xECA8642BFDB97530, 0xECA8642A00000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 34).should eq make_ti(0xD950C857FB72EA61, 0xD950C85400000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 35).should eq make_ti(0xB2A190AFF6E5D4C3, 0xB2A190A800000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 36).should eq make_ti(0x6543215FEDCBA987, 0x6543215000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 60).should eq make_ti(0x5FEDCBA987654321, 0x5000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 61).should eq make_ti(0xBFDB97530ECA8642, 0xA000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 62).should eq make_ti(0x7FB72EA61D950C85, 0x4000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 63).should eq make_ti(0xFF6E5D4C3B2A190A, 0x8000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 64).should eq make_ti(0xFEDCBA9876543215, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 65).should eq make_ti(0xFDB97530ECA8642A, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 66).should eq make_ti(0xFB72EA61D950C854, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 67).should eq make_ti(0xF6E5D4C3B2A190A8, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 68).should eq make_ti(0xEDCBA98765432150, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 92).should eq make_ti(0x8765432150000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 93).should eq make_ti(0x0ECA8642A0000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 94).should eq make_ti(0x1D950C8540000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 95).should eq make_ti(0x3B2A190A80000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 96).should eq make_ti(0x7654321500000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 97).should eq make_ti(0xECA8642A00000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 98).should eq make_ti(0xD950C85400000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 99).should eq make_ti(0xB2A190A800000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 100).should eq make_ti(0x6543215000000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 124).should eq make_ti(0x5000000000000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 125).should eq make_ti(0xA000000000000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 126).should eq make_ti(0x4000000000000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215, 0xFEDCBA9876543215), 127).should eq make_ti(0x8000000000000000, 0x0000000000000000)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 0).should eq make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 1).should eq make_ti(0xFDB97530ECA8642Bu64, 0xFDB97530ECA8642Au64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 2).should eq make_ti(0xFB72EA61D950C857u64, 0xFB72EA61D950C854u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 3).should eq make_ti(0xF6E5D4C3B2A190AFu64, 0xF6E5D4C3B2A190A8u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 4).should eq make_ti(0xEDCBA9876543215Fu64, 0xEDCBA98765432150u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 28).should eq make_ti(0x876543215FEDCBA9u64, 0x8765432150000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 29).should eq make_ti(0x0ECA8642BFDB9753u64, 0x0ECA8642A0000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 30).should eq make_ti(0x1D950C857FB72EA6u64, 0x1D950C8540000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 31).should eq make_ti(0x3B2A190AFF6E5D4Cu64, 0x3B2A190A80000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 32).should eq make_ti(0x76543215FEDCBA98u64, 0x7654321500000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 33).should eq make_ti(0xECA8642BFDB97530u64, 0xECA8642A00000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 34).should eq make_ti(0xD950C857FB72EA61u64, 0xD950C85400000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 35).should eq make_ti(0xB2A190AFF6E5D4C3u64, 0xB2A190A800000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 36).should eq make_ti(0x6543215FEDCBA987u64, 0x6543215000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 60).should eq make_ti(0x5FEDCBA987654321u64, 0x5000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 61).should eq make_ti(0xBFDB97530ECA8642u64, 0xA000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 62).should eq make_ti(0x7FB72EA61D950C85u64, 0x4000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 63).should eq make_ti(0xFF6E5D4C3B2A190Au64, 0x8000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 64).should eq make_ti(0xFEDCBA9876543215u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 65).should eq make_ti(0xFDB97530ECA8642Au64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 66).should eq make_ti(0xFB72EA61D950C854u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 67).should eq make_ti(0xF6E5D4C3B2A190A8u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 68).should eq make_ti(0xEDCBA98765432150u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 92).should eq make_ti(0x8765432150000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 93).should eq make_ti(0x0ECA8642A0000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 94).should eq make_ti(0x1D950C8540000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 95).should eq make_ti(0x3B2A190A80000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 96).should eq make_ti(0x7654321500000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 97).should eq make_ti(0xECA8642A00000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 98).should eq make_ti(0xD950C85400000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 99).should eq make_ti(0xB2A190A800000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 100).should eq make_ti(0x6543215000000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 124).should eq make_ti(0x5000000000000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 125).should eq make_ti(0xA000000000000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 126).should eq make_ti(0x4000000000000000u64, 0x0000000000000000u64)
__ashlti3(make_ti(0xFEDCBA9876543215u64, 0xFEDCBA9876543215u64), 127).should eq make_ti(0x8000000000000000u64, 0x0000000000000000u64)
end
Loading