authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-24 14:06:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-24 14:06:44-07:00
log995fd7314cd230ca7c829bb478f88b1ab7efd7b4
tree44566c0e999e8977a69d69f06fbfea8e4cc3ffd6
parent978a38ee40e13c3eed625f2df7b36be49fd049e0

Revert "Support taking extern pointers at comptime"

This reverts commit d3ebd428650748e60db70dd2171cc044855814b1. This caused a build failure on multiple targets.

8 files changed, 47 insertions(+), 284 deletions(-)

src/codegen.cpp+20-50
...@@ -7754,13 +7754,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n...@@ -7754,13 +7754,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
7754}7754}
77557755
7756static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name) {7756static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name) {
7757 if (const_val->special == ConstValSpecialRuntime) {
7758 // `const_val` refers to an extern variable. Don't generate an `LLVMValueRef` for
7759 // the variable. We shouldn't call `LLVMSetInitializer` on it either.
7760 assert(const_val->llvm_global);
7761 return;
7762 }
7763
7764 if (!const_val->llvm_value)7757 if (!const_val->llvm_value)
7765 const_val->llvm_value = gen_const_val(g, const_val, name);7758 const_val->llvm_value = gen_const_val(g, const_val, name);
77667759
...@@ -7769,13 +7762,6 @@ static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name)...@@ -7769,13 +7762,6 @@ static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name)
7769}7762}
77707763
7771static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name) {7764static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name) {
7772 if (const_val->special == ConstValSpecialRuntime) {
7773 // `const_val` refers to an extern variable. `llvm_global` should already
7774 // have been created by an earlier codegen pass.
7775 assert(const_val->llvm_global);
7776 return;
7777 }
7778
7779 if (!const_val->llvm_global) {7765 if (!const_val->llvm_global) {
7780 LLVMTypeRef type_ref = const_val->llvm_value ?7766 LLVMTypeRef type_ref = const_val->llvm_value ?
7781 LLVMTypeOf(const_val->llvm_value) : get_llvm_type(g, const_val->type);7767 LLVMTypeOf(const_val->llvm_value) : get_llvm_type(g, const_val->type);
...@@ -7905,39 +7891,6 @@ static void do_code_gen(CodeGen *g) {...@@ -7905,39 +7891,6 @@ static void do_code_gen(CodeGen *g) {
79057891
7906 generate_error_name_table(g);7892 generate_error_name_table(g);
79077893
7908 // Create extern variables
7909 for (size_t i = 0; i < g->global_vars.length; i += 1) {
7910 TldVar *tld_var = g->global_vars.at(i);
7911 ZigVar *var = tld_var->var;
7912
7913 bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr;
7914 if (!externally_initialized) {
7915 continue;
7916 }
7917
7918 assert(var->decl_node->data.variable_declaration.is_extern);
7919 const char *symbol_name = var->name;
7920
7921 LLVMValueRef global_value;
7922 LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, symbol_name);
7923 if (existing_llvm_var) {
7924 global_value = LLVMConstBitCast(existing_llvm_var,
7925 LLVMPointerType(get_llvm_type(g, var->var_type), 0));
7926 } else {
7927 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name);
7928 // TODO debug info for the extern variable
7929
7930 LLVMSetLinkage(global_value, LLVMExternalLinkage);
7931 maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
7932 LLVMSetAlignment(global_value, var->align_bytes);
7933 LLVMSetGlobalConstant(global_value, var->gen_is_const);
7934 set_global_tls(g, var, global_value);
7935 }
7936
7937 var->value_ref = global_value;
7938 var->const_value->llvm_global = global_value;
7939 }
7940
7941 // Generate module level variables7894 // Generate module level variables
7942 for (size_t i = 0; i < g->global_vars.length; i += 1) {7895 for (size_t i = 0; i < g->global_vars.length; i += 1) {
7943 TldVar *tld_var = g->global_vars.at(i);7896 TldVar *tld_var = g->global_vars.at(i);
...@@ -8003,12 +7956,28 @@ static void do_code_gen(CodeGen *g) {...@@ -8003,12 +7956,28 @@ static void do_code_gen(CodeGen *g) {
8003 linkage = global_export->linkage;7956 linkage = global_export->linkage;
8004 }7957 }
80057958
7959 LLVMValueRef global_value;
8006 bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr;7960 bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr;
8007 if (!externally_initialized) {7961 if (externally_initialized) {
7962 LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, symbol_name);
7963 if (existing_llvm_var) {
7964 global_value = LLVMConstBitCast(existing_llvm_var,
7965 LLVMPointerType(get_llvm_type(g, var->var_type), 0));
7966 } else {
7967 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name);
7968 // TODO debug info for the extern variable
7969
7970 LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
7971 maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
7972 LLVMSetAlignment(global_value, var->align_bytes);
7973 LLVMSetGlobalConstant(global_value, var->gen_is_const);
7974 set_global_tls(g, var, global_value);
7975 }
7976 } else {
8008 bool exported = (linkage != GlobalLinkageIdInternal);7977 bool exported = (linkage != GlobalLinkageIdInternal);
8009 render_const_val(g, var->const_value, symbol_name);7978 render_const_val(g, var->const_value, symbol_name);
8010 render_const_val_global(g, var->const_value, symbol_name);7979 render_const_val_global(g, var->const_value, symbol_name);
8011 LLVMValueRef global_value = var->const_value->llvm_global;7980 global_value = var->const_value->llvm_global;
80127981
8013 if (exported) {7982 if (exported) {
8014 LLVMSetLinkage(global_value, to_llvm_linkage(linkage));7983 LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
...@@ -8028,9 +7997,10 @@ static void do_code_gen(CodeGen *g) {...@@ -8028,9 +7997,10 @@ static void do_code_gen(CodeGen *g) {
80287997
8029 LLVMSetGlobalConstant(global_value, var->gen_is_const);7998 LLVMSetGlobalConstant(global_value, var->gen_is_const);
8030 set_global_tls(g, var, global_value);7999 set_global_tls(g, var, global_value);
8031 var->value_ref = global_value;
8032 }8000 }
80338001
8002 var->value_ref = global_value;
8003
8034 for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) {8004 for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) {
8035 GlobalExport *global_export = &var->export_list.items[export_i];8005 GlobalExport *global_export = &var->export_list.items[export_i];
8036 LLVMAddAlias(g->module, LLVMTypeOf(var->value_ref), var->value_ref, buf_ptr(&global_export->name));8006 LLVMAddAlias(g->module, LLVMTypeOf(var->value_ref), var->value_ref, buf_ptr(&global_export->name));
src/ir.cpp+27-34
...@@ -19894,34 +19894,30 @@ static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *v...@@ -19894,34 +19894,30 @@ static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *v
19894 IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var);19894 IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var);
19895 result->value->type = var_ptr_type;19895 result->value->type = var_ptr_type;
1989619896
19897 bool is_local_var = !var->decl_node->data.variable_declaration.is_extern &&19897 if (!linkage_makes_it_runtime && !var->is_thread_local && value_is_comptime(var->const_value)) {
19898 var->const_value->special == ConstValSpecialRuntime;
19899
19900 // The address of a thread-local variable can't be resolved even by a linker because
19901 // it's dependent on the current thread. The concept of current thread doesn't exist
19902 // at compile time, so even if we had a symbolic (i.e., relocatable) representation
19903 // of a pointer to a thread-local variable, there would be no ways to make use of it
19904 // in a meaningful way.
19905 //
19906 // The same goes for local variables - They are stored in a stack frame, whose
19907 // instance doesn't even exist at compile/link time.
19908 if (!var->is_thread_local && !is_local_var) {
19909 ZigValue *val = var->const_value;19898 ZigValue *val = var->const_value;
1991019899 switch (val->special) {
19911 ConstPtrMut ptr_mut;19900 case ConstValSpecialRuntime:
19912 if (comptime_var_mem) {19901 break;
19913 ptr_mut = ConstPtrMutComptimeVar;19902 case ConstValSpecialStatic: // fallthrough
19914 } else if (var->gen_is_const && !linkage_makes_it_runtime) {19903 case ConstValSpecialLazy: // fallthrough
19915 ptr_mut = ConstPtrMutComptimeConst;19904 case ConstValSpecialUndef: {
19916 } else {19905 ConstPtrMut ptr_mut;
19917 assert(!comptime_var_mem);19906 if (comptime_var_mem) {
19918 ptr_mut = ConstPtrMutRuntimeVar;19907 ptr_mut = ConstPtrMutComptimeVar;
19908 } else if (var->gen_is_const) {
19909 ptr_mut = ConstPtrMutComptimeConst;
19910 } else {
19911 assert(!comptime_var_mem);
19912 ptr_mut = ConstPtrMutRuntimeVar;
19913 }
19914 result->value->special = ConstValSpecialStatic;
19915 result->value->data.x_ptr.mut = ptr_mut;
19916 result->value->data.x_ptr.special = ConstPtrSpecialRef;
19917 result->value->data.x_ptr.data.ref.pointee = val;
19918 return result;
19919 }
19919 }19920 }
19920 result->value->special = ConstValSpecialStatic;
19921 result->value->data.x_ptr.mut = ptr_mut;
19922 result->value->data.x_ptr.special = ConstPtrSpecialRef;
19923 result->value->data.x_ptr.data.ref.pointee = val;
19924 return result;
19925 }19921 }
1992619922
19927 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);19923 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
...@@ -22292,15 +22288,12 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins...@@ -22292,15 +22288,12 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
22292 if (type_is_invalid(struct_val->type))22288 if (type_is_invalid(struct_val->type))
22293 return ira->codegen->invalid_inst_gen;22289 return ira->codegen->invalid_inst_gen;
2229422290
22295 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {22291 // This to allow lazy values to be resolved.
22296 // This to allow lazy values to be resolved.22292 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
22297 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,22293 source_instr->source_node, struct_val, UndefOk)))
22298 source_instr->source_node, struct_val, UndefOk)))22294 {
22299 {22295 return ira->codegen->invalid_inst_gen;
22300 return ira->codegen->invalid_inst_gen;
22301 }
22302 }22296 }
22303
22304 if (initializing && struct_val->special == ConstValSpecialUndef) {22297 if (initializing && struct_val->special == ConstValSpecialUndef) {
22305 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);22298 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
22306 struct_val->special = ConstValSpecialStatic;22299 struct_val->special = ConstValSpecialStatic;
test/compile_errors.zig-22
...@@ -7637,26 +7637,4 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7637,26 +7637,4 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7637 , &[_][]const u8{7637 , &[_][]const u8{
7638 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'",7638 "tmp.zig:4:9: error: expected type '*c_void', found '?*c_void'",
7639 });7639 });
7640
7641 cases.add("pointer to a local runtime `var` is not constant",
7642 \\export fn get_ptr() *const u32 {
7643 \\ var local_var: u32 = 42;
7644 \\ return struct {
7645 \\ const ptr = &local_var;
7646 \\ }.ptr;
7647 \\}
7648 , &[_][]const u8{
7649 ":4:21: error: cannot store runtime value in compile time variable",
7650 });
7651
7652 cases.add("pointer to a local runtime `const` is not constant",
7653 \\export fn get_ptr(x: u32) *const u32 {
7654 \\ const local_var: u32 = x;
7655 \\ return struct {
7656 \\ const ptr = &local_var;
7657 \\ }.ptr;
7658 \\}
7659 , &[_][]const u8{
7660 ":4:21: error: cannot store runtime value in compile time variable",
7661 });
7662}7640}
test/standalone.zig-1
...@@ -19,7 +19,6 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -19,7 +19,6 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
19 cases.addBuildFile("test/standalone/use_alias/build.zig");19 cases.addBuildFile("test/standalone/use_alias/build.zig");
20 cases.addBuildFile("test/standalone/brace_expansion/build.zig");20 cases.addBuildFile("test/standalone/brace_expansion/build.zig");
21 cases.addBuildFile("test/standalone/empty_env/build.zig");21 cases.addBuildFile("test/standalone/empty_env/build.zig");
22 cases.addBuildFile("test/standalone/extern_ref/build.zig");
23 if (std.Target.current.os.tag != .wasi) {22 if (std.Target.current.os.tag != .wasi) {
24 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");23 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
25 }24 }
test/standalone/extern_ref/build.zig deleted-15
...@@ -1,15 +0,0 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const mode = b.standardReleaseOptions();
5
6 const obj = b.addStaticLibrary("obj", "obj.zig");
7 obj.setBuildMode(mode);
8
9 const main = b.addTest("main.zig");
10 main.setBuildMode(mode);
11 main.linkLibrary(obj);
12
13 const test_step = b.step("test", "Test it");
14 test_step.dependOn(&main.step);
15}
test/standalone/extern_ref/main.zig deleted-120
...@@ -1,120 +0,0 @@
1const std = @import("std");
2const eql = std.mem.eql;
3
4// These are defined in `obj.zig`
5extern var global_var: usize;
6extern const global_const: usize;
7
8const TheStruct = @import("./types.zig").TheStruct;
9extern var global_var_struct: TheStruct;
10extern const global_const_struct: TheStruct;
11
12const TheUnion = @import("./types.zig").TheUnion;
13extern var global_var_union: TheUnion;
14extern const global_const_union: TheUnion;
15
16extern var global_var_array: [4]u32;
17extern const global_const_array: [4]u32;
18
19// Take the pointers to external entities as constant values
20const p_global_var = &global_var;
21const p_global_const = &global_const;
22
23test "access the external integers" {
24 std.testing.expect(p_global_var.* == 2);
25 std.testing.expect(p_global_const.* == 422);
26}
27
28const p_global_var_struct = &global_var_struct;
29const p_global_const_struct = &global_const_struct;
30
31const p_global_var_struct_val = &global_var_struct.value;
32const p_global_const_struct_val = &global_const_struct.value;
33
34const p_global_var_struct_array = &global_var_struct.array;
35const p_global_const_struct_array = &global_const_struct.array;
36
37const p_global_var_struct_array2 = global_var_struct.array[1..3];
38const p_global_const_struct_array2 = global_const_struct.array[1..3];
39
40const p_global_var_struct_array3 = &global_var_struct.array[1];
41const p_global_const_struct_array3 = &global_const_struct.array[1];
42
43test "access the external integers in a struct through comptime ptrs" {
44 std.testing.expect(p_global_var_struct.value == 2);
45 std.testing.expect(p_global_const_struct.value == 422);
46
47 std.testing.expect(p_global_var_struct_val.* == 2);
48 std.testing.expect(p_global_const_struct_val.* == 422);
49}
50
51test "access the external arrays in a struct through comptime ptrs" {
52 // TODO
53 // std.testing.expect(eql(u32, &p_global_var_struct.array, &[_]u32{1, 2, 3, 4}));
54 // std.testing.expect(eql(u32, &p_global_const_struct.array, &[_]u32{5, 6, 7, 8}));
55
56 // TODO
57 // std.testing.expect(eql(u32, p_global_var_struct_array, &[_]u32{1, 2, 3, 4}));
58 // std.testing.expect(eql(u32, p_global_const_struct_array, &[_]u32{5, 6, 7, 8}));
59
60 // TODO
61 // std.testing.expect(eql(u32, p_global_var_struct_array2, &[_]u32{2, 3}));
62 // std.testing.expect(eql(u32, p_global_const_struct_array2, &[_]u32{6, 7}));
63
64 // TODO
65 // std.testing.expect(p_global_var_struct_array3.* == 2);
66 // std.testing.expect(p_global_const_struct_array3.* == 6);
67}
68
69test "access the external integers with indirection through comptime ptrs" {
70 std.testing.expect(p_global_var_struct.p_value.* == 3);
71 std.testing.expect(p_global_const_struct.p_value.* == 423);
72}
73
74const p_global_var_struct_inner_val = &global_var_struct.inner.value;
75const p_global_const_struct_inner_val = &global_const_struct.inner.value;
76
77test "access the external integers in a nested struct through comptime ptrs" {
78 // TODO
79 // std.testing.expect(p_global_var_struct_inner_val.* == 4);
80 // std.testing.expect(p_global_const_struct_inner_val.* == 424);
81}
82
83const p_global_var_union = &global_var_union;
84const p_global_const_union = &global_const_union;
85
86const p_global_var_union_val = &global_var_union.U32;
87const p_global_const_union_val = &global_const_union.U32;
88
89test "access the external integers in a union through comptime ptrs" {
90 std.testing.expect(p_global_var_union.U32 == 10);
91 std.testing.expect(p_global_const_union.U32 == 20);
92
93 // TODO
94 // std.testing.expect(p_global_var_union_val.* == 10);
95 // std.testing.expect(p_global_const_union_val.* == 20);
96}
97
98const p_global_var_array = &global_var_array;
99const p_global_const_array = &global_const_array;
100
101const p_global_var_array2 = global_var_array[1..3];
102const p_global_const_array2 = global_const_array[1..3];
103
104const p_global_var_array3 = &global_var_array[1];
105const p_global_const_array3 = &global_const_array[1];
106
107test "access the external arrays through comptime ptrs" {
108 std.testing.expect(eql(u32, &global_var_array, &[_]u32{1, 2, 3, 4}));
109 std.testing.expect(eql(u32, &global_const_array, &[_]u32{5, 6, 7, 8}));
110
111 std.testing.expect(eql(u32, p_global_var_array, &[_]u32{1, 2, 3, 4}));
112 std.testing.expect(eql(u32, p_global_const_array, &[_]u32{5, 6, 7, 8}));
113
114 std.testing.expect(eql(u32, p_global_var_array2, &[_]u32{2, 3}));
115 std.testing.expect(eql(u32, p_global_const_array2, &[_]u32{6, 7}));
116
117 // TODO
118 // std.testing.expect(p_global_var_array3.* == 2);
119 // std.testing.expect(p_global_const_array3.* == 6);
120}
test/standalone/extern_ref/obj.zig deleted-27
...@@ -1,27 +0,0 @@
1export var global_var: usize = 2;
2export const global_const: usize = 422;
3
4const TheStruct = @import("./types.zig").TheStruct;
5export var global_var_struct = TheStruct{
6 .value = 2,
7 .array = [_]u32{ 1, 2, 3, 4 },
8 .p_value = &@as(u32, 3),
9 .inner = .{ .value = 4 },
10};
11export const global_const_struct = TheStruct{
12 .value = 422,
13 .array = [_]u32{ 5, 6, 7, 8 },
14 .p_value = &@as(u32, 423),
15 .inner = .{ .value = 424 },
16};
17
18const TheUnion = @import("./types.zig").TheUnion;
19export var global_var_union = TheUnion{
20 .U32 = 10,
21};
22export const global_const_union = TheUnion{
23 .U32 = 20,
24};
25
26export var global_var_array = [4]u32{ 1, 2, 3, 4 };
27export const global_const_array = [4]u32{ 5, 6, 7, 8 };
test/standalone/extern_ref/types.zig deleted-15
...@@ -1,15 +0,0 @@
1pub const TheStruct = extern struct {
2 value: u32,
3 array: [4]u32,
4 p_value: *const u32,
5 inner: InnerStruct,
6};
7
8pub const InnerStruct = extern struct {
9 value: u32,
10};
11
12pub const TheUnion = extern union {
13 U32: u32,
14 Bool: bool,
15};