C++: Remove potential FPs in cpp/wrong-type-format-argument in BMN

This commit is contained in:
Calum Grant
2025-01-23 19:22:10 +00:00
parent 231e3c2949
commit 9b53a390c0
3 changed files with 9 additions and 6 deletions

View File

@@ -152,6 +152,12 @@ predicate trivialConversion(ExpectedType expected, Type actual) {
*/
int sizeof_IntType() { exists(IntType it | result = it.getSize()) }
predicate buildModeNoneIntLongConversion(IntType formatType, LongType argumentType) {
exists(formatType) and
exists(argumentType) and
exists(Compilation c | c.buildModeNone())
}
from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual
where
(
@@ -171,7 +177,8 @@ where
not arg.isAffectedByMacro() and
not arg.isFromUninstantiatedTemplate(_) and
not actual.stripType() instanceof ErroneousType and
not arg.(Call).mayBeFromImplicitlyDeclaredFunction()
not arg.(Call).mayBeFromImplicitlyDeclaredFunction() and
not buildModeNoneIntLongConversion(expected, actual.getUnspecifiedType())
select arg,
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
actual.getUnspecifiedType().getName() + "'."

View File

@@ -1,8 +1,4 @@
| tests.c:7:18:7:18 | 1 | This format specifier for type 'char *' does not match the argument type 'int'. |
| tests.c:12:27:12:29 | 42 | This format specifier for type 'int' does not match the argument type 'long'. |
| tests.c:12:32:12:35 | 42 | This format specifier for type 'int' does not match the argument type 'unsigned long'. |
| tests.c:12:38:12:40 | 42 | This format specifier for type 'unsigned int' does not match the argument type 'long'. |
| tests.c:12:43:12:46 | 42 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long'. |
| tests.c:13:27:13:30 | 42 | This format specifier for type 'int' does not match the argument type 'long long'. |
| tests.c:13:33:13:37 | 42 | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
| tests.c:13:40:13:43 | 42 | This format specifier for type 'unsigned int' does not match the argument type 'long long'. |

View File

@@ -9,7 +9,7 @@ void f(UNKNOWN_CHAR * str) {
sprintf(0, "%s", ""); // GOOD
fprintf(0, "%s", ""); // GOOD
printf("%s", str); // GOOD: erroneous type is ignored
printf("%d %d %u %u", 42l, 42ul, 42l, 42ul); // BAD (FP)
printf("%d %d %u %u", 42l, 42ul, 42l, 42ul); // GOOD: build mode none
printf("%d %d %u %u", 42ll, 42ull, 42ll, 42ull); // BAD
printf("%ld %ld %lu %lu", 42, 42u, 42, 42u); // BAD
}