From ce90abdb1fb2a727994b3ac3ca2606dde1d82073 Mon Sep 17 00:00:00 2001 From: Jan Schlosser Date: Wed, 21 Oct 2026 13:54:42 +0200 Subject: [PATCH] Rule 5.13.4: Remove false positives in macro expansions The CodeQL extractor does not preserve the source spelling of literals expanded from a macro: getValueText() either drops the suffix (e.g. `0U` becomes `0`) or returns the text of the whole macro invocation. As a result, correctly suffixed literals such as `TEST_MACRO(1U == 0U)` were reported as missing a `U` suffix. Exclude literals generated by macro expansions, consistent with the fix for RULE-7-2 (github/codeql-coding-standards#705). Unsuffixed literals in macro expansions are now a known false negative, documented in the test. This also applies to M2-13-3, which shares the query. --- ...26-10-19-fix-fp-rule-5-13-4-macro-expanded-literals.md | 2 ++ .../UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll | 3 +++ .../test.cpp | 8 ++++++++ 3 files changed, 13 insertions(+) create mode 100644 change_notes/2026-10-19-fix-fp-rule-5-13-4-macro-expanded-literals.md diff --git a/change_notes/2026-10-19-fix-fp-rule-5-13-4-macro-expanded-literals.md b/change_notes/2026-10-19-fix-fp-rule-5-13-4-macro-expanded-literals.md new file mode 100644 index 0000000000..32836faf63 --- /dev/null +++ b/change_notes/2026-10-19-fix-fp-rule-5-13-4-macro-expanded-literals.md @@ -0,0 +1,2 @@ +- `RULE-5-13-4`, `M2-13-3` - `UnsignedIntegerLiteralsNotAppropriatelySuffixed.ql`, `MissingUSuffix.ql`: + - Remove false positives for literals in macro expansions (e.g. `0U`), as the suffix information is lost in this case. This is consistent with `RULE-7-2`. diff --git a/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll b/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll index 8f07ebb58b..47552a949b 100644 --- a/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll +++ b/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll @@ -26,6 +26,9 @@ query predicate problems(Cpp14Literal::NumericLiteral nl, string message) { nl.getType().getUnspecifiedType().(IntegralType).isUnsigned() and // The literal already has a `u` or `U` suffix. not nl.getValueText().regexpMatch(".*[lL]*[uU][lL]*") and + // Exclude literals generated by macro expansions, because the suffix information is lost in + // this case, so can cause false positives. + not nl.isInMacroExpansion() and // exclude literals derived from template instantiations not nl.isFromTemplateInstantiation(_) and message = literalKind + " literal is an unsigned integer but does not include a 'U' suffix." diff --git a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp index b168bafcca..6688dc9871 100644 --- a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp +++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp @@ -560,3 +560,11 @@ template unsigned long long instantiated_literal_exclusion() { void test_instantiated_literal_exclusion() { instantiated_literal_exclusion(); } + +#define TEST_MACRO(value) (value) + +void test_literals_in_macro_argument() { + TEST_MACRO(1U == 0U); // COMPLIANT + TEST_MACRO(020000000000); // NON_COMPLIANT[FALSE_NEGATIVE] - cannot determine + // suffix in macro expansions +}