From f43b0b3a7b873ee935b19e4e5f26a8ceda7d3d61 Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Sat, 27 Apr 2024 15:13:21 -0400 Subject: [PATCH] feat: init --- README.md | 3 + conf.toml | 34 ++++++ expected.json | 1 + src/sillycode.cpp | 262 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+) create mode 100644 README.md create mode 100644 conf.toml create mode 100644 expected.json create mode 100644 src/sillycode.cpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..205fc8d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# cpplint sillycode + +From . diff --git a/conf.toml b/conf.toml new file mode 100644 index 0000000..11d4bfc --- /dev/null +++ b/conf.toml @@ -0,0 +1,34 @@ +skipGitea = true +[[stages]] +name = "keyword" +[stages.executor] +name = "sandbox" +[stages.executor.with.default] +args = ["bash", "-c", "cpplint src/*.cpp"] +env = ["PATH=/usr/bin:/bin:/usr/local/bin"] +cpuLimit = 10_000_000_000 +memoryLimit = 104_857_600 +procLimit = 50 +copyInCwd = true +copyOut = ["stdout", "stderr"] +[stages.executor.with.default.stdin] +content = "" +[stages.executor.with.default.stdout] +name = "stdout" +max = 65_536 +[stages.executor.with.default.stderr] +name = "stderr" +max = 65_536 +[stages.parser] +name = "keyword" +[stages.parser.with] +fullScore = 100 +minScore = 0 +files = ["stderr"] +endOnMatch = true +[[stages.parser.with.matches]] +keyword = "[legal/copyright]" +score = 5 +[[stages.parser.with.matches]] +keyword = "[runtime/references]" +score = 2 diff --git a/expected.json b/expected.json new file mode 100644 index 0000000..6ed58cf --- /dev/null +++ b/expected.json @@ -0,0 +1 @@ +[{"name":"keyword","results":[{"score":85,"comment":"Matched keyword 1 time(s): [legal/copyright]\nMatched keyword 5 time(s): [runtime/references]\n"}]}] diff --git a/src/sillycode.cpp b/src/sillycode.cpp new file mode 100644 index 0000000..45c294d --- /dev/null +++ b/src/sillycode.cpp @@ -0,0 +1,262 @@ +#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;