From e740770605acd5a003db18afde1b1e829fd2bfec Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sun, 3 Nov 2024 01:19:54 -0500 Subject: [PATCH] feat: new tests --- CMakeLists.txt | 2 +- expected.json | 2 +- src/sillycode.cpp | 262 ---------------------------------------------- src/simple.cpp | 143 +++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 264 deletions(-) delete mode 100644 src/sillycode.cpp create mode 100644 src/simple.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 354597d..a4f298a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,4 +2,4 @@ cmake_minimum_required(VERSION 3.0) project(MyProject) -add_executable(main src/sillycode.cpp) +add_executable(main src/simple.cpp) diff --git a/expected.json b/expected.json index 827d1c1..844fe69 100644 --- a/expected.json +++ b/expected.json @@ -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}] diff --git a/src/sillycode.cpp b/src/sillycode.cpp deleted file mode 100644 index e743a7d..0000000 --- a/src/sillycode.cpp +++ /dev/null @@ -1,262 +0,0 @@ -// #include - -// #include - -// #include -class Date { - // ... -public: - Month month() const; // do - int month(); // don't - // ... -}; - -void do_something(vector& 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 -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); // consumes the widget - -void sink(widget*); // just uses the widget - -void thinko(const unique_ptr&); // usually not what you want - -void reseat(unique_ptr&); // "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 - ec = p.first; - return p.second; -}(); - -Value v = [] { - auto p = get_value(); // get_value() returns a pair - 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::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; diff --git a/src/simple.cpp b/src/simple.cpp new file mode 100644 index 0000000..d266608 --- /dev/null +++ b/src/simple.cpp @@ -0,0 +1,143 @@ +#include +#include +#include + +// 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; +}