125 lines · cpp
1// RUN: %clang_analyze_cc1 -verify %s \2// RUN: -analyzer-checker=alpha.clone.CloneChecker \3// RUN: -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false \4// RUN: -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=105 6// Tests finding a suspicious clone that references local variables.7 8void log();9 10int max(int a, int b) {11 log();12 if (a > b)13 return a;14 return b; // expected-note{{Similar code using 'b' here}}15}16 17int maxClone(int x, int y, int z) {18 log();19 if (x > y)20 return x;21 return z; // expected-warning{{Potential copy-paste error; did you really mean to use 'z' here?}}22}23 24// Test that the checker works with [[clang::suppress]].25int max_suppressed(int a, int b) {26 log();27 if (a > b)28 return a;29 30 // This [[clang::suppress]] doesn't suppress anything but we need it here31 // because otherwise the other function won't count as a perfect clone.32 // FIXME: The checker should probably skip the attribute entirely33 // when detecting clones. Otherwise warnings will still get suppressed,34 // but for a completely wrong reason.35 [[clang::suppress]]36 return b; // no-note37}38 39int maxClone_suppressed(int x, int y, int z) {40 log();41 if (x > y)42 return x;43 [[clang::suppress]]44 return z; // no-warning45}46 47 48// Tests finding a suspicious clone that references global variables.49 50struct mutex {51 bool try_lock();52 void unlock();53};54 55mutex m1;56mutex m2;57int i;58 59void busyIncrement() {60 while (true) {61 if (m1.try_lock()) {62 ++i;63 m1.unlock(); // expected-note{{Similar code using 'm1' here}}64 if (i > 1000) {65 return;66 }67 }68 }69}70 71void faultyBusyIncrement() {72 while (true) {73 if (m1.try_lock()) {74 ++i;75 m2.unlock(); // expected-warning{{Potential copy-paste error; did you really mean to use 'm2' here?}}76 if (i > 1000) {77 return;78 }79 }80 }81}82 83// Tests that we provide two suggestions in cases where two fixes are possible.84 85int foo(int a, int b, int c) {86 a += b + c;87 b /= a + b;88 c -= b * a; // expected-warning{{Potential copy-paste error; did you really mean to use 'b' here?}}89 return c;90}91 92int fooClone(int a, int b, int c) {93 a += b + c;94 b /= a + b;95 c -= a * a; // expected-note{{Similar code using 'a' here}}96 return c;97}98 99 100// Tests that for clone groups with a many possible suspicious clone pairs, at101// most one warning per clone group is generated and every relevant clone is102// reported through either a warning or a note.103 104long bar1(long a, long b, long c, long d) {105 c = a - b;106 c = c / d * a;107 d = b * b - c; // expected-warning{{Potential copy-paste error; did you really mean to use 'b' here?}}108 return d;109}110 111long bar2(long a, long b, long c, long d) {112 c = a - b;113 c = c / d * a;114 d = c * b - c; // expected-note{{Similar code using 'c' here}} \115 // expected-warning{{Potential copy-paste error; did you really mean to use 'c' here?}}116 return d;117}118 119long bar3(long a, long b, long c, long d) {120 c = a - b;121 c = c / d * a;122 d = a * b - c; // expected-note{{Similar code using 'a' here}}123 return d;124}125