From 997573d842d55e68ca341d129fdedfa7fb7e5c62 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:00:46 +0100 Subject: [PATCH 1/9] Avoid multiple declarations of lineno It's declared in lex.l, so it should just be extern in the header. GCC 10 and later default to -fno-common, so this avoids a compile error with all recent versions. --- dis.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dis.h b/dis.h index c48a6c2..f9598eb 100644 --- a/dis.h +++ b/dis.h @@ -124,7 +124,7 @@ char *get_name(addr_t loc); #define OFS 267 extern FILE *yyin, *yyout; -int lineno; +extern int lineno; int yywrap(), yyerror(); char *emalloc(); From f90c18cff88fb7148e83ccd1845b6f2f6e696875 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:03:42 +0100 Subject: [PATCH 2/9] Remove prototypes for string.h functions. This avoids build errors with GCC 15, which defaults to C23 where () means the same as (void). --- lex.l | 1 - print.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/lex.l b/lex.l index 3c637c6..ef773b2 100644 --- a/lex.l +++ b/lex.l @@ -28,7 +28,6 @@ #include #include "dis.h" int lineno = 0; -char *strcpy(); %} %option nounput diff --git a/print.c b/print.c index 1a3f25c..991f012 100644 --- a/print.c +++ b/print.c @@ -31,9 +31,6 @@ #include "dis.h" -char *strcpy(); -char *strcat(); - static char *lname (addr_t i, int offset_ok) { From c0f77eeec6642caf9ae830fe589bfd87aef71e62 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:07:12 +0100 Subject: [PATCH 3/9] Make emalloc's prototype match malloc Returning void * means you never need to cast the result. This also removes a pre-ANSI function definition, which isn't valid in C23 (and produces warnings with GCC 15). --- dis.h | 4 +++- lex.l | 12 ++++++------ ref.c | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dis.h b/dis.h index f9598eb..91dfcb9 100644 --- a/dis.h +++ b/dis.h @@ -20,6 +20,8 @@ */ +#include + extern bool sevenbit; /* if true, mask character data with 0x7f to ignore MSB */ @@ -127,7 +129,7 @@ extern FILE *yyin, *yyout; extern int lineno; int yywrap(), yyerror(); -char *emalloc(); +void *emalloc (size_t n); typedef union { int ival; diff --git a/lex.l b/lex.l index ef773b2..a87e2d9 100644 --- a/lex.l +++ b/lex.l @@ -23,6 +23,7 @@ %{ #undef ECHO #include +#include #include #include #include @@ -74,7 +75,7 @@ alphanum [0-9a-zA-Z_] } {alpha}{alphanum}* { - token.sval = emalloc((unsigned) strlen(yytext)+1); + token.sval = emalloc(strlen(yytext)+1); (void)strcpy((char *)token.sval, (char *)yytext); return NAME; } @@ -89,13 +90,12 @@ alphanum [0-9a-zA-Z_] %% -char * -emalloc(n) -unsigned n; +void * +emalloc(size_t n) { - char *ptr; + void *ptr; - if ((ptr = malloc(n)) == (char *) 0) { + if ((ptr = malloc(n)) == NULL) { (void) fprintf(stderr,"out of core"); exit(1); } diff --git a/ref.c b/ref.c index 5a40156..134f9b2 100644 --- a/ref.c +++ b/ref.c @@ -71,7 +71,7 @@ void save_ref (addr_t refer, addr_t refee) struct ref_chain *rc; struct hashslot *hp; - rc = (struct ref_chain *)emalloc(sizeof(*rc)); + rc = emalloc(sizeof(*rc)); rc->who = refer; hp = hash(refee, 1); rc->next = hp->ref; From af99f98ee786acda6a034302fd2e355300cffc65 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:11:05 +0100 Subject: [PATCH 4/9] Use emalloc for all allocations There were a few calls to malloc that didn't check whether it returned NULL. Use emalloc in these cases, since that does the check anyway. --- main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index a6f101d..77ff587 100644 --- a/main.c +++ b/main.c @@ -232,7 +232,7 @@ void do_ptrace (void) { for (int i = 0; i Date: Fri, 11 Jul 2025 15:18:03 +0100 Subject: [PATCH 5/9] Remove unnecessary strcpy/strlen We can just include the string in the following sprintf. --- print.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/print.c b/print.c index 991f012..0223844 100644 --- a/print.c +++ b/print.c @@ -40,8 +40,8 @@ static char *lname (addr_t i, int offset_ok) if (f[i] & NAMED) return(get_name(i)); if (f[i] & OFFSET) { - (void)strcpy(buf, get_name(i+offset[i])); - sprintf (buf + strlen (buf), "%c%ld", + sprintf (buf, "%s%c%ld", + get_name(i+offset[i]), (offset [i] <= 0) ? '+' : '-', labs (offset [i])); return (buf); From b922ce880661723800b41ae6ba0ac000eb9ad9a7 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:19:08 +0100 Subject: [PATCH 6/9] Increase buffer size in lname GCC 15 warns that the buffer might not be long enough, which is correct (if unlikely) as %ld on its own might be 20 characters on a 64-bit system. --- print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print.c b/print.c index 0223844..76cc95e 100644 --- a/print.c +++ b/print.c @@ -34,7 +34,7 @@ static char *lname (addr_t i, int offset_ok) { - static char buf[20]; + static char buf[40]; /* ~6-char label, +/-, long int */ char t; if (f[i] & NAMED) From 2a244fef81c9812488e20e351109a8424b08c0af Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:28:37 +0100 Subject: [PATCH 7/9] Always initialize operand in print_inst/trace_inst It was set to a value in the switch statement later, but clang's analyzer can't prove that one of the cases must execute, so it warns that it may still be used uninitialized. Just set it to 0 when it's declared. --- main.c | 3 +-- print.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 77ff587..03eebe9 100644 --- a/main.c +++ b/main.c @@ -90,7 +90,7 @@ void trace_inst (addr_t addr) { int opcode; register struct info *ip; - int operand; + int operand = 0; int istart; for (;;) @@ -116,7 +116,6 @@ void trace_inst (addr_t addr) switch(ip->nb) { case 1: - operand = 0; /* only to avoid "may be used unitialized" warning */ break; case 2: operand = getbyte(addr); diff --git a/print.c b/print.c index 76cc95e..17657a8 100644 --- a/print.c +++ b/print.c @@ -165,7 +165,7 @@ int print_inst(addr_t addr) { int opcode; register struct info *ip; - int operand; + int operand = 0; opcode = getbyte(addr); ip = &optbl[opcode]; @@ -176,8 +176,6 @@ int print_inst(addr_t addr) switch(ip->nb) { case 1: - operand = 0; /* only to avoid "may be used - unitialized" warning */ break; case 2: operand = getbyte(addr); From c90668a54768cbfba05d8a81a03e8250e94e6c7e Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:30:45 +0100 Subject: [PATCH 8/9] Add missing fcloses clang's analyzer correctly warns that none of the file-reading functions closed the file once they were done. --- main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main.c b/main.c index 03eebe9..d440162 100644 --- a/main.c +++ b/main.c @@ -510,6 +510,8 @@ void loadboot (void) if (fread((char *)&d[base_addr], 1, len, fp) != len) crash("input too short"); + fclose(fp); + for(int i = base_addr; len > 0; len--) f[i++] |= LOADED; @@ -543,6 +545,7 @@ void loadfile (void) i = getword(RUNLOC); start_trace(i, "**RUN**"); } + fclose(fp); return; } @@ -607,6 +610,8 @@ void c64loadfile (void) f[i++] |= LOADED; } + fclose(fp); + start_trace(base_addr, "**C64BIN**"); } @@ -636,6 +641,8 @@ void binaryloadfile (void) f [i++] |= LOADED; } + fclose(fp); + reset = vector_address - 4; irq = vector_address - 2; nmi = vector_address - 6; From b894082d57de55dd331d04c91128797f26e9527a Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Fri, 11 Jul 2025 15:37:19 +0100 Subject: [PATCH 9/9] Add %option noinput The input function isn't used in lex.l, so this avoids an unused function warning. --- lex.l | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lex.l b/lex.l index a87e2d9..e8bb8e2 100644 --- a/lex.l +++ b/lex.l @@ -31,7 +31,7 @@ int lineno = 0; %} -%option nounput +%option noinput nounput digit [0-9] hexdigit [0-9a-fA-F]