clang-tidy parser and executor #26
							
								
								
									
										1
									
								
								examples/clang-tidy/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								examples/clang-tidy/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | ||||||
| *.json |  | ||||||
|  | @ -1,5 +0,0 @@ | ||||||
| cmake_minimum_required(VERSION 3.0) |  | ||||||
| 
 |  | ||||||
| project(MyProject) |  | ||||||
| 
 |  | ||||||
| add_executable(main sillycode.cpp) |  | ||||||
|  | @ -1,62 +0,0 @@ | ||||||
| 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 |  | ||||||
|  | @ -1 +1 @@ | ||||||
| Subproject commit adb271587b82936a092a1675213a4924782e9018 | Subproject commit a2c3c2f9141a769968858ab77fce45bbd2e408b5 | ||||||
|  | @ -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; |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user