mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
QL code and tests for C#/C++/JavaScript.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
| tst.c:1:12:1:18 | // lgtm | lgtm | lgtm | tst.c:1:1:1:18 | suppression range |
|
||||
| tst.c:2:1:2:30 | // lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tst.c:2:1:2:30 | suppression range |
|
||||
| tst.c:3:1:3:61 | // lgtm[js/debugger-statement, js/invocation-of-non-function] | lgtm[js/debugger-statement, js/invocation-of-non-function] | lgtm[js/debugger-statement, js/invocation-of-non-function] | tst.c:3:1:3:61 | suppression range |
|
||||
| tst.c:4:1:4:22 | // lgtm[@tag:nullness] | lgtm[@tag:nullness] | lgtm[@tag:nullness] | tst.c:4:1:4:22 | suppression range |
|
||||
| tst.c:5:1:5:44 | // lgtm[@tag:nullness,js/debugger-statement] | lgtm[@tag:nullness,js/debugger-statement] | lgtm[@tag:nullness,js/debugger-statement] | tst.c:5:1:5:44 | suppression range |
|
||||
| tst.c:6:1:6:28 | // lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | tst.c:6:1:6:28 | suppression range |
|
||||
| tst.c:7:1:7:70 | // lgtm[js/invocation-of-non-function] because I know better than lgtm | lgtm[js/invocation-of-non-function] because I know better than lgtm | lgtm[js/invocation-of-non-function] | tst.c:7:1:7:70 | suppression range |
|
||||
| tst.c:8:1:8:18 | // lgtm: blah blah | lgtm: blah blah | lgtm | tst.c:8:1:8:18 | suppression range |
|
||||
| tst.c:9:1:9:32 | // lgtm blah blah #falsepositive | lgtm blah blah #falsepositive | lgtm | tst.c:9:1:9:32 | suppression range |
|
||||
| tst.c:10:1:10:39 | //lgtm [js/invocation-of-non-function] | lgtm [js/invocation-of-non-function] | lgtm [js/invocation-of-non-function] | tst.c:10:1:10:39 | suppression range |
|
||||
| tst.c:12:1:12:9 | // lgtm[] | lgtm[] | lgtm[] | tst.c:12:1:12:9 | suppression range |
|
||||
| tst.c:14:1:14:6 | //lgtm | lgtm | lgtm | tst.c:14:1:14:6 | suppression range |
|
||||
| tst.c:15:1:15:7 | //\tlgtm | \tlgtm | lgtm | tst.c:15:1:15:7 | suppression range |
|
||||
| tst.c:16:1:16:31 | // lgtm\t[js/debugger-statement] | lgtm\t[js/debugger-statement] | lgtm\t[js/debugger-statement] | tst.c:16:1:16:31 | suppression range |
|
||||
| tst.c:19:1:19:12 | // foo; lgtm | foo; lgtm | lgtm | tst.c:19:1:19:12 | suppression range |
|
||||
| tst.c:20:1:20:35 | // foo; lgtm[js/debugger-statement] | foo; lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tst.c:20:1:20:35 | suppression range |
|
||||
| tst.c:22:1:22:34 | // foo lgtm[js/debugger-statement] | foo lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tst.c:22:1:22:34 | suppression range |
|
||||
| tst.c:24:1:24:38 | // foo lgtm[js/debugger-statement] bar | foo lgtm[js/debugger-statement] bar | lgtm[js/debugger-statement] | tst.c:24:1:24:38 | suppression range |
|
||||
| tst.c:25:1:25:8 | // LGTM! | LGTM! | LGTM | tst.c:25:1:25:8 | suppression range |
|
||||
| tst.c:26:1:26:30 | // LGTM[js/debugger-statement] | LGTM[js/debugger-statement] | LGTM[js/debugger-statement] | tst.c:26:1:26:30 | suppression range |
|
||||
| tst.c:27:1:27:70 | // lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] | tst.c:27:1:27:70 | suppression range |
|
||||
| tst.c:27:1:27:70 | // lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/invocation-of-non-function] | tst.c:27:1:27:70 | suppression range |
|
||||
| tst.c:28:1:28:36 | // lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement]; lgtm | lgtm | tst.c:28:1:28:36 | suppression range |
|
||||
| tst.c:28:1:28:36 | // lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement] | tst.c:28:1:28:36 | suppression range |
|
||||
| tstWindows.c:1:12:1:18 | // lgtm | lgtm | lgtm | tstWindows.c:1:1:1:18 | suppression range |
|
||||
| tstWindows.c:2:1:2:30 | // lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tstWindows.c:2:1:2:30 | suppression range |
|
||||
| tstWindows.c:3:1:3:61 | // lgtm[js/debugger-statement, js/invocation-of-non-function] | lgtm[js/debugger-statement, js/invocation-of-non-function] | lgtm[js/debugger-statement, js/invocation-of-non-function] | tstWindows.c:3:1:3:61 | suppression range |
|
||||
| tstWindows.c:4:1:4:22 | // lgtm[@tag:nullness] | lgtm[@tag:nullness] | lgtm[@tag:nullness] | tstWindows.c:4:1:4:22 | suppression range |
|
||||
| tstWindows.c:5:1:5:44 | // lgtm[@tag:nullness,js/debugger-statement] | lgtm[@tag:nullness,js/debugger-statement] | lgtm[@tag:nullness,js/debugger-statement] | tstWindows.c:5:1:5:44 | suppression range |
|
||||
| tstWindows.c:6:1:6:28 | // lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | tstWindows.c:6:1:6:28 | suppression range |
|
||||
| tstWindows.c:7:1:7:70 | // lgtm[js/invocation-of-non-function] because I know better than lgtm | lgtm[js/invocation-of-non-function] because I know better than lgtm | lgtm[js/invocation-of-non-function] | tstWindows.c:7:1:7:70 | suppression range |
|
||||
| tstWindows.c:8:1:8:18 | // lgtm: blah blah | lgtm: blah blah | lgtm | tstWindows.c:8:1:8:18 | suppression range |
|
||||
| tstWindows.c:9:1:9:32 | // lgtm blah blah #falsepositive | lgtm blah blah #falsepositive | lgtm | tstWindows.c:9:1:9:32 | suppression range |
|
||||
| tstWindows.c:10:1:10:39 | //lgtm [js/invocation-of-non-function] | lgtm [js/invocation-of-non-function] | lgtm [js/invocation-of-non-function] | tstWindows.c:10:1:10:39 | suppression range |
|
||||
| tstWindows.c:12:1:12:9 | // lgtm[] | lgtm[] | lgtm[] | tstWindows.c:12:1:12:9 | suppression range |
|
||||
| tstWindows.c:14:1:14:6 | //lgtm | lgtm | lgtm | tstWindows.c:14:1:14:6 | suppression range |
|
||||
| tstWindows.c:15:1:15:7 | //\tlgtm | \tlgtm | lgtm | tstWindows.c:15:1:15:7 | suppression range |
|
||||
| tstWindows.c:16:1:16:31 | // lgtm\t[js/debugger-statement] | lgtm\t[js/debugger-statement] | lgtm\t[js/debugger-statement] | tstWindows.c:16:1:16:31 | suppression range |
|
||||
| tstWindows.c:19:1:19:12 | // foo; lgtm | foo; lgtm | lgtm | tstWindows.c:19:1:19:12 | suppression range |
|
||||
| tstWindows.c:20:1:20:35 | // foo; lgtm[js/debugger-statement] | foo; lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tstWindows.c:20:1:20:35 | suppression range |
|
||||
| tstWindows.c:22:1:22:34 | // foo lgtm[js/debugger-statement] | foo lgtm[js/debugger-statement] | lgtm[js/debugger-statement] | tstWindows.c:22:1:22:34 | suppression range |
|
||||
| tstWindows.c:24:1:24:38 | // foo lgtm[js/debugger-statement] bar | foo lgtm[js/debugger-statement] bar | lgtm[js/debugger-statement] | tstWindows.c:24:1:24:38 | suppression range |
|
||||
| tstWindows.c:25:1:25:8 | // LGTM! | LGTM! | LGTM | tstWindows.c:25:1:25:8 | suppression range |
|
||||
| tstWindows.c:26:1:26:30 | // LGTM[js/debugger-statement] | LGTM[js/debugger-statement] | LGTM[js/debugger-statement] | tstWindows.c:26:1:26:30 | suppression range |
|
||||
| tstWindows.c:27:1:27:70 | // lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] | tstWindows.c:27:1:27:70 | suppression range |
|
||||
| tstWindows.c:27:1:27:70 | // lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function] | lgtm[js/invocation-of-non-function] | tstWindows.c:27:1:27:70 | suppression range |
|
||||
| tstWindows.c:28:1:28:36 | // lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement]; lgtm | lgtm | tstWindows.c:28:1:28:36 | suppression range |
|
||||
| tstWindows.c:28:1:28:36 | // lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement]; lgtm | lgtm[js/debugger-statement] | tstWindows.c:28:1:28:36 | suppression range |
|
||||
@@ -0,0 +1 @@
|
||||
AlertSuppression.ql
|
||||
28
cpp/ql/test/query-tests/AlertSuppression/tst.c
Normal file
28
cpp/ql/test/query-tests/AlertSuppression/tst.c
Normal file
@@ -0,0 +1,28 @@
|
||||
int x = 0; // lgtm
|
||||
// lgtm[js/debugger-statement]
|
||||
// lgtm[js/debugger-statement, js/invocation-of-non-function]
|
||||
// lgtm[@tag:nullness]
|
||||
// lgtm[@tag:nullness,js/debugger-statement]
|
||||
// lgtm[@expires:2017-06-11]
|
||||
// lgtm[js/invocation-of-non-function] because I know better than lgtm
|
||||
// lgtm: blah blah
|
||||
// lgtm blah blah #falsepositive
|
||||
//lgtm [js/invocation-of-non-function]
|
||||
/* lgtm */
|
||||
// lgtm[]
|
||||
// lgtmfoo
|
||||
//lgtm
|
||||
// lgtm
|
||||
// lgtm [js/debugger-statement]
|
||||
// foolgtm[js/debugger-statement]
|
||||
// foolgtm
|
||||
// foo; lgtm
|
||||
// foo; lgtm[js/debugger-statement]
|
||||
// foo lgtm
|
||||
// foo lgtm[js/debugger-statement]
|
||||
// foo lgtm bar
|
||||
// foo lgtm[js/debugger-statement] bar
|
||||
// LGTM!
|
||||
// LGTM[js/debugger-statement]
|
||||
// lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function]
|
||||
// lgtm[js/debugger-statement]; lgtm
|
||||
28
cpp/ql/test/query-tests/AlertSuppression/tstWindows.c
Normal file
28
cpp/ql/test/query-tests/AlertSuppression/tstWindows.c
Normal file
@@ -0,0 +1,28 @@
|
||||
int x = 0; // lgtm
|
||||
// lgtm[js/debugger-statement]
|
||||
// lgtm[js/debugger-statement, js/invocation-of-non-function]
|
||||
// lgtm[@tag:nullness]
|
||||
// lgtm[@tag:nullness,js/debugger-statement]
|
||||
// lgtm[@expires:2017-06-11]
|
||||
// lgtm[js/invocation-of-non-function] because I know better than lgtm
|
||||
// lgtm: blah blah
|
||||
// lgtm blah blah #falsepositive
|
||||
//lgtm [js/invocation-of-non-function]
|
||||
/* lgtm */
|
||||
// lgtm[]
|
||||
// lgtmfoo
|
||||
//lgtm
|
||||
// lgtm
|
||||
// lgtm [js/debugger-statement]
|
||||
// foolgtm[js/debugger-statement]
|
||||
// foolgtm
|
||||
// foo; lgtm
|
||||
// foo; lgtm[js/debugger-statement]
|
||||
// foo lgtm
|
||||
// foo lgtm[js/debugger-statement]
|
||||
// foo lgtm bar
|
||||
// foo lgtm[js/debugger-statement] bar
|
||||
// LGTM!
|
||||
// LGTM[js/debugger-statement]
|
||||
// lgtm[js/debugger-statement] and lgtm[js/invocation-of-non-function]
|
||||
// lgtm[js/debugger-statement]; lgtm
|
||||
@@ -0,0 +1,3 @@
|
||||
| a.cpp:10:6:10:7 | f1 | Function f1 could be moved to file $@ since it has 5 dependencies to that file, but 0 dependencies to its own file. | b.cpp:0:0:0:0 | b.cpp | b.cpp |
|
||||
| a.cpp:18:6:18:7 | f2 | Function f2 could be moved to file $@ since it has 5 dependencies to that file, but only 1 dependency to its own file. | b.cpp:0:0:0:0 | b.cpp | b.cpp |
|
||||
| a.cpp:48:6:48:7 | f5 | Function f5 could be moved to file $@ since it has 5 dependencies to that file, but 0 dependencies to its own file. | b.cpp:0:0:0:0 | b.cpp | b.cpp |
|
||||
@@ -0,0 +1 @@
|
||||
Architecture/FeatureEnvy.ql
|
||||
57
cpp/ql/test/query-tests/Architecture/FeatureEnvy/a.cpp
Normal file
57
cpp/ql/test/query-tests/Architecture/FeatureEnvy/a.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
#include "b.h"
|
||||
|
||||
void local1(void) { }
|
||||
void local2(void) { }
|
||||
void local3(void) { }
|
||||
void local4(void) { }
|
||||
void local5(void) { }
|
||||
|
||||
void f1(void) {
|
||||
g();
|
||||
h();
|
||||
i();
|
||||
j();
|
||||
k();
|
||||
}
|
||||
|
||||
void f2(void) {
|
||||
local1();
|
||||
g();
|
||||
h();
|
||||
i();
|
||||
j();
|
||||
k();
|
||||
}
|
||||
|
||||
void f3(void) {
|
||||
local1();
|
||||
g();
|
||||
local2();
|
||||
h();
|
||||
local3();
|
||||
i();
|
||||
local4();
|
||||
j();
|
||||
local5();
|
||||
k();
|
||||
}
|
||||
|
||||
void f4(void) {
|
||||
local1();
|
||||
g();
|
||||
h();
|
||||
i();
|
||||
j();
|
||||
}
|
||||
|
||||
void f5(void) {
|
||||
MyClass m;
|
||||
|
||||
m.mg();
|
||||
m.mh();
|
||||
m.mi();
|
||||
m.mj();
|
||||
m.mk();
|
||||
}
|
||||
|
||||
33
cpp/ql/test/query-tests/Architecture/FeatureEnvy/b.cpp
Normal file
33
cpp/ql/test/query-tests/Architecture/FeatureEnvy/b.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
#include "b.h"
|
||||
|
||||
void g(void) {
|
||||
}
|
||||
|
||||
void h(void) {
|
||||
}
|
||||
|
||||
void i(void) {
|
||||
}
|
||||
|
||||
void j(void) {
|
||||
}
|
||||
|
||||
void k(void) {
|
||||
}
|
||||
|
||||
void MyClass::mg(void) {
|
||||
}
|
||||
|
||||
void MyClass::mh(void) {
|
||||
}
|
||||
|
||||
void MyClass::mi(void) {
|
||||
}
|
||||
|
||||
void MyClass::mj(void) {
|
||||
}
|
||||
|
||||
void MyClass::mk(void) {
|
||||
}
|
||||
|
||||
16
cpp/ql/test/query-tests/Architecture/FeatureEnvy/b.h
Normal file
16
cpp/ql/test/query-tests/Architecture/FeatureEnvy/b.h
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
void g(void);
|
||||
void h(void);
|
||||
void i(void);
|
||||
void j(void);
|
||||
void k(void);
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
void mg(void);
|
||||
void mh(void);
|
||||
void mi(void);
|
||||
void mj(void);
|
||||
void mk(void);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| a.c:0:0:0:0 | a.c | File is too closely tied to $@ (22 dependencies one way and 21 the other). | b.c:0:0:0:0 | b.c | b.c |
|
||||
| c.cpp:0:0:0:0 | c.cpp | File is too closely tied to $@ (22 dependencies one way and 21 the other). | d.cpp:0:0:0:0 | d.cpp | d.cpp |
|
||||
@@ -0,0 +1 @@
|
||||
Architecture/InappropriateIntimacy.ql
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#include "b.h"
|
||||
|
||||
void f1(void) { g1(); }
|
||||
void f2(void) { g2(); }
|
||||
void f3(void) { g3(); }
|
||||
void f4(void) { g4(); }
|
||||
void f5(void) { g5(); }
|
||||
void f6(void) { g6(); }
|
||||
void f7(void) { g7(); }
|
||||
void f8(void) { g8(); }
|
||||
void f9(void) { g9(); }
|
||||
void f10(void) { g10(); }
|
||||
void f11(void) { g11(); }
|
||||
void f12(void) { g12(); }
|
||||
void f13(void) { g13(); }
|
||||
void f14(void) { g14(); }
|
||||
void f15(void) { g15(); }
|
||||
void f16(void) { g16(); }
|
||||
void f17(void) { g17(); }
|
||||
void f18(void) { g18(); }
|
||||
void f19(void) { g19(); }
|
||||
void f20(void) { g20(); }
|
||||
void f21(void) { g21(); }
|
||||
void f22(void) { g22(); }
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
void f1(void);
|
||||
void f2(void);
|
||||
void f3(void);
|
||||
void f4(void);
|
||||
void f5(void);
|
||||
void f6(void);
|
||||
void f7(void);
|
||||
void f8(void);
|
||||
void f9(void);
|
||||
void f10(void);
|
||||
void f11(void);
|
||||
void f12(void);
|
||||
void f13(void);
|
||||
void f14(void);
|
||||
void f15(void);
|
||||
void f16(void);
|
||||
void f17(void);
|
||||
void f18(void);
|
||||
void f19(void);
|
||||
void f20(void);
|
||||
void f21(void);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#include "a.h"
|
||||
|
||||
void g1(void) { f1(); }
|
||||
void g2(void) { f2(); }
|
||||
void g3(void) { f3(); }
|
||||
void g4(void) { f4(); }
|
||||
void g5(void) { f5(); }
|
||||
void g6(void) { f6(); }
|
||||
void g7(void) { f7(); }
|
||||
void g8(void) { f8(); }
|
||||
void g9(void) { f9(); }
|
||||
void g10(void) { f10(); }
|
||||
void g11(void) { f11(); }
|
||||
void g12(void) { f12(); }
|
||||
void g13(void) { f13(); }
|
||||
void g14(void) { f14(); }
|
||||
void g15(void) { f15(); }
|
||||
void g16(void) { f16(); }
|
||||
void g17(void) { f17(); }
|
||||
void g18(void) { f18(); }
|
||||
void g19(void) { f19(); }
|
||||
void g20(void) { f20(); }
|
||||
void g21(void) { f21(); }
|
||||
void g22(void) { }
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
void g1(void);
|
||||
void g2(void);
|
||||
void g3(void);
|
||||
void g4(void);
|
||||
void g5(void);
|
||||
void g6(void);
|
||||
void g7(void);
|
||||
void g8(void);
|
||||
void g9(void);
|
||||
void g10(void);
|
||||
void g11(void);
|
||||
void g12(void);
|
||||
void g13(void);
|
||||
void g14(void);
|
||||
void g15(void);
|
||||
void g16(void);
|
||||
void g17(void);
|
||||
void g18(void);
|
||||
void g19(void);
|
||||
void g20(void);
|
||||
void g21(void);
|
||||
void g22(void);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#include "c.h"
|
||||
#include "d.h"
|
||||
|
||||
void C::f1() { d->g1(); }
|
||||
void C::f2() { d->g2(); }
|
||||
void C::f3() { d->g3(); }
|
||||
void C::f4() { d->g4(); }
|
||||
void C::f5() { d->g5(); }
|
||||
void C::f6() { d->g6(); }
|
||||
void C::f7() { d->g7(); }
|
||||
void C::f8() { d->g8(); }
|
||||
void C::f9() { d->g9(); }
|
||||
void C::f10() { d->g10(); }
|
||||
void C::f11() { d->g11(); }
|
||||
void C::f12() { d->g12(); }
|
||||
void C::f13() { d->g13(); }
|
||||
void C::f14() { d->g14(); }
|
||||
void C::f15() { d->g15(); }
|
||||
void C::f16() { d->g16(); }
|
||||
void C::f17() { d->g17(); }
|
||||
void C::f18() { d->g18(); }
|
||||
void C::f19() { d->g19(); }
|
||||
void C::f20() { d->g20(); }
|
||||
void C::f21() { d->g21(); }
|
||||
void C::f22() { d->g22(); }
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
class D;
|
||||
|
||||
class C {
|
||||
D *d;
|
||||
public:
|
||||
void f1();
|
||||
void f2();
|
||||
void f3();
|
||||
void f4();
|
||||
void f5();
|
||||
void f6();
|
||||
void f7();
|
||||
void f8();
|
||||
void f9();
|
||||
void f10();
|
||||
void f11();
|
||||
void f12();
|
||||
void f13();
|
||||
void f14();
|
||||
void f15();
|
||||
void f16();
|
||||
void f17();
|
||||
void f18();
|
||||
void f19();
|
||||
void f20();
|
||||
void f21();
|
||||
void f22();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#include "c.h"
|
||||
#include "d.h"
|
||||
|
||||
void D::g1() { c->f1(); }
|
||||
void D::g2() { c->f2(); }
|
||||
void D::g3() { c->f3(); }
|
||||
void D::g4() { c->f4(); }
|
||||
void D::g5() { c->f5(); }
|
||||
void D::g6() { c->f6(); }
|
||||
void D::g7() { c->f7(); }
|
||||
void D::g8() { c->f8(); }
|
||||
void D::g9() { c->f9(); }
|
||||
void D::g10() { c->f10(); }
|
||||
void D::g11() { c->f11(); }
|
||||
void D::g12() { c->f12(); }
|
||||
void D::g13() { c->f13(); }
|
||||
void D::g14() { c->f14(); }
|
||||
void D::g15() { c->f15(); }
|
||||
void D::g16() { c->f16(); }
|
||||
void D::g17() { c->f17(); }
|
||||
void D::g18() { c->f18(); }
|
||||
void D::g19() { c->f19(); }
|
||||
void D::g20() { c->f20(); }
|
||||
void D::g21() { c->f21(); }
|
||||
void D::g22() { }
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
class C;
|
||||
|
||||
class D {
|
||||
C *c;
|
||||
public:
|
||||
void g1();
|
||||
void g2();
|
||||
void g3();
|
||||
void g4();
|
||||
void g5();
|
||||
void g6();
|
||||
void g7();
|
||||
void g8();
|
||||
void g9();
|
||||
void g10();
|
||||
void g11();
|
||||
void g12();
|
||||
void g13();
|
||||
void g14();
|
||||
void g15();
|
||||
void g16();
|
||||
void g17();
|
||||
void g18();
|
||||
void g19();
|
||||
void g20();
|
||||
void g21();
|
||||
void g22();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// semmle-extractor-options: --clang
|
||||
#define TEN(X) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10)
|
||||
|
||||
#define int_f(n) int f##n;
|
||||
#define int_g(n) int g##n;
|
||||
|
||||
struct aa {
|
||||
TEN(int_f)
|
||||
TEN(int_g)
|
||||
};
|
||||
|
||||
class bb {
|
||||
TEN(int_f)
|
||||
TEN(int_g)
|
||||
};
|
||||
|
||||
union cc_not_flagged_up_because_unions_are_not_classes_in_this_sense {
|
||||
TEN(int_f)
|
||||
TEN(int_g)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct dd {
|
||||
TEN(int_f)
|
||||
TEN(int_g)
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
struct ee {
|
||||
TEN(int_f)
|
||||
TEN(int_g)
|
||||
};
|
||||
|
||||
void instantiate() {
|
||||
dd<float> d1;
|
||||
dd<int> d2;
|
||||
}
|
||||
|
||||
// from the qhelp (30 fields)
|
||||
struct MyParticle {
|
||||
bool isActive;
|
||||
int priority;
|
||||
|
||||
float x, y, z;
|
||||
float dx, dy, dz;
|
||||
float ddx, ddy, ddz;
|
||||
bool isCollider;
|
||||
|
||||
int age, maxAge;
|
||||
float size1, size2;
|
||||
|
||||
bool hasColor;
|
||||
unsigned char r1, g1, b1, a1;
|
||||
unsigned char r2, g2, b2, a2;
|
||||
|
||||
class texture *tex;
|
||||
float u1, v1, u2, v2;
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
| cwmf.cpp:8:3:9:12 | aa | Struct aa has 20 fields, which is too many. | cwmf.cpp:8:3:9:12 | group of 20 fields here | group of 20 fields here |
|
||||
| cwmf.cpp:13:3:14:12 | bb | Class bb has 20 fields, which is too many. | cwmf.cpp:13:3:14:12 | group of 20 fields here | group of 20 fields here |
|
||||
| cwmf.cpp:24:3:25:12 | dd<T> | Template class dd<T> has 20 fields, which is too many. | cwmf.cpp:24:3:25:12 | group of 20 fields here | group of 20 fields here |
|
||||
| cwmf.cpp:30:3:31:12 | ee<U> | Template class ee<U> has 20 fields, which is too many. | cwmf.cpp:30:3:31:12 | group of 20 fields here | group of 20 fields here |
|
||||
| cwmf.cpp:41:8:57:22 | MyParticle | Struct MyParticle has 30 fields, which is too many. | cwmf.cpp:41:8:57:22 | group of 30 fields here | group of 30 fields here |
|
||||
| different_types.h:15:15:33:10 | DifferentTypes2 | Class DifferentTypes2 has 18 fields, which is too many. | different_types.h:15:15:33:10 | group of 18 fields here | group of 18 fields here |
|
||||
| different_types.h:15:15:33:10 | DifferentTypes2 | Class DifferentTypes2 has 18 fields, which is too many. | different_types.h:15:15:33:10 | group of 18 fields here | group of 18 fields here |
|
||||
@@ -0,0 +1 @@
|
||||
Architecture/Refactoring Opportunities/ClassesWithManyFields.ql
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
class DifferentTypes {
|
||||
SOME_TYPE i1;
|
||||
SOME_TYPE i2;
|
||||
SOME_TYPE i3;
|
||||
SOME_TYPE i4;
|
||||
SOME_TYPE i5;
|
||||
SOME_TYPE i6;
|
||||
SOME_TYPE i7;
|
||||
SOME_TYPE i8;
|
||||
SOME_TYPE i9;
|
||||
};
|
||||
|
||||
class DifferentTypes2 {
|
||||
SOME_TYPE i1;
|
||||
SOME_TYPE i2;
|
||||
SOME_TYPE i3;
|
||||
SOME_TYPE i4;
|
||||
SOME_TYPE i5;
|
||||
SOME_TYPE i6;
|
||||
SOME_TYPE i7;
|
||||
SOME_TYPE i8;
|
||||
SOME_TYPE i9;
|
||||
|
||||
int j1;
|
||||
int j2;
|
||||
int j3;
|
||||
int j4;
|
||||
int j5;
|
||||
int j6;
|
||||
int j7;
|
||||
int j8;
|
||||
int j9;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
#define SOME_TYPE unsigned char
|
||||
#include "different_types.h"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
#define SOME_TYPE signed char
|
||||
#include "different_types.h"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| complex.c:14:6:14:6 | h | This function makes too many calls (112) |
|
||||
@@ -0,0 +1 @@
|
||||
Architecture/Refactoring Opportunities/ComplexFunctions.ql
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
void f(void) { }
|
||||
|
||||
void g(void) {
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
}
|
||||
|
||||
void h(void) {
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f(); f();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| hiding.cpp:4:17:4:18 | ii | Local variable 'ii' hides a $@. | hiding.cpp:2:12:2:13 | definition of ii | parameter of the same name |
|
||||
| hiding.cpp:15:15:15:16 | kk | Local variable 'kk' hides a $@. | hiding.cpp:12:25:12:26 | definition of kk | parameter of the same name |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Hiding/DeclarationHidesParameter.ql
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
void f(int ii) {
|
||||
if (1) {
|
||||
for(int ii = 1; ii < 10; ii++) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace foo {
|
||||
namespace bar {
|
||||
void f2(int ii, int kk) {
|
||||
try {
|
||||
for (ii = 0; ii < 3; ii++) {
|
||||
int kk;
|
||||
}
|
||||
}
|
||||
catch (int ee) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| hiding.cpp:6:17:6:17 | i | Variable i hides another variable of the same name (on $@). | hiding.cpp:4:13:4:13 | i | line 4 |
|
||||
| hiding.cpp:18:15:18:15 | k | Variable k hides another variable of the same name (on $@). | hiding.cpp:15:11:15:11 | k | line 15 |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Hiding/DeclarationHidesVariable.ql
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
void f(void) {
|
||||
if (1) {
|
||||
int i;
|
||||
|
||||
for(int i = 1; i < 10; i++) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace foo {
|
||||
namespace bar {
|
||||
void f2(int i) {
|
||||
int k;
|
||||
try {
|
||||
for (i = 0; i < 3; i++) {
|
||||
int k;
|
||||
}
|
||||
}
|
||||
catch (int e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| Hiding.c:15:25:15:25 | i | Variable i hides another variable of the same name (on $@). | Hiding.c:7:9:7:9 | i | line 7 |
|
||||
| Hiding.c:16:25:16:25 | j | Variable j hides another variable of the same name (on $@). | Hiding.c:10:13:10:13 | j | line 10 |
|
||||
| Hiding.c:17:25:17:25 | k | Variable k hides another variable of the same name (on $@). | Hiding.c:13:21:13:21 | k | line 13 |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Hiding/DeclarationHidesVariable.ql
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
int gi;
|
||||
extern int gj;
|
||||
static int gk;
|
||||
|
||||
void f(void) {
|
||||
int i;
|
||||
|
||||
if (1) {
|
||||
int j;
|
||||
if (1)
|
||||
if(1) {
|
||||
int k;
|
||||
if(1) {
|
||||
int i; // BAD (hides local)
|
||||
int j; // BAD (hides local)
|
||||
int k; // BAD (hides local)
|
||||
int l;
|
||||
int m;
|
||||
int n;
|
||||
|
||||
int gi; // BAD (hides global)
|
||||
int gj; // BAD (hides global)
|
||||
int gk; // BAD (hides global)
|
||||
}
|
||||
int l; // GOOD (scopes do not overlap)
|
||||
}
|
||||
int m; // GOOD (scopes do not overlap)
|
||||
}
|
||||
int n; // GOOD (scopes do not overlap)
|
||||
}
|
||||
|
||||
int g1, g2, g3, g4, g5;
|
||||
|
||||
void function1(int g1); // GOOD (the hiding name isn't associated with a code block)
|
||||
extern void function2(int g2); // GOOD (the hiding name isn't associated with a code block)
|
||||
void function3(int g3) {}; // BAD
|
||||
|
||||
void function4(int g4); // GOOD (the hiding name isn't associated with a code block)
|
||||
void function4(int g5) {}; // BAD
|
||||
@@ -0,0 +1,5 @@
|
||||
| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides $@ with the same name. | Hiding.c:2:5:2:6 | gi | a global variable |
|
||||
| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides $@ with the same name. | Hiding.c:3:12:3:13 | gj | a global variable |
|
||||
| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides $@ with the same name. | Hiding.c:4:12:4:13 | gk | a global variable |
|
||||
| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides $@ with the same name. | Hiding.c:33:13:33:14 | g3 | a global variable |
|
||||
| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides $@ with the same name. | Hiding.c:33:21:33:22 | g5 | a global variable |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql
|
||||
@@ -0,0 +1,3 @@
|
||||
| empty_block.cpp:7:10:7:11 | { ... } | Empty block without comment |
|
||||
| empty_block.cpp:10:10:11:3 | { ... } | Empty block without comment |
|
||||
| empty_block.cpp:18:10:19:3 | { ... } | Empty block without comment |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Likely Errors/EmptyBlock.ql
|
||||
@@ -0,0 +1,51 @@
|
||||
// GOOD:
|
||||
void f() {
|
||||
}
|
||||
|
||||
int f(int x) {
|
||||
// BAD:
|
||||
if (x) {}
|
||||
|
||||
// BAD:
|
||||
if (x) {
|
||||
}
|
||||
|
||||
if (x) {
|
||||
// GOOD (has comment)
|
||||
}
|
||||
|
||||
// BAD (comment comes after):
|
||||
if (x) {
|
||||
}
|
||||
// comment
|
||||
|
||||
// GOOD (exception for loops with block on same line):
|
||||
while (--x == 27) {}
|
||||
|
||||
// GOOD:
|
||||
while (--x == 2) {
|
||||
}
|
||||
|
||||
// GOOD:
|
||||
do {
|
||||
} while (--x == 2);
|
||||
|
||||
// GOOD:
|
||||
if (x) {
|
||||
#ifdef NOT_DEFINED
|
||||
return 7;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define EMPTY
|
||||
// GOOD:
|
||||
if (x) {
|
||||
EMPTY
|
||||
}
|
||||
|
||||
// GOOD (no block)
|
||||
if (1) ;
|
||||
|
||||
// GOOD (no block)
|
||||
for (;;) ;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| test.cpp:13:3:13:9 | ... = ... | This assignment expression slices from type $@ to $@ | test.cpp:6:8:6:13 | Point3 | Point3 | test.cpp:1:8:1:13 | Point2 | Point2 |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Likely Errors/Slicing.ql
|
||||
@@ -0,0 +1,20 @@
|
||||
struct Point2 {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct Point3 : Point2 {
|
||||
int z;
|
||||
};
|
||||
|
||||
void f() {
|
||||
Point2 p2;
|
||||
Point3 p3;
|
||||
p2 = p3;
|
||||
}
|
||||
|
||||
void g() {
|
||||
Point2* p2 = 0;
|
||||
Point3* p3 = 0;
|
||||
p2 = p3;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
| a123.c:5:9:5:11 | 123 | Magic constant: literal '123' is repeated 33 times and should be encapsulated in a constant. |
|
||||
| b123.c:3:14:3:16 | 123 | Magic constant: literal '123' is repeated 33 times and should be encapsulated in a constant. |
|
||||
| case.c:4:10:4:12 | 123 | Magic constant: literal '123' is repeated 33 times and should be encapsulated in a constant. |
|
||||
| case.c:4:18:4:20 | 129 | Magic constant: literal '129' is repeated 31 times and should be encapsulated in a constant. |
|
||||
| constants.h:5:9:5:11 | 123 | Magic constant: literal '123' is repeated 33 times and should be encapsulated in a constant. |
|
||||
| constants.h:5:9:5:11 | 123 | Magic constant: literal '123' is repeated 33 times and should be encapsulated in a constant. |
|
||||
| constants.h:60:9:60:14 | 120 | Magic constant: literal '120' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:60:9:60:14 | 120 | Magic constant: literal '120' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:91:9:91:14 | 504 | Magic constant: literal '504' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:91:9:91:14 | 504 | Magic constant: literal '504' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:122:9:122:13 | 278 | Magic constant: literal '278' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:122:9:122:13 | 278 | Magic constant: literal '278' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:153:10:153:12 | 129 | Magic constant: literal '129' is repeated 31 times and should be encapsulated in a constant. |
|
||||
| constants.h:153:10:153:12 | 129 | Magic constant: literal '129' is repeated 31 times and should be encapsulated in a constant. |
|
||||
| functions.h:3:2:3:4 | 102 | Magic constant: literal '102' is repeated 21 times and should be encapsulated in a constant. |
|
||||
| functions.h:3:8:3:10 | 102 | Magic constant: literal '102' is repeated 21 times and should be encapsulated in a constant. |
|
||||
| functions.h:3:14:3:16 | 102 | Magic constant: literal '102' is repeated 21 times and should be encapsulated in a constant. |
|
||||
| functions.h:12:11:12:13 | 103 | Magic constant: literal '103' is repeated 21 times and should be encapsulated in a constant. |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Magic Constants/MagicConstantsNumbers.ql
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
static void f(void) {
|
||||
int i;
|
||||
|
||||
i = 123;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
static void f(void) {
|
||||
char str[123];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
static void f(void) {
|
||||
const int i = 120;
|
||||
|
||||
char str[i + 3];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
void f(int i) {
|
||||
switch(i) {
|
||||
case 123 ... 129:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
|
||||
void FUN(void) {
|
||||
int i, j, k;
|
||||
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
i = 123;
|
||||
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
j = 456;
|
||||
|
||||
k = 789;
|
||||
k = 789;
|
||||
k = 789;
|
||||
k = 789;
|
||||
k = 789;
|
||||
k = 789;
|
||||
k = 789;
|
||||
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
i = 0x0078;
|
||||
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
i = 0x01f8;
|
||||
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
i = 278UL;
|
||||
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
i = -129;
|
||||
|
||||
int a123 = 127;
|
||||
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
i = a123;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
static void f(void) {
|
||||
const int i = 120;
|
||||
const int j = i + 3;
|
||||
|
||||
char str[j];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// GENERATED FILE
|
||||
// ...
|
||||
// it's not, it's a hand-written test, but we want to assume it is one.
|
||||
|
||||
static void f(void) {
|
||||
int i;
|
||||
|
||||
i = 123;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
int myFunction1(int x =
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102 +
|
||||
102 + 102 + 102);
|
||||
|
||||
void myFunction2(
|
||||
int p1 = 103,
|
||||
int p2 = 103,
|
||||
int p3 = 103,
|
||||
int p4 = 103,
|
||||
int p5 = 103,
|
||||
int p6 = 103,
|
||||
int p7 = 103,
|
||||
int p8 = 103,
|
||||
int p9 = 103,
|
||||
int p10 = 103,
|
||||
int p11 = 103,
|
||||
int p12 = 103,
|
||||
int p13 = 103,
|
||||
int p14 = 103,
|
||||
int p15 = 103,
|
||||
int p16 = 103,
|
||||
int p17 = 103,
|
||||
int p18 = 103,
|
||||
int p19 = 103,
|
||||
int p20 = 103,
|
||||
int p21 = 103
|
||||
) {};
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#define FUN f
|
||||
#include "constants.h"
|
||||
#undef FUN
|
||||
|
||||
#define FUN g
|
||||
#include "constants.h"
|
||||
#undef FUN
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
#include "functions.h"
|
||||
|
||||
int myFunction1(int x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
void myCaller() {
|
||||
myFunction1();
|
||||
myFunction1();
|
||||
myFunction1(104);
|
||||
myFunction2(105);
|
||||
myFunction2();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
| constants.h:5:9:5:19 | abcabcabc | Magic constant: literal 'abcabcabc' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| constants.h:5:9:5:19 | abcabcabc | Magic constant: literal 'abcabcabc' is repeated 30 times and should be encapsulated in a constant. |
|
||||
| joining.cpp:39:5:39:18 | testrepo.git | Magic constant: literal 'testrepo.git' is repeated 21 times and should be encapsulated in a constant. |
|
||||
| joining.cpp:107:8:107:28 | NO T_VOID CONSTRUCT | Magic constant: literal 'NO T_VOID CONSTRUCT' is repeated 21 times and should be encapsulated in a constant. |
|
||||
| joining.cpp:173:8:173:47 | compiler error: no const of base type | Magic constant: literal 'compiler error: no const of base type ' is repeated 21 times and should be encapsulated in a constant. |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Magic Constants/MagicConstantsString.ql
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
void FUN(void) {
|
||||
const char *s;
|
||||
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
s = "abcabcabc";
|
||||
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
s = "defdefdef";
|
||||
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
s = "ghighighi";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
|
||||
// --- string ---
|
||||
|
||||
class string
|
||||
{
|
||||
public:
|
||||
string(const char *str)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// ...
|
||||
};
|
||||
|
||||
string operator+(const string &lhs, const string &rhs)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// --- ostream ---
|
||||
|
||||
class ostream
|
||||
{
|
||||
public:
|
||||
// ...
|
||||
};
|
||||
|
||||
ostream &operator<<(ostream &stream, const string &str)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// --- tests ---
|
||||
|
||||
void fn(const string &str1);
|
||||
|
||||
void joining_test(const string &x, const string &y) \
|
||||
{
|
||||
fn("testrepo.git"); // BAD: "testrepo.git"
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git");
|
||||
fn("testrepo.git"); // (21 times)
|
||||
|
||||
fn(x + " extends " + y); // GOOD
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y);
|
||||
fn(x + " extends " + y); // (21 times)
|
||||
|
||||
fn("type error: " + x + " has no field " + y); // GOOD
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y);
|
||||
fn("type error: " + x + " has no field " + y); // (21 times)
|
||||
|
||||
ostream os;
|
||||
|
||||
os << "NO T_VOID CONSTRUCT"; // BAD: "NO T_VOID CONSTRUCT"
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT";
|
||||
os << "NO T_VOID CONSTRUCT"; // (21 times)
|
||||
|
||||
os << "{" << x << "} else {" << y << "}"; // GOOD
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}";
|
||||
os << "{" << x << "} else {" << y << "}"; // (21 times)
|
||||
|
||||
os << "writeString(" << x << ")"; // GOOD
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")";
|
||||
os << "writeString(" << x << ")"; // (21 times)
|
||||
|
||||
os << "compiler error: no const of base type " + x; // BAD: "compiler error: no const of base type "
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x;
|
||||
os << "compiler error: no const of base type " + x; // (21 times)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#define FUN f
|
||||
#include "constants.h"
|
||||
#undef FUN
|
||||
|
||||
#define FUN g
|
||||
#include "constants.h"
|
||||
#undef FUN
|
||||
|
||||
313
cpp/ql/test/query-tests/Best Practices/RuleOfTwo/RuleOfTwo.cpp
Normal file
313
cpp/ql/test/query-tests/Best Practices/RuleOfTwo/RuleOfTwo.cpp
Normal file
@@ -0,0 +1,313 @@
|
||||
// NOT OK
|
||||
struct CopyButNoAssign {
|
||||
CopyButNoAssign() : n(0) {}
|
||||
CopyButNoAssign(const CopyButNoAssign& copy_from) : n(copy_from.n) {}
|
||||
int n;
|
||||
};
|
||||
|
||||
// NOT OK
|
||||
struct AssignButNoCopy {
|
||||
AssignButNoCopy& operator=(const AssignButNoCopy& assign_from) { return *this; }
|
||||
};
|
||||
|
||||
// OK: before C++11, marking a constructor as private was an
|
||||
// acceptable way to delete it. The constructor still might get used by
|
||||
// accident within the scope of the class and its friends, but we tolerate that
|
||||
// in order to avoid false positives on such code.
|
||||
struct NotCopyable {
|
||||
NotCopyable() {}
|
||||
private:
|
||||
NotCopyable(const NotCopyable& cannot_copy) {}
|
||||
};
|
||||
|
||||
// OK: C++11 version of NotCopyable
|
||||
struct NotCopyable11 {
|
||||
NotCopyable11(const NotCopyable11&) = delete;
|
||||
};
|
||||
|
||||
// OK: both defined
|
||||
struct HasBoth {
|
||||
HasBoth() {}
|
||||
HasBoth(const HasBoth& copy_from) {}
|
||||
HasBoth& operator=(const HasBoth& assign_from) { return *this; }
|
||||
};
|
||||
|
||||
// OK: both generated
|
||||
struct HasGenerated {
|
||||
HasBoth m_member;
|
||||
};
|
||||
|
||||
// OK: this class gets a generated copy constructor but no copy
|
||||
// assignment. We don't flag this as an error -- trying to copy-assign it will
|
||||
// be a compilation error.
|
||||
struct ConstMember {
|
||||
const int x;
|
||||
};
|
||||
|
||||
// OK: this class declares a copy constructor but no copy
|
||||
// assignment. But because it has a const member, it does not get a
|
||||
// compiler-defined copy assignment operator, so there is no potential
|
||||
// memory safety problem.
|
||||
struct ConstMemberAndCopy {
|
||||
const int x;
|
||||
ConstMemberAndCopy(): x(4) {}
|
||||
ConstMemberAndCopy(const ConstMemberAndCopy& that): x(that.x) {}
|
||||
};
|
||||
|
||||
// OK: Our class won't get a copy constructor.
|
||||
struct NoAutoCopy {
|
||||
NotCopyable x; // has no copy constructor but has copy assignment
|
||||
NoAutoCopy& operator=(const NoAutoCopy& that) { x = that.x; return *this; }
|
||||
};
|
||||
|
||||
// OK: When viewed in isolation, this class seems to use the pre-C++11 idiom of
|
||||
// suppressing an auto-generated member by making it inaccessible.
|
||||
struct CopyableByFriend {
|
||||
friend struct MyClassFriend;
|
||||
private:
|
||||
CopyableByFriend(CopyableByFriend &) {} // OK: private
|
||||
};
|
||||
|
||||
// OK: No auto-generated copy constructor
|
||||
struct NotFriend {
|
||||
CopyableByFriend x;
|
||||
NotFriend& operator=(const NotFriend& that) { return *this; }
|
||||
};
|
||||
|
||||
// NOT OK: Gets an auto-generated copy constructor because the class is a
|
||||
// friend of CopyableByFriend.
|
||||
struct MyClassFriend {
|
||||
CopyableByFriend x;
|
||||
MyClassFriend& operator=(const MyClassFriend& that) { return *this; }
|
||||
};
|
||||
|
||||
// OK or NOT OK? An explicit default and an explicit implementation.
|
||||
struct UsesDefault {
|
||||
UsesDefault(UsesDefault&) = default;
|
||||
UsesDefault& operator=(UsesDefault& ud) { return *this; }
|
||||
};
|
||||
|
||||
// OK: copy constructor is user-defined, and there is no copy assignment.
|
||||
struct DeletedAssign {
|
||||
DeletedAssign(DeletedAssign&) {}
|
||||
DeletedAssign& operator=(DeletedAssign& ud) = delete;
|
||||
};
|
||||
|
||||
// OK: volatile instances can only be copied but not assigned, and that is
|
||||
// not a correctness problem.
|
||||
struct ProtectedVolatile {
|
||||
protected:
|
||||
ProtectedVolatile(const volatile ProtectedVolatile& that) {}
|
||||
public:
|
||||
ProtectedVolatile() {}
|
||||
ProtectedVolatile(const ProtectedVolatile& that) {}
|
||||
ProtectedVolatile& operator=(const ProtectedVolatile& that) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// OK: because `pv` is volatile, the compiler will try to generate a call to
|
||||
// the protected copy constructor of ProtectedVolatile that takes a volatile
|
||||
// argument. When access to this constructor fails, this class does not get an
|
||||
// auto-generated copy constructor at all.
|
||||
struct HasVPV {
|
||||
volatile ProtectedVolatile vpv;
|
||||
HasVPV& operator=(const HasVPV& that) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// FALSE NEGATIVE: the relevant copy constructor of ProtectedVolatile is
|
||||
// accessible, so our class will get a generated copy constructor. Our query
|
||||
// thinks the copy constructor is inaccessible because it picks up the other
|
||||
// copy constructor. To fix this, our library should be changed to distinguish
|
||||
// between copy constructors and resolve overloading properly instead of
|
||||
// assuming that there is at most one.
|
||||
struct HasPV {
|
||||
ProtectedVolatile pv;
|
||||
HasPV& operator=(const HasPV& that) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// OK: has explicit copy constructor and copy assignment operator.
|
||||
struct ProtectedAssign {
|
||||
ProtectedAssign() {}
|
||||
ProtectedAssign(const ProtectedAssign& that) {}
|
||||
protected:
|
||||
ProtectedAssign& operator=(const ProtectedAssign& that) { return *this; }
|
||||
};
|
||||
|
||||
// NOT OK: this class gets a copy assignment operator because it can access the
|
||||
// (protected) copy assignment operator of its base class.
|
||||
struct IsAProtectedAssign: public ProtectedAssign {
|
||||
IsAProtectedAssign(const IsAProtectedAssign& that) {}
|
||||
};
|
||||
|
||||
// OK: this class gets no copy assignment operator. It cannot access the
|
||||
// (protected) copy assignment operator of its field even though it can access
|
||||
// the same operator on its base class. For protected members, access is
|
||||
// special when going through objects with the class of `this`.
|
||||
struct HasAndIsAProtectedAssign: public ProtectedAssign {
|
||||
ProtectedAssign fieldB;
|
||||
HasAndIsAProtectedAssign(const HasAndIsAProtectedAssign& that) {}
|
||||
};
|
||||
|
||||
// OK: has explicit copy constructor and copy assignment operator.
|
||||
struct ProtectedCC {
|
||||
ProtectedCC() {}
|
||||
ProtectedCC& operator=(const ProtectedCC& that) { return *this; }
|
||||
protected:
|
||||
ProtectedCC(const ProtectedCC& that) {}
|
||||
};
|
||||
|
||||
// NOT OK: this class gets a copy constructor because it can access the
|
||||
// (protected) copy constructor of its base class.
|
||||
struct IsAProtectedCC: public ProtectedCC {
|
||||
IsAProtectedCC& operator=(const IsAProtectedCC& that) { return *this; }
|
||||
};
|
||||
|
||||
// OK: this class gets no copy constructor. It cannot access the (protected)
|
||||
// copy constructor of its field even though it can access the same operator on
|
||||
// its base class. For protected members, access is special when going through
|
||||
// objects with the class of `this`.
|
||||
struct HasAndIsAProtectedCC: public ProtectedCC {
|
||||
ProtectedCC fieldB;
|
||||
HasAndIsAProtectedCC& operator=(const HasAndIsAProtectedCC& that) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// OK: defines both
|
||||
struct DerivesVirtual: virtual public NotCopyable {
|
||||
DerivesVirtual(const DerivesVirtual& that) {}
|
||||
DerivesVirtual& operator=(const DerivesVirtual& that) { return *this; }
|
||||
};
|
||||
|
||||
// OK: overrides only assignment but gets no auto-generated copy constructor
|
||||
// because a virtual non-direct base class is not copyable.
|
||||
struct DerivesDerivesVirtual: public DerivesVirtual {
|
||||
DerivesDerivesVirtual& operator=(const DerivesDerivesVirtual& that) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// OK: templates and their instantiations are ignored, but this class would
|
||||
// be correct anyway.
|
||||
template<class T>
|
||||
struct HasBoth_template {
|
||||
T t_;
|
||||
HasBoth_template() {}
|
||||
HasBoth_template(const HasBoth_template<T>& copy_from)
|
||||
: t_(copy_from.t_)
|
||||
{}
|
||||
HasBoth_template& operator=(const HasBoth_template<T>& assign_from) {
|
||||
t_ = assign_from.t_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void use_copy_ctor(HasBoth_template<int> obj) {
|
||||
HasBoth_template<int> copy = obj;
|
||||
}
|
||||
|
||||
// NOT OK (FALSE NEGATIVE): because this template is never instantiated, it
|
||||
// does not appear in the database and is not caught by the analysis.
|
||||
template<class T>
|
||||
struct CopyButNoAssign_template {
|
||||
CopyButNoAssign_template() : n() {}
|
||||
CopyButNoAssign_template(const CopyButNoAssign_template& copy_from) : n(copy_from.n) {}
|
||||
T n;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// OK: copy assignment operator is uncallable because (a) it's private and (b)
|
||||
// it has only a declaration but no definition, so the program would fail to
|
||||
// link.
|
||||
class UncallableCopyAssignment {
|
||||
public:
|
||||
UncallableCopyAssignment(const UncallableCopyAssignment& other) { }
|
||||
UncallableCopyAssignment() { }
|
||||
private:
|
||||
void operator=(UncallableCopyAssignment const &);
|
||||
};
|
||||
|
||||
// OK: both members are "default"
|
||||
struct BothDefault {
|
||||
BothDefault(BothDefault&) = default;
|
||||
BothDefault& operator=(BothDefault& bd) = default;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// OK: template class _with_ initializer on extra argument of copy constructor.
|
||||
// We do not extract initializers of template functions or of functions in
|
||||
// template classes, so our definition of a copy constructor is conservative
|
||||
// and assumes they are present, which is correct in this case (`x` has `= 0`).
|
||||
template<typename T>
|
||||
class TemplateWithInit {
|
||||
public:
|
||||
TemplateWithInit() {}
|
||||
|
||||
TemplateWithInit(const TemplateWithInit& rhs, int x = 0) {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
TemplateWithInit& operator=(const TemplateWithInit& rhs) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void useGenericPointerAssign(TemplateWithInit<char> twi) {
|
||||
TemplateWithInit<char> twi2;
|
||||
twi2 = twi;
|
||||
}
|
||||
|
||||
// NOT OK (FALSE NEGATIVE): template class _without_ initializer on extra
|
||||
// argument of copy constructor. Like `TemplateWithInit` above but without `= 0`
|
||||
// on `x`.
|
||||
template<typename T>
|
||||
class TemplateWithExtraArg {
|
||||
public:
|
||||
TemplateWithExtraArg() {}
|
||||
|
||||
TemplateWithExtraArg(const TemplateWithExtraArg& rhs, int x) {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
TemplateWithExtraArg& operator=(const TemplateWithExtraArg& rhs) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void useTemplateWithExtraArgAssign(TemplateWithExtraArg<char> twaa) {
|
||||
TemplateWithExtraArg<char> twaa2;
|
||||
twaa2 = twaa;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// OK: no user-defined copy constructor or assignment.
|
||||
struct R1_A {
|
||||
R1_A() { }
|
||||
// Note: user-declared move constructor means copy constructor and
|
||||
// assignment are both implicitly deleted.
|
||||
R1_A(R1_A&& a) { }
|
||||
};
|
||||
|
||||
// OK: copy assignment implicitly deleted due to R1_A field.
|
||||
class R1_B {
|
||||
public:
|
||||
R1_B(const R1_B& b) {}
|
||||
R1_A t;
|
||||
};
|
||||
|
||||
// NOT OK: copy constructor user-defined and public, but copy assignment
|
||||
// is generated by the compiler and callable outside the class.
|
||||
class R1_C {
|
||||
public:
|
||||
R1_C(const R1_C& c) {}
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
| RuleOfTwo.cpp:4:3:4:17 | CopyButNoAssign | No matching copy assignment operator in class CopyButNoAssign. It is good practice to match a copy constructor with a copy assignment operator. |
|
||||
| RuleOfTwo.cpp:10:20:10:28 | operator= | No matching copy constructor in class AssignButNoCopy. It is good practice to match a copy assignment operator with a copy constructor. |
|
||||
| RuleOfTwo.cpp:81:18:81:26 | operator= | No matching copy constructor in class MyClassFriend. It is good practice to match a copy assignment operator with a copy constructor. |
|
||||
| RuleOfTwo.cpp:144:3:144:20 | IsAProtectedAssign | No matching copy assignment operator in class IsAProtectedAssign. It is good practice to match a copy constructor with a copy assignment operator. |
|
||||
| RuleOfTwo.cpp:167:19:167:27 | operator= | No matching copy constructor in class IsAProtectedCC. It is good practice to match a copy assignment operator with a copy constructor. |
|
||||
| RuleOfTwo.cpp:312:5:312:8 | R1_C | No matching copy assignment operator in class R1_C. It is good practice to match a copy constructor with a copy assignment operator. |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/RuleOfTwo.ql
|
||||
@@ -0,0 +1,2 @@
|
||||
| main.cpp:3:5:3:5 | x | Poor global variable name 'x'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
|
||||
| main.cpp:4:5:4:6 | ys | Poor global variable name 'ys'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/SloppyGlobal.ql
|
||||
@@ -0,0 +1,7 @@
|
||||
// main.cpp
|
||||
|
||||
int x; // BAD: too short
|
||||
int ys[1000000]; // BAD: too short
|
||||
int descriptive_name; // GOOD: sufficient
|
||||
|
||||
static int z; // GOOD: not a global
|
||||
@@ -0,0 +1,3 @@
|
||||
// a.h
|
||||
|
||||
int my_func_a();
|
||||
@@ -0,0 +1,3 @@
|
||||
// b.h
|
||||
|
||||
int my_func_b();
|
||||
@@ -0,0 +1,3 @@
|
||||
// c.h
|
||||
|
||||
extern int my_var_c;
|
||||
@@ -0,0 +1,3 @@
|
||||
// d.hpp
|
||||
|
||||
class class_d;
|
||||
@@ -0,0 +1,3 @@
|
||||
// e.hpp
|
||||
|
||||
class class_e;
|
||||
@@ -0,0 +1,3 @@
|
||||
// f.fwd.hpp
|
||||
|
||||
class class_f;
|
||||
@@ -0,0 +1 @@
|
||||
// g
|
||||
@@ -0,0 +1,13 @@
|
||||
// unusedIncludes.cpp
|
||||
|
||||
#include "a.h" // unused
|
||||
#include "b.h"
|
||||
#include "c.h"
|
||||
#include "d.hpp"
|
||||
#include "e.hpp" // unused
|
||||
#include "f.fwd.hpp" // unused
|
||||
#include "g" // unused
|
||||
|
||||
int val_b = my_func_b();
|
||||
int *my_c_ptr = &my_var_c;
|
||||
class_d *my_d_ptr;
|
||||
@@ -0,0 +1,4 @@
|
||||
| unusedIncludes.cpp:3:1:3:14 | #include "a.h" | Redundant include, this file does not require $@. | a.h:0:0:0:0 | a.h | a.h |
|
||||
| unusedIncludes.cpp:7:1:7:16 | #include "e.hpp" | Redundant include, this file does not require $@. | e.hpp:0:0:0:0 | e.hpp | e.hpp |
|
||||
| unusedIncludes.cpp:8:1:8:20 | #include "f.fwd.hpp" | Redundant include, this file does not require $@. | f.fwd.hpp:0:0:0:0 | f.fwd.hpp | f.fwd.hpp |
|
||||
| unusedIncludes.cpp:9:1:9:12 | #include "g" | Redundant include, this file does not require $@. | g:0:0:0:0 | g | g |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Unused Entities/UnusedIncludes.ql
|
||||
@@ -0,0 +1,24 @@
|
||||
| code2.cpp:4:6:4:7 | v1 | Variable v1 is not used |
|
||||
| code2.cpp:6:6:6:7 | v3 | Variable v3 is not used |
|
||||
| code2.cpp:10:16:10:17 | v7 | Variable v7 is not used |
|
||||
| code2.cpp:25:16:25:17 | v1 | Variable v1 is not used |
|
||||
| code2.cpp:26:16:26:17 | v2 | Variable v2 is not used |
|
||||
| code2.cpp:41:11:41:16 | myVar1 | Variable myVar1 is not used |
|
||||
| code2.cpp:63:7:63:8 | v3 | Variable v3 is not used |
|
||||
| code.c:10:18:10:18 | y | Variable y is not used |
|
||||
| code.c:11:18:11:18 | z | Variable z is not used |
|
||||
| code.c:18:7:18:7 | x | Variable x is not used |
|
||||
| code.c:19:10:19:10 | y | Variable y is not used |
|
||||
| code.c:30:45:30:45 | n | Variable n is not used |
|
||||
| code.c:46:6:46:6 | x | Variable x is not used |
|
||||
| code.c:52:8:52:8 | x | Variable x is not used |
|
||||
| code.c:67:6:67:9 | arr5 | Variable arr5 is not used |
|
||||
| code.cpp:17:18:17:18 | e | Variable e is not used |
|
||||
| code.cpp:32:11:32:16 | mc_ptr | Variable mc_ptr is not used |
|
||||
| code.cpp:33:11:33:16 | mc_ref | Variable mc_ref is not used |
|
||||
| code.cpp:104:16:104:24 | my_static | Variable my_static is not used |
|
||||
| code.cpp:104:16:104:24 | my_static | Variable my_static is not used |
|
||||
| code.cpp:104:16:104:24 | my_static | Variable my_static is not used |
|
||||
| code.cpp:132:17:132:25 | my_static | Variable my_static is not used |
|
||||
| code.cpp:248:16:248:18 | mmc | Variable mmc is not used |
|
||||
| errors.c:10:9:10:9 | x | Variable x is not used |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Unused Entities/UnusedLocals.ql
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
void f1(unsigned int x) {
|
||||
unsigned int y = x + 1;
|
||||
unsigned int z = x + 2; // BAD: 'z' is unused [NOT DETECTED - due to ASM code]
|
||||
|
||||
asm volatile("decl %[cnt];" : [cnt] "+r" (y));
|
||||
}
|
||||
|
||||
void f2(unsigned int x) {
|
||||
unsigned int y = x + 1; // BAD: 'y' is unused
|
||||
unsigned int z = x + 2; // BAD: 'z' is unused
|
||||
}
|
||||
|
||||
#define my_int int
|
||||
#define COMPLEX_MACRO do { int z = 3; } while(0)
|
||||
|
||||
void f3() {
|
||||
int x = 1; // BAD: 'x' is unused
|
||||
my_int y = 2; // BAD: 'y' is unused
|
||||
COMPLEX_MACRO; // GOOD: unused locals declared in macros are considered OK.
|
||||
}
|
||||
|
||||
void write_ptr(int *ptr) {
|
||||
ptr = 1;
|
||||
}
|
||||
|
||||
#define ZERO(x) x = 0
|
||||
|
||||
int f4() {
|
||||
int a, b, c, d, e, f, g, h, i, j, k, l, m, n; // BAD: 'n' is unused
|
||||
|
||||
a = b;
|
||||
c++;
|
||||
if (d) {
|
||||
int *ptr = &e;
|
||||
ptr = &f;
|
||||
}
|
||||
write_ptr(&g);
|
||||
h = (i) ? (j) : (k);
|
||||
ZERO(l);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void f5() {
|
||||
int x; // BAD: 'x' is unused
|
||||
|
||||
{
|
||||
int x;
|
||||
|
||||
{
|
||||
int x; // BAD: 'x' is unused
|
||||
}
|
||||
|
||||
x = 12;
|
||||
}
|
||||
}
|
||||
|
||||
typedef unsigned int size_t;
|
||||
void *memset(void *ptr, int value, size_t num);
|
||||
|
||||
void f6() {
|
||||
int arr1[10];
|
||||
int arr2[10];
|
||||
int arr3[10];
|
||||
int arr4[10];
|
||||
int arr5[10]; // BAD: 'arr5' is unused
|
||||
int *ptr;
|
||||
int x;
|
||||
|
||||
x = 6;
|
||||
arr1[5] = arr2[x];
|
||||
ptr = arr3;
|
||||
memset(arr4, 0, sizeof(arr4));
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
|
||||
void write_ref(int &ref) {
|
||||
ref = 1;
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
MyClass();
|
||||
~MyClass();
|
||||
|
||||
private:
|
||||
int val;
|
||||
};
|
||||
|
||||
MyClass :: MyClass()
|
||||
{
|
||||
int a, b, c, d, e; // BAD: 'e' is unused
|
||||
int &f = d;
|
||||
|
||||
write_ref(a);
|
||||
val = b + f;
|
||||
throw c;
|
||||
}
|
||||
|
||||
MyClass :: ~MyClass()
|
||||
{
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
MyClass mc; // GOOD: constructor and destructor may have side-effects
|
||||
MyClass *mc_ptr; // BAD: 'mc_ptr' is unused
|
||||
MyClass &mc_ref = mc; // BAD: 'mc_ref' is unused
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
template<class T> class container {
|
||||
public:
|
||||
T t;
|
||||
};
|
||||
|
||||
// static int variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction()
|
||||
{
|
||||
static int my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
|
||||
// static template parameter variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction2()
|
||||
{
|
||||
static T my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static template derived variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction3()
|
||||
{
|
||||
static container<T *> *my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static unused int variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction4()
|
||||
{
|
||||
static int my_static; // BAD
|
||||
static void* my_ptr = 0;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static int variable in twice instantiated template function
|
||||
template<typename T> void *instantiatedTemplateFunction()
|
||||
{
|
||||
static int my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
|
||||
// static template parameter variable in twice instantiated template function
|
||||
template<typename T> void *instantiatedTemplateFunction2()
|
||||
{
|
||||
static T my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static template derived variable in twice instantiated template function
|
||||
template<typename T> void *instantiatedTemplateFunction3()
|
||||
{
|
||||
static container<T *> *my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static unused int variable in twice instantiated template function
|
||||
template<typename T> void *instantiatedTemplateFunction4()
|
||||
{
|
||||
static int my_static; // BAD
|
||||
static void* my_ptr = 0;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
void caller()
|
||||
{
|
||||
instantiatedTemplateFunction<int>();
|
||||
instantiatedTemplateFunction<float>();
|
||||
instantiatedTemplateFunction2<int>();
|
||||
instantiatedTemplateFunction2<float>();
|
||||
instantiatedTemplateFunction3<int>();
|
||||
instantiatedTemplateFunction3<float>();
|
||||
instantiatedTemplateFunction4<int>();
|
||||
instantiatedTemplateFunction4<float>();
|
||||
}
|
||||
|
||||
// This is a non-template version of the above.
|
||||
void *nonTemplateFunction()
|
||||
{
|
||||
static int *my_static; // GOOD
|
||||
static void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// This is a non-template version of the above.
|
||||
void *nonTemplateFunction2()
|
||||
{
|
||||
static int *my_static; // BAD
|
||||
static void* my_ptr = 0;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// non-static int variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction5()
|
||||
{
|
||||
int my_local; // GOOD
|
||||
void* my_ptr = &my_local;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// non-static template parameter variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction6()
|
||||
{
|
||||
T my_local; // GOOD
|
||||
void* my_ptr = &my_local;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// non-static template derived variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction7()
|
||||
{
|
||||
container<T *> *my_local; // GOOD
|
||||
void* my_ptr = &my_local;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// non-static unused int variable in non-instantiated template function
|
||||
template<typename T> void *templateFunction8()
|
||||
{
|
||||
int my_local; // BAD
|
||||
void* my_ptr = 0;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
template<typename T> class templateClass
|
||||
{
|
||||
public:
|
||||
// static int variable in class template method
|
||||
void *templateClassMethod()
|
||||
{
|
||||
static int my_static; // GOOD
|
||||
void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static template parameter variable in class template method
|
||||
void *templateClassMethod2()
|
||||
{
|
||||
static T my_static; // GOOD
|
||||
void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static template derived variable in class template method
|
||||
void *templateClassMethod3()
|
||||
{
|
||||
static container<T *> *my_static; // GOOD
|
||||
void* my_ptr = &my_static;
|
||||
return my_ptr;
|
||||
}
|
||||
|
||||
// static unused int variable in class template method
|
||||
void *templateClassMethod4()
|
||||
{
|
||||
static int my_static; // BAD
|
||||
void* my_ptr = 0;
|
||||
return my_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
templateClass<int> tc_i;
|
||||
|
||||
template<typename T> class MyTemplateClass2
|
||||
{
|
||||
public:
|
||||
void method()
|
||||
{
|
||||
static T *a; // BAD
|
||||
static T b; // GOOD - T could have a constructor / destructor
|
||||
static container<T> *c; // BAD
|
||||
static container<T *> d; // BAD [NOT DETECTED - due to type container<T *> depending on type container<T>, which *could* have a constructor, though as used here it can't]
|
||||
static container<T> e; // GOOD - T could have a constructor / destructor
|
||||
}
|
||||
};
|
||||
|
||||
// ---
|
||||
|
||||
int myGlobal;
|
||||
|
||||
class MyMethodClass
|
||||
{
|
||||
public:
|
||||
void MyMethod() {myGlobal++;} // side-effect
|
||||
};
|
||||
|
||||
class MyConstructorClass
|
||||
{
|
||||
public:
|
||||
MyConstructorClass() {myGlobal++;} // side-effect
|
||||
};
|
||||
|
||||
class MyDerivedClass : public MyConstructorClass
|
||||
{
|
||||
};
|
||||
|
||||
class MyContainingClass
|
||||
{
|
||||
private:
|
||||
MyConstructorClass mcc;
|
||||
};
|
||||
|
||||
void testFunction()
|
||||
{
|
||||
MyMethodClass mmc; // BAD: unused
|
||||
MyConstructorClass mcc; // GOOD
|
||||
MyDerivedClass mdc; // GOOD
|
||||
MyContainingClass mcc2; // GOOD
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
|
||||
int test_const_init()
|
||||
{
|
||||
int v1; // BAD: unused
|
||||
int v2; // GOOD
|
||||
int v3 = 0; // BAD: unused
|
||||
int v4 = 0; // GOOD
|
||||
const int v5 = 0; // BAD: unused [NOT DETECTED]
|
||||
const int v6 = 0; // GOOD
|
||||
constexpr int v7 = 0; // BAD: unused
|
||||
constexpr int v8 = 0; // GOOD
|
||||
|
||||
return v2 + v4 + v6 + v8;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
template<int i>
|
||||
void myFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void test_template_parameter()
|
||||
{
|
||||
constexpr int v1 = 0; // BAD: unused
|
||||
constexpr int v2 = 0; // GOOD: used as a template parameter below [FALSE POSITIVE]
|
||||
|
||||
myFunction<v2>();
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
class MyBuffer
|
||||
{
|
||||
public:
|
||||
unsigned char buffer[40];
|
||||
};
|
||||
|
||||
void test_unused()
|
||||
{
|
||||
MyBuffer myVar1; // BAD: unused
|
||||
MyBuffer myVar2; // GOOD: used in deliberate void cast below
|
||||
MyBuffer myVar3 __attribute((__unused__)); // GOOD: unused but acknowledged
|
||||
|
||||
(void)myVar2;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
#define likely(x) __builtin_expect ((x), 1)
|
||||
#define unlikely(x) __builtin_expect ((x), 0)
|
||||
|
||||
static int getter() {}
|
||||
|
||||
void test_expect()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 100000; i++)
|
||||
{
|
||||
int v1 = getter(); // GOOD: v1 is used
|
||||
int v2 = getter(); // GOOD: v2 is used
|
||||
int v3 = getter(); // BAD: unused
|
||||
|
||||
if (unlikely(v1 < 0))
|
||||
{
|
||||
int a = i;
|
||||
int b = a;
|
||||
a += b;
|
||||
b = -1;
|
||||
break;
|
||||
}
|
||||
if (__builtin_expect(v2, 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// semmle-extractor-options: --expect_errors
|
||||
void f_error(void) {
|
||||
int x, z;
|
||||
// There is an error in here, so we don't see the use of x. But we
|
||||
// still don't want to report it as unused.
|
||||
z = y + x;
|
||||
}
|
||||
|
||||
void g_error(void) {
|
||||
int x, y, z;
|
||||
// This one should be reported despite the error in another function.
|
||||
z = y + y;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
| unused_static_functions.cpp:19:13:19:14 | f2 | Static function f2 is unreachable | unused_static_functions.cpp:19:13:19:14 | f2 | f2 |
|
||||
| unused_static_functions.cpp:33:13:33:14 | f5 | Static function f5 is unreachable ($@ must be removed at the same time) | unused_static_functions.cpp:34:13:34:14 | f6 | f6 |
|
||||
| unused_static_functions.cpp:34:13:34:14 | f6 | Static function f6 is unreachable ($@ must be removed at the same time) | unused_static_functions.cpp:33:13:33:14 | f5 | f5 |
|
||||
| used_by_var_ref.c:8:13:8:13 | g | Static function g is unreachable ($@ must be removed at the same time) | used_by_var_ref.c:13:16:13:17 | n2 | n2 |
|
||||
| used_by_var_ref.c:10:13:10:13 | i | Static function i is unreachable ($@ must be removed at the same time) | used_by_var_ref.c:20:13:20:13 | k | k |
|
||||
| used_by_var_ref.c:20:13:20:13 | k | Static function k is unreachable | used_by_var_ref.c:20:13:20:13 | k | k |
|
||||
@@ -0,0 +1 @@
|
||||
Best Practices/Unused Entities/UnusedStaticFunctions.ql
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
// f1 is reachable via fs
|
||||
static void f1(void) { }
|
||||
|
||||
struct funstr {
|
||||
void (*someFun)(void);
|
||||
};
|
||||
|
||||
class myClass {
|
||||
public:
|
||||
static const funstr fs[];
|
||||
};
|
||||
|
||||
const funstr myClass::fs[] = {
|
||||
{ f1 },
|
||||
};
|
||||
|
||||
// f2 is unreachable
|
||||
static void f2(void) { }
|
||||
|
||||
// f3 is reachable via f4/pf3
|
||||
static void f3(void) { }
|
||||
|
||||
// f4 is reachable due to not being static
|
||||
void f4(void) {
|
||||
static void (*pf3)(void);
|
||||
|
||||
pf3 = f3;
|
||||
}
|
||||
|
||||
// f5 and f6 are mutually recursive unreachable static functions
|
||||
static void f6(void);
|
||||
static void f5(void) { f6(); }
|
||||
static void f6(void) { f5(); }
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
typedef struct _num_fun {
|
||||
int num;
|
||||
void (*fun)(void);
|
||||
} num_fun;
|
||||
|
||||
static void f(void) {} // Used, via n1
|
||||
static void g(void) {} // Not used (n2 is static)
|
||||
static void h(void) {} // Used, via n3, via j
|
||||
static void i(void) {} // Not used (k is static)
|
||||
|
||||
num_fun n1 = {1, f};
|
||||
static num_fun n2 = {1, g};
|
||||
static num_fun n3 = {1, h};
|
||||
|
||||
void j(void) { // Used (not static)
|
||||
num_fun n = n3;
|
||||
}
|
||||
|
||||
static void k(void) { // Not used (static)
|
||||
num_fun n = {1, i};
|
||||
n1.fun = i;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| test.cpp:5:13:5:18 | unused | Dead Code: this function is never called. |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/DeadCodeFunction.ql
|
||||
32
cpp/ql/test/query-tests/Critical/DeadCodeFunction/test.cpp
Normal file
32
cpp/ql/test/query-tests/Critical/DeadCodeFunction/test.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
static void usedByUnused() {
|
||||
}
|
||||
|
||||
static void unused() {
|
||||
usedByUnused();
|
||||
}
|
||||
|
||||
class Base {
|
||||
virtual void f() { }
|
||||
public:
|
||||
Base() { }
|
||||
|
||||
void process() {
|
||||
f();
|
||||
}
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
virtual void f() { }
|
||||
public:
|
||||
Derived() { }
|
||||
};
|
||||
|
||||
void caller() {
|
||||
Base b;
|
||||
Derived d;
|
||||
|
||||
b.process();
|
||||
d.process();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| file.c:8:15:8:19 | call to fopen | The file opened here may not be closed at $@. | file.c:12:13:12:19 | return ... | this exit point |
|
||||
| file.c:18:15:18:19 | call to fopen | The file opened here may not be closed at $@. | file.c:22:13:22:24 | return ... | this exit point |
|
||||
| file.c:66:5:66:34 | ... = ... | The file opened here may not be closed at $@. | file.c:74:5:74:13 | return ... | this exit point |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/FileMayNotBeClosed.ql
|
||||
@@ -0,0 +1 @@
|
||||
| file.c:34:15:34:19 | call to fopen | The file is never closed |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/FileNeverClosed.ql
|
||||
98
cpp/ql/test/query-tests/Critical/FileClosed/file.c
Normal file
98
cpp/ql/test/query-tests/Critical/FileClosed/file.c
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
typedef void FILE;
|
||||
FILE *fopen(const char *path, const char *mode);
|
||||
int fclose(FILE *fp);
|
||||
#define NULL ((FILE *)0)
|
||||
|
||||
void f1(int i) {
|
||||
FILE *f = fopen("somefile.txt", "r");
|
||||
|
||||
if (!f) return;
|
||||
|
||||
if (!i) return; // Not closed here
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
FILE *f2(int i) {
|
||||
FILE *f = fopen("somefile.txt", "r");
|
||||
|
||||
if (!f) return NULL;
|
||||
|
||||
if (!i) return NULL; // Not closed here
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void g2(int i) {
|
||||
FILE *f = f2(i);
|
||||
|
||||
fclose(f); // This makes the final return in f2 count as closed
|
||||
}
|
||||
|
||||
void f3(int i) {
|
||||
FILE *f = fopen("somefile.txt", "r"); // Never closed
|
||||
|
||||
if (!f) return;
|
||||
|
||||
if (!i) return;
|
||||
}
|
||||
|
||||
void f4(void) {
|
||||
FILE *f = fopen("somefile.txt", "r"); // Always closed
|
||||
|
||||
if (!f) return;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
FILE *f5(void) {
|
||||
FILE *f = fopen("somefile.txt", "r"); // Always closed, by g5
|
||||
|
||||
if (!f) return NULL;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void g5(void) {
|
||||
FILE *f = f5();
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int f6(int b) {
|
||||
FILE *f;
|
||||
|
||||
f = fopen("somefile.txt", "r"); // Not always closed
|
||||
|
||||
if (f) {
|
||||
if (b) {
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f7(void) {
|
||||
FILE *f;
|
||||
|
||||
f = fopen("somefile.txt", "r"); // Always closed
|
||||
|
||||
if (f) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int f8(void) {
|
||||
FILE *f;
|
||||
|
||||
if (f = fopen("somefile.txt", "r")) { // Always closed
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.cpp:16:13:16:14 | _t | This parameter of type $@ is 4096 bytes - consider passing a pointer/reference instead. | test.cpp:6:8:6:20 | myLargeStruct | myLargeStruct |
|
||||
| test.cpp:24:44:24:48 | mtc_t | This parameter of type $@ is 4096 bytes - consider passing a pointer/reference instead. | test.cpp:11:7:11:21 | myTemplateClass<myLargeStruct> | myTemplateClass<myLargeStruct> |
|
||||
| test.cpp:28:49:28:49 | b | This parameter of type $@ is 4096 bytes - consider passing a pointer/reference instead. | test.cpp:6:8:6:20 | myLargeStruct | myLargeStruct |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/LargeParameter.ql
|
||||
46
cpp/ql/test/query-tests/Critical/LargeParameter/test.cpp
Normal file
46
cpp/ql/test/query-tests/Critical/LargeParameter/test.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
struct mySmallStruct {
|
||||
char data[4];
|
||||
};
|
||||
|
||||
struct myLargeStruct {
|
||||
char data[4096];
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class myTemplateClass
|
||||
{
|
||||
public:
|
||||
myTemplateClass() {}
|
||||
|
||||
void set(T _t) { // BAD: T can be myLargeStruct, which is large
|
||||
t = _t;
|
||||
}
|
||||
|
||||
T t;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void myTemplateFunction(myTemplateClass<T> mtc_t) // BAD: T can be myLargeStruct, which is large
|
||||
{
|
||||
}
|
||||
|
||||
void myFunction1(mySmallStruct a, myLargeStruct b) // BAD: b is large
|
||||
{
|
||||
myTemplateClass<mySmallStruct> mtc_a;
|
||||
myTemplateClass<myLargeStruct> mtc_b;
|
||||
|
||||
mtc_a.set(a);
|
||||
mtc_b.set(b);
|
||||
|
||||
myTemplateFunction(mtc_a);
|
||||
myTemplateFunction(mtc_b);
|
||||
}
|
||||
|
||||
void myFunction2(mySmallStruct *a, myLargeStruct *b) // GOOD
|
||||
{
|
||||
}
|
||||
|
||||
void myFunction3(mySmallStruct &a, myLargeStruct &b) // GOOD
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:20:26:20:28 | ptr |
|
||||
| my_auto_ptr.cpp:26:12:26:14 | ptr |
|
||||
| my_auto_ptr.cpp:26:12:26:14 | ptr |
|
||||
| test.cpp:28:7:28:12 | array1 |
|
||||
| test.cpp:33:7:33:12 | array2 |
|
||||
| test.cpp:34:7:34:12 | array7 |
|
||||
| test.cpp:44:7:44:12 | array3 |
|
||||
| test.cpp:45:7:45:12 | array5 |
|
||||
| test.cpp:50:7:50:12 | array6 |
|
||||
| test.cpp:75:7:75:12 | array1 |
|
||||
| test.cpp:80:7:80:12 | array2 |
|
||||
| test.cpp:81:7:81:12 | array7 |
|
||||
| test.cpp:91:7:91:12 | array3 |
|
||||
| test.cpp:92:7:92:12 | array5 |
|
||||
| test.cpp:97:7:97:12 | array6 |
|
||||
| test.cpp:115:10:115:12 | mc2 |
|
||||
| test.cpp:125:8:125:9 | v1 |
|
||||
| test.cpp:126:8:126:9 | i2 |
|
||||
| test.cpp:127:8:127:9 | i3 |
|
||||
| test.cpp:128:15:128:16 | v4 |
|
||||
| virtual.cpp:18:10:18:10 | a |
|
||||
| virtual.cpp:19:10:19:10 | c |
|
||||
| virtual.cpp:38:10:38:10 | b |
|
||||
| virtual.cpp:39:10:39:10 | d |
|
||||
| virtual.cpp:46:9:46:9 | c |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user