]> git.sur5r.net Git - cc65/commitdiff
Fix regression of #pragma bss-name 411/head
authorPiotr Fusik <fox@scene.pl>
Tue, 21 Mar 2017 21:35:25 +0000 (22:35 +0100)
committerPiotr Fusik <fox@scene.pl>
Tue, 21 Mar 2017 21:35:25 +0000 (22:35 +0100)
Closes #409

cfg/sim6502.cfg
cfg/sim65c02.cfg
src/cc65/compile.c
src/cc65/symentry.c
src/cc65/symentry.h
test/err/bss-name-conflict.c [new file with mode: 0644]
test/val/bss-name-decl.c [new file with mode: 0644]
test/val/bss-name.c [new file with mode: 0644]

index b4f7738f5866ad8ad0432c90b932e55e496ac219..530787489f6679580f409a6306e1771f1fb70a3f 100644 (file)
@@ -3,7 +3,7 @@ SYMBOLS {
     __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
-    ZP:     file = "",               start = $0000, size = $001A;
+    ZP:     file = "",               start = $0000, size = $001B;
     HEADER: file = %O,               start = $0000, size = $0001;
     MAIN:   file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__;
 }
index b4f7738f5866ad8ad0432c90b932e55e496ac219..530787489f6679580f409a6306e1771f1fb70a3f 100644 (file)
@@ -3,7 +3,7 @@ SYMBOLS {
     __STACKSIZE__: type = weak, value = $0800; # 2k stack
 }
 MEMORY {
-    ZP:     file = "",               start = $0000, size = $001A;
+    ZP:     file = "",               start = $0000, size = $001B;
     HEADER: file = %O,               start = $0000, size = $0001;
     MAIN:   file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__;
 }
index 48a5c29d35adca95c566a0adf9f490b041ffbab9..4425b6aad71cd3f52ab3732cd1cdac5ed86c47f1 100644 (file)
@@ -242,16 +242,24 @@ static void Parse (void)
                             Error ("Variable `%s' has unknown size", Decl.Ident);
                         }
                         Entry->Flags &= ~(SC_STORAGE | SC_DEF);
+                    } else {
+                        /* A global (including static) uninitialized variable
+                        ** is only a tentative definition. For example, this is valid:
+                        ** int i;
+                        ** int i;
+                        ** static int j;
+                        ** static int j = 42;
+                        ** Code for these will be generated in FinishCompile.
+                        ** For now, just save the BSS segment name
+                        ** (can be set with #pragma bss-name)
+                        */
+                        const char* bssName = GetSegName (SEG_BSS);
+                        if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {
+                            Error ("Global variable `%s' has already been defined in `%s' segment",
+                                   Entry->Name, Entry->V.BssName);
+                        }
+                        Entry->V.BssName = xstrdup (bssName);
                     }
-
-                    /* A global (including static) uninitialized variable
-                    ** is only a tentative definition. For example, this is valid:
-                    ** int i;
-                    ** int i;
-                    ** static int j;
-                    ** static int j = 42;
-                    ** Code for these will be generated in FinishCompile.
-                    */
                 }
 
             }
@@ -418,6 +426,8 @@ void FinishCompile (void)
         } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
             /* Tentative definition of uninitialized global variable */
             g_usebss ();
+            SetSegName (SEG_BSS, Entry->V.BssName);
+            g_segname (SEG_BSS); /* TODO: skip if same as before */
             g_defgloblabel (Entry->Name);
             g_res (SizeOf (Entry->Type));
             /* Mark as defined, so that it will be exported not imported */
index 980ee27f2dab87e2c62fcf7f847a7ec5f12e842b..d6e68d1bbbdd291b51d175ba28a600add40acae9 100644 (file)
@@ -71,6 +71,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
     E->Type     = 0;
     E->Attr     = 0;
     E->AsmName  = 0;
+    E->V.BssName = 0;
     memcpy (E->Name, Name, Len+1);
 
     /* Return the new entry */
index 4fa84255b4b4d8d1e07349dba19c49dce4a9f403..ff136702f6cfd9849918988ed84aee204e6ec2d2 100644 (file)
@@ -153,6 +153,8 @@ struct SymEntry {
             struct LiteralPool* LitPool;  /* Literal pool for this function */
         } F;
 
+        /* Segment name for tentantive global definitions */
+        const char*             BssName;
     } V;
     char                       Name[1]; /* Name, dynamically allocated */
 };
diff --git a/test/err/bss-name-conflict.c b/test/err/bss-name-conflict.c
new file mode 100644 (file)
index 0000000..1d6cd50
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+  !!DESCRIPTION!! conflicting bss-name pragmas
+  !!ORIGIN!!      cc65 regression tests
+  !!LICENCE!!     Public Domain
+  !!AUTHOR!!      Piotr Fusik
+*/
+
+/*
+  see: https://github.com/cc65/cc65/issues/409
+*/
+
+char oam_off;
+#pragma bss-name (push,"ZEROPAGE")
+char oam_off;
+#pragma bss-name (pop)
+
+int main(void)
+{
+    return 0;
+}
diff --git a/test/val/bss-name-decl.c b/test/val/bss-name-decl.c
new file mode 100644 (file)
index 0000000..9a53584
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+  !!DESCRIPTION!! bss-name pragma not affecting declarations
+  !!ORIGIN!!      cc65 regression tests
+  !!LICENCE!!     Public Domain
+  !!AUTHOR!!      Piotr Fusik
+*/
+
+/*
+  see: https://github.com/cc65/cc65/issues/409
+*/
+
+#pragma bss-name (push,"ZEROPAGE")
+
+char n; /* only a declaration because followed by definition */
+char n = 1; /* not BSS */
+
+#pragma bss-name (pop)
+
+int main(void)
+{
+    return (unsigned) &n >= 0x100 ? 0 : 1;
+}
diff --git a/test/val/bss-name.c b/test/val/bss-name.c
new file mode 100644 (file)
index 0000000..f0ad711
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+  !!DESCRIPTION!! bss-name pragma
+  !!ORIGIN!!      cc65 regression tests
+  !!LICENCE!!     Public Domain
+  !!AUTHOR!!      Piotr Fusik
+*/
+
+/*
+  see: https://github.com/cc65/cc65/issues/409
+*/
+
+#pragma bss-name (push,"ZEROPAGE")
+
+char zp_var;
+
+#pragma bss-name (pop)
+
+int main(void)
+{
+    return (unsigned) &zp_var < 0x100 ? 0 : 1;
+}