parent
067968c57f
commit
079728752e
19
src/ir.cpp
19
src/ir.cpp
|
@ -3674,6 +3674,22 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
|
||||||
return ir_build_const_null(irb, scope, node);
|
return ir_build_const_null(irb, scope, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) {
|
||||||
|
ScopeDecls *scope_decls = nullptr;
|
||||||
|
while (scope != nullptr) {
|
||||||
|
if (scope->id == ScopeIdDecls) {
|
||||||
|
scope_decls = reinterpret_cast<ScopeDecls *>(scope);
|
||||||
|
}
|
||||||
|
scope = scope->parent;
|
||||||
|
}
|
||||||
|
TldVar *tld_var = allocate<TldVar>(1);
|
||||||
|
init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
|
||||||
|
tld_var->base.resolution = TldResolutionInvalid;
|
||||||
|
tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
|
||||||
|
&g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid);
|
||||||
|
scope_decls->decl_table.put(var_name, &tld_var->base);
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
|
static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
|
||||||
Error err;
|
Error err;
|
||||||
assert(node->type == NodeTypeSymbol);
|
assert(node->type == NodeTypeSymbol);
|
||||||
|
@ -3727,8 +3743,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
|
||||||
return irb->codegen->invalid_instruction;
|
return irb->codegen->invalid_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO put a variable of same name with invalid type in global scope
|
// put a variable of same name with invalid type in global scope
|
||||||
// so that future references to this same name will find a variable with an invalid type
|
// so that future references to this same name will find a variable with an invalid type
|
||||||
|
populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name);
|
||||||
add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
|
add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
|
||||||
return irb->codegen->invalid_instruction;
|
return irb->codegen->invalid_instruction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
const tests = @import("tests.zig");
|
const tests = @import("tests.zig");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.addCase(x: {
|
||||||
|
var tc = cases.create(
|
||||||
|
"deduplicate undeclared identifier",
|
||||||
|
\\export fn a() void {
|
||||||
|
\\ x += 1;
|
||||||
|
\\}
|
||||||
|
\\export fn b() void {
|
||||||
|
\\ x += 1;
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
".tmp_source.zig:2:5: error: use of undeclared identifier 'x'",
|
||||||
|
);
|
||||||
|
tc.expect_exact = true;
|
||||||
|
break :x tc;
|
||||||
|
});
|
||||||
|
|
||||||
cases.addTest(
|
cases.addTest(
|
||||||
"export generic function",
|
"export generic function",
|
||||||
\\export fn foo(num: var) i32 {
|
\\export fn foo(num: var) i32 {
|
||||||
|
@ -2280,7 +2296,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
|
".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
|
||||||
".tmp_source.zig:2:12: error: use of undeclared identifier 'i'",
|
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
|
@ -5618,8 +5633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid",
|
".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid",
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add("compileLog of tagged enum doesn't crash the compiler",
|
||||||
"compileLog of tagged enum doesn't crash the compiler",
|
|
||||||
\\const Bar = union(enum(u32)) {
|
\\const Bar = union(enum(u32)) {
|
||||||
\\ X: i32 = 1
|
\\ X: i32 = 1
|
||||||
\\};
|
\\};
|
||||||
|
@ -5631,7 +5645,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
\\pub fn main () void {
|
\\pub fn main () void {
|
||||||
\\ comptime testCompileLog(Bar{.X = 123});
|
\\ comptime testCompileLog(Bar{.X = 123});
|
||||||
\\}
|
\\}
|
||||||
,
|
, ".tmp_source.zig:6:5: error: found compile log statement");
|
||||||
".tmp_source.zig:6:5: error: found compile log statement"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -716,7 +716,8 @@ pub const CompileErrorContext = struct {
|
||||||
for (self.case.expected_errors.toSliceConst()) |expected| {
|
for (self.case.expected_errors.toSliceConst()) |expected| {
|
||||||
if (mem.indexOf(u8, stderr, expected) == null) {
|
if (mem.indexOf(u8, stderr, expected) == null) {
|
||||||
warn(
|
warn(
|
||||||
\\\n=========== Expected compile error: ============
|
\\
|
||||||
|
\\=========== Expected compile error: ============
|
||||||
\\{}
|
\\{}
|
||||||
\\
|
\\
|
||||||
, expected);
|
, expected);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user