Merge pull request #16939 from geoffw0/docsforautofix

C++: Assorted minor doc improvements
This commit is contained in:
Mathias Vorreiter Pedersen
2024-07-11 18:30:45 +01:00
committed by GitHub
22 changed files with 330 additions and 209 deletions

View File

@@ -172,5 +172,5 @@ where
not arg.isFromUninstantiatedTemplate(_) and
not actual.getUnspecifiedType() instanceof ErroneousType
select arg,
"This argument should be of type '" + expected.getName() + "' but is of type '" +
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
actual.getUnspecifiedType().getName() + "'."

View File

@@ -1,7 +0,0 @@
Record* fixRecord(Record* r) {
Record myRecord = *r;
delete r;
myRecord.fix();
return &myRecord; //returns reference to myRecord, which is a stack-allocated object
}

View File

@@ -5,22 +5,23 @@
<overview>
<p>This rule finds return statements that return pointers to an object allocated on the stack.
The lifetime of a stack allocated memory location only lasts until the function returns, and
the contents of that memory become undefined after that. Clearly, using a pointer to stack
<p>This rule finds return statements that return pointers to an object allocated on the stack.
The lifetime of a stack allocated memory location only lasts until the function returns, and
the contents of that memory become undefined after that. Clearly, using a pointer to stack
memory after the function has already returned will have undefined results. </p>
</overview>
<recommendation>
<p>Use the functions of the <tt>malloc</tt> family to dynamically allocate memory on the heap for data that is used across function calls.</p>
<p>Use the functions of the <tt>malloc</tt> family, or <tt>new</tt>, to dynamically allocate memory on the heap for data that is used across function calls.</p>
</recommendation>
<example><sample src="ReturnStackAllocatedMemory.cpp" />
<example>
<p>The following example allocates an object on the stack and returns a pointer to it. This is incorrect because the object is deallocated
when the function returns, and the pointer becomes invalid.</p>
<sample src="ReturnStackAllocatedMemoryBad.cpp" />
<p>To fix this, allocate the object on the heap using <tt>new</tt> and return a pointer to the heap-allocated object.</p>
<sample src="ReturnStackAllocatedMemoryGood.cpp" />
</example>
<references>

View File

@@ -0,0 +1,5 @@
Record *mkRecord(int value) {
Record myRecord(value);
return &myRecord; // BAD: returns a pointer to `myRecord`, which is a stack-allocated object.
}

View File

@@ -0,0 +1,5 @@
Record *mkRecord(int value) {
Record *myRecord = new Record(value);
return myRecord; // GOOD: returns a pointer to a `myRecord`, which is a heap-allocated object.
}

View File

@@ -1,5 +1,14 @@
unsigned limit = get_limit();
unsigned total = 0;
while (limit - total > 0) { // wrong: if `total` is greater than `limit` this will underflow and continue executing the loop.
uint32_t limit = get_limit();
uint32_t total = 0;
while (limit - total > 0) { // BAD: if `total` is greater than `limit` this will underflow and continue executing the loop.
total += get_data();
}
}
while (total < limit) { // GOOD: never underflows here because there is no arithmetic.
total += get_data();
}
while ((int64_t)limit - total > 0) { // GOOD: never underflows here because the result always fits in an `int64_t`.
total += get_data();
}

View File

@@ -1,15 +1,17 @@
char *file_name;
FILE *f_ptr;
/* Initialize file_name */
f_ptr = fopen(file_name, "w");
if (f_ptr == NULL) {
/* Handle error */
}
/* ... */
if (chmod(file_name, S_IRUSR) == -1) {
/* Handle error */
}
}
fclose(f_ptr);

View File

@@ -1,8 +1,8 @@
char *file_name;
int fd;
/* Initialize file_name */
fd = open(
file_name,
O_WRONLY | O_CREAT | O_EXCL,
@@ -11,9 +11,11 @@ fd = open(
if (fd == -1) {
/* Handle error */
}
/* ... */
if (fchmod(fd, S_IRUSR) == -1) {
/* Handle error */
}
}
close(fd);

View File

@@ -34,7 +34,7 @@ void good1(std::size_t length) noexcept {
// GOOD: the allocation failure is handled appropriately.
void good2(std::size_t length) noexcept {
int* dest = new int[length];
int* dest = new(std::nothrow) int[length];
if(!dest) {
return;
}

View File

@@ -1,11 +1,38 @@
void write_default_config_bad() {
// BAD - this is world-writable so any user can overwrite the config
int out = creat(OUTFILE, 0666);
dprintf(out, DEFAULT_CONFIG);
if (out < 0) {
// handle error
}
dprintf(out, "%s", DEFAULT_CONFIG);
close(out);
}
void write_default_config_good() {
// GOOD - this allows only the current user to modify the file
int out = creat(OUTFILE, S_IWUSR | S_IRUSR);
dprintf(out, DEFAULT_CONFIG);
if (out < 0) {
// handle error
}
dprintf(out, "%s", DEFAULT_CONFIG);
close(out);
}
void write_default_config_good_2() {
// GOOD - this allows only the current user to modify the file
int out = open(OUTFILE, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
if (out < 0) {
// handle error
}
FILE *fd = fdopen(out, "w");
if (fd == NULL) {
close(out);
// handle error
}
fprintf(fd, "%s", DEFAULT_CONFIG);
fclose(fd);
}

View File

@@ -29,10 +29,11 @@ so it is important that they cannot be controlled by an attacker.
</p>
<p>
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
file world-writable, so that an attacker could write in their own configuration that would be read by the program. The second example uses
more restrictive permissions: a combination of the standard Unix constants <code>S_IWUSR</code> and <code>S_IRUSR</code> which means that
only the current user will have read and write access to the file.
only the current user will have read and write access to the file. The third example shows another way to create a file with more restrictive
permissions if a <code>FILE *</code> stream pointer is required rather than a file descriptor.
</p>
<sample src="DoNotCreateWorldWritable.c" />

View File

@@ -1,12 +1,12 @@
| tests.cpp:18:15:18:22 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
| tests.cpp:19:15:19:22 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'char16_t *' but is of type 'char *'. |
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *'. |
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *'. |
| tests.cpp:35:36:35:43 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
| tests.cpp:39:36:39:43 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
| tests.cpp:42:37:42:44 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
| tests.cpp:43:37:43:44 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
| tests.cpp:45:37:45:43 | Hello | This argument should be of type 'char16_t *' but is of type 'char *'. |
| tests.cpp:47:37:47:44 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
| tests.cpp:18:15:18:22 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
| tests.cpp:19:15:19:22 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char *'. |
| tests.cpp:26:17:26:24 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
| tests.cpp:30:17:30:24 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char16_t *'. |
| tests.cpp:35:36:35:43 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
| tests.cpp:39:36:39:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
| tests.cpp:42:37:42:44 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
| tests.cpp:43:37:43:44 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
| tests.cpp:45:37:45:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
| tests.cpp:47:37:47:44 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |

View File

@@ -1,4 +1,4 @@
| tests_32.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *'. |
| tests_32.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long'. |
| tests_64.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *'. |
| tests_64.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long'. |
| tests_32.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
| tests_32.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |
| tests_64.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
| tests_64.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |

View File

@@ -1,62 +1,62 @@
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
| linux.cpp:15:24:15:41 | call to get_template_value | This argument should be of type 'int' but is of type 'long'. |
| linux_c.c:11:15:11:18 | str3 | This argument should be of type 'char *' but is of type 'short *'. |
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:113:17:113:17 | d | This argument should be of type 'long double' but is of type 'double'. |
| printf1.h:114:18:114:18 | d | This argument should be of type 'long double' but is of type 'double'. |
| printf1.h:147:19:147:19 | i | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:148:19:148:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| printf1.h:160:18:160:18 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:161:21:161:21 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:167:17:167:17 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:168:18:168:18 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:169:19:169:19 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:174:17:174:17 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:175:18:175:18 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:176:19:176:19 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:180:17:180:17 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:181:20:181:20 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:183:18:183:18 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:184:21:184:21 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:186:19:186:19 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:187:22:187:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:189:19:189:19 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:190:22:190:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:192:19:192:19 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:193:22:193:22 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:194:25:194:25 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:198:24:198:24 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:199:21:199:21 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:202:26:202:26 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:203:23:203:23 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:206:25:206:25 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:207:22:207:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:210:26:210:26 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:211:23:211:23 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:214:28:214:28 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:215:28:215:28 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:216:25:216:25 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:221:18:221:18 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:222:20:222:20 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:225:23:225:23 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:228:24:228:24 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:231:25:231:25 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:234:25:234:25 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:235:22:235:22 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:276:32:276:32 | s | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:278:17:278:17 | s | This argument should be of type 'int' but is of type 'char *'. |
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
| linux.cpp:15:24:15:41 | call to get_template_value | This format specifier for type 'int' does not match the argument type 'long'. |
| linux_c.c:11:15:11:18 | str3 | This format specifier for type 'char *' does not match the argument type 'short *'. |
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:113:17:113:17 | d | This format specifier for type 'long double' does not match the argument type 'double'. |
| printf1.h:114:18:114:18 | d | This format specifier for type 'long double' does not match the argument type 'double'. |
| printf1.h:147:19:147:19 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:148:19:148:20 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| printf1.h:160:18:160:18 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:161:21:161:21 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:167:17:167:17 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:168:18:168:18 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:169:19:169:19 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:174:17:174:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:175:18:175:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:176:19:176:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:180:17:180:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:181:20:181:20 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:183:18:183:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:184:21:184:21 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:186:19:186:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:187:22:187:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:189:19:189:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:190:22:190:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:192:19:192:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:193:22:193:22 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:194:25:194:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:198:24:198:24 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:199:21:199:21 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:202:26:202:26 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:203:23:203:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:206:25:206:25 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:207:22:207:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:210:26:210:26 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:211:23:211:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:214:28:214:28 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:215:28:215:28 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:216:25:216:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:221:18:221:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:222:20:222:20 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:225:23:225:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:228:24:228:24 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:231:25:231:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:234:25:234:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:235:22:235:22 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:276:32:276:32 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:278:17:278:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |

View File

@@ -1,2 +1,2 @@
| printf.cpp:43:29:43:35 | test | This argument should be of type 'char *' but is of type 'char16_t *'. |
| printf.cpp:50:29:50:35 | test | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
| printf.cpp:43:29:43:35 | test | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
| printf.cpp:50:29:50:35 | test | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |

View File

@@ -1,20 +1,20 @@
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:168:19:168:19 | i | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:169:19:169:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:168:19:168:19 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:169:19:169:20 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |

View File

@@ -1,37 +1,37 @@
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:74:19:74:22 | C_ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:75:19:75:28 | sizeof(<expr>) | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:84:23:84:35 | ... - ... | This argument should be of type 'ssize_t' but is of type 'long long'. |
| printf1.h:116:16:116:24 | myString3 | This argument should be of type '__wchar_t *' but is of type 'int *'. |
| printf1.h:117:16:117:24 | myString4 | This argument should be of type '__wchar_t *' but is of type 'int *'. |
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:181:21:181:22 | ll | This argument should be of type 'int' but is of type 'long long'. |
| printf1.h:182:21:182:23 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:185:21:185:23 | i64 | This argument should be of type 'int' but is of type 'long long'. |
| printf1.h:186:21:186:23 | u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:188:21:188:21 | i | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:189:21:189:22 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| printf1.h:190:21:190:21 | l | This argument should be of type 'long long' but is of type 'long'. |
| printf1.h:191:21:191:22 | ul | This argument should be of type 'unsigned long long' but is of type 'unsigned long'. |
| printf1.h:194:21:194:23 | i32 | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:195:21:195:23 | u32 | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
| wide_string.h:29:19:29:22 | c | This argument should be of type 'wchar_t' but is of type '__wchar_t *'. |
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:71:19:71:20 | st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:72:19:72:20 | ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:73:19:73:22 | c_st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:74:19:74:22 | C_ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:75:19:75:28 | sizeof(<expr>) | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:84:23:84:35 | ... - ... | This format specifier for type 'ssize_t' does not match the argument type 'long long'. |
| printf1.h:116:16:116:24 | myString3 | This format specifier for type '__wchar_t *' does not match the argument type 'int *'. |
| printf1.h:117:16:117:24 | myString4 | This format specifier for type '__wchar_t *' does not match the argument type 'int *'. |
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:181:21:181:22 | ll | This format specifier for type 'int' does not match the argument type 'long long'. |
| printf1.h:182:21:182:23 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:185:21:185:23 | i64 | This format specifier for type 'int' does not match the argument type 'long long'. |
| printf1.h:186:21:186:23 | u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:188:21:188:21 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:189:21:189:22 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| printf1.h:190:21:190:21 | l | This format specifier for type 'long long' does not match the argument type 'long'. |
| printf1.h:191:21:191:22 | ul | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned long'. |
| printf1.h:194:21:194:23 | i32 | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:195:21:195:23 | u32 | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
| wide_string.h:29:19:29:22 | c | This format specifier for type 'wchar_t' does not match the argument type '__wchar_t *'. |

View File

@@ -1,35 +1,35 @@
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:74:19:74:22 | C_ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:75:19:75:28 | sizeof(<expr>) | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
| printf1.h:84:23:84:35 | ... - ... | This argument should be of type 'ssize_t' but is of type 'long long'. |
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
| printf1.h:155:21:155:22 | ll | This argument should be of type 'int' but is of type 'long long'. |
| printf1.h:156:21:156:23 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:159:21:159:23 | i64 | This argument should be of type 'int' but is of type 'long long'. |
| printf1.h:160:21:160:23 | u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
| printf1.h:162:21:162:21 | i | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:163:21:163:22 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| printf1.h:164:21:164:21 | l | This argument should be of type 'long long' but is of type 'long'. |
| printf1.h:165:21:165:22 | ul | This argument should be of type 'unsigned long long' but is of type 'unsigned long'. |
| printf1.h:168:21:168:23 | i32 | This argument should be of type 'long long' but is of type 'int'. |
| printf1.h:169:21:169:23 | u32 | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
| wide_string.h:29:19:29:22 | c | This argument should be of type 'wchar_t' but is of type 'unsigned short *'. |
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:71:19:71:20 | st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:72:19:72:20 | ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:73:19:73:22 | c_st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:74:19:74:22 | C_ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:75:19:75:28 | sizeof(<expr>) | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
| printf1.h:84:23:84:35 | ... - ... | This format specifier for type 'ssize_t' does not match the argument type 'long long'. |
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
| printf1.h:155:21:155:22 | ll | This format specifier for type 'int' does not match the argument type 'long long'. |
| printf1.h:156:21:156:23 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:159:21:159:23 | i64 | This format specifier for type 'int' does not match the argument type 'long long'. |
| printf1.h:160:21:160:23 | u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
| printf1.h:162:21:162:21 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:163:21:163:22 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| printf1.h:164:21:164:21 | l | This format specifier for type 'long long' does not match the argument type 'long'. |
| printf1.h:165:21:165:22 | ul | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned long'. |
| printf1.h:168:21:168:23 | i32 | This format specifier for type 'long long' does not match the argument type 'int'. |
| printf1.h:169:21:169:23 | u32 | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
| wide_string.h:29:19:29:22 | c | This format specifier for type 'wchar_t' does not match the argument type 'unsigned short *'. |

View File

@@ -13,3 +13,4 @@
| test.cpp:266:10:266:24 | ... > ... | Unsigned subtraction can never be negative. |
| test.cpp:276:11:276:19 | ... > ... | Unsigned subtraction can never be negative. |
| test.cpp:288:10:288:18 | ... > ... | Unsigned subtraction can never be negative. |
| test.cpp:312:9:312:25 | ... > ... | Unsigned subtraction can never be negative. |

View File

@@ -43,7 +43,7 @@ void test(unsigned x, unsigned y, bool unknown) {
while(cond()) {
if(unknown) { y--; }
}
if(x - y > 0) { } // GOOD
x = y;
@@ -298,3 +298,26 @@ int test18() {
return (a - b > 0); // GOOD (as b = 0)
}
typedef unsigned int uint32_t;
typedef long long int64_t;
uint32_t get_limit();
uint32_t get_data();
void test19() {
// from the doc:
uint32_t limit = get_limit();
uint32_t total = 0;
while (limit - total > 0) { // BAD: if `total` is greater than `limit` this will underflow and continue executing the loop.
total += get_data();
}
while (total < limit) { // GOOD: never underflows here because there is no arithmetic.
total += get_data();
}
while ((int64_t)limit - total > 0) { // GOOD: never underflows here because the result always fits in an `int64_t`.
total += get_data();
}
}

View File

@@ -16,3 +16,4 @@
| test.cpp:151:9:151:24 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:152:15:152:18 | { ... } | This catch block |
| test.cpp:199:15:199:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:201:16:201:19 | { ... } | This catch block |
| test.cpp:212:14:212:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:213:34:213:36 | { ... } | This catch block |
| test.cpp:246:17:246:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:247:8:247:12 | ! ... | This check |

View File

@@ -233,3 +233,54 @@ void test_operator_new_without_exception_spec() {
int* p = new(42, std::nothrow) int; // GOOD
if(p == nullptr) {}
}
namespace std {
void *memset(void *s, int c, size_t n);
}
// from the qhelp:
namespace qhelp {
// BAD: the allocation will throw an unhandled exception
// instead of returning a null pointer.
void bad1(std::size_t length) noexcept {
int* dest = new int[length];
if(!dest) {
return;
}
std::memset(dest, 0, length);
// ...
}
// BAD: the allocation won't throw an exception, but
// instead return a null pointer. [NOT DETECTED]
void bad2(std::size_t length) noexcept {
try {
int* dest = new(std::nothrow) int[length];
std::memset(dest, 0, length);
// ...
} catch(std::bad_alloc&) {
// ...
}
}
// GOOD: the allocation failure is handled appropriately.
void good1(std::size_t length) noexcept {
try {
int* dest = new int[length];
std::memset(dest, 0, length);
// ...
} catch(std::bad_alloc&) {
// ...
}
}
// GOOD: the allocation failure is handled appropriately.
void good2(std::size_t length) noexcept {
int* dest = new(std::nothrow) int[length];
if(!dest) {
return;
}
std::memset(dest, 0, length);
// ...
}
}