Commit 0db9e90e8f

xackus <14938807+xackus@users.noreply.github.com>
2020-05-03 05:11:00
stage1: fix assert fail on opaque fn ptr param
1 parent 9b788b7
src/analyze.cpp
@@ -1893,50 +1893,30 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
             }
         }
 
-        switch (type_entry->id) {
-            case ZigTypeIdInvalid:
-                zig_unreachable();
-            case ZigTypeIdUnreachable:
-            case ZigTypeIdUndefined:
-            case ZigTypeIdNull:
-            case ZigTypeIdOpaque:
+        if(!is_valid_param_type(type_entry)){
+            if(type_entry->id == ZigTypeIdOpaque){
+                add_node_error(g, param_node->data.param_decl.type,
+                    buf_sprintf("parameter of opaque type '%s' not allowed", buf_ptr(&type_entry->name)));
+            } else {
                 add_node_error(g, param_node->data.param_decl.type,
                     buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
-                return g->builtin_types.entry_invalid;
-            case ZigTypeIdComptimeFloat:
-            case ZigTypeIdComptimeInt:
-            case ZigTypeIdEnumLiteral:
-            case ZigTypeIdBoundFn:
-            case ZigTypeIdMetaType:
-            case ZigTypeIdVoid:
-            case ZigTypeIdBool:
-            case ZigTypeIdInt:
-            case ZigTypeIdFloat:
-            case ZigTypeIdPointer:
-            case ZigTypeIdArray:
-            case ZigTypeIdStruct:
-            case ZigTypeIdOptional:
-            case ZigTypeIdErrorUnion:
-            case ZigTypeIdErrorSet:
-            case ZigTypeIdEnum:
-            case ZigTypeIdUnion:
-            case ZigTypeIdFn:
-            case ZigTypeIdVector:
-            case ZigTypeIdFnFrame:
-            case ZigTypeIdAnyFrame:
-                switch (type_requires_comptime(g, type_entry)) {
-                    case ReqCompTimeNo:
-                        break;
-                    case ReqCompTimeYes:
-                        add_node_error(g, param_node->data.param_decl.type,
-                            buf_sprintf("parameter of type '%s' must be declared comptime",
-                            buf_ptr(&type_entry->name)));
-                        return g->builtin_types.entry_invalid;
-                    case ReqCompTimeInvalid:
-                        return g->builtin_types.entry_invalid;
-                }
+            }
+
+            return g->builtin_types.entry_invalid;
+        }
+
+        switch (type_requires_comptime(g, type_entry)) {
+            case ReqCompTimeNo:
                 break;
+            case ReqCompTimeYes:
+                add_node_error(g, param_node->data.param_decl.type,
+                    buf_sprintf("parameter of type '%s' must be declared comptime",
+                    buf_ptr(&type_entry->name)));
+                return g->builtin_types.entry_invalid;
+            case ReqCompTimeInvalid:
+                return g->builtin_types.entry_invalid;
         }
+
         FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
         param_info->type = type_entry;
         param_info->is_noalias = param_node->data.param_decl.is_noalias;
@@ -2059,6 +2039,20 @@ bool is_valid_return_type(ZigType* type) {
     zig_unreachable();
 }
 
+bool is_valid_param_type(ZigType* type) {
+    switch (type->id) {
+        case ZigTypeIdInvalid:
+        case ZigTypeIdUndefined:
+        case ZigTypeIdNull:
+        case ZigTypeIdOpaque:
+        case ZigTypeIdUnreachable:
+            return false;
+        default:
+            return true;
+    }
+    zig_unreachable();
+}
+
 bool type_is_invalid(ZigType *type_entry) {
     switch (type_entry->id) {
         case ZigTypeIdInvalid:
src/analyze.hpp
@@ -269,6 +269,7 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
 bool fn_is_async(ZigFn *fn);
 CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
 bool is_valid_return_type(ZigType* type);
+bool is_valid_param_type(ZigType* type);
 
 Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
 Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
src/ir.cpp
@@ -31082,6 +31082,19 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
             ZigType *param_type = ir_resolve_type(ira, param_type_inst);
             if (type_is_invalid(param_type))
                 return nullptr;
+
+            if(!is_valid_param_type(param_type)){
+                if(param_type->id == ZigTypeIdOpaque){
+                    ir_add_error(ira, &param_type_inst->base,
+                        buf_sprintf("parameter of opaque type '%s' not allowed", buf_ptr(&param_type->name)));
+                } else {
+                    ir_add_error(ira, &param_type_inst->base,
+                        buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&param_type->name)));
+                }
+
+                return nullptr;
+            }
+
             switch (type_requires_comptime(ira->codegen, param_type)) {
             case ReqCompTimeYes:
                 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
test/compile_errors.zig
@@ -6979,6 +6979,32 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:2:1: note: function declared here",
     });
 
+    cases.add("function parameter is opaque",
+        \\const FooType = @OpaqueType();
+        \\export fn entry1() void {
+        \\    const someFuncPtr: fn (FooType) void = undefined;
+        \\}
+        \\
+        \\export fn entry2() void {
+        \\    const someFuncPtr: fn (@TypeOf(null)) void = undefined;
+        \\}
+        \\
+        \\fn foo(p: FooType) void {}
+        \\export fn entry3() void {
+        \\    _ = foo;
+        \\}
+        \\
+        \\fn bar(p: @TypeOf(null)) void {}
+        \\export fn entry4() void {
+        \\    _ = bar;
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed",
+        "tmp.zig:7:28: error: parameter of type '(null)' not allowed",
+        "tmp.zig:10:11: error: parameter of opaque type 'FooType' not allowed",
+        "tmp.zig:15:11: error: parameter of type '(null)' not allowed",
+    });
+
     cases.add( // fixed bug #2032
         "compile diagnostic string for top level decl type",
         \\export fn entry() void {