| author | |
| committer | |
| log | 0e47bd16dac9dcdfc12168c07104030af8eaaa8b |
| tree | f0187c40b264ad1a85d9f050a43074c3e38ef23b |
| parent | 4d1b15bd9d4175127a63595f4fd80761c2e6564c |
This clarifies that it is legal to return an invalid pointer from a
function, provided that such pointer is not dereferenced.
This matches current status quo of the language. Any change to this
should be a proposal that argues for different semantics.
It is also legal in C to return a pointer to a local. The C backend
lowers such thing directly, so the corresponding warning in C must be
disabled (`-Wno-return-stack-address`).2 files changed, 32 insertions(+), 0 deletions(-)
test/behavior/fn.zig+27| ... | @@ -742,3 +742,30 @@ test "coerce generic function making generic parameter concrete" { | ... | @@ -742,3 +742,30 @@ test "coerce generic function making generic parameter concrete" { |
| 742 | const result = coerced({}, 123); | 742 | const result = coerced({}, 123); |
| 743 | try expect(result == 123); | 743 | try expect(result == 123); |
| 744 | } | 744 | } |
| 745 | |||
| 746 | test "return undefined pointer from function, directly and by expired local" { | ||
| 747 | const S = struct { | ||
| 748 | var global: i32 = 1; | ||
| 749 | |||
| 750 | fn returnGlobalPointer() *i32 { | ||
| 751 | return &global; | ||
| 752 | } | ||
| 753 | |||
| 754 | fn returnUndefPointer() *i32 { | ||
| 755 | return undefined; | ||
| 756 | } | ||
| 757 | |||
| 758 | /// Semantically equivalent to `returnUndefPointer`. | ||
| 759 | fn returnStackPointer() *i32 { | ||
| 760 | var stack_allocation: i32 = 1234; | ||
| 761 | return &stack_allocation; | ||
| 762 | } | ||
| 763 | }; | ||
| 764 | |||
| 765 | const ok_ptr = S.returnGlobalPointer(); | ||
| 766 | try expect(ok_ptr.* == 1); | ||
| 767 | const bad_ptr_1 = S.returnStackPointer(); | ||
| 768 | _ = bad_ptr_1; // dereferencing this would be illegal behavior | ||
| 769 | const bad_ptr_2 = S.returnStackPointer(); | ||
| 770 | _ = bad_ptr_2; // dereferencing this would be illegal behavior | ||
| 771 | } |
test/tests.zig+5| ... | @@ -2385,6 +2385,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { | ... | @@ -2385,6 +2385,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2385 | 2385 | ||
| 2386 | // https://github.com/llvm/llvm-project/issues/153314 | 2386 | // https://github.com/llvm/llvm-project/issues/153314 |
| 2387 | "-Wno-unterminated-string-initialization", | 2387 | "-Wno-unterminated-string-initialization", |
| 2388 | |||
| 2389 | // In both Zig and C it is legal to return a pointer to a | ||
| 2390 | // local. The C backend lowers such thing directly, so the | ||
| 2391 | // corresponding warning in C must be disabled. | ||
| 2392 | "-Wno-return-stack-address", | ||
| 2388 | }, | 2393 | }, |
| 2389 | }); | 2394 | }); |
| 2390 | compile_c.addIncludePath(b.path("lib")); // for zig.h | 2395 | compile_c.addIncludePath(b.path("lib")); // for zig.h |