authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-18 18:18:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-18 18:18:41-07:00
logff1ab3fe9ce82a79f1e08236b8a7be42de1ff792
tree8715cf4371f04f52030c85c6e2ae4e4ae3b1e3b8
parentf4c7e1bf4971503e2d33af80537aef27ed2e4fe1

fix crash in non-const expression in struct literal outside fn


2 files changed, 18 insertions(+), 1 deletions(-)

src/analyze.cpp+9-1
...@@ -2195,6 +2195,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry...@@ -2195,6 +2195,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
2195 int expr_field_count = container_init_expr->entries.length;2195 int expr_field_count = container_init_expr->entries.length;
2196 int actual_field_count = container_type->data.structure.src_field_count;2196 int actual_field_count = container_type->data.structure.src_field_count;
21972197
2198 AstNode *non_const_expr_culprit = nullptr;
2199
2198 int *field_use_counts = allocate<int>(actual_field_count);2200 int *field_use_counts = allocate<int>(actual_field_count);
2199 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;2201 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2200 const_val->ok = true;2202 const_val->ok = true;
...@@ -2239,11 +2241,17 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry...@@ -2239,11 +2241,17 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
2239 const_val->depends_on_compile_var = const_val->depends_on_compile_var || field_val->depends_on_compile_var;2241 const_val->depends_on_compile_var = const_val->depends_on_compile_var || field_val->depends_on_compile_var;
2240 } else {2242 } else {
2241 const_val->ok = false;2243 const_val->ok = false;
2244 non_const_expr_culprit = val_field_node->data.struct_val_field.expr;
2242 }2245 }
2243 }2246 }
2244 }2247 }
2245 if (!const_val->ok) {2248 if (!const_val->ok) {
2246 context->fn_entry->struct_val_expr_alloca_list.append(codegen);2249 assert(non_const_expr_culprit);
2250 if (context->fn_entry) {
2251 context->fn_entry->struct_val_expr_alloca_list.append(codegen);
2252 } else {
2253 add_node_error(g, non_const_expr_culprit, buf_sprintf("unable to evaluate constant expression"));
2254 }
2247 }2255 }
22482256
2249 for (int i = 0; i < actual_field_count; i += 1) {2257 for (int i = 0; i < actual_field_count; i += 1) {
test/run_tests.cpp+9
...@@ -1191,6 +1191,15 @@ fn fibbonaci(x: i32) -> i32 {...@@ -1191,6 +1191,15 @@ fn fibbonaci(x: i32) -> i32 {
1191 add_compile_fail_case("@embed_file with bogus file", R"SOURCE(1191 add_compile_fail_case("@embed_file with bogus file", R"SOURCE(
1192const resource = @embed_file("bogus.txt");1192const resource = @embed_file("bogus.txt");
1193 )SOURCE", 1, ".tmp_source.zig:2:18: error: unable to find './bogus.txt'");1193 )SOURCE", 1, ".tmp_source.zig:2:18: error: unable to find './bogus.txt'");
1194
1195
1196 add_compile_fail_case("non-const expression in struct literal outside function", R"SOURCE(
1197struct Foo {
1198 x: i32,
1199}
1200const a = Foo {.x = get_it()};
1201extern fn get_it() -> i32;
1202 )SOURCE", 1, ".tmp_source.zig:5:27: error: unable to evaluate constant expression");
1194}1203}
11951204
1196//////////////////////////////////////////////////////////////////////////////1205//////////////////////////////////////////////////////////////////////////////