1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-16 16:31:04 +00:00

Add warnings for calling from one segment to another overlapping one (#42) and -Wnone flag

This commit is contained in:
Karol Stasiak 2020-03-16 00:03:01 +01:00
parent 83b85ef0fc
commit ec8f2e6a1c
6 changed files with 37 additions and 1 deletions

View File

@ -8,6 +8,8 @@
* Added `breakpoint` macro (#44).
* Added warnings for calling from one segment to another overlapping one.
* 6502: Fixed undocumented mnemonics.
* Create output directories when needed (#21)

View File

@ -260,6 +260,10 @@ command line options `--inline`, `--dangerous-optimizations` `--fipo` and `--fno
## Warning options
By default, the compiler emits only some of the most important warnings.
* `-Wall` Enable extra warnings.
* `-Wnone` Disable all warnings.
* `-Wfatal` Treat warnings as errors.

View File

@ -409,6 +409,7 @@ object Cpu extends Enumeration {
private val alwaysDefaultFlags = Set(
VariableOverlap, CompactReturnDispatchParams, FunctionFallthrough, RegisterVariables, FunctionDeduplication, EnableBreakpoints,
NonZeroTerminatedLiteralWarning, CallToOverlappingBankWarning,
)
private val mosAlwaysDefaultFlags = alwaysDefaultFlags
@ -564,6 +565,7 @@ object CompilationFlag extends Enumeration {
ExtraComparisonWarnings,
RorWarning,
NonZeroTerminatedLiteralWarning,
CallToOverlappingBankWarning,
FatalWarnings,
// special options for internal compiler use
EnableInternalTestSyntax,

View File

@ -758,6 +758,10 @@ object Main {
CompilationFlag.allWarnings.foldLeft(c) { (c, f) => c.changeFlag(f, true) }
}.description("Enable extra warnings.")
flag("-Wnone", "--Wnone").action { c =>
CompilationFlag.allWarnings.foldLeft(c) { (c, f) => c.changeFlag(f, false) }
}.description("Disable all warnings.")
flag("-Wfatal", "--Wfatal").action { c =>
c.changeFlag(CompilationFlag.FatalWarnings, true)
}.description("Treat warnings as errors.")

View File

@ -46,6 +46,19 @@ class Platform(
def cpuFamily: CpuFamily.Value = CpuFamily.forType(this.cpu)
def isBigEndian: Boolean = CpuFamily.isBigEndian(cpuFamily)
private def bankStart(bank: String): Int = codeAllocators(bank).startAt min variableAllocators(bank).startAt
private def bankEndBefore(bank: String): Int = codeAllocators(bank).endBefore max variableAllocators(bank).endBefore
def isUnsafeToJump(bank1: String, bank2: String): Boolean = {
if (bank1 == bank2) return false
val s1 = bankStart(bank1)
val s2 = bankStart(bank2)
val e1 = bankEndBefore(bank1)
val e2 = bankEndBefore(bank2)
e2 > s1 && s2 < e1
}
}
object Platform {

View File

@ -544,7 +544,18 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
ctx.env.maybeGet[Thing](name) match {
case Some(_: MacroFunction) =>
FunctionCallExpression(name, args.map(arg => optimizeExpr(arg, Map()))).pos(pos)
case _ =>
case a =>
if (ctx.options.flag(CompilationFlag.CallToOverlappingBankWarning)) {
a match {
case Some(f: FunctionInMemory) =>
val thisBank = ctx.function.bank(ctx.options)
val targetBank = f.bank(ctx.options)
if (ctx.options.platform.isUnsafeToJump(targetBank, thisBank)) {
ctx.log.warn(s"Unsafe call to function `${f.name}` in segment `$targetBank` from function `${ctx.function.name}` in overlapping segment `$thisBank`", expr.position)
}
case _ =>
}
}
FunctionCallExpression(name, args.map(arg => optimizeExpr(arg, currentVarValues))).pos(pos)
}
case SumExpression(expressions, false) if optimizeSum =>