Commit 596ca6cf70

Vexu <git@vexu.eu>
2020-07-17 19:16:23
allow non-pointer extern opaque variables
1 parent 78962ee
Changed files (4)
src
test
stage1
behavior
src/analyze.cpp
@@ -3823,15 +3823,18 @@ static Error resolve_decl_container(CodeGen *g, TldContainer *tld_container) {
     }
 }
 
-ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry) {
+ZigType *validate_var_type(CodeGen *g, AstNodeVariableDeclaration *source_node, ZigType *type_entry) {
     switch (type_entry->id) {
         case ZigTypeIdInvalid:
             return g->builtin_types.entry_invalid;
+        case ZigTypeIdOpaque:
+            if (source_node->is_extern)
+                return type_entry;
+            ZIG_FALLTHROUGH;
         case ZigTypeIdUnreachable:
         case ZigTypeIdUndefined:
         case ZigTypeIdNull:
-        case ZigTypeIdOpaque:
-            add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
+            add_node_error(g, source_node->type, buf_sprintf("variable of type '%s' not allowed",
                 buf_ptr(&type_entry->name)));
             return g->builtin_types.entry_invalid;
         case ZigTypeIdComptimeFloat:
@@ -3973,7 +3976,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
         } else {
             tld_var->analyzing_type = true;
             ZigType *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type);
-            explicit_type = validate_var_type(g, var_decl->type, proposed_type);
+            explicit_type = validate_var_type(g, var_decl, proposed_type);
         }
     }
 
src/analyze.hpp
@@ -77,7 +77,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool all
 ZigType *get_src_ptr_type(ZigType *type);
 uint32_t get_ptr_align(CodeGen *g, ZigType *type);
 bool get_ptr_const(CodeGen *g, ZigType *type);
-ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry);
+ZigType *validate_var_type(CodeGen *g, AstNodeVariableDeclaration *source_node, ZigType *type_entry);
 ZigType *container_ref_type(ZigType *type_entry);
 bool type_is_complete(ZigType *type_entry);
 bool type_is_resolved(ZigType *type_entry, ResolveStatus status);
src/ir.cpp
@@ -18505,7 +18505,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
     if (decl_var_instruction->var_type != nullptr) {
         var_type = decl_var_instruction->var_type->child;
         ZigType *proposed_type = ir_resolve_type(ira, var_type);
-        explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type);
+        explicit_type = validate_var_type(ira->codegen, &var->decl_node->data.variable_declaration, proposed_type);
         if (type_is_invalid(explicit_type)) {
             var->var_type = ira->codegen->builtin_types.entry_invalid;
             return ira->codegen->invalid_inst_gen;
test/stage1/behavior/misc.zig
@@ -713,3 +713,10 @@ test "auto created variables have correct alignment" {
     expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
     comptime expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a);
 }
+
+extern var opaque_extern_var: @Type(.Opaque);
+var var_to_export: u32 = 42;
+test "extern variable with non-pointer opaque type" {
+    @export(var_to_export, .{ .name = "opaque_extern_var" });
+    expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42);
+}