mirror of
https://github.com/cc65/cc65.git
synced 2025-02-24 09:29:07 +00:00
Add a warning for an address expression that is usually the result of a typo
and almost never used in this form. git-svn-id: svn://svn.cc65.org/cc65/trunk@2158 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
43f59de557
commit
be00adb757
@ -75,6 +75,7 @@ void WarningMsg (const FilePos* Pos, unsigned WarnNum, va_list ap)
|
|||||||
{ 2, "Symbol `%s' is defined but never used" },
|
{ 2, "Symbol `%s' is defined but never used" },
|
||||||
{ 2, "Symbol `%s' is imported but never used" },
|
{ 2, "Symbol `%s' is imported but never used" },
|
||||||
{ 1, "Cannot track processor status byte" },
|
{ 1, "Cannot track processor status byte" },
|
||||||
|
{ 1, "Suspicious address expression" },
|
||||||
{ 0, "User warning: %s" },
|
{ 0, "User warning: %s" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ enum Warnings {
|
|||||||
WARN_SYM_NOT_REFERENCED,
|
WARN_SYM_NOT_REFERENCED,
|
||||||
WARN_IMPORT_NOT_REFERENCED,
|
WARN_IMPORT_NOT_REFERENCED,
|
||||||
WARN_CANNOT_TRACK_STATUS,
|
WARN_CANNOT_TRACK_STATUS,
|
||||||
|
WARN_SUSPICIOUS_ADDREXPR,
|
||||||
WARN_USER,
|
WARN_USER,
|
||||||
WARN_COUNT /* Warning count */
|
WARN_COUNT /* Warning count */
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "objcode.h"
|
#include "objcode.h"
|
||||||
|
#include "symtab.h"
|
||||||
#include "instr.h"
|
#include "instr.h"
|
||||||
|
|
||||||
|
|
||||||
@ -606,21 +607,42 @@ static void PutAll (const InsDesc* Ins)
|
|||||||
* modes.
|
* modes.
|
||||||
*/
|
*/
|
||||||
if (Expr && (AddrModeSet & AM_ZP) && !IsByteExpr (Expr)) {
|
if (Expr && (AddrModeSet & AM_ZP) && !IsByteExpr (Expr)) {
|
||||||
AddrModeSet &= ~AM_ZP;
|
AddrModeSet &= ~AM_ZP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have any adressing modes left */
|
/* Check if we have any adressing modes left */
|
||||||
if (AddrModeSet == 0) {
|
if (AddrModeSet == 0) {
|
||||||
Error (ERR_ILLEGAL_ADDR_MODE);
|
Error (ERR_ILLEGAL_ADDR_MODE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddrMode = BitFind (AddrModeSet);
|
AddrMode = BitFind (AddrModeSet);
|
||||||
|
|
||||||
|
/* If the instruction has a one byte operand and immediate addressing is
|
||||||
|
* allowed but not used, check for an operand expression in the form
|
||||||
|
* <label or >label, where label is a far or absolute label. If found,
|
||||||
|
* emit a warning. This warning protects against a typo, where the '#'
|
||||||
|
* for the immediate operand is omitted.
|
||||||
|
*/
|
||||||
|
if (Expr && (Ins->AddrMode & AM_IMM) &&
|
||||||
|
(AddrModeSet & (AM_DIR | AM_ABS | AM_ABS_LONG)) &&
|
||||||
|
ExtBytes[AddrMode] == 1) {
|
||||||
|
|
||||||
|
/* Found, check the expression */
|
||||||
|
ExprNode* Left = Expr->Left;
|
||||||
|
if ((Expr->Op == EXPR_BYTE0 || Expr->Op == EXPR_BYTE1) &&
|
||||||
|
Left->Op == EXPR_SYMBOL &&
|
||||||
|
!SymIsZP (Left->V.Sym)) {
|
||||||
|
|
||||||
|
/* Output a warning */
|
||||||
|
Warning (WARN_SUSPICIOUS_ADDREXPR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Build the opcode */
|
/* Build the opcode */
|
||||||
OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
|
OpCode = Ins->BaseCode | EATab [Ins->ExtCode][AddrMode];
|
||||||
|
|
||||||
/* Check how many extension bytes are needed and output the instruction */
|
/* Check how many extension bytes are needed and output the instruction */
|
||||||
switch (ExtBytes [AddrMode]) {
|
switch (ExtBytes[AddrMode]) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
Emit0 (OpCode);
|
Emit0 (OpCode);
|
||||||
@ -637,7 +659,7 @@ static void PutAll (const InsDesc* Ins)
|
|||||||
* mode, force this address into 16 bit range to allow
|
* mode, force this address into 16 bit range to allow
|
||||||
* addressing inside a 64K segment.
|
* addressing inside a 64K segment.
|
||||||
*/
|
*/
|
||||||
Emit2 (OpCode, ForceWordExpr (Expr));
|
Emit2 (OpCode, ForceWordExpr (Expr));
|
||||||
} else {
|
} else {
|
||||||
Emit2 (OpCode, Expr);
|
Emit2 (OpCode, Expr);
|
||||||
}
|
}
|
||||||
|
@ -95,19 +95,19 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Description for one instruction */
|
/* Description for one instruction */
|
||||||
typedef struct InsDesc_ InsDesc;
|
typedef struct InsDesc InsDesc;
|
||||||
struct InsDesc_ {
|
struct InsDesc {
|
||||||
char Mnemonic [4];
|
char Mnemonic [4];
|
||||||
unsigned long AddrMode; /* Valid adressing modes */
|
unsigned long AddrMode; /* Valid adressing modes */
|
||||||
unsigned char BaseCode; /* Base opcode */
|
unsigned char BaseCode; /* Base opcode */
|
||||||
unsigned char ExtCode; /* Number of ext code table */
|
unsigned char ExtCode; /* Number of ext code table */
|
||||||
void (*Emit) (const InsDesc*);/* Handler function */
|
void (*Emit) (const InsDesc*);/* Handler function */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An instruction table */
|
/* An instruction table */
|
||||||
typedef struct InsTable_ InsTable;
|
typedef struct InsTable InsTable;
|
||||||
struct InsTable_ {
|
struct InsTable {
|
||||||
unsigned Count; /* Number of intstructions */
|
unsigned Count; /* Number of intstructions */
|
||||||
InsDesc Ins[1]; /* Varying length */
|
InsDesc Ins[1]; /* Varying length */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ extern unsigned char ExtBytes [AMI_COUNT];
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user