Summary: So far we used a value of 10 which was useful for testing but produces many false-positives in real programs. The usual suspicious clones we find seem to be at around a complexity value of 70 and for normal clone-reporting everything above 50 seems to be a valid normal clone for users, so let's just go with 50 for now and set this as the new default value. This patch also explicitly sets the complexity value for the regression tests as they serve more of a regression testing/debugging purpose and shouldn't really be reported by default in real programs. I'll add more tests that reflect actual found bugs that then need to pass with the default setting in the future. Reviewers: NoQ Subscribers: cfe-commits, javed.absar, xazax.hun, v.g.vassilev Differential Revision: https://reviews.llvm.org/D34178 llvm-svn: 312468
98 lines
2.4 KiB
C++
98 lines
2.4 KiB
C++
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
|
|
|
|
// Tests finding a suspicious clone that references local variables.
|
|
|
|
void log();
|
|
|
|
int max(int a, int b) {
|
|
log();
|
|
if (a > b)
|
|
return a;
|
|
return b; // expected-note{{Similar code using 'b' here}}
|
|
}
|
|
|
|
int maxClone(int x, int y, int z) {
|
|
log();
|
|
if (x > y)
|
|
return x;
|
|
return z; // expected-warning{{Potential copy-paste error; did you really mean to use 'z' here?}}
|
|
}
|
|
|
|
// Tests finding a suspicious clone that references global variables.
|
|
|
|
struct mutex {
|
|
bool try_lock();
|
|
void unlock();
|
|
};
|
|
|
|
mutex m1;
|
|
mutex m2;
|
|
int i;
|
|
|
|
void busyIncrement() {
|
|
while (true) {
|
|
if (m1.try_lock()) {
|
|
++i;
|
|
m1.unlock(); // expected-note{{Similar code using 'm1' here}}
|
|
if (i > 1000) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void faultyBusyIncrement() {
|
|
while (true) {
|
|
if (m1.try_lock()) {
|
|
++i;
|
|
m2.unlock(); // expected-warning{{Potential copy-paste error; did you really mean to use 'm2' here?}}
|
|
if (i > 1000) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tests that we provide two suggestions in cases where two fixes are possible.
|
|
|
|
int foo(int a, int b, int c) {
|
|
a += b + c;
|
|
b /= a + b;
|
|
c -= b * a; // expected-warning{{Potential copy-paste error; did you really mean to use 'b' here?}}
|
|
return c;
|
|
}
|
|
|
|
int fooClone(int a, int b, int c) {
|
|
a += b + c;
|
|
b /= a + b;
|
|
c -= a * a; // expected-note{{Similar code using 'a' here}}
|
|
return c;
|
|
}
|
|
|
|
|
|
// Tests that for clone groups with a many possible suspicious clone pairs, at
|
|
// most one warning per clone group is generated and every relevant clone is
|
|
// reported through either a warning or a note.
|
|
|
|
long bar1(long a, long b, long c, long d) {
|
|
c = a - b;
|
|
c = c / d * a;
|
|
d = b * b - c; // expected-warning{{Potential copy-paste error; did you really mean to use 'b' here?}}
|
|
return d;
|
|
}
|
|
|
|
long bar2(long a, long b, long c, long d) {
|
|
c = a - b;
|
|
c = c / d * a;
|
|
d = c * b - c; // expected-note{{Similar code using 'c' here}} \
|
|
// expected-warning{{Potential copy-paste error; did you really mean to use 'c' here?}}
|
|
return d;
|
|
}
|
|
|
|
long bar3(long a, long b, long c, long d) {
|
|
c = a - b;
|
|
c = c / d * a;
|
|
d = a * b - c; // expected-note{{Similar code using 'a' here}}
|
|
return d;
|
|
}
|