Commit 0db9e90e8f
Changed files (4)
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, ¶m_type_inst->base,
+ buf_sprintf("parameter of opaque type '%s' not allowed", buf_ptr(¶m_type->name)));
+ } else {
+ ir_add_error(ira, ¶m_type_inst->base,
+ buf_sprintf("parameter of type '%s' not allowed", buf_ptr(¶m_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 {