authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-28 03:47:02-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-28 03:47:02-05:00
loga9acc8cb4574ce8f1792fbfa9bd93985a6b47f87
treed31ec81c7dec180d4f744950e8d504b18c3aa761
parentdc26dec8e0c86c42485842eb3949edfe816f0e55

IR: error for returning from defer expression

also fix peer type resolution for pure error mixed with error union

5 files changed, 57 insertions(+), 5 deletions(-)

src/all_types.hpp+12-1
......@@ -344,7 +344,7 @@ struct AstNodeDefer {
344344
345345 // temporary data used in IR generation
346346 Scope *child_scope;
347 Scope *parent_scope;
347 Scope *expr_scope;
348348};
349349
350350struct AstNodeVariableDeclaration {
......@@ -1280,6 +1280,7 @@ enum ScopeId {
12801280 ScopeIdDecls,
12811281 ScopeIdBlock,
12821282 ScopeIdDefer,
1283 ScopeIdDeferExpr,
12831284 ScopeIdVarDecl,
12841285 ScopeIdCImport,
12851286 ScopeIdLoop,
......@@ -1321,11 +1322,21 @@ struct ScopeBlock {
13211322};
13221323
13231324// This scope is created from every defer expression.
1325// It's the code following the defer statement.
13241326// NodeTypeDefer
13251327struct ScopeDefer {
13261328 Scope base;
13271329};
13281330
1331// This scope is created from every defer expression.
1332// It's the parent of the defer expression itself.
1333// NodeTypeDefer
1334struct ScopeDeferExpr {
1335 Scope base;
1336
1337 bool reported_err;
1338};
1339
13291340// This scope is created for every variable declaration inside an IrExecutable
13301341// NodeTypeVariableDeclaration, NodeTypeParamDecl
13311342struct ScopeVarDecl {
src/analyze.cpp+8
......@@ -163,6 +163,13 @@ ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {
163163 return scope;
164164}
165165
166ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) {
167 assert(node->type == NodeTypeDefer);
168 ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
169 init_scope(&scope->base, ScopeIdDeferExpr, node, parent);
170 return scope;
171}
172
166173Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
167174 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
168175 init_scope(&scope->base, ScopeIdVarDecl, node, parent);
......@@ -2183,6 +2190,7 @@ FnTableEntry *scope_get_fn_if_root(Scope *scope) {
21832190 return nullptr;
21842191 case ScopeIdDecls:
21852192 case ScopeIdDefer:
2193 case ScopeIdDeferExpr:
21862194 case ScopeIdVarDecl:
21872195 case ScopeIdCImport:
21882196 case ScopeIdLoop:
src/analyze.hpp+1
......@@ -84,6 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
8484
8585ScopeBlock *create_block_scope(AstNode *node, Scope *parent);
8686ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
87ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);
8788Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);
8889ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);
8990Scope *create_loop_scope(AstNode *node, Scope *parent);
src/codegen.cpp+2
......@@ -325,6 +325,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
325325 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
326326 return scope->di_scope;
327327 }
328 case ScopeIdDeferExpr:
329 return get_di_scope(g, scope->parent);
328330 }
329331 zig_unreachable();
330332}
src/ir.cpp+34-4
......@@ -1980,7 +1980,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
19801980 (gen_maybe_defers && defer_kind == ReturnKindMaybe))
19811981 {
19821982 AstNode *defer_expr_node = defer_node->data.defer.expr;
1983 ir_gen_node(irb, defer_expr_node, defer_node->data.defer.parent_scope);
1983 ir_gen_node(irb, defer_expr_node, defer_node->data.defer.expr_scope);
19841984 }
19851985
19861986 }
......@@ -1994,6 +1994,18 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
19941994 irb->current_basic_block = basic_block;
19951995}
19961996
1997static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
1998 while (scope) {
1999 if (scope->id == ScopeIdDeferExpr)
2000 return (ScopeDeferExpr *)scope;
2001 if (scope->id == ScopeIdFnDef)
2002 return nullptr;
2003
2004 scope = scope->parent;
2005 }
2006 return nullptr;
2007}
2008
19972009static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
19982010 assert(node->type == NodeTypeReturnExpr);
19992011
......@@ -2003,6 +2015,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
20032015 return irb->codegen->invalid_instruction;
20042016 }
20052017
2018 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope);
2019 if (scope_defer_expr) {
2020 if (!scope_defer_expr->reported_err) {
2021 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression"));
2022 scope_defer_expr->reported_err = true;
2023 }
2024 return irb->codegen->invalid_instruction;
2025 }
2026
20062027 Scope *outer_scope = fn_entry->child_scope;
20072028
20082029 AstNode *expr_node = node->data.return_expr.expr;
......@@ -2593,6 +2614,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
25932614 return irb->codegen->invalid_instruction;
25942615 }
25952616
2617 // TODO put a variable of same name with invalid type in global scope
2618 // so that future references to this same name will find a variable with an invalid type
25962619 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
25972620 return irb->codegen->invalid_instruction;
25982621}
......@@ -4012,9 +4035,11 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n
40124035static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
40134036 assert(node->type == NodeTypeDefer);
40144037
4015 ScopeDefer *defer_scope = create_defer_scope(node, parent_scope);
4016 node->data.defer.child_scope = &defer_scope->base;
4017 node->data.defer.parent_scope = parent_scope;
4038 ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope);
4039 node->data.defer.child_scope = &defer_child_scope->base;
4040
4041 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope);
4042 node->data.defer.expr_scope = &defer_expr_scope->base;
40184043
40194044 return ir_build_const_void(irb, parent_scope, node);
40204045}
......@@ -4665,6 +4690,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
46654690 ir_add_error_node(ira, source_node,
46664691 buf_sprintf("unable to make error union out of null literal"));
46674692 return ira->codegen->builtin_types.entry_invalid;
4693 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {
4694 return prev_inst->value.type;
46684695 } else {
46694696 return get_error_type(ira->codegen, prev_inst->value.type);
46704697 }
......@@ -4675,6 +4702,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
46754702 ir_add_error_node(ira, source_node,
46764703 buf_sprintf("unable to make maybe out of number literal"));
46774704 return ira->codegen->builtin_types.entry_invalid;
4705 } else if (prev_inst->value.type->id == TypeTableEntryIdMaybe) {
4706 return prev_inst->value.type;
46784707 } else {
46794708 return get_maybe_type(ira->codegen, prev_inst->value.type);
46804709 }
......@@ -9955,6 +9984,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
99559984static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
99569985 IrInstructionUnwrapErrPayload *instruction)
99579986{
9987 assert(instruction->value->other);
99589988 IrInstruction *value = instruction->value->other;
99599989 if (value->value.type->id == TypeTableEntryIdInvalid)
99609990 return ira->codegen->builtin_types.entry_invalid;