authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-11 22:57:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-11 22:57:32-07:00
log954a451c516288b3638692febf557ee8190918dc
tree4381165cacb4fa10faf4e07c528f4c8e39df0f5f
parent4a3bce4b638cf94482afe010af9bae722249f548

unsigned ints implicitly cast to signed ints when they fit

also fix #135

2 files changed, 29 insertions(+), 11 deletions(-)

src/analyze.cpp+20-11
......@@ -1855,6 +1855,14 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
18551855 return true;
18561856 }
18571857
1858 // small enough unsigned ints can get casted to large enough signed ints
1859 if (expected_type->id == TypeTableEntryIdInt && expected_type->data.integral.is_signed &&
1860 actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed &&
1861 expected_type->data.integral.bit_count > actual_type->data.integral.bit_count)
1862 {
1863 return true;
1864 }
1865
18581866 // implicit float widening conversion
18591867 if (expected_type->id == TypeTableEntryIdFloat &&
18601868 actual_type->id == TypeTableEntryIdFloat &&
......@@ -1889,27 +1897,30 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
18891897 return false;
18901898}
18911899
1892static AstNode *create_ast_node(CodeGen *g, ImportTableEntry *import, NodeType kind) {
1900static AstNode *create_ast_node(CodeGen *g, ImportTableEntry *import, NodeType kind, AstNode *source_node) {
18931901 AstNode *node = allocate<AstNode>(1);
18941902 node->type = kind;
18951903 node->owner = import;
18961904 node->create_index = g->next_node_index;
18971905 g->next_node_index += 1;
1906 node->line = source_node->line;
1907 node->column = source_node->column;
18981908 return node;
18991909}
19001910
1901static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeTableEntry *type_entry) {
1902 AstNode *node = create_ast_node(g, import, NodeTypeSymbol);
1911static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeTableEntry *type_entry,
1912 AstNode *source_node)
1913{
1914 AstNode *node = create_ast_node(g, import, NodeTypeSymbol, source_node);
19031915 node->data.symbol_expr.override_type_entry = type_entry;
19041916 return node;
19051917}
19061918
19071919static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNode *source_node) {
1908 AstNode *node = create_ast_node(g, import, NodeTypeContainerInitExpr);
1920 AstNode *node = create_ast_node(g, import, NodeTypeContainerInitExpr, source_node);
19091921 node->data.container_init_expr.kind = ContainerInitKindArray;
1910 node->data.container_init_expr.type = create_ast_type_node(g, import, g->builtin_types.entry_void);
1911 node->line = source_node->line;
1912 node->column = source_node->column;
1922 node->data.container_init_expr.type = create_ast_type_node(g, import, g->builtin_types.entry_void,
1923 source_node);
19131924 normalize_parent_ptrs(node);
19141925 return node;
19151926}
......@@ -1917,13 +1928,11 @@ static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNo
19171928static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,
19181929 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)
19191930{
1920 AstNode *new_parent_node = create_ast_node(g, import, NodeTypeFnCallExpr);
1921 new_parent_node->line = node->line;
1922 new_parent_node->column = node->column;
1931 AstNode *new_parent_node = create_ast_node(g, import, NodeTypeFnCallExpr, node);
19231932 *node->parent_field = new_parent_node;
19241933 new_parent_node->parent_field = node->parent_field;
19251934
1926 new_parent_node->data.fn_call_expr.fn_ref_expr = create_ast_type_node(g, import, cast_to_type);
1935 new_parent_node->data.fn_call_expr.fn_ref_expr = create_ast_type_node(g, import, cast_to_type, node);
19271936 new_parent_node->data.fn_call_expr.params.append(node);
19281937 normalize_parent_ptrs(new_parent_node);
19291938
test/self_hosted.zig+9
......@@ -811,3 +811,12 @@ fn cast_undefined() {
811811 test_cast_undefined(slice);
812812}
813813fn test_cast_undefined(x: []u8) {}
814
815
816#attribute("test")
817fn cast_small_unsigned_to_larger_signed() {
818 assert(cast_small_unsigned_to_larger_signed_1(200) == i16(200));
819 assert(cast_small_unsigned_to_larger_signed_2(9999) == isize(9999));
820}
821fn cast_small_unsigned_to_larger_signed_1(x: u8) -> i16 { x }
822fn cast_small_unsigned_to_larger_signed_2(x: u16) -> isize { x }