feat: new tests
This commit is contained in:
parent
e00e6bd275
commit
e740770605
|
@ -2,4 +2,4 @@ cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(MyProject)
|
project(MyProject)
|
||||||
|
|
||||||
add_executable(main src/sillycode.cpp)
|
add_executable(main src/simple.cpp)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
[{"name":"cppcheck","results":[{"score":95,"comment":"### Test results summary\n\n1. error: 1\n2. warning: 0\n3. portability: 0\n4. performance: 0\n5. style: 0\n6. information: 0\n7. debug: 0\n"}],"force_quit":false}]
|
[{"name":"cppcheck","results":[{"score":32,"comment":"### Test results summary\n\n1. error: 8\n2. warning: 3\n3. portability: 0\n4. performance: 0\n5. style: 22\n6. information: 3\n7. debug: 0\n"}],"force_quit":false}]
|
||||||
|
|
|
@ -1,262 +0,0 @@
|
||||||
// #include <vector>
|
|
||||||
|
|
||||||
// #include <gtest/test.h>
|
|
||||||
|
|
||||||
// #include <something.hh>
|
|
||||||
class Date {
|
|
||||||
// ...
|
|
||||||
public:
|
|
||||||
Month month() const; // do
|
|
||||||
int month(); // don't
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
void do_something(vector<string>& v)
|
|
||||||
{
|
|
||||||
string val;
|
|
||||||
cin >> val;
|
|
||||||
// ...
|
|
||||||
int index = 0; // bad
|
|
||||||
for (int i = 0; i < v.size(); ++i)
|
|
||||||
if (v[i] == val) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
struct X {
|
|
||||||
char ch;
|
|
||||||
int i;
|
|
||||||
string s;
|
|
||||||
char ch2;
|
|
||||||
|
|
||||||
X& operator=(const X& a); // NOLINT(clang-analyzer-valist.Uninitialized)
|
|
||||||
X(const X&);
|
|
||||||
};
|
|
||||||
|
|
||||||
X waste(const char* p)
|
|
||||||
{
|
|
||||||
if (p == nullptr) throw Nullptr_error{};
|
|
||||||
int n = strlen(p);
|
|
||||||
auto buf = new char[n];
|
|
||||||
if (buf == nullptr) throw Allocation_error{};
|
|
||||||
for (int i = 0; i < n; ++i) buf[i] = p[i];
|
|
||||||
// ... manipulate buffer ...
|
|
||||||
X x;
|
|
||||||
x.ch = 'a';
|
|
||||||
x.s = string(n); // give x.s space for *ps
|
|
||||||
for (int i = 0; i < x.s.size(); ++i) x.s[i] = buf[i]; // copy buf into x.s
|
|
||||||
delete buf;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void driver()
|
|
||||||
{
|
|
||||||
X x = waste("Typical argument");
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
class X { // BAD
|
|
||||||
int i;
|
|
||||||
string s;
|
|
||||||
int j;
|
|
||||||
public:
|
|
||||||
X() :i{666}, s{"qqq"} { } // j is uninitialized
|
|
||||||
X(int ii) :i{ii} {} // s is "" and j is uninitialized
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
class X2 {
|
|
||||||
int i {666};
|
|
||||||
string s {"qqq"};
|
|
||||||
int j {0};
|
|
||||||
public:
|
|
||||||
X2() = default; // all members are initialized to their defaults
|
|
||||||
X2(int ii) :i{ii} {} // s and j initialized to their defaults
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
class X3 { // BAD: inexplicit, argument passing overhead
|
|
||||||
int i;
|
|
||||||
string s;
|
|
||||||
int j;
|
|
||||||
public:
|
|
||||||
X3(int ii = 666, const string& ss = "qqq", int jj = 0)
|
|
||||||
:i{ii}, s{ss}, j{jj} { } // all members are initialized to their defaults
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
string s;
|
|
||||||
int i;
|
|
||||||
public:
|
|
||||||
Foo& operator=(Foo&& a);
|
|
||||||
// ...
|
|
||||||
};
|
|
||||||
|
|
||||||
Foo& Foo::operator=(Foo&& a) // OK, but there is a cost
|
|
||||||
{
|
|
||||||
if (this == &a) return *this; // this line is redundant
|
|
||||||
s = std::move(a.s);
|
|
||||||
i = a.i;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class Vector2 {
|
|
||||||
// ...
|
|
||||||
Vector2(Vector2&& a) { *this = a; } // just use the copy
|
|
||||||
Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy
|
|
||||||
//...
|
|
||||||
public:
|
|
||||||
T* elem;
|
|
||||||
int sz;
|
|
||||||
};
|
|
||||||
|
|
||||||
void f2(N::X& a, N::X& b)
|
|
||||||
{
|
|
||||||
swap(a,b); // calls N::swap
|
|
||||||
}
|
|
||||||
|
|
||||||
void f3(N::X& a, N::X& b)
|
|
||||||
{
|
|
||||||
using std::swap; // make std::swap available
|
|
||||||
swap(a,b); // calls N::swap if it exists, otherwise std::swap
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// webcolors.h (third party header)
|
|
||||||
#define RED 0xFF0000
|
|
||||||
#define GREEN 0x00FF00
|
|
||||||
#define BLUE 0x0000FF
|
|
||||||
|
|
||||||
// productinfo.h
|
|
||||||
// The following define product subtypes based on color
|
|
||||||
#define RED 0
|
|
||||||
#define PURPLE 1
|
|
||||||
#define BLUE 2
|
|
||||||
|
|
||||||
int webby = BLUE; // webby==2; probably not what was desired
|
|
||||||
|
|
||||||
enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
|
|
||||||
enum class Productinfo { red=0, purple=1, blue=2 };
|
|
||||||
|
|
||||||
int webby = blue; // error: be specific
|
|
||||||
Webcolor webby = Webcolor::blue;
|
|
||||||
|
|
||||||
enum Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
|
|
||||||
enum Productinfo { red=0, purple=1, blue=2 };
|
|
||||||
|
|
||||||
int webby = blue; // error, ambiguous: be specific
|
|
||||||
Webcolor webby = Webcolor::blue;
|
|
||||||
|
|
||||||
enum class Webcolor { red=0xFF0000, green=0x00FF00, blue=0x0000FF };
|
|
||||||
enum class Productinfo { red=0, purple=1, blue=2 };
|
|
||||||
|
|
||||||
int webby = blue; // error: blue undefined in this scope
|
|
||||||
Webcolor webby = Webcolor::blue;
|
|
||||||
|
|
||||||
|
|
||||||
void sink(unique_ptr<widget>); // consumes the widget
|
|
||||||
|
|
||||||
void sink(widget*); // just uses the widget
|
|
||||||
|
|
||||||
void thinko(const unique_ptr<widget>&); // usually not what you want
|
|
||||||
|
|
||||||
void reseat(unique_ptr<widget>&); // "will" or "might" reseat pointer
|
|
||||||
|
|
||||||
constexpr int max = 8*1024;
|
|
||||||
int buf[max]; // OK, but suspicious: uninitialized
|
|
||||||
f.read(buf, max);
|
|
||||||
|
|
||||||
constexpr int max = 8*1024;
|
|
||||||
int buf[max] = {0}; // better in some situations
|
|
||||||
f.read(buf, max);
|
|
||||||
|
|
||||||
string s; // s is default initialized to ""
|
|
||||||
cin >> s; // s expands to hold the string
|
|
||||||
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
Value v = [&] {
|
|
||||||
auto p = get_value(); // get_value() returns a pair<error_code, Value>
|
|
||||||
ec = p.first;
|
|
||||||
return p.second;
|
|
||||||
}();
|
|
||||||
|
|
||||||
Value v = [] {
|
|
||||||
auto p = get_value(); // get_value() returns a pair<error_code, Value>
|
|
||||||
if (p.first) throw Bad_value{p.first};
|
|
||||||
return p.second;
|
|
||||||
}();
|
|
||||||
|
|
||||||
SomeLargeType var; // ugly CaMeLcAsEvArIaBlE
|
|
||||||
|
|
||||||
if (cond) // some non-trivial condition
|
|
||||||
Set(&var);
|
|
||||||
else if (cond2 || !cond3) {
|
|
||||||
var = Set2(3.14);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var = 0;
|
|
||||||
for (auto& e : something)
|
|
||||||
var += e;
|
|
||||||
}
|
|
||||||
|
|
||||||
string var = [&]{
|
|
||||||
if (!in) return ""; // default
|
|
||||||
string s;
|
|
||||||
for (char c : in >> c)
|
|
||||||
s += toupper(c);
|
|
||||||
return s;
|
|
||||||
}(); // note ()
|
|
||||||
|
|
||||||
void use(int n)
|
|
||||||
{
|
|
||||||
switch (n) { // good
|
|
||||||
case 0: // ...
|
|
||||||
case 7: // ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int n = numeric_limits<int>::max();
|
|
||||||
int m = n + 1; // bad
|
|
||||||
|
|
||||||
std::string s = "hello world";
|
|
||||||
double* p = (double*)(&s); // BAD
|
|
||||||
|
|
||||||
class base { public: virtual ~base() = 0; };
|
|
||||||
|
|
||||||
class derived1 : public base { };
|
|
||||||
|
|
||||||
class derived2 : public base {
|
|
||||||
std::string s;
|
|
||||||
public:
|
|
||||||
std::string get_s() { return s; }
|
|
||||||
};
|
|
||||||
|
|
||||||
derived1 d1;
|
|
||||||
base* p = &d1; // ok, implicit conversion to pointer to base is fine
|
|
||||||
|
|
||||||
derived2* p2 = (derived2*)(p); // BAD, tries to treat d1 as a derived2, which it is not
|
|
||||||
cout << p2.get_s(); // tries to access d1's nonexistent string member, instead sees arbitrary bytes near d1
|
|
||||||
|
|
||||||
void f(const int& i) {
|
|
||||||
(int&)(i) = 42; // BAD
|
|
||||||
}
|
|
||||||
|
|
||||||
static int i = 0;
|
|
||||||
static const int j = 0;
|
|
||||||
|
|
||||||
f(i); // silent side effect
|
|
||||||
f(j); // undefined behavior
|
|
||||||
|
|
||||||
|
|
||||||
auto x = m*v1 + vv; // multiply m with v1 and add the result to vv
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < max; ++i); // bug waiting to happen
|
|
||||||
if (i == j)
|
|
||||||
return i;
|
|
143
src/simple.cpp
Normal file
143
src/simple.cpp
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#include <climits>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Uninitialized member warning
|
||||||
|
class BadClass {
|
||||||
|
int uninitMember;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BadClass() {} // Missing member initialization
|
||||||
|
void print() { std::cout << uninitMember << std::endl; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memory leak and resource management warnings
|
||||||
|
void memoryLeaks() {
|
||||||
|
int *ptr = new int(42);
|
||||||
|
// Missing delete - memory leak
|
||||||
|
|
||||||
|
int *array = new int[100];
|
||||||
|
delete ptr; // Wrong deletion type for array
|
||||||
|
|
||||||
|
// Double deletion
|
||||||
|
int *doubleDel = new int(5);
|
||||||
|
delete doubleDel;
|
||||||
|
delete doubleDel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null pointer dereferencing
|
||||||
|
void nullPointerDereference(int *ptr) {
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
*ptr = 42; // Dereferencing null pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array bounds warnings
|
||||||
|
void arrayBoundsIssues() {
|
||||||
|
int arr[5];
|
||||||
|
for (int i = 0; i <= 5; i++) { // Off-by-one error
|
||||||
|
arr[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using uninitialized array
|
||||||
|
int uninitArr[10];
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
sum += uninitArr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unused variables and dead code
|
||||||
|
void unusedVariables() {
|
||||||
|
int unused = 42;
|
||||||
|
std::string neverUsed = "hello";
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
int unreachable = 10;
|
||||||
|
} else {
|
||||||
|
// Dead code
|
||||||
|
std::cout << "This will never execute" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integer overflow
|
||||||
|
void integerOverflow() {
|
||||||
|
int max = INT_MAX;
|
||||||
|
max += 1; // Overflow
|
||||||
|
|
||||||
|
unsigned int i = 0;
|
||||||
|
for (i = 10; i >= 0; i--) { // Infinite loop due to unsigned underflow
|
||||||
|
std::cout << i << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource leak in exception
|
||||||
|
void resourceLeak() {
|
||||||
|
FILE *file = fopen("nonexistent.txt", "r");
|
||||||
|
// Missing fclose and no exception handling
|
||||||
|
char buffer[100];
|
||||||
|
fgets(buffer, 100, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninitialized variable usage
|
||||||
|
void uninitializedVariables() {
|
||||||
|
int x;
|
||||||
|
if (x > 0) { // Using x without initialization
|
||||||
|
std::cout << "x is positive" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool flag;
|
||||||
|
while (flag) { // Using uninitialized flag
|
||||||
|
std::cout << "Loop" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Division by zero
|
||||||
|
void divisionByZero(int divisor) {
|
||||||
|
int result = 100 / divisor; // No check for zero
|
||||||
|
}
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
void normalFunction() {}
|
||||||
|
virtual void virtualFunction() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {
|
||||||
|
public:
|
||||||
|
void normalFunction() {} // Hiding base class function
|
||||||
|
void virtualFunction() {} // Missing override keyword
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Memory management issues
|
||||||
|
memoryLeaks();
|
||||||
|
|
||||||
|
// Null pointer issues
|
||||||
|
int *nullPtr = nullptr;
|
||||||
|
nullPointerDereference(nullPtr);
|
||||||
|
|
||||||
|
// Array issues
|
||||||
|
arrayBoundsIssues();
|
||||||
|
|
||||||
|
// Dead code and unused variables
|
||||||
|
unusedVariables();
|
||||||
|
|
||||||
|
// Integer issues
|
||||||
|
integerOverflow();
|
||||||
|
|
||||||
|
// Resource management
|
||||||
|
resourceLeak();
|
||||||
|
|
||||||
|
// Uninitialized variables
|
||||||
|
uninitializedVariables();
|
||||||
|
|
||||||
|
// Division by zero
|
||||||
|
divisionByZero(0);
|
||||||
|
|
||||||
|
// Object slicing
|
||||||
|
Derived derived;
|
||||||
|
Base base = derived; // Object slicing
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user