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 {...@@ -344,7 +344,7 @@ struct AstNodeDefer {
344344
345 // temporary data used in IR generation345 // temporary data used in IR generation
346 Scope *child_scope;346 Scope *child_scope;
347 Scope *parent_scope;347 Scope *expr_scope;
348};348};
349349
350struct AstNodeVariableDeclaration {350struct AstNodeVariableDeclaration {
...@@ -1280,6 +1280,7 @@ enum ScopeId {...@@ -1280,6 +1280,7 @@ enum ScopeId {
1280 ScopeIdDecls,1280 ScopeIdDecls,
1281 ScopeIdBlock,1281 ScopeIdBlock,
1282 ScopeIdDefer,1282 ScopeIdDefer,
1283 ScopeIdDeferExpr,
1283 ScopeIdVarDecl,1284 ScopeIdVarDecl,
1284 ScopeIdCImport,1285 ScopeIdCImport,
1285 ScopeIdLoop,1286 ScopeIdLoop,
...@@ -1321,11 +1322,21 @@ struct ScopeBlock {...@@ -1321,11 +1322,21 @@ struct ScopeBlock {
1321};1322};
13221323
1323// This scope is created from every defer expression.1324// This scope is created from every defer expression.
1325// It's the code following the defer statement.
1324// NodeTypeDefer1326// NodeTypeDefer
1325struct ScopeDefer {1327struct ScopeDefer {
1326 Scope base;1328 Scope base;
1327};1329};
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
1329// This scope is created for every variable declaration inside an IrExecutable1340// This scope is created for every variable declaration inside an IrExecutable
1330// NodeTypeVariableDeclaration, NodeTypeParamDecl1341// NodeTypeVariableDeclaration, NodeTypeParamDecl
1331struct ScopeVarDecl {1342struct ScopeVarDecl {
src/analyze.cpp+8
...@@ -163,6 +163,13 @@ ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {...@@ -163,6 +163,13 @@ ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {
163 return scope;163 return scope;
164}164}
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
166Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {173Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
167 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);174 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
168 init_scope(&scope->base, ScopeIdVarDecl, node, parent);175 init_scope(&scope->base, ScopeIdVarDecl, node, parent);
...@@ -2183,6 +2190,7 @@ FnTableEntry *scope_get_fn_if_root(Scope *scope) {...@@ -2183,6 +2190,7 @@ FnTableEntry *scope_get_fn_if_root(Scope *scope) {
2183 return nullptr;2190 return nullptr;
2184 case ScopeIdDecls:2191 case ScopeIdDecls:
2185 case ScopeIdDefer:2192 case ScopeIdDefer:
2193 case ScopeIdDeferExpr:
2186 case ScopeIdVarDecl:2194 case ScopeIdVarDecl:
2187 case ScopeIdCImport:2195 case ScopeIdCImport:
2188 case ScopeIdLoop:2196 case ScopeIdLoop:
src/analyze.hpp+1
...@@ -84,6 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *...@@ -84,6 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
8484
85ScopeBlock *create_block_scope(AstNode *node, Scope *parent);85ScopeBlock *create_block_scope(AstNode *node, Scope *parent);
86ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);86ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
87ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);
87Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);88Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);
88ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);89ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);
89Scope *create_loop_scope(AstNode *node, Scope *parent);90Scope *create_loop_scope(AstNode *node, Scope *parent);
src/codegen.cpp+2
...@@ -325,6 +325,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -325,6 +325,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
325 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);325 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
326 return scope->di_scope;326 return scope->di_scope;
327 }327 }
328 case ScopeIdDeferExpr:
329 return get_di_scope(g, scope->parent);
328 }330 }
329 zig_unreachable();331 zig_unreachable();
330}332}
src/ir.cpp+34-4
...@@ -1980,7 +1980,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o...@@ -1980,7 +1980,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
1980 (gen_maybe_defers && defer_kind == ReturnKindMaybe))1980 (gen_maybe_defers && defer_kind == ReturnKindMaybe))
1981 {1981 {
1982 AstNode *defer_expr_node = defer_node->data.defer.expr;1982 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);
1984 }1984 }
19851985
1986 }1986 }
...@@ -1994,6 +1994,18 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {...@@ -1994,6 +1994,18 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
1994 irb->current_basic_block = basic_block;1994 irb->current_basic_block = basic_block;
1995}1995}
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
1997static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {2009static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1998 assert(node->type == NodeTypeReturnExpr);2010 assert(node->type == NodeTypeReturnExpr);
19992011
...@@ -2003,6 +2015,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2003,6 +2015,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
2003 return irb->codegen->invalid_instruction;2015 return irb->codegen->invalid_instruction;
2004 }2016 }
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
2006 Scope *outer_scope = fn_entry->child_scope;2027 Scope *outer_scope = fn_entry->child_scope;
20072028
2008 AstNode *expr_node = node->data.return_expr.expr;2029 AstNode *expr_node = node->data.return_expr.expr;
...@@ -2593,6 +2614,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2593,6 +2614,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
2593 return irb->codegen->invalid_instruction;2614 return irb->codegen->invalid_instruction;
2594 }2615 }
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
2596 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));2619 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
2597 return irb->codegen->invalid_instruction;2620 return irb->codegen->invalid_instruction;
2598}2621}
...@@ -4012,9 +4035,11 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n...@@ -4012,9 +4035,11 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n
4012static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {4035static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
4013 assert(node->type == NodeTypeDefer);4036 assert(node->type == NodeTypeDefer);
40144037
4015 ScopeDefer *defer_scope = create_defer_scope(node, parent_scope);4038 ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope);
4016 node->data.defer.child_scope = &defer_scope->base;4039 node->data.defer.child_scope = &defer_child_scope->base;
4017 node->data.defer.parent_scope = parent_scope;4040
4041 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope);
4042 node->data.defer.expr_scope = &defer_expr_scope->base;
40184043
4019 return ir_build_const_void(irb, parent_scope, node);4044 return ir_build_const_void(irb, parent_scope, node);
4020}4045}
...@@ -4665,6 +4690,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -4665,6 +4690,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
4665 ir_add_error_node(ira, source_node,4690 ir_add_error_node(ira, source_node,
4666 buf_sprintf("unable to make error union out of null literal"));4691 buf_sprintf("unable to make error union out of null literal"));
4667 return ira->codegen->builtin_types.entry_invalid;4692 return ira->codegen->builtin_types.entry_invalid;
4693 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {
4694 return prev_inst->value.type;
4668 } else {4695 } else {
4669 return get_error_type(ira->codegen, prev_inst->value.type);4696 return get_error_type(ira->codegen, prev_inst->value.type);
4670 }4697 }
...@@ -4675,6 +4702,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -4675,6 +4702,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
4675 ir_add_error_node(ira, source_node,4702 ir_add_error_node(ira, source_node,
4676 buf_sprintf("unable to make maybe out of number literal"));4703 buf_sprintf("unable to make maybe out of number literal"));
4677 return ira->codegen->builtin_types.entry_invalid;4704 return ira->codegen->builtin_types.entry_invalid;
4705 } else if (prev_inst->value.type->id == TypeTableEntryIdMaybe) {
4706 return prev_inst->value.type;
4678 } else {4707 } else {
4679 return get_maybe_type(ira->codegen, prev_inst->value.type);4708 return get_maybe_type(ira->codegen, prev_inst->value.type);
4680 }4709 }
...@@ -9955,6 +9984,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,...@@ -9955,6 +9984,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
9955static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,9984static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
9956 IrInstructionUnwrapErrPayload *instruction)9985 IrInstructionUnwrapErrPayload *instruction)
9957{9986{
9987 assert(instruction->value->other);
9958 IrInstruction *value = instruction->value->other;9988 IrInstruction *value = instruction->value->other;
9959 if (value->value.type->id == TypeTableEntryIdInvalid)9989 if (value->value.type->id == TypeTableEntryIdInvalid)
9960 return ira->codegen->builtin_types.entry_invalid;9990 return ira->codegen->builtin_types.entry_invalid;