parent
1691074b4b
commit
2e512a0e6e
@ -201,6 +201,12 @@ enum RuntimeHintMaybe {
|
|||||||
RuntimeHintMaybeNonNull,
|
RuntimeHintMaybeNonNull,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RuntimeHintPtr {
|
||||||
|
RuntimeHintPtrUnknown,
|
||||||
|
RuntimeHintPtrStack,
|
||||||
|
RuntimeHintPtrNonStack,
|
||||||
|
};
|
||||||
|
|
||||||
struct ConstFn {
|
struct ConstFn {
|
||||||
FnTableEntry *fn_entry;
|
FnTableEntry *fn_entry;
|
||||||
bool is_inline;
|
bool is_inline;
|
||||||
@ -233,6 +239,7 @@ struct ConstExprValue {
|
|||||||
// populated if special == ConstValSpecialRuntime
|
// populated if special == ConstValSpecialRuntime
|
||||||
RuntimeHintErrorUnion rh_error_union;
|
RuntimeHintErrorUnion rh_error_union;
|
||||||
RuntimeHintMaybe rh_maybe;
|
RuntimeHintMaybe rh_maybe;
|
||||||
|
RuntimeHintPtr rh_ptr;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
11
src/ir.cpp
11
src/ir.cpp
@ -7538,6 +7538,13 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,
|
|||||||
if (casted_value == ira->codegen->invalid_instruction)
|
if (casted_value == ira->codegen->invalid_instruction)
|
||||||
return ir_unreach_error(ira);
|
return ir_unreach_error(ira);
|
||||||
|
|
||||||
|
if (casted_value->value.special == ConstValSpecialRuntime &&
|
||||||
|
casted_value->value.type->id == TypeTableEntryIdPointer &&
|
||||||
|
casted_value->value.data.rh_ptr == RuntimeHintPtrStack)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable"));
|
||||||
|
return ir_unreach_error(ira);
|
||||||
|
}
|
||||||
ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value);
|
ir_build_return_from(&ira->new_irb, &return_instruction->base, casted_value);
|
||||||
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
|
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
|
||||||
}
|
}
|
||||||
@ -8467,6 +8474,10 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
|
|||||||
instruction->scope, instruction->source_node, var, is_const, is_volatile);
|
instruction->scope, instruction->source_node, var, is_const, is_volatile);
|
||||||
var_ptr_instruction->value.type = get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
|
var_ptr_instruction->value.type = get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
|
||||||
type_ensure_zero_bits_known(ira->codegen, var->value->type);
|
type_ensure_zero_bits_known(ira->codegen, var->value->type);
|
||||||
|
|
||||||
|
bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
|
||||||
|
var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack;
|
||||||
|
|
||||||
return var_ptr_instruction;
|
return var_ptr_instruction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,7 +887,7 @@ pub const LibExeObjStep = struct {
|
|||||||
%%zig_args.append(lib_path);
|
%%zig_args.append(lib_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
%%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst());
|
%return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst());
|
||||||
|
|
||||||
if (self.kind == Kind.Lib and !self.static) {
|
if (self.kind == Kind.Lib and !self.static) {
|
||||||
// sym link for libfoo.so.1 to libfoo.so.1.2.3
|
// sym link for libfoo.so.1 to libfoo.so.1.2.3
|
||||||
@ -994,7 +994,7 @@ pub const TestStep = struct {
|
|||||||
%%zig_args.append(lib_path);
|
%%zig_args.append(lib_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
%%builder.spawnChild(builder.zig_exe, zig_args.toSliceConst());
|
%return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1610,4 +1610,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
|
|||||||
,
|
,
|
||||||
".tmp_source.zig:3:5: error: cannot set section of external function 'foo'",
|
".tmp_source.zig:3:5: error: cannot set section of external function 'foo'",
|
||||||
".tmp_source.zig:1:8: note: declared here");
|
".tmp_source.zig:1:8: note: declared here");
|
||||||
|
|
||||||
|
cases.add("returning address of local variable",
|
||||||
|
\\export fn foo() -> &i32 {
|
||||||
|
\\ var a: i32 = undefined;
|
||||||
|
\\ return &a;
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
".tmp_source.zig:3:13: error: function returns address of local variable");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user