Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7973c4347c60
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d8eac43727e4
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Jun 3, 2017

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    7eba0e8 View commit details
  2. Copy the full SHA
    d8eac43 View commit details
25 changes: 25 additions & 0 deletions spec/compiler/codegen/sizeof_spec.cr
Original file line number Diff line number Diff line change
@@ -167,4 +167,29 @@ describe "Code gen: sizeof" do
x.size
)).to_i.should eq(12)
end

{% if flag?(:x86_64) %}
it "returns correct sizeof for abstract struct (#4319)" do
size = run(%(
abstract struct Entry
end
struct FooEntry < Entry
def initialize
@uid = ""
end
end
struct BarEntry < Entry
def initialize
@uid = ""
end
end
sizeof(Entry)
)).to_i

size.should eq(16)
end
{% end %}
end
3 changes: 3 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -1475,6 +1475,9 @@ describe "Parser" do

assert_syntax_error %(def foo("bar");end), "expected argument internal name"

assert_syntax_error %({"a" : 1})
assert_syntax_error %({"a": 1, "b" : 2})

describe "end locations" do
assert_end_location "nil"
assert_end_location "false"
4 changes: 2 additions & 2 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
@@ -678,12 +678,12 @@ module Crystal
end

def visit(node : SizeOf)
@last = trunc(llvm_size(node.exp.type.instance_type.devirtualize), llvm_context.int32)
@last = trunc(llvm_size(node.exp.type.sizeof_type), llvm_context.int32)
false
end

def visit(node : InstanceSizeOf)
@last = trunc(llvm_struct_size(node.exp.type.instance_type.devirtualize), llvm_context.int32)
@last = trunc(llvm_struct_size(node.exp.type.sizeof_type), llvm_context.int32)
false
end

4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -2452,7 +2452,7 @@ module Crystal
# (useful for sizeof inside as a generic type argument, but also
# to make it easier for LLVM to optimize things)
if (type = node.exp.type?) && !node.exp.is_a?(TypeOf)
expanded = NumberLiteral.new(@program.size_of(type.devirtualize))
expanded = NumberLiteral.new(@program.size_of(type.sizeof_type))
expanded.type = @program.int32
node.expanded = expanded
end
@@ -2469,7 +2469,7 @@ module Crystal
# (useful for sizeof inside as a generic type argument, but also
# to make it easier for LLVM to optimize things)
if (type = node.exp.type?) && type.instance_type.devirtualize.class? && !node.exp.is_a?(TypeOf)
expanded = NumberLiteral.new(@program.instance_size_of(type.devirtualize))
expanded = NumberLiteral.new(@program.instance_size_of(type.sizeof_type))
expanded.type = @program.int32
node.expanded = expanded
end
32 changes: 18 additions & 14 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
@@ -1743,7 +1743,7 @@ module Crystal
value : String | ASTNode,
line_number : Int32

def parse_delimiter
def parse_delimiter(want_skip_space = true)
if @token.type == :STRING
return node_and_next_token StringLiteral.new(@token.value.to_s)
end
@@ -1761,7 +1761,7 @@ module Crystal

delimiter_state, has_interpolation, options, token_end_location = consume_delimiter pieces, delimiter_state, has_interpolation

if delimiter_state.kind == :string
if delimiter_state.kind == :string && want_skip_space
while true
passed_backslash_newline = @token.passed_backslash_newline
skip_space
@@ -1981,14 +1981,14 @@ module Crystal
end
end

def parse_string_without_interpolation(context)
def parse_string_without_interpolation(context, want_skip_space = true)
location = @token.location

unless string_literal_start?
raise "expected string literal for #{context}, not #{@token}"
end

string = parse_delimiter
string = parse_delimiter(want_skip_space)
if string.is_a?(StringLiteral)
string.value
else
@@ -2096,18 +2096,22 @@ module Crystal
end
return parse_named_tuple(location)
else
first_key = parse_op_assign_no_control
case @token.type
when :":"
if first_key.is_a?(StringLiteral)
if string_literal_start?
first_key = parse_delimiter(want_skip_space: false)
if first_key.is_a?(StringLiteral) && @token.type == :":"
# It's a named tuple
unless allow_of
raise "can't use named tuple syntax for Hash-like literal, use '=>'", @token
end
return parse_named_tuple(location, first_key.value)
else
check :"=>"
end
else
first_key = parse_op_assign_no_control
end

skip_space

case @token.type
when :","
slash_is_regex!
next_token_skip_space_or_newline
@@ -2121,10 +2125,10 @@ module Crystal
else
check :"=>"
end
slash_is_regex!
next_token_skip_space
parse_hash_literal first_key, location, allow_of
end
slash_is_regex!
next_token_skip_space
parse_hash_literal first_key, location, allow_of
end
end

@@ -2265,7 +2269,7 @@ module Crystal
if named_tuple_start?
next_token
elsif string_literal_start?
key = parse_string_without_interpolation("named tuple name")
key = parse_string_without_interpolation("named tuple name", want_skip_space: false)
else
raise "expected '}' or named tuple name, not #{@token}", @token
end
11 changes: 11 additions & 0 deletions src/compiler/crystal/types.cr
Original file line number Diff line number Diff line change
@@ -578,6 +578,17 @@ module Crystal
false
end

# Returns the type that has to be used in sizeof and instance_sizeof computations
def sizeof_type
if struct?
# In the case of an abstract struct we want to consider the union type
# of all subtypes (if it's not abstract it's concrete and this will return self)
virtual_type.remove_indirection
else
devirtualize
end
end

def inspect(io)
to_s(io)
end