Commit 0683bd8bf6

Andrew Kelley <superjoe30@gmail.com>
2016-04-10 21:04:25
fix crash when casting undefined to slice
also fix crash having to do with runtime allocated stack memory
1 parent fddfc31
Changed files (3)
src/analyze.cpp
@@ -3838,6 +3838,7 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
         return;
     }
     const_val->depends_on_compile_var = other_val->depends_on_compile_var;
+    const_val->undef = other_val->undef;
 
     assert(other_val != const_val);
     switch (node->data.fn_call_expr.cast_op) {
src/codegen.cpp
@@ -2479,37 +2479,40 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
                 value, variable->type, expr_type);
     } else {
         bool ignore_uninit = false;
-        TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
-        if (var_type->id == TypeTableEntryIdStruct &&
-            var_type->data.structure.is_unknown_size_array)
-        {
-            assert(var_decl->type->type == NodeTypeArrayType);
-            AstNode *size_node = var_decl->type->data.array_type.size;
-            if (size_node) {
-                ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
-                if (!const_val->ok) {
-                    TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
-                    assert(ptr_type->id == TypeTableEntryIdPointer);
-                    TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
-
-                    LLVMValueRef size_val = gen_expr(g, size_node);
-
-                    add_debug_source_node(g, source_node);
-                    LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
-                            size_val, "");
-
-                    // store the freshly allocated pointer in the unknown size array struct
-                    LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
-                            variable->value_ref, 0, "");
-                    LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
-
-                    // store the size in the len field
-                    LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
-                            variable->value_ref, 1, "");
-                    LLVMBuildStore(g->builder, size_val, len_field_ptr);
-
-                    // don't clobber what we just did with debug initialization
-                    ignore_uninit = true;
+        // handle runtime stack allocation
+        if (var_decl->type) {
+            TypeTableEntry *var_type = get_type_for_type_node(var_decl->type);
+            if (var_type->id == TypeTableEntryIdStruct &&
+                var_type->data.structure.is_unknown_size_array)
+            {
+                assert(var_decl->type->type == NodeTypeArrayType);
+                AstNode *size_node = var_decl->type->data.array_type.size;
+                if (size_node) {
+                    ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
+                    if (!const_val->ok) {
+                        TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry;
+                        assert(ptr_type->id == TypeTableEntryIdPointer);
+                        TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
+
+                        LLVMValueRef size_val = gen_expr(g, size_node);
+
+                        add_debug_source_node(g, source_node);
+                        LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref,
+                                size_val, "");
+
+                        // store the freshly allocated pointer in the unknown size array struct
+                        LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder,
+                                variable->value_ref, 0, "");
+                        LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr);
+
+                        // store the size in the len field
+                        LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder,
+                                variable->value_ref, 1, "");
+                        LLVMBuildStore(g->builder, size_val, len_field_ptr);
+
+                        // don't clobber what we just did with debug initialization
+                        ignore_uninit = true;
+                    }
                 }
             }
         }
test/self_hosted.zig
@@ -609,3 +609,11 @@ entry:
     if (b) goto exit;
 }
 
+
+#attribute("test")
+fn cast_undefined() {
+    const array: [100]u8 = undefined;
+    const slice = ([]u8)(array);
+    test_cast_undefined(slice);
+}
+fn test_cast_undefined(x: []u8) {}