feat: clang-tidy/sillycode

This commit is contained in:
张佳澈520370910044 2024-05-05 18:19:05 +08:00
parent 52a0383ddd
commit adb271587b
4 changed files with 330 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.json

5
CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.0)
project(MyProject)
add_executable(main sillycode.cpp)

62
conf.toml Normal file
View File

@ -0,0 +1,62 @@
skipGitea = true
[[stages]]
name = "prepare"
[stages.executor]
name = "sandbox"
[stages.executor.with.default]
args = ["cmake", "-S", ".", "-DDRONE=ON", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "-B", "build"]
env = ["PATH=/usr/bin:/bin"]
cpuLimit = 10_000_000_000
memoryLimit = 104_857_600
procLimit = 50
copyInCwd = true
copyOut = ["stdout"]
copyOutCached = ["build/compile_commands.json"]
[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 = "dummy"
[stages.parser.with]
score = 0
comment = ""
[[stages]]
name = "clang-tidy"
[stages.executor]
name = "sandbox"
[stages.executor.with.default]
args = ["clang-tidy", "--header-filter=.*", "--quiet", "-checks=*", "sillycode.cpp", "-p", "build"]
env = ["PATH=/usr/bin:/bin"]
cpuLimit = 10_000_000_000
memoryLimit = 104_857_600
procLimit = 50
copyInCwd = true
copyOut = ["stdout"]
[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.executor.with.default.copyInCached]
"build/compile_commands.json" = "build/compile_commands.json"
[stages.parser]
name = "clang-tidy"
[stages.parser.with]
score = 100
[[stages.parser.with.matches]]
keyword = ["cppcoreguidelines-avoid-non-const-global-variables"]
score = 5
[[stages.parser.with.matches]]
keyword = ["readability-identifier-length","misc-use-anonymous-namespace"]
score = 2
[[stages.parser.with.matches]]
keyword = ["llvmlibc-implementation-in-namespace"]
score = 0

262
src/sillycode.cpp Normal file
View File

@ -0,0 +1,262 @@
#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;