From 165b79546c1797d85d9c34d7ff89b503106928b4 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 27 Sep 2026 20:49:21 -0400 Subject: [PATCH] Add RGBASM `-Winclude-shadow` warning (#2180) --- contrib/bash_compl/_rgbasm.bash | 1 + contrib/zsh_compl/_rgbasm | 1 + include/asm/warning.hpp | 1 + man/rgbasm.1 | 7 ++++ src/asm/fstack.cpp | 38 ++++++++++++++++++-- src/asm/warning.cpp | 1 + test/asm/include-shadow.asm | 2 ++ test/asm/include-shadow.err | 2 ++ test/asm/include-shadow.flags | 1 + test/asm/include-shadow.inc | 1 + test/asm/include-shadow.out | 1 + test/asm/include/include-shadow.inc | 1 + test/asm/include/include2/include-shadow.inc | 1 + 13 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 test/asm/include-shadow.asm create mode 100644 test/asm/include-shadow.err create mode 100644 test/asm/include-shadow.flags create mode 100644 test/asm/include-shadow.inc create mode 100644 test/asm/include-shadow.out create mode 100644 test/asm/include/include-shadow.inc create mode 100644 test/asm/include/include2/include-shadow.inc diff --git a/contrib/bash_compl/_rgbasm.bash b/contrib/bash_compl/_rgbasm.bash index a3f98746..b6e35726 100755 --- a/contrib/bash_compl/_rgbasm.bash +++ b/contrib/bash_compl/_rgbasm.bash @@ -185,6 +185,7 @@ _rgbasm_completions() { empty-macro-arg empty-strrpl export-undefined + include-shadow large-constant macro-shift nested-comment diff --git a/contrib/zsh_compl/_rgbasm b/contrib/zsh_compl/_rgbasm index af57af08..704c7427 100644 --- a/contrib/zsh_compl/_rgbasm +++ b/contrib/zsh_compl/_rgbasm @@ -17,6 +17,7 @@ _rgbasm_warnings() { 'empty-macro-arg:Warn on empty macro arg' 'empty-strrpl:Warn on calling STRRPL with empty pattern' 'export-undefined:Warn on EXPORT of an undefined symbol' + 'include-shadow:Warn on multiple INCLUDE/INCBIN file candidates' 'large-constant:Warn on constants too large for a signed 32-bit int' 'macro-shift:Warn when shifting macro args part their limits' 'nested-comment:Warn on "/*" inside block comments' diff --git a/include/asm/warning.hpp b/include/asm/warning.hpp index 7b61ad2e..1a876924 100644 --- a/include/asm/warning.hpp +++ b/include/asm/warning.hpp @@ -24,6 +24,7 @@ enum WarningID { WARNING_EMPTY_MACRO_ARG, // Empty macro argument WARNING_EMPTY_STRRPL, // Empty second argument in `STRRPL` WARNING_EXPORT_UNDEFINED, // `EXPORT` of an undefined symbol + WARNING_INCLUDE_SHADOW, // Multiple `INCLUDE/INCBIN` file candidates WARNING_LARGE_CONSTANT, // Constants too large WARNING_MACRO_SHIFT, // `SHIFT` past available arguments in macro WARNING_NESTED_COMMENT, // Comment-start delimiter in a block comment diff --git a/man/rgbasm.1 b/man/rgbasm.1 index 5d532795..5fbc870c 100644 --- a/man/rgbasm.1 +++ b/man/rgbasm.1 @@ -473,6 +473,13 @@ This warning is enabled by Warn when exporting an undefined symbol. This warning is enabled by .Fl Wall . +.It Fl Winclude-shadow +Warn when there are multiple files with the same name in different include paths. +(The one in the first include path +.Dq shadows +the others.) +This warning is enabled by +.Fl Weverything . .It Fl Wno-large-constant Warn when a constant too large to fit in a signed 32-bit integer is encountered. .It Fl Wmacro-shift diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index e00cc695..1473b800 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -186,13 +186,47 @@ static void printDep(std::string const &path) { } std::optional fstk_FindFile(std::string const &path) { + std::optional foundFile = std::nullopt; + std::vector shadowed; + + bool warnIncludeShadow = + warnings.getWarningBehavior(WARNING_INCLUDE_SHADOW) != WarningBehavior::DISABLED; + for (std::string &incPath : includePaths) { if (std::string fullPath = incPath + path; isValidFilePath(fullPath)) { - printDep(fullPath); - return fullPath; + if (foundFile.has_value()) { + shadowed.push_back(fullPath); + } else { + foundFile = fullPath; + // If this does not need to print a `-Winclude-shadow` warning, it can immediately + // use the first path found instead of collecting all the `shadowed` paths. + if (!warnIncludeShadow) { + break; + } + } } } + if (!shadowed.empty()) { + assume(foundFile.has_value()); + size_t nbSummarized = shadowed.size() - 1; + std::string summary = nbSummarized > 0 ? " and " + std::to_string(nbSummarized) + " other" + + (nbSummarized != 1 ? "s" : "") + : ""; + warning( + WARNING_INCLUDE_SHADOW, + "File \"%s\" shadows \"%s\"%s", + foundFile->c_str(), + shadowed[0].c_str(), + summary.c_str() + ); + } + + if (foundFile.has_value()) { + printDep(*foundFile); + return foundFile; + } + if (options.missingIncludeState != INC_ERROR) { printDep(path); } diff --git a/src/asm/warning.cpp b/src/asm/warning.cpp index 86d2e7ba..037a92ad 100644 --- a/src/asm/warning.cpp +++ b/src/asm/warning.cpp @@ -31,6 +31,7 @@ Diagnostics warnings = { {"empty-macro-arg", LEVEL_EXTRA }, {"empty-strrpl", LEVEL_ALL }, {"export-undefined", LEVEL_ALL }, + {"include-shadow", LEVEL_EVERYTHING}, {"large-constant", LEVEL_DEFAULT }, {"macro-shift", LEVEL_EXTRA }, {"nested-comment", LEVEL_DEFAULT }, diff --git a/test/asm/include-shadow.asm b/test/asm/include-shadow.asm new file mode 100644 index 00000000..ae66291d --- /dev/null +++ b/test/asm/include-shadow.asm @@ -0,0 +1,2 @@ +INCLUDE "include-shadow.inc" +PRINTLN "N = {d:N}" diff --git a/test/asm/include-shadow.err b/test/asm/include-shadow.err new file mode 100644 index 00000000..7e66ec67 --- /dev/null +++ b/test/asm/include-shadow.err @@ -0,0 +1,2 @@ +warning: File "include-shadow.inc" shadows "include/include-shadow.inc" and 1 other [-Winclude-shadow] + at include-shadow.asm(1) diff --git a/test/asm/include-shadow.flags b/test/asm/include-shadow.flags new file mode 100644 index 00000000..cca62afc --- /dev/null +++ b/test/asm/include-shadow.flags @@ -0,0 +1 @@ +-I include -I include/include2 diff --git a/test/asm/include-shadow.inc b/test/asm/include-shadow.inc new file mode 100644 index 00000000..97cd3baf --- /dev/null +++ b/test/asm/include-shadow.inc @@ -0,0 +1 @@ +DEF N EQU 1 diff --git a/test/asm/include-shadow.out b/test/asm/include-shadow.out new file mode 100644 index 00000000..257d35a4 --- /dev/null +++ b/test/asm/include-shadow.out @@ -0,0 +1 @@ +N = 1 diff --git a/test/asm/include/include-shadow.inc b/test/asm/include/include-shadow.inc new file mode 100644 index 00000000..527e43c7 --- /dev/null +++ b/test/asm/include/include-shadow.inc @@ -0,0 +1 @@ +DEF N EQU 2 diff --git a/test/asm/include/include2/include-shadow.inc b/test/asm/include/include2/include-shadow.inc new file mode 100644 index 00000000..1388af16 --- /dev/null +++ b/test/asm/include/include2/include-shadow.inc @@ -0,0 +1 @@ +DEF N EQU 3