Commit c7615c1a80

Andrew Kelley <superjoe30@gmail.com>
2015-12-04 22:33:57
error for extern function with void parameter
1 parent 139e5ca
src/analyze.cpp
@@ -115,7 +115,16 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
     for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
         AstNode *child = node->data.fn_proto.params.at(i);
         assert(child->type == NodeTypeParamDecl);
-        resolve_type(g, child->data.param_decl.type);
+        TypeTableEntry *type_entry = resolve_type(g, child->data.param_decl.type);
+        if (type_entry == g->builtin_types.entry_unreachable) {
+            add_node_error(g, child->data.param_decl.type,
+                buf_sprintf("parameter of type 'unreachable' not allowed"));
+        } else if (type_entry == g->builtin_types.entry_void) {
+            if (node->data.fn_proto.visib_mod == FnProtoVisibModExport) {
+                add_node_error(g, child->data.param_decl.type,
+                    buf_sprintf("parameter of type 'void' not allowed on exported functions"));
+            }
+        }
     }
 
     resolve_type(g, node->data.fn_proto.return_type);
@@ -423,18 +432,18 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
                     resolve_type(g, variable_declaration->type) : nullptr;
                 if (explicit_type == g->builtin_types.entry_unreachable) {
                     add_node_error(g, variable_declaration->type,
-                        buf_sprintf("variable of type 'unreachable' is not allowed."));
+                        buf_sprintf("variable of type 'unreachable' not allowed"));
                 }
 
                 TypeTableEntry *implicit_type = variable_declaration->expr != nullptr ?
                     analyze_expression(g, import, context, explicit_type, variable_declaration->expr) : nullptr;
                 if (implicit_type == g->builtin_types.entry_unreachable) {
                     add_node_error(g, node,
-                        buf_sprintf("variable initialization is unreachable."));
+                        buf_sprintf("variable initialization is unreachable"));
                 }
 
                 if (implicit_type == nullptr) {
-                    add_node_error(g, node, buf_sprintf("initial values are required for variable declaration."));
+                    add_node_error(g, node, buf_sprintf("initial values are required for variable declaration"));
                 }
 
                 TypeTableEntry *type = explicit_type != nullptr ? explicit_type : implicit_type;
@@ -443,7 +452,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
                 LocalVariableTableEntry *existing_variable = find_local_variable(context, &variable_declaration->symbol);
                 if (existing_variable) {
                     add_node_error(g, node,
-                        buf_sprintf("redeclaration of variable '%s'.", buf_ptr(&variable_declaration->symbol)));
+                        buf_sprintf("redeclaration of variable '%s'", buf_ptr(&variable_declaration->symbol)));
                 } else {
                     LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1);
                     buf_init_from_buf(&variable_entry->name, &variable_declaration->symbol);
@@ -723,11 +732,6 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
                     assert(param_decl->type->type == NodeTypeType);
                     TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry;
 
-                    if (type == g->builtin_types.entry_unreachable) {
-                        add_node_error(g, param_decl->type,
-                            buf_sprintf("parameter of type 'unreachable' is not allowed."));
-                    }
-
                     LocalVariableTableEntry *variable_entry = allocate<LocalVariableTableEntry>(1);
                     buf_init_from_buf(&variable_entry->name, &param_decl->name);
                     variable_entry->type = type;
src/errmsg.cpp
@@ -19,7 +19,9 @@ void print_err_msg(ErrorMsg *err, ErrColor color) {
         assert(err->line_offsets);
 
         int line_start_offset = err->line_offsets->at(err->line_start);
-        int line_end_offset = err->line_offsets->at(err->line_start + 1);
+        int end_line = err->line_start + 1;
+        int line_end_offset = (end_line >= err->line_offsets->length) ?
+            buf_len(err->source) : err->line_offsets->at(err->line_start + 1);
 
         fwrite(buf_ptr(err->source) + line_start_offset, 1, line_end_offset - line_start_offset - 1, stderr);
         fprintf(stderr, "\n");
test/run_tests.cpp
@@ -418,20 +418,20 @@ fn b() {}
     add_compile_fail_case("parameter redeclaration", R"SOURCE(
 fn f(a : i32, a : i32) {
 }
-    )SOURCE", 1, ".tmp_source.zig:2:1: error: redeclaration of parameter 'a'.");
+    )SOURCE", 1, ".tmp_source.zig:2:1: error: redeclaration of parameter 'a'");
 
     add_compile_fail_case("local variable redeclaration", R"SOURCE(
 fn f() {
     let a : i32 = 0;
     let a = 0;
 }
-    )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'.");
+    )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");
 
     add_compile_fail_case("local variable redeclares parameter", R"SOURCE(
 fn f(a : i32) {
     let a = 0;
 }
-    )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'.");
+    )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
 
     add_compile_fail_case("variable has wrong type", R"SOURCE(
 fn f() -> i32 {
@@ -450,17 +450,21 @@ fn f() {
 fn f() {
     let a = return;
 }
-    )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable.");
+    )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable");
 
     add_compile_fail_case("unreachable variable", R"SOURCE(
 fn f() {
     let a : unreachable = return;
 }
-    )SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' is not allowed.");
+    )SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' not allowed");
 
     add_compile_fail_case("unreachable parameter", R"SOURCE(
 fn f(a : unreachable) {}
-    )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' is not allowed.");
+    )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' not allowed");
+
+    add_compile_fail_case("exporting a void parameter", R"SOURCE(
+export fn f(a : void) {}
+    )SOURCE", 1, ".tmp_source.zig:2:17: error: parameter of type 'void' not allowed on exported functions");
 
 }
 
README.md
@@ -43,7 +43,6 @@ make
 ## Roadmap
 
  * parseh: unreachable <--> noreturn attribute
- * error for extern function with void parameter
  * unused label error
  * loops
  * structs