diff --git a/cpp/ql/test/examples/BadLocking/AV Rule 107.expected b/cpp/ql/test/examples/BadLocking/AV Rule 107.expected new file mode 100644 index 00000000000..521d787b752 --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/AV Rule 107.expected @@ -0,0 +1,2 @@ +| UnintendedDeclaration.cpp:48:2:48:22 | declaration | Functions should be declared at file scope, not inside blocks. | +| UnintendedDeclaration.cpp:69:2:69:27 | declaration | Functions should be declared at file scope, not inside blocks. | diff --git a/cpp/ql/test/examples/BadLocking/AV Rule 107.qlref b/cpp/ql/test/examples/BadLocking/AV Rule 107.qlref new file mode 100644 index 00000000000..57f35c3bcf2 --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/AV Rule 107.qlref @@ -0,0 +1 @@ +jsf/4.13 Functions/AV Rule 107.ql diff --git a/cpp/ql/test/examples/BadLocking/DeclStmts.expected b/cpp/ql/test/examples/BadLocking/DeclStmts.expected new file mode 100644 index 00000000000..617563ec7e2 --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/DeclStmts.expected @@ -0,0 +1,7 @@ +| UnintendedDeclaration.cpp:41:2:41:29 | declaration | myLock | Variable | +| UnintendedDeclaration.cpp:48:2:48:22 | declaration | myLock | Function | +| UnintendedDeclaration.cpp:55:2:55:20 | declaration | myLock | Variable | +| UnintendedDeclaration.cpp:62:2:62:22 | declaration | myMutex | Variable | +| UnintendedDeclaration.cpp:69:2:69:27 | declaration | myLock | Function | +| UnintendedDeclaration.cpp:79:3:79:34 | declaration | myLock | Variable | +| UnintendedDeclaration.cpp:86:3:86:27 | declaration | memberMutex | Variable | diff --git a/cpp/ql/test/examples/BadLocking/DeclStmts.ql b/cpp/ql/test/examples/BadLocking/DeclStmts.ql new file mode 100644 index 00000000000..772daa66f46 --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/DeclStmts.ql @@ -0,0 +1,18 @@ +import cpp + +string describe(Declaration d) +{ + ( + d instanceof Variable and + result = "Variable" + ) or ( + d instanceof Function and + result = "Function" + ) +} + +from DeclStmt ds, Declaration d +where + ds.getADeclaration() = d +select + ds, concat(d.getName(), ", "), concat(describe(d), ", ") diff --git a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected new file mode 100644 index 00000000000..f57dd9581ba --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected @@ -0,0 +1 @@ +| UnintendedDeclaration.cpp:62:14:62:20 | definition of myMutex | Local variable myMutex hides $@ with the same name. | UnintendedDeclaration.cpp:37:7:37:13 | myMutex | a global variable | diff --git a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.qlref b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.qlref new file mode 100644 index 00000000000..0267b31251d --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.qlref @@ -0,0 +1 @@ +Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql diff --git a/cpp/ql/test/examples/BadLocking/UnintendedDeclaration.cpp b/cpp/ql/test/examples/BadLocking/UnintendedDeclaration.cpp new file mode 100644 index 00000000000..b449be466a1 --- /dev/null +++ b/cpp/ql/test/examples/BadLocking/UnintendedDeclaration.cpp @@ -0,0 +1,93 @@ + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + +private: + // ... +}; + +template +class Lock +{ +public: + Lock() : m(0) + { + } + + Lock(T &_m) : m(&_m) + { + m->lock(); + } + + ~Lock() + { + m->unlock(); + } + +private: + T *m; +}; + +Mutex myMutex; + +void test1() +{ + Lock myLock(myMutex); // GOOD (creates `myLock` on `myMutex`) + + // ... +} + +void test2() +{ + Lock myLock(); // BAD (interpreted as a function declaration, this does nothing) + + // ... +} + +void test3() +{ + Lock myLock; // GOOD (creates an uninitialized variable called `myLock`, probably intended) + + // ... +} + +void test4() +{ + Lock(myMutex); // BAD (creates an uninitialized variable called `myMutex`, probably not intended) + + // ... +} + +void test5() +{ + Lock myLock(Mutex); // BAD (interpreted as a function declaration, this does nothing) + + // ... +} + +class MyTestClass +{ +public: + void test6() + { + Lock myLock(memberMutex); // GOOD (creates `myLock` on `memberMutex`) + + // ... + } + + void test7() + { + Lock(memberMutex); // BAD (creates an uninitialized variable called `memberMutex`, probably not intended) [NOT DETECTED] + + // ... + } + +private: + Mutex memberMutex; +};