aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/parse.c8
-rw-r--r--tests/static_linkage.sh48
2 files changed, 54 insertions, 2 deletions
diff --git a/src/parse.c b/src/parse.c
index 39bd8f2..819c418 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1433,8 +1433,12 @@ static AstNode* parse_func_def(Parser* p, AstNode* decls) {
}
Type* ty = decls->node_items[0].ty;
- ty->storage_class = ty->result->storage_class;
- ty->result->storage_class = StorageClass_unspecified;
+ Type* base_ty = ty->result;
+ while (base_ty->base) {
+ base_ty = base_ty->base;
+ }
+ ty->storage_class = base_ty->storage_class;
+ base_ty->storage_class = StorageClass_unspecified;
const char* name = decls->node_items[0].name;
AstNode* params = ty->params;
diff --git a/tests/static_linkage.sh b/tests/static_linkage.sh
new file mode 100644
index 0000000..de6120f
--- /dev/null
+++ b/tests/static_linkage.sh
@@ -0,0 +1,48 @@
+cat > main.c <<'EOF'
+int f1() { return 0; }
+int* f2() { return 0; }
+int** f3() { return 0; }
+
+static int f4() { return 0; }
+static int* f5() { return 0; }
+static int** f6() { return 0; }
+
+char* f7() { return 0; }
+static char* f8() { return 0; }
+
+void** f9() { return 0; }
+static void** f10() { return 0; }
+
+int main() { }
+EOF
+
+"$ducc" -o main.s main.c
+
+function assert_global() {
+ local func=$1
+ if ! grep -q "\.globl $func\$" main.s; then
+ echo "expected .globl for non-static function: $func" >&2
+ exit 1
+ fi
+}
+
+function assert_local() {
+ local func=$1
+ if grep -q "\.globl $func\$" main.s; then
+ echo "unexpected .globl for static function: $func" >&2
+ exit 1
+ fi
+}
+
+assert_global f1
+assert_global f2
+assert_global f3
+assert_global f7
+assert_global f9
+assert_global main
+
+assert_local f4
+assert_local f5
+assert_local f6
+assert_local f8
+assert_local f10