aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-11-25 18:16:33 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-11-25 18:16:33 -0500
commita2afcae9ff1f2eed5c6a19a2bd63af288b9171ad (patch)
tree14778ba4c1e3151888ca209dd06b4ba72d545569 /src
parent48ebb65cc7a976599c0a2b9e6647ea057727cf21 (diff)
downloadzig-a2afcae9ff1f2eed5c6a19a2bd63af288b9171ad.tar.gz
zig-a2afcae9ff1f2eed5c6a19a2bd63af288b9171ad.zip
fix crash when constant inside comptime function has compile error
closes #625
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp3
-rw-r--r--src/ir.cpp27
2 files changed, 26 insertions, 4 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 2b09131bef..2fccf08e88 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -36,6 +36,7 @@ struct IrInstructionCast;
struct IrBasicBlock;
struct ScopeDecls;
struct ZigWindowsSDK;
+struct Tld;
struct IrGotoItem {
AstNode *source_node;
@@ -59,7 +60,9 @@ struct IrExecutable {
Buf *c_import_buf;
AstNode *source_node;
IrExecutable *parent_exec;
+ IrExecutable *source_exec;
Scope *begin_scope;
+ ZigList<Tld *> tld_list;
};
enum OutType {
diff --git a/src/ir.cpp b/src/ir.cpp
index a58374dc8c..f632a261f6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -6332,6 +6332,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
}
irb->codegen->resolve_queue.append(&tld_container->base);
+ // Add this to the list to mark as invalid if analyzing this exec fails.
+ irb->exec->tld_list.append(&tld_container->base);
+
return ir_build_const_type(irb, parent_scope, node, container_type);
}
@@ -6554,6 +6557,20 @@ static bool ir_goto_pass2(IrBuilder *irb) {
return true;
}
+static void invalidate_exec(IrExecutable *exec) {
+ if (exec->invalid)
+ return;
+
+ exec->invalid = true;
+
+ for (size_t i = 0; i < exec->tld_list.length; i += 1) {
+ exec->tld_list.items[i]->resolution = TldResolutionInvalid;
+ }
+
+ if (exec->source_exec != nullptr)
+ invalidate_exec(exec->source_exec);
+}
+
bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
assert(node->owner);
@@ -6577,7 +6594,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
}
if (!ir_goto_pass2(irb)) {
- irb->exec->invalid = true;
+ invalidate_exec(ir_executable);
return false;
}
@@ -6603,7 +6620,7 @@ static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg
}
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
- exec->invalid = true;
+ invalidate_exec(exec);
ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
if (exec->parent_exec) {
add_call_stack_errors(codegen, exec, err_msg, 10);
@@ -8056,6 +8073,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
IrExecutable analyzed_executable = {0};
analyzed_executable.source_node = source_node;
analyzed_executable.parent_exec = parent_exec;
+ analyzed_executable.source_exec = &ir_executable;
analyzed_executable.name = exec_name;
analyzed_executable.is_inline = true;
analyzed_executable.fn_entry = fn_entry;
@@ -10490,10 +10508,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
- if (type_is_invalid(result->value.type))
- return ira->codegen->builtin_types.entry_invalid;
ira->codegen->memoized_fn_eval_table.put(exec_scope, result);
+
+ if (type_is_invalid(result->value.type))
+ return ira->codegen->builtin_types.entry_invalid;
}
ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base);