Skip to content

Commit 44de127

Browse files
committed
C++: Extend and improve the testcases for cpp/detect-and-handle-memory-allocation-errors.
1 parent d288b92 commit 44de127

File tree

2 files changed

+134
-90
lines changed

2 files changed

+134
-90
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
| test.cpp:30:15:30:26 | call to operator new[] | memory allocation error check is incorrect or missing |
2-
| test.cpp:38:9:38:20 | call to operator new[] | memory allocation error check is incorrect or missing |
3-
| test.cpp:50:13:50:38 | call to operator new[] | memory allocation error check is incorrect or missing |
4-
| test.cpp:51:22:51:47 | call to operator new[] | memory allocation error check is incorrect or missing |
5-
| test.cpp:53:18:53:43 | call to operator new[] | memory allocation error check is incorrect or missing |
1+
| test.cpp:29:13:29:24 | call to operator new[] | memory allocation error check is incorrect or missing |
2+
| test.cpp:37:13:37:24 | call to operator new[] | memory allocation error check is incorrect or missing |
3+
| test.cpp:41:13:41:24 | call to operator new[] | memory allocation error check is incorrect or missing |
4+
| test.cpp:49:8:49:19 | call to operator new[] | memory allocation error check is incorrect or missing |
5+
| test.cpp:58:8:58:19 | call to operator new[] | memory allocation error check is incorrect or missing |
6+
| test.cpp:63:8:63:19 | call to operator new[] | memory allocation error check is incorrect or missing |
7+
| test.cpp:92:5:92:31 | call to operator new[] | memory allocation error check is incorrect or missing |
8+
| test.cpp:93:15:93:41 | call to operator new[] | memory allocation error check is incorrect or missing |
9+
| test.cpp:96:10:96:36 | call to operator new[] | memory allocation error check is incorrect or missing |
Lines changed: 125 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,137 @@
1-
#define NULL ((void*)0)
1+
#define NULL ((void *)0)
2+
3+
namespace std {
4+
struct nothrow_t {};
5+
typedef unsigned long size_t;
6+
27
class exception {};
8+
class bad_alloc : public exception {};
39

4-
namespace std{
5-
struct nothrow_t {};
6-
typedef unsigned long size_t;
7-
class bad_alloc{
8-
const char* what() const throw();
9-
};
10-
extern const std::nothrow_t nothrow;
11-
}
10+
extern const std::nothrow_t nothrow;
11+
} // namespace std
1212

1313
using namespace std;
1414

15-
void* operator new(std::size_t _Size);
16-
void* operator new[](std::size_t _Size);
17-
void* operator new( std::size_t count, const std::nothrow_t& tag ) noexcept;
18-
void* operator new[]( std::size_t count, const std::nothrow_t& tag ) noexcept;
19-
20-
void badNew_0_0()
21-
{
22-
while (true) {
23-
new int[100]; // BAD [NOT DETECTED]
24-
if(!(new int[100])) // BAD [NOT DETECTED]
25-
return;
26-
}
27-
}
28-
void badNew_0_1()
29-
{
30-
int * i = new int[100]; // BAD
31-
if(i == 0)
32-
return;
33-
if(!i)
34-
return;
35-
if(i == NULL)
36-
return;
37-
int * j;
38-
j = new int[100]; // BAD
39-
if(j == 0)
40-
return;
41-
if(!j)
42-
return;
43-
if(j == NULL)
44-
return;
15+
void *operator new(std::size_t);
16+
void *operator new[](std::size_t);
17+
void *operator new(std::size_t, const std::nothrow_t &) noexcept;
18+
void *operator new[](std::size_t, const std::nothrow_t &) noexcept;
19+
20+
void bad_new_in_condition() {
21+
if (!(new int)) { // BAD [NOT DETECTED]
22+
return;
23+
}
4524
}
46-
void badNew_1_0()
47-
{
48-
try {
49-
while (true) {
50-
new(std::nothrow) int[100]; // BAD
51-
int* p = new(std::nothrow) int[100]; // BAD
52-
int* p1;
53-
p1 = new(std::nothrow) int[100]; // BAD
54-
}
55-
} catch (const exception &){//const std::bad_alloc& e) {
56-
// std::cout << e.what() << '\n';
57-
}
25+
26+
void foo(int**);
27+
28+
void bad_new_missing_exception_handling() {
29+
int *p1 = new int[100]; // BAD
30+
if (p1 == 0)
31+
return;
32+
33+
int *p2 = new int[100]; // BAD [NOT DETECTED]
34+
if (!p2)
35+
return;
36+
37+
int *p3 = new int[100]; // BAD
38+
if (p3 == NULL)
39+
return;
40+
41+
int *p4 = new int[100]; // BAD
42+
if (p4 == nullptr)
43+
return;
44+
45+
int *p5 = new int[100]; // BAD [NOT DETECTED]
46+
if (p5) {} else return;
47+
48+
int *p6;
49+
p6 = new int[100]; // BAD
50+
if (p6 == 0) return;
51+
52+
int *p7;
53+
p7 = new int[100]; // BAD [NOT DETECTED]
54+
if (!p7)
55+
return;
56+
57+
int *p8;
58+
p8 = new int[100]; // BAD
59+
if (p8 == NULL)
60+
return;
61+
62+
int *p9;
63+
p9 = new int[100]; // BAD
64+
if (p9 != nullptr) {
65+
} else
66+
return;
67+
68+
int *p10;
69+
p10 = new int[100]; // BAD [NOT DETECTED]
70+
if (p10 != 0) {
71+
}
72+
73+
int *p11;
74+
do {
75+
p11 = new int[100]; // BAD [NOT DETECTED]
76+
} while (!p11);
77+
78+
int* p12 = new int[100];
79+
foo(&p12);
80+
if(p12) {} else return; // GOOD: p12 is probably modified in foo, so it's
81+
// not the return value of the new that's checked.
82+
83+
int* p13 = new int[100];
84+
foo(&p13);
85+
if(!p13) {
86+
return;
87+
} else { }; // GOOD: same as above.
5888
}
59-
void badNew_1_1()
60-
{
61-
while (true) {
62-
int* p = new(std::nothrow) int[100]; // BAD [NOT DETECTED]
63-
new(std::nothrow) int[100]; // BAD [NOT DETECTED]
64-
}
89+
90+
void bad_new_nothrow_in_exception_body() {
91+
try {
92+
new (std::nothrow) int[100]; // BAD
93+
int *p1 = new (std::nothrow) int[100]; // BAD
94+
95+
int *p2;
96+
p2 = new (std::nothrow) int[100]; // BAD
97+
} catch (const std::bad_alloc &) {
98+
}
6599
}
66100

67-
void goodNew_0_0()
68-
{
69-
try {
70-
while (true) {
71-
new int[100]; // GOOD
72-
}
73-
} catch (const exception &){//const std::bad_alloc& e) {
74-
// std::cout << e.what() << '\n';
75-
}
101+
void good_new_has_exception_handling() {
102+
try {
103+
int *p1 = new int[100]; // GOOD
104+
} catch (...) {
105+
}
76106
}
77107

78-
void goodNew_1_0()
79-
{
80-
while (true) {
81-
int* p = new(std::nothrow) int[100]; // GOOD
82-
if (p == nullptr) {
83-
// std::cout << "Allocation returned nullptr\n";
84-
break;
85-
}
86-
int* p1;
87-
p1 = new(std::nothrow) int[100]; // GOOD
88-
if (p1 == nullptr) {
89-
// std::cout << "Allocation returned nullptr\n";
90-
break;
91-
}
92-
if (new(std::nothrow) int[100] == nullptr) { // GOOD
93-
// std::cout << "Allocation returned nullptr\n";
94-
break;
95-
}
96-
}
108+
void good_new_handles_nullptr() {
109+
int *p1 = new (std::nothrow) int[100]; // GOOD
110+
if (p1 == nullptr)
111+
return;
112+
113+
int *p2;
114+
p2 = new (std::nothrow) int[100]; // GOOD
115+
if (p2 == nullptr)
116+
return;
117+
118+
int *p3;
119+
p3 = new (std::nothrow) int[100]; // GOOD
120+
if (p3 != nullptr) {
121+
}
122+
123+
int *p4;
124+
p4 = new (std::nothrow) int[100]; // GOOD
125+
if (p4) {
126+
} else
127+
return;
128+
129+
int *p5;
130+
p5 = new (std::nothrow) int[100]; // GOOD
131+
if (p5 != nullptr) {
132+
} else
133+
return;
134+
135+
if (new (std::nothrow) int[100] == nullptr)
136+
return; // GOOD
97137
}

0 commit comments

Comments
 (0)