Skip to content

Commit

Permalink
Fix crash when using sizeof, instance_sizeof, or offsetof as a …
Browse files Browse the repository at this point in the history
…type arg (#12577)
  • Loading branch information
keidax authored Nov 30, 2022
1 parent a83537e commit 1b93218
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
24 changes: 24 additions & 0 deletions spec/compiler/semantic/static_array_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,28 @@ describe "Semantic: static array" do
),
"expected argument #1 to 'fn' to be StaticArray(Int32, 11), not StaticArray(Int32, 10)"
end

it "doesn't crash on sizeof (#8858)" do
assert_error %(
alias BadArray = Int32[sizeof(Int32)]
),
"can't use sizeof(Int32) as a generic type argument"
end

it "doesn't crash on instance_sizeof (#8858)" do
assert_error %(
alias BadArray = Int32[instance_sizeof(String)]
),
"can't use instance_sizeof(String) as a generic type argument"
end

it "doesn't crash on offsetof (#8858)" do
assert_error %(
class Foo
@foo : Int32 = 0
end
alias BadArray = Int32[offsetof(Foo, @foo)]
),
"can't use offsetof(Foo, @foo) as a generic type argument"
end
end
4 changes: 4 additions & 0 deletions src/compiler/crystal/semantic/type_lookup.cr
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ class Crystal::Type
type_var.raise "can only splat tuple type, not #{splat_type}"
end
next
when SizeOf, InstanceSizeOf, OffsetOf
next unless @raise

type_var.raise "can't use #{type_var} as a generic type argument"
end

# Check the case of T resolving to a number
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5771,6 +5771,7 @@ module Crystal
end

def parse_sizeof(klass)
sizeof_location = @token.location
next_token_skip_space

check :OP_LPAREN
Expand All @@ -5785,10 +5786,11 @@ module Crystal
check :OP_RPAREN
next_token_skip_space

klass.new(exp).at_end(end_location)
klass.new(exp).at(sizeof_location).at_end(end_location)
end

def parse_offsetof
offsetof_location = @token.location
next_token_skip_space
check :OP_LPAREN

Expand Down Expand Up @@ -5817,7 +5819,7 @@ module Crystal
check :OP_RPAREN
next_token_skip_space

OffsetOf.new(type, offset).at_end(end_location)
OffsetOf.new(type, offset).at(offsetof_location).at_end(end_location)
end

def parse_type_def
Expand Down

0 comments on commit 1b93218

Please sign in to comment.