From 43065894d9513e9227ef10bf752a0c4da39b33d7 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Mon, 27 Nov 2023 09:39:55 -0800 Subject: [PATCH 1/2] Type: check for matching parameter count in function type comparison Closes #580 --- src/aro/Type.zig | 1 + test/cases/functions.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/aro/Type.zig b/src/aro/Type.zig index 1369d7bb..999bd34d 100644 --- a/src/aro/Type.zig +++ b/src/aro/Type.zig @@ -114,6 +114,7 @@ pub const Func = struct { } return true; } + return false; } if ((a_spec == .func) != (b_spec == .func)) return false; // TODO validate this diff --git a/test/cases/functions.c b/test/cases/functions.c index 99824524..b4cf7d73 100644 --- a/test/cases/functions.c +++ b/test/cases/functions.c @@ -75,6 +75,9 @@ int (*return_array_ptr(void))[2] { return &ARRAY; } +void no_params(void); +void no_params(int x){} + #define EXPECTED_ERRORS "functions.c:10:12: error: parameter named 'quux' is missing" \ "functions.c:20:14: error: illegal initializer (only variables can be initialized)" \ "functions.c:18:2: warning: non-void function 'foooo' does not return a value [-Wreturn-type]" \ @@ -85,3 +88,6 @@ int (*return_array_ptr(void))[2] { "functions.c:50:3: error: parameter has incomplete type 'union Union'" \ "functions.c:53:30: error: parameter has incomplete type 'enum E'" \ "functions.c:55:9: error: parameter has incomplete type 'enum EE'" \ + "functions.c:79:6: error: redefinition of 'no_params' with a different type" \ + "functions.c:78:6: note: previous definition is here" \ + From efed2292f668c3e9a59c6b7ca77c5d1632a8bce7 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Mon, 27 Nov 2023 10:10:55 -0800 Subject: [PATCH 2/2] Type: old & new style function types can be equal if there are no parameters --- src/aro/Type.zig | 1 + test/cases/redefinitions.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/aro/Type.zig b/src/aro/Type.zig index 999bd34d..22ab28e9 100644 --- a/src/aro/Type.zig +++ b/src/aro/Type.zig @@ -105,6 +105,7 @@ pub const Func = struct { fn eql(a: *const Func, b: *const Func, a_spec: Specifier, b_spec: Specifier, comp: *const Compilation) bool { // return type cannot have qualifiers if (!a.return_type.eql(b.return_type, comp, false)) return false; + if (a.params.len == 0 and b.params.len == 0) return true; if (a.params.len != b.params.len) { if (a_spec == .old_style_func or b_spec == .old_style_func) { diff --git a/test/cases/redefinitions.c b/test/cases/redefinitions.c index c8e2d0ff..00711feb 100644 --- a/test/cases/redefinitions.c +++ b/test/cases/redefinitions.c @@ -85,6 +85,12 @@ int f4(int); int f5(int (*)(), double (*)[3]); int f5(int (*)(char), double (*)[]); // not compatible since char undergoes default argument promotion +void f6(); +void f6(void) {} + +void f7(void); +void f7() {} + #define EXPECTED_ERRORS "redefinitions.c:4:5: error: redefinition of 'foo' as different kind of symbol" \ "redefinitions.c:1:5: note: previous definition is here" \ "redefinitions.c:5:5: error: redefinition of 'foo' as different kind of symbol" \