Top Banner
The Current State of (Free) Static Analysis Copyright 2015 Jason Turner @lefticus 1 / 65
65

Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Mar 17, 2018

Download

Documents

duongquynh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

The Current State of (Free) StaticAnalysis

Copyright 2015 Jason Turner @lefticus 1 / 65

Page 2: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Jason Turner

- Open Session Thursday (tomorrow) morning at 8:00-8:45

Independent Contractor

http://github.com/lefticus/presentationshttp://cppcast.comhttp://chaiscript.comhttp://cppbestpractices.com

Copyright 2015 Jason Turner @lefticus 2 / 65

Page 3: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Static Analysishttps://en.wikipedia.org/wiki/Static_program_analysis

Static program analysis is the analysis of computer software thatis performed without actually executing programs...

We will be focusing onsource code analysis (as opposed to object code)tools that are freely availableissues I've seen in the wild

Technically static analysis includes compiler warningsmodern compiler warnings are very sophisticated, and include things that used to beconsidered 'analysis' (ex: analysis of printf formatting issues occurs on GCC with noextra warnings enabled)compiler warnings will only be brought up if they are unique to a particular compiler

Copyright 2015 Jason Turner @lefticus 3 / 65

Page 4: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Toolscppcheckclang's analyzermsvc++ analyzecoverity's 'scan' (free for open source projects)

Honorable Mentionmetrix++copy-paste detectors

Copyright 2015 Jason Turner @lefticus 4 / 65

Page 5: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Just Scratching The SurfaceThere are dozens (hundreds?) of code analysis tools available.cppcheck has clang has MSVC has

320 checks56 checks~286 checks

Copyright 2015 Jason Turner @lefticus 5 / 65

Page 6: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Let's Play: Spot the Bug

Copyright 2015 Jason Turner @lefticus 6 / 65

Page 7: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

assert#include <cassert>

bool do_something(int &i){ ++i; return i < 10;}

int main(){ int i = 0;

assert(do_something(i));

}

Copyright 2015 Jason Turner @lefticus 7 / 65

Page 8: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

assert#include <cassert>

bool do_something(int &i){ ++i; return i < 10;}

int main(){ int i = 0;

// what happens in a release build? assert(do_something(i)); // warning: i is initialized but unused}

Copyright 2015 Jason Turner @lefticus 8 / 65

Page 9: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

assert#include <cassert>

bool do_something(int &i){ ++i; return i < 10;}

int main(){ int i = 0;

// what happens in a release build? assert(do_something(i)); if (i > 2) { /* ... */ } // no warning}

Copyright 2015 Jason Turner @lefticus 9 / 65

Page 10: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

assert - ConclusionsNo tool tested complained as long as i was used.clang and cppcheck say they are supposed to catch assert statements with side effects

Copyright 2015 Jason Turner @lefticus 10 / 65

Page 11: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

branching.1bool test_value_1() { return true; }

bool do_something(){ if (test_value_1()) {

return true; } else {

return true; }}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 11 / 65

Page 12: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

branching.1bool test_value_1() { return true; }

bool do_something(){ if (test_value_1()) {

return true; } else { // pointless duplication return true; }}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 12 / 65

Page 13: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

branching.2bool test_value_1() { return true; }bool test_value_2() { return true; }

bool do_something(){ if (test_value_1()) {

if (test_value_2()) { return true; }

return true; }

return false;}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 13 / 65

Page 14: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

branching.2bool test_value_1() { return true; }bool test_value_2() { return true; }

bool do_something(){ if (test_value_1()) { // this test is useless if (test_value_2()) { return true; }

return true; }

return false;}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 14 / 65

Page 15: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

branching - Duplicate Branch -Conclusions

Only cppcheck caught either caseSurprisingly, this more complicated case was caught by Coverity Scan in ChaiScript

if (rt.bare_equal(boxed_type)){ if (lt.bare_equal(boxed_pod_type)) { return true; }

return true;}

It is unknown why our simplified case was not caught by coverity.

Copyright 2015 Jason Turner @lefticus 15 / 65

Page 16: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.1// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

for (unsigned l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 16 / 65

Page 17: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.1// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^32 elements for (unsigned l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 17 / 65

Page 18: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.2// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

for (long l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 18 / 65

Page 19: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.2// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^63 elements for (long l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 19 / 65

Page 20: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

for (int l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 20 / 65

Page 21: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^31 elements for (int l = 0; l < v.size(); ++l) { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 21 / 65

Page 22: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^31 elements for (int l = 0; l < v.size(); ++l) // what else is odd? { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 22 / 65

Page 23: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^31 elements for (int l = 0; l < v.size(); ++l) // Empty vector { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 23 / 65

Page 24: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^31 elements for (int l = 0; l < v.size(); ++l) // Anything else odd? { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 24 / 65

Page 25: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision.3// Assume modern 64bit platform#include <vector>#include <iostream>

int main(){ std::vector<int> v;

// this is bad because it limits the loop to 2^31 elements for (int l = 0; l < v.size(); ++l) // We should be using a range-based loop { std::cout << v[l] << '\n'; }}

Copyright 2015 Jason Turner @lefticus 25 / 65

Page 26: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision - Loss of Sign and Size -Conclusion

clang and MSVC warn about sign comparisonsNo tool catches both

Bonus

cppcheck warns us we are iterating over an empty vectorclang-tidy's modernize checks warn us the loop should be a range based loop

Copyright 2015 Jason Turner @lefticus 26 / 65

Page 27: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

precision - Real WorldAdapted from http://googleresearch.blogspot.no/2006/06/extra-extra-read-all-about-it-nearly.html

#include <vector>

uint64_t binarySearch(const std::vector <int64_t> &v, int64_t key) { int low = 0; int high = v.size() - 1; // loss of precision

while (low <= high) { int mid = (low + high) / 2; int64_t midVal = v[mid]; // What happens with > 2B objects?

if (midVal < key) { low = mid + 1; } else if (midVal > key) { high = mid - 1; } else { return mid; // key found } }

return -(low + 1); // key not found. What if negative?}

int main(){ return binarySearch(std::vector<int64_t>{1,2,3,4,5}, 2);}

Copyright 2015 Jason Turner @lefticus 27 / 65

Page 28: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

deadcode#include <system_error>

enum Enum{ Value1, Value2, Value3};

int go(Enum t_enum) { switch (t_enum) { case Enum::Value1: return 0; case Enum::Value2: return 1; default: throw std::runtime_error("unknown value"); } throw std::runtime_error("unknown value"); }

int main(){ go(Enum::Value3);}

Copyright 2015 Jason Turner @lefticus 28 / 65

Page 29: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

deadcode#include <system_error>

enum Enum{ Value1, Value2, Value3};

int go(Enum t_enum) { switch (t_enum) { case Enum::Value1: return 0; case Enum::Value2: return 1; default: throw std::runtime_error("unknown value"); } throw std::runtime_error("unknown value");// this code is unreachable}

int main(){ go(Enum::Value3);}

Copyright 2015 Jason Turner @lefticus 29 / 65

Page 30: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

deadcode - ConclusionsMSVC warns about this in the IDEclang warns with -Weverything / clang-tidy warns

Bonus

coverity scan notes that the throw is unhandled in main

Copyright 2015 Jason Turner @lefticus 30 / 65

Page 31: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr.1void do_something(){ int *i = nullptr;

*i = 5;}

int main(){ null_dereference_1();}

Copyright 2015 Jason Turner @lefticus 31 / 65

Page 32: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr.1void do_something(){ int *i = nullptr; // dereferencing obviously null value *i = 5;}

int main(){ null_dereference_1();}

Copyright 2015 Jason Turner @lefticus 32 / 65

Page 33: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr.2int *get_i() { return nullptr;}

void do_something() { int *i = get_i();

*i = 5;}

int main(){ null_dereference_2();}

Copyright 2015 Jason Turner @lefticus 33 / 65

Page 34: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr.2int *get_i() { return nullptr;}

void do_something() { int *i = get_i(); // Indirect dereference *i = 5;}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 34 / 65

Page 35: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr.3#include <memory>

void do_something(){ std::shared_ptr<int> i; // dereferencing obviously null value *i = 5;}

int main(){ do_something();}

Copyright 2015 Jason Turner @lefticus 35 / 65

Page 36: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

nullptr - Null Dereferences -Conclusions

Everyone caught the obvious oneOnly cppcheck could catch the indirect nullptr dereferenceNo tools could catch the smart pointer version

Copyright 2015 Jason Turner @lefticus 36 / 65

Page 37: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

arrayint main(){ int a[5]; return a[5];}

Copyright 2015 Jason Turner @lefticus 37 / 65

Page 38: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

arrayint main(){ int a[5]; return a[5]; // indexing past end of array}

Copyright 2015 Jason Turner @lefticus 38 / 65

Page 39: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

std::array#include <array>

int main(){ std::array<int, 5> a; return a[5];}

Copyright 2015 Jason Turner @lefticus 39 / 65

Page 40: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

std::array#include <array>

int main(){ std::array<int, 5> a; return a[5]; // indexing past end of array}

Copyright 2015 Jason Turner @lefticus 40 / 65

Page 41: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

array - ConclusionsThe c-style array is caught by all toolsstd::array issue is only caught by cppcheck

Bonus

MSVC notices that the c-style array is used uninitialized.

Copyright 2015 Jason Turner @lefticus 41 / 65

Page 42: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.1#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value = 1;

return [&some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 42 / 65

Page 43: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.1#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value = 1;

// some_value won't exist when this function is returned return [&some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 43 / 65

Page 44: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.2#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value;

return [some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 44 / 65

Page 45: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.2#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value;

// some_value is used uninitialized return [some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 45 / 65

Page 46: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.3#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value;

return [&some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 46 / 65

Page 47: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas.3#include <functional>#include <iostream>

std::function<void ()> do_something(){ int some_value;

// uninitialized and captured local by reference return [&some_value](){ std::cout << some_value << '\n'; };}

int main(){ const auto f = do_something(); f();}

Copyright 2015 Jason Turner @lefticus 47 / 65

Page 48: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

lambdas - Capture Local - Conclusionscppcheck, clang, and coverity got confused as to whether the variable was initialized ifcaptured by referencemsvc caught nothing

No tool warned about the actual capture local by reference and return

Copyright 2015 Jason Turner @lefticus 48 / 65

Page 49: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

&&#include <utility>

struct Object { void do_something() {}};

void take(Object &&) { }

void do(){ Object o; take(std::move(o)); o.do_something();}

int main(){ do();}

Copyright 2015 Jason Turner @lefticus 49 / 65

Page 50: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

&&#include <utility>

struct Object { void do_something() {}};

void take(Object &&) { }

void do(){ Object o; take(std::move(o)); o.do_something(); // use of local after move}

int main(){ do();}

Copyright 2015 Jason Turner @lefticus 50 / 65

Page 51: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

&& - Use After Move - ConclusionsNo tool commented on this problem at all.

Bonus

cppcheck points out that technically Object::do_something can be static

Copyright 2015 Jason Turner @lefticus 51 / 65

Page 52: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

bonus slide - iterator mismatch#include <vector>

int main(){ std::vector<int> v; std::vector<int> v2(2,4); std::vector<int> v3(3,4);

v.insert(v.begin(), v2.begin(), v3.end());}

Copyright 2015 Jason Turner @lefticus 52 / 65

Page 53: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

bonus slide - iterator mismatch#include <vector>

int main(){ std::vector<int> v; std::vector<int> v2(2,4); std::vector<int> v3(3,4);

v.insert(v.begin(), v2.begin(), v3.end()); // coverity catches this}

Copyright 2015 Jason Turner @lefticus 53 / 65

Page 54: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

bonus slide - pointer invalidation#include <memory>

int main(){ auto s = std::make_shared<int>(1);

int *p = s.get(); *p = 1;

s = std::make_shared<int>(2); *p = 5;}

Copyright 2015 Jason Turner @lefticus 54 / 65

Page 55: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

bonus slide - pointer invalidation#include <memory>

int main(){ auto s = std::make_shared<int>(1);

int *p = s.get(); *p = 1;

s = std::make_shared<int>(2); // nobody catches this yet *p = 5;}

Copyright 2015 Jason Turner @lefticus 55 / 65

Page 56: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Honorable Mention - metrix++analyzes code for various metricscan calculate - a measure of code's complexity -and warn on overly complex sections of code

cyclomatic complexity

static Common_Types get_common_type(const Boxed_Value &t_bv) { const Type_Info &inp_ = t_bv.get_type_info();

if (inp_ == typeid(int)) { return get_common_type(sizeof(int), true); } else if (inp_ == typeid(double)) { return Common_Types::t_double; } else if (inp_ == typeid(long double)) { return Common_Types::t_long_double; } else if (inp_ == typeid(float)) { return Common_Types::t_float; } else if (inp_ == typeid(char)) { return get_common_type(sizeof(char), std::is_signed<char>::value); } else if (inp_ == typeid(unsigned char)) { return get_common_type(sizeof(unsigned char), false); } else if (inp_ == typeid(unsigned int)) { return get_common_type(sizeof(unsigned int), false); } else if (inp_ == typeid(long)) { return get_common_type(sizeof(long), true); } else if (inp_ == typeid(unsigned long)) { return get_common_type(sizeof(unsigned long), false); /* etc... */

Copyright 2015 Jason Turner @lefticus 56 / 65

Page 57: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Honorable Mention - Copy-Paste-Detectors

From the project can detect duplicated code throughout your code basePMD } else { if (*s == '\\') { if (is_escaped) { match.push_back('\\'); is_escaped = false; } else { is_escaped = true; } } else { if (is_escaped) { switch (*s) { case ('b') : match.push_back('\b'); break; case ('f') : match.push_back('\f'); break; case ('n') : match.push_back('\n'); break; case ('r') : match.push_back('\r'); break; case ('t') : match.push_back('\t'); break; case ('\'') : match.push_back('\''); break; case ('\"') : match.push_back('\"'); break; case ('$') : match.push_back('$'); break;

Copyright 2015 Jason Turner @lefticus 57 / 65

Page 58: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Downsides - False Positives#include <vector>

template<typename T>T add(T t, T u){ return t + u;}

template<typename ... T>std::vector<int> add_values(int value, T ... t){ return {add(t, value)...};}

int main(){ add_values(4);}

Copyright 2015 Jason Turner @lefticus 58 / 65

Page 59: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Downsides - False Positives#include <vector>

template<typename T>T add(T t, T u){ return t + u;}

template<typename ... T>std::vector<int> add_values(int value, T ... t){ return {add(t, value)...}; // msvc complains `value` is unused in 0th case}

int main(){ add_values(4);}

Copyright 2015 Jason Turner @lefticus 59 / 65

Page 60: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

downsides - false sense of securityChaiScript passed all of these analyzers (plus some free trials of commercials ones).

And then we discovered the sanitizers.

And a few more issues were found.

And then we discovered fuzzy testing

And MANY more issues were found.

Copyright 2015 Jason Turner @lefticus 60 / 65

Page 61: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Real World Cleanupbool Switch() { bool retval = false;

size_t prev_stack_top = m_match_stack.size();

if (Keyword("switch")) { retval = true;

if (!Char('(')) { throw exception::eval_error("Incomplete 'switch' expression", File_Position(m_line, m_col), *m_filename); /* snip */ while (Eol()) {}

if (Char('{')) { retval = true; /* snip */ }

build_match(AST_NodePtr(new eval::Switch_AST_Node()), prev_stack_top);

}

return retval;}

Copyright 2015 Jason Turner @lefticus 61 / 65

Page 62: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Real World Cleanupbool Switch() {

size_t prev_stack_top = m_match_stack.size();

if (Keyword("switch")) {

if (!Char('(')) { throw exception::eval_error("Incomplete 'switch' expression", File_Position(m_line, m_col), *m_filename); /* snip */ while (Eol()) {}

if (Char('{')) {

/* snip */ }

build_match(AST_NodePtr(new eval::Switch_AST_Node()), prev_stack_top);

return true; } else { return false; }}

Copyright 2015 Jason Turner @lefticus 62 / 65

Page 63: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

ConclusionC style issues are largely a "solved problem"But there are still many ways to abuse current best practicesModern C++ and C++ >= 11 analysis checking still has a long way to goYou must use a combination of compilers / analyzersC++ Core Guidelines will almost certainly start steering the course of analysis soon

Copyright 2015 Jason Turner @lefticus 63 / 65

Page 64: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

ActionsConsider -Werror -Weverything (with selective disables) on clangConsider /W3 /WX /analyze (with selective disables) on MSVCConsider building your own analysis with libclang or adding to cppcheckConsider adding to where these tests andothers live

https://github.com/lefticus/AnalysisTestSuite

Copyright 2015 Jason Turner @lefticus 64 / 65

Page 65: Analysis The Current State of (Free) Static - schd.wsschd.ws/hosted_files/cppcon2015/c4/CurrentStateOfStaticAnalysis.pdf · The Current State of ... clang and cppcheck say they are

Jason Turner - Open Session Thursday (tomorrow) morning at 9:00-9:30

Independent Contractor - Always looking for new clients

http://github.com/lefticushttp://chaiscript.comhttp://cppcast.comhttp://cppbestpractices.com

Copyright 2015 Jason Turner @lefticus 65 / 65