authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-28 18:18:52-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-28 18:19:27-04:00
logb66438eb8092ea93b255f0ba11f857b1d6ccb052
tree7e351e82aeb9f5131a2a74f13ac1b9cc0aac5aee
parent528c151a55a76451b278057c40b29242241a70fd
signaturelock-open Commit is signed but in an unrecognized format.

no "use of undeclared identifer" in dead comptime branches


7 files changed, 70 insertions(+), 28 deletions(-)

src/all_types.hpp+7
...@@ -2306,6 +2306,7 @@ enum IrInstructionId {...@@ -2306,6 +2306,7 @@ enum IrInstructionId {
2306 IrInstructionIdAssertZero,2306 IrInstructionIdAssertZero,
2307 IrInstructionIdAssertNonNull,2307 IrInstructionIdAssertNonNull,
2308 IrInstructionIdHasDecl,2308 IrInstructionIdHasDecl,
2309 IrInstructionIdUndeclaredIdent,
2309};2310};
23102311
2311struct IrInstruction {2312struct IrInstruction {
...@@ -3519,6 +3520,12 @@ struct IrInstructionHasDecl {...@@ -3519,6 +3520,12 @@ struct IrInstructionHasDecl {
3519 IrInstruction *name;3520 IrInstruction *name;
3520};3521};
35213522
3523struct IrInstructionUndeclaredIdent {
3524 IrInstruction base;
3525
3526 Buf *name;
3527};
3528
3522static const size_t slice_ptr_index = 0;3529static const size_t slice_ptr_index = 0;
3523static const size_t slice_len_index = 1;3530static const size_t slice_len_index = 1;
35243531
src/codegen.cpp+1
...@@ -5606,6 +5606,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5606,6 +5606,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5606 case IrInstructionIdBitCast:5606 case IrInstructionIdBitCast:
5607 case IrInstructionIdGlobalAsm:5607 case IrInstructionIdGlobalAsm:
5608 case IrInstructionIdHasDecl:5608 case IrInstructionIdHasDecl:
5609 case IrInstructionIdUndeclaredIdent:
5609 zig_unreachable();5610 zig_unreachable();
56105611
5611 case IrInstructionIdDeclVarGen:5612 case IrInstructionIdDeclVarGen:
src/ir.cpp+39-12
...@@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {...@@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {
1015 return IrInstructionIdHasDecl;1015 return IrInstructionIdHasDecl;
1016}1016}
10171017
1018static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) {
1019 return IrInstructionIdUndeclaredIdent;
1020}
1021
1018template<typename T>1022template<typename T>
1019static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1023static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1020 T *special_instruction = allocate<T>(1);1024 T *special_instruction = allocate<T>(1);
...@@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s...@@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s
3031 return &instruction->base;3035 return &instruction->base;
3032}3036}
30333037
3038static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node,
3039 Buf *name)
3040{
3041 IrInstructionUndeclaredIdent *instruction = ir_build_instruction<IrInstructionUndeclaredIdent>(irb, scope, source_node);
3042 instruction->name = name;
3043
3044 return &instruction->base;
3045}
3046
3034static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {3047static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
3035 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);3048 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
3036 instruction->scope_is_comptime = scope_is_comptime;3049 instruction->scope_is_comptime = scope_is_comptime;
...@@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
38963909
3897 Buf *variable_name = node->data.symbol_expr.symbol;3910 Buf *variable_name = node->data.symbol_expr.symbol;
38983911
3899 if (buf_eql_str(variable_name, "_") && lval == LValPtr) {3912 if (buf_eql_str(variable_name, "_")) {
3900 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);3913 if (lval == LValPtr) {
3901 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,3914 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
3902 irb->codegen->builtin_types.entry_void, false);3915 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
3903 const_instruction->base.value.special = ConstValSpecialStatic;3916 irb->codegen->builtin_types.entry_void, false);
3904 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;3917 const_instruction->base.value.special = ConstValSpecialStatic;
3905 return &const_instruction->base;3918 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;
3919 return &const_instruction->base;
3920 } else {
3921 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to"));
3922 return irb->codegen->invalid_instruction;
3923 }
3906 }3924 }
39073925
3908 ZigType *primitive_type;3926 ZigType *primitive_type;
...@@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
3943 return irb->codegen->invalid_instruction;3961 return irb->codegen->invalid_instruction;
3944 }3962 }
39453963
3946 // put a variable of same name with invalid type in global scope3964 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
3947 // so that future references to this same name will find a variable with an invalid type
3948 populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name);
3949 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
3950 return irb->codegen->invalid_instruction;
3951}3965}
39523966
3953static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {3967static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
...@@ -23237,6 +23251,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct...@@ -23237,6 +23251,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct
23237 return ir_const_bool(ira, &instruction->base, true);23251 return ir_const_bool(ira, &instruction->base, true);
23238}23252}
2323923253
23254static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) {
23255 // put a variable of same name with invalid type in global scope
23256 // so that future references to this same name will find a variable with an invalid type
23257 populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node,
23258 instruction->name);
23259 ir_add_error(ira, &instruction->base,
23260 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name)));
23261 return ira->codegen->invalid_instruction;
23262}
23263
23240static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {23264static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
23241 switch (instruction->id) {23265 switch (instruction->id) {
23242 case IrInstructionIdInvalid:23266 case IrInstructionIdInvalid:
...@@ -23533,6 +23557,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23533,6 +23557,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23533 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);23557 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);
23534 case IrInstructionIdHasDecl:23558 case IrInstructionIdHasDecl:
23535 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);23559 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
23560 case IrInstructionIdUndeclaredIdent:
23561 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
23536 }23562 }
23537 zig_unreachable();23563 zig_unreachable();
23538}23564}
...@@ -23667,6 +23693,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -23667,6 +23693,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
23667 case IrInstructionIdAssertNonNull:23693 case IrInstructionIdAssertNonNull:
23668 case IrInstructionIdResizeSlice:23694 case IrInstructionIdResizeSlice:
23669 case IrInstructionIdGlobalAsm:23695 case IrInstructionIdGlobalAsm:
23696 case IrInstructionIdUndeclaredIdent:
23670 return true;23697 return true;
2367123698
23672 case IrInstructionIdPhi:23699 case IrInstructionIdPhi:
src/ir_print.cpp+7
...@@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) {...@@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) {
1461 fprintf(irp->f, ")");1461 fprintf(irp->f, ")");
1462}1462}
14631463
1464static void ir_print_undeclared_ident(IrPrint *irp, IrInstructionUndeclaredIdent *instruction) {
1465 fprintf(irp->f, "@undeclaredIdent(%s)", buf_ptr(instruction->name));
1466}
1467
1464static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1468static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1465 ir_print_prefix(irp, instruction);1469 ir_print_prefix(irp, instruction);
1466 switch (instruction->id) {1470 switch (instruction->id) {
...@@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1931 case IrInstructionIdHasDecl:1935 case IrInstructionIdHasDecl:
1932 ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction);1936 ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction);
1933 break;1937 break;
1938 case IrInstructionIdUndeclaredIdent:
1939 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
1940 break;
1934 }1941 }
1935 fprintf(irp->f, "\n");1942 fprintf(irp->f, "\n");
1936}1943}
std/os/bits/windows.zig-7
...@@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140;...@@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140;
158pub const EDQUOT = 10069;158pub const EDQUOT = 10069;
159159
160pub const F_OK = 0;160pub const F_OK = 0;
161
162// These are workarounds for "use of undeclared identifier" compile errors
163// TODO make the compiler even more lazy. don't emit "use of undeclared identifier" errors
164// for if branches that aren't taken.
165pub const SIGKILL = @compileError("Windows libc does not have this");
166
167
test/compile_errors.zig+3-4
...@@ -1219,7 +1219,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1219,7 +1219,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1219 \\}1219 \\}
1220 ,1220 ,
1221 "tmp.zig:2:5: error: `_` is not a declarable symbol",1221 "tmp.zig:2:5: error: `_` is not a declarable symbol",
1222 "tmp.zig:3:12: error: use of undeclared identifier '_'",
1223 );1222 );
12241223
1225 cases.add(1224 cases.add(
...@@ -1232,7 +1231,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1232,7 +1231,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1232 \\ }1231 \\ }
1233 \\}1232 \\}
1234 ,1233 ,
1235 "tmp.zig:4:20: error: use of undeclared identifier '_'",1234 "tmp.zig:4:20: error: `_` may only be used to assign things to",
1236 );1235 );
12371236
1238 cases.add(1237 cases.add(
...@@ -1248,7 +1247,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1248,7 +1247,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1248 \\ return 1;1247 \\ return 1;
1249 \\}1248 \\}
1250 ,1249 ,
1251 "tmp.zig:4:20: error: use of undeclared identifier '_'",1250 "tmp.zig:4:20: error: `_` may only be used to assign things to",
1252 );1251 );
12531252
1254 cases.add(1253 cases.add(
...@@ -1266,7 +1265,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1266,7 +1265,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1266 \\ return error.optionalReturnError;1265 \\ return error.optionalReturnError;
1267 \\}1266 \\}
1268 ,1267 ,
1269 "tmp.zig:6:17: error: use of undeclared identifier '_'",1268 "tmp.zig:6:17: error: `_` may only be used to assign things to",
1270 );1269 );
12711270
1272 cases.add(1271 cases.add(
test/stage1/behavior/eval.zig+13-5
...@@ -93,11 +93,13 @@ pub const Vec3 = struct {...@@ -93,11 +93,13 @@ pub const Vec3 = struct {
93 data: [3]f32,93 data: [3]f32,
94};94};
95pub fn vec3(x: f32, y: f32, z: f32) Vec3 {95pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
96 return Vec3{ .data = []f32{96 return Vec3{
97 x,97 .data = []f32{
98 y,98 x,
99 z,99 y,
100 } };100 z,
101 },
102 };
101}103}
102104
103test "constant expressions" {105test "constant expressions" {
...@@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 {...@@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 {
776fn scalar(x: u32) u32 {778fn scalar(x: u32) u32 {
777 return x;779 return x;
778}780}
781
782test "no undeclared identifier error in unanalyzed branches" {
783 if (false) {
784 lol_this_doesnt_exist = nonsense;
785 }
786}