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_...@@ -1855,6 +1855,14 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
1855 return true;1855 return true;
1856 }1856 }
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
1858 // implicit float widening conversion1866 // implicit float widening conversion
1859 if (expected_type->id == TypeTableEntryIdFloat &&1867 if (expected_type->id == TypeTableEntryIdFloat &&
1860 actual_type->id == TypeTableEntryIdFloat &&1868 actual_type->id == TypeTableEntryIdFloat &&
...@@ -1889,27 +1897,30 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_...@@ -1889,27 +1897,30 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
1889 return false;1897 return false;
1890}1898}
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) {
1893 AstNode *node = allocate<AstNode>(1);1901 AstNode *node = allocate<AstNode>(1);
1894 node->type = kind;1902 node->type = kind;
1895 node->owner = import;1903 node->owner = import;
1896 node->create_index = g->next_node_index;1904 node->create_index = g->next_node_index;
1897 g->next_node_index += 1;1905 g->next_node_index += 1;
1906 node->line = source_node->line;
1907 node->column = source_node->column;
1898 return node;1908 return node;
1899}1909}
19001910
1901static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeTableEntry *type_entry) {1911static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeTableEntry *type_entry,
1902 AstNode *node = create_ast_node(g, import, NodeTypeSymbol);1912 AstNode *source_node)
1913{
1914 AstNode *node = create_ast_node(g, import, NodeTypeSymbol, source_node);
1903 node->data.symbol_expr.override_type_entry = type_entry;1915 node->data.symbol_expr.override_type_entry = type_entry;
1904 return node;1916 return node;
1905}1917}
19061918
1907static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNode *source_node) {1919static 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);
1909 node->data.container_init_expr.kind = ContainerInitKindArray;1921 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);1922 node->data.container_init_expr.type = create_ast_type_node(g, import, g->builtin_types.entry_void,
1911 node->line = source_node->line;1923 source_node);
1912 node->column = source_node->column;
1913 normalize_parent_ptrs(node);1924 normalize_parent_ptrs(node);
1914 return node;1925 return node;
1915}1926}
...@@ -1917,13 +1928,11 @@ static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNo...@@ -1917,13 +1928,11 @@ static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNo
1917static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,1928static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,
1918 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)1929 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)
1919{1930{
1920 AstNode *new_parent_node = create_ast_node(g, import, NodeTypeFnCallExpr);1931 AstNode *new_parent_node = create_ast_node(g, import, NodeTypeFnCallExpr, node);
1921 new_parent_node->line = node->line;
1922 new_parent_node->column = node->column;
1923 *node->parent_field = new_parent_node;1932 *node->parent_field = new_parent_node;
1924 new_parent_node->parent_field = node->parent_field;1933 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);
1927 new_parent_node->data.fn_call_expr.params.append(node);1936 new_parent_node->data.fn_call_expr.params.append(node);
1928 normalize_parent_ptrs(new_parent_node);1937 normalize_parent_ptrs(new_parent_node);
19291938
test/self_hosted.zig+9
...@@ -811,3 +811,12 @@ fn cast_undefined() {...@@ -811,3 +811,12 @@ fn cast_undefined() {
811 test_cast_undefined(slice);811 test_cast_undefined(slice);
812}812}
813fn test_cast_undefined(x: []u8) {}813fn 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 }