Skip to content

C++: suggest specifiers for simple integer format mismatches - #23108

Open
SkyCipherr wants to merge 2 commits into
github:mainfrom
SkyCipherr:codex/issue-15028-integer-format-hints
Open

SkyCipherr wants to merge 2 commits into
github:mainfrom
SkyCipherr:codex/issue-15028-integer-format-hints

Conversation

@SkyCipherr

Copy link
Copy Markdown
Contributor

Summary

Related to #15028.

Add a format-specifier suggestion to existing cpp/wrong-type-format-argument alerts for simple decimal integer conversions. For example, a %d conversion with an unsigned long argument on LP64 now suggests %lu.

The suggestion uses the argument type after default argument promotions and distinguishes int, long, and long long, including unsigned variants. It retains i for signed i conversions and uses u for unsigned arguments. The detection predicates and existing message text are unchanged; suggestions are appended only to conversion-value arguments.

This intentionally covers only plain %d, %i, %u, and their l/ll forms. Flags, width, precision, positional arguments, non-decimal conversions, and other types retain their existing messages. It does not attempt to close the full issue or change the existing treatment of equal-width integer types.

Validation

Validated with CodeQL CLI 2.27.4 against main at fbf9fca5ce7c3b64c2f5d719ea0444577850cb4a:

  • All 12 existing tests and 2 new Linux/Microsoft target-model tests pass (14/14).
  • Across all 14 test result files, result counts, locations, and original messages are unchanged after removing the suggestion suffixes.
  • A separate database extracted through real MinGW-w64 GCC 16.1.0 compilation has the same 19 alerts before and after; 10 gain suggestions. This LLP64 database uses long long cases because the issue's unsigned long versus int example is equal-width and is not reported by the existing query on that target. The original example is covered by the Linux target-model test.
  • The 10 suggested replacements from that database, plus the original example's %lu replacement, pass GCC -Wformat=2 -Werror=format compilation checks. Mismatched calls were not executed.
  • QL compilation, QL formatting, and git diff --check pass.

The full repository suite and large-project evaluation were not run. Upstream CI has not yet run for this change.

@SkyCipherr
SkyCipherr requested a review from a team as a code owner November 12, 2026 03:10
Copilot AI dynamic review requested due to automatic review settings November 12, 2026 03:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The production-query change lacks the repository’s broader DCA evaluation to check for unexpected diagnostic regressions beyond the focused tests and MinGW database.

1 open issue
What changed in this PR

Adds format-specifier suggestions to the C++ cpp/wrong-type-format-argument query, partially addressing #15028 without changing mismatch detection.

Changes:

  • Suggests matching specifiers for plain decimal integer conversions using promoted argument types.
  • Adds Linux and Microsoft target-model tests covering suggestions and excluded cases.
  • Updates existing expected diagnostics and adds a release note.
File Description
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​WrongTypeFormatArguments/​Microsoft/​WrongTypeFormatArguments.expected Updates Microsoft diagnostic expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​WrongTypeFormatArguments/​Microsoft_no_wchar/​WrongTypeFormatArguments.expected Updates no-wchar diagnostic expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​WrongTypeFormatArguments/​Linux_unsigned_chars/​WrongTypeFormatArguments.expected Updates unsigned-char diagnostic expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​WrongTypeFormatArguments/​Linux_signed_chars/​WrongTypeFormatArguments.expected Updates signed-char diagnostic expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​WrongTypeFormatArguments/​Buildless/​WrongTypeFormatArguments.expected Updates buildless diagnostic expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Microsoft/​WrongTypeFormatArguments.qlref Connects Microsoft tests to the query.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Microsoft/​WrongTypeFormatArguments.expected Records Microsoft suggestion expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Microsoft/​options Configures the Microsoft target model.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Microsoft/​integer-hints.c Adds Microsoft suggestion and exclusion cases.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Linux/​WrongTypeFormatArguments.qlref Connects Linux tests to the query.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Linux/​WrongTypeFormatArguments.expected Records Linux suggestion expectations.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Linux/​options Configures the Linux test extractor.
cpp/​ql/​test/​query-tests/​Likely Bugs/​Format/​IntegerFormatSuggestions/​Linux/​integer-hints.c Adds Linux suggestion and exclusion cases.
cpp/​ql/​src/​Likely Bugs/​Format/​WrongTypeFormatArguments.ql Appends suggestions for supported integer mismatches.
cpp/​ql/​src/​change-notes/​2026-11-12-integer-format-suggestions.md Documents the diagnostic enhancement.

Review effort: Balanced (auto)

select arg,
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
actual.getUnspecifiedType().getName() + "'."
actual.getUnspecifiedType().getName() + "'." + integerFormatSuggestion(ffc, n, arg, actual)
@jketema

jketema commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

This feels very hacky. I think a more principled approach would likely be to update cpp/ql/lib/semmle/code/cpp/commons/Printf.qll to provide this information.

@SkyCipherr

Copy link
Copy Markdown
Contributor Author

Thanks @jketema. Following your suggestion, I've reworked this in 0dc2c48.

Printf.qll now exposes FormatLiteral.getSuggestedIntegerConversionSpecifier(int n, Type type). It uses the existing parseConvSpec fields and the supplied promoted argument type to provide the replacement specifier. The query no longer has its own type-to-specifier mapping or regular-expression check; it only checks that the diagnostic concerns the conversion-value argument and formats the suggestion message. The alert detection predicates are unchanged.

The API is deliberately limited to the existing scope: plain decimal d, i, and u conversions with optional l or ll, for signed/unsigned int, long, and long long types. It preserves i for signed arguments and has no result for unsupported types, flags, width, precision, positional parameters, or other conversions. Its documentation states that callers supply the type after default argument promotions; it provides specifier information independently of whether a mismatch is reported. I've also added a library feature change note.

Validation with CodeQL CLI 2.27.4:

  • All 20 relevant tests pass: the 14 existing PR query tests, 4 existing printf library tests, and 2 new direct API tests.
  • Each new Linux/Microsoft API test checks 61 conversion positions: 27 supported and 34 excluded. These cover type categories independent of ABI widths, signedness, i preservation, typedefs/qualifiers, raw versus promoted narrow types, per-conversion mapping, decorators, positional parameters, and malformed/unsupported formats.
  • All 14 existing query result files are unchanged, including locations and complete messages.
  • Reanalysis of the existing real-GCC reproducer still produces the same 19 alerts and 10 suggestions, with identical messages and locations.
  • The 26 corrected calls from the new library fixtures and the previous 11 corrected calls pass GCC -Wformat=2 -Werror=format compilation checks. Mismatched calls were not executed.
  • QL compilation, formatting, and git diff --check pass.

These are local validation results. I have not run the full repository suite or refreshed upstream DCA for this commit; it still needs upstream CI/DCA.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants