Compare commits

...

2 Commits

Author SHA1 Message Date
Calum Grant
9b53a390c0 C++: Remove potential FPs in cpp/wrong-type-format-argument in BMN 2025-01-23 19:22:10 +00:00
Calum Grant
231e3c2949 C++: Tests for cpp/wrong-type-format-argument 2025-01-23 17:12:39 +00:00
3 changed files with 22 additions and 4 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 +1,9 @@
| tests.c:7:18:7:18 | 1 | This format specifier for type 'char *' does not match the argument type 'int'. |
| 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'. |
| tests.c:13:46:13:50 | 42 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| tests.c:14:31:14:32 | 42 | This format specifier for type 'long' does not match the argument type 'int'. |
| tests.c:14:35:14:37 | 42 | This format specifier for type 'long' does not match the argument type 'unsigned int'. |
| tests.c:14:40:14:41 | 42 | This format specifier for type 'unsigned long' does not match the argument type 'int'. |
| tests.c:14:44:14:46 | 42 | This format specifier for type 'unsigned long' does not match the argument type 'unsigned int'. |

View File

@@ -1,12 +1,15 @@
// semmle-extractor-options: --expect_errors
// semmle-extractor-options: --expect_errors --build-mode none
int printf(const char * format, ...);
int fprintf();
void f(UNKNOWN_CHAR * str) {
printf("%s", 1); // BAD
printf("%s", implicit_function()); // GOOD - we should ignore the type
printf("%s", implicit_function()); // GOOD: we should ignore the type
sprintf(0, "%s", ""); // GOOD
fprintf(0, "%s", ""); // GOOD
printf("%s", str); // GOOD - erroneous type is ignored
printf("%s", str); // GOOD: erroneous type is ignored
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
}