summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/copypaste/asm.cpp44
-rw-r--r--clang/test/Analysis/copypaste/attributes.cpp28
-rw-r--r--clang/test/Analysis/copypaste/call.cpp24
-rw-r--r--clang/test/Analysis/copypaste/catch.cpp29
-rw-r--r--clang/test/Analysis/copypaste/delete.cpp29
-rw-r--r--clang/test/Analysis/copypaste/dependent-exist.cpp18
-rw-r--r--clang/test/Analysis/copypaste/expr-types.cpp17
-rw-r--r--clang/test/Analysis/copypaste/false-positives.cpp8
-rw-r--r--clang/test/Analysis/copypaste/fold.cpp35
-rw-r--r--clang/test/Analysis/copypaste/function-try-block.cpp9
-rw-r--r--clang/test/Analysis/copypaste/functions.cpp25
-rw-r--r--clang/test/Analysis/copypaste/generic.c31
-rw-r--r--clang/test/Analysis/copypaste/labels.cpp51
-rw-r--r--clang/test/Analysis/copypaste/lambda.cpp24
14 files changed, 364 insertions, 8 deletions
diff --git a/clang/test/Analysis/copypaste/asm.cpp b/clang/test/Analysis/copypaste/asm.cpp
new file mode 100644
index 00000000000..61f0def594d
--- /dev/null
+++ b/clang/test/Analysis/copypaste/asm.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+int foo1(int src) {
+ int dst = src;
+ if (src < 100 && src > 0) {
+
+ asm ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+
+ }
+ return dst;
+}
+
+// Identical to foo1 except that it adds two instead of one, so it's no clone.
+int foo2(int src) {
+ int dst = src;
+ if (src < 100 && src > 0) {
+
+ asm ("mov %1, %0\n\t"
+ "add $2, %0"
+ : "=r" (dst)
+ : "r" (src));
+
+ }
+ return dst;
+}
+
+// Identical to foo1 except that its a volatile asm statement, so it's no clone.
+int foo3(int src) {
+ int dst = src;
+ if (src < 100 && src > 0) {
+
+ asm volatile ("mov %1, %0\n\t"
+ "add $1, %0"
+ : "=r" (dst)
+ : "r" (src));
+
+ }
+ return dst;
+}
diff --git a/clang/test/Analysis/copypaste/attributes.cpp b/clang/test/Analysis/copypaste/attributes.cpp
new file mode 100644
index 00000000000..72d654c6e06
--- /dev/null
+++ b/clang/test/Analysis/copypaste/attributes.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+int foo1(int n) {
+ int result = 0;
+ switch (n) {
+ case 33:
+ result += 33;
+ [[clang::fallthrough]];
+ case 44:
+ result += 44;
+ }
+ return result;
+}
+
+// Identical to foo1 except the missing attribute.
+int foo2(int n) {
+ int result = 0;
+ switch (n) {
+ case 33:
+ result += 33;
+ ;
+ case 44:
+ result += 44;
+ }
+ return result;
+}
diff --git a/clang/test/Analysis/copypaste/call.cpp b/clang/test/Analysis/copypaste/call.cpp
new file mode 100644
index 00000000000..06aa633fe96
--- /dev/null
+++ b/clang/test/Analysis/copypaste/call.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+bool a();
+bool b();
+
+// Calls method a with some extra code to pass the minimum complexity
+bool foo1(int x) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ return a();
+ return true;
+}
+
+// Calls method b with some extra code to pass the minimum complexity
+bool foo2(int x) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ return b();
+ return true;
+}
diff --git a/clang/test/Analysis/copypaste/catch.cpp b/clang/test/Analysis/copypaste/catch.cpp
new file mode 100644
index 00000000000..590ce8f223f
--- /dev/null
+++ b/clang/test/Analysis/copypaste/catch.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+bool foo1(int x) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ try { x--; } catch (int i) {}
+ return true;
+}
+
+// Uses parenthesis instead of type
+bool foo2(int x) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ try { x--; } catch (...) {}
+ return true;
+}
+
+// Catches a different type (long instead of int)
+bool foo3(int x) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ try { x--; } catch (long i) {}
+ return true;
+}
diff --git a/clang/test/Analysis/copypaste/delete.cpp b/clang/test/Analysis/copypaste/delete.cpp
new file mode 100644
index 00000000000..dc42c9c0595
--- /dev/null
+++ b/clang/test/Analysis/copypaste/delete.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+bool foo1(int x, int* a) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ delete a;
+ return true;
+}
+
+// Explicit global delete
+bool foo2(int x, int* a) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ ::delete a;
+ return true;
+}
+
+// Array delete
+bool foo3(int x, int* a) {
+ if (x > 0)
+ return false;
+ else if (x < 0)
+ delete[] a;
+ return true;
+}
diff --git a/clang/test/Analysis/copypaste/dependent-exist.cpp b/clang/test/Analysis/copypaste/dependent-exist.cpp
new file mode 100644
index 00000000000..5182ba61c9d
--- /dev/null
+++ b/clang/test/Analysis/copypaste/dependent-exist.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -analyze -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+bool foo1(int x) {
+ if (x < 0) {
+ __if_exists(x) { return false; }
+ }
+ return true;
+}
+
+// Same as above, but __if_not_exists
+bool foo2(int x) {
+ if (x < 0) {
+ __if_not_exists(x) { return false; }
+ }
+ return true;
+}
diff --git a/clang/test/Analysis/copypaste/expr-types.cpp b/clang/test/Analysis/copypaste/expr-types.cpp
new file mode 100644
index 00000000000..14eef6eac63
--- /dev/null
+++ b/clang/test/Analysis/copypaste/expr-types.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+
+int foo1(int a, int b) {
+ if (a > b)
+ return a;
+ return b;
+}
+
+// Different types, so not a clone
+int foo2(long a, long b) {
+ if (a > b)
+ return a;
+ return b;
+}
diff --git a/clang/test/Analysis/copypaste/false-positives.cpp b/clang/test/Analysis/copypaste/false-positives.cpp
index 8d649c790b8..4c6275949da 100644
--- a/clang/test/Analysis/copypaste/false-positives.cpp
+++ b/clang/test/Analysis/copypaste/false-positives.cpp
@@ -12,14 +12,6 @@ int max(int a, int b) { // expected-warning{{Detected code clone.}}
return b;
}
-// FIXME: Detect different binary operator kinds.
-int min1(int a, int b) { // expected-note{{Related code clone is here.}}
- log();
- if (a < b)
- return a;
- return b;
-}
-
// FIXME: Detect different variable patterns.
int min2(int a, int b) { // expected-note{{Related code clone is here.}}
log();
diff --git a/clang/test/Analysis/copypaste/fold.cpp b/clang/test/Analysis/copypaste/fold.cpp
new file mode 100644
index 00000000000..548dfb19af5
--- /dev/null
+++ b/clang/test/Analysis/copypaste/fold.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+int global = 0;
+
+template<typename ...Args>
+int foo1(Args&&... args) {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return (args + ...);
+ return 1;
+}
+
+// Different opeator in fold expression.
+template<typename ...Args>
+int foo2(Args&&... args) {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return (args - ...);
+ return 1;
+}
+
+// Parameter pack on a different side
+template<typename ...Args>
+int foo3(Args&&... args) {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return -1;
+ return (... + args);
+return 1;
+}
diff --git a/clang/test/Analysis/copypaste/function-try-block.cpp b/clang/test/Analysis/copypaste/function-try-block.cpp
new file mode 100644
index 00000000000..b13096d949a
--- /dev/null
+++ b/clang/test/Analysis/copypaste/function-try-block.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// Tests if function try blocks are correctly handled.
+
+void nonCompoundStmt1(int& x)
+ try { x += 1; } catch(...) { x -= 1; } // expected-warning{{Detected code clone.}}
+
+void nonCompoundStmt2(int& x)
+ try { x += 1; } catch(...) { x -= 1; } // expected-note{{Related code clone is here.}}
diff --git a/clang/test/Analysis/copypaste/functions.cpp b/clang/test/Analysis/copypaste/functions.cpp
index 29f389a5eac..bedd374b79d 100644
--- a/clang/test/Analysis/copypaste/functions.cpp
+++ b/clang/test/Analysis/copypaste/functions.cpp
@@ -20,6 +20,31 @@ int maxClone(int x, int y) { // expected-note{{Related code clone is here.}}
// Functions below are not clones and should not be reported.
+// The next two functions test that statement classes are still respected when
+// checking for clones in expressions. This will show that the statement
+// specific data of all base classes is collected, and not just the data of the
+// first base class.
+int testBaseClass(int a, int b) { // no-warning
+ log();
+ if (a > b)
+ return true ? a : b;
+ return b;
+}
+int testBaseClass2(int a, int b) { // no-warning
+ log();
+ if (a > b)
+ return __builtin_choose_expr(true, a, b);
+ return b;
+}
+
+
+int min1(int a, int b) { // no-warning
+ log();
+ if (a < b)
+ return a;
+ return b;
+}
+
int foo(int a, int b) { // no-warning
return a + b;
}
diff --git a/clang/test/Analysis/copypaste/generic.c b/clang/test/Analysis/copypaste/generic.c
new file mode 100644
index 00000000000..9d8392139b3
--- /dev/null
+++ b/clang/test/Analysis/copypaste/generic.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -analyze -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+int global;
+
+int foo1() {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return _Generic(global, double: 1, float: 2, default: 3);
+ return 1;
+}
+
+// Different associated type (int instead of float)
+int foo2() {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return _Generic(global, double: 1, int: 2, default: 4);
+ return 1;
+}
+
+// Different number of associated types.
+int foo3() {
+ if (global > 0)
+ return 0;
+ else if (global < 0)
+ return _Generic(global, double: 1, default: 4);
+ return 1;
+}
diff --git a/clang/test/Analysis/copypaste/labels.cpp b/clang/test/Analysis/copypaste/labels.cpp
new file mode 100644
index 00000000000..26318ac4051
--- /dev/null
+++ b/clang/test/Analysis/copypaste/labels.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -analyze -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+
+bool foo1(int x) {
+ start:
+ if (x != 3) {
+ ++x;
+ void *ptr = &&start;
+ goto start;
+ }
+ end:
+ return false;
+}
+
+// Targeting a different label with the address-of-label operator.
+bool foo2(int x) {
+ start:
+ if (x != 3) {
+ ++x;
+ void *ptr = &&end;
+ goto start;
+ }
+ end:
+ return false;
+}
+
+// Different target label in goto
+bool foo3(int x) {
+ start:
+ if (x != 3) {
+ ++x;
+ void *ptr = &&start;
+ goto end;
+ }
+ end:
+ return false;
+}
+
+// FIXME: Can't detect same algorithm as in foo1 but with different label names.
+bool foo4(int x) {
+ foo:
+ if (x != 3) {
+ ++x;
+ void *ptr = &&foo;
+ goto foo;
+ }
+ end:
+ return false;
+}
diff --git a/clang/test/Analysis/copypaste/lambda.cpp b/clang/test/Analysis/copypaste/lambda.cpp
new file mode 100644
index 00000000000..c13c56f6671
--- /dev/null
+++ b/clang/test/Analysis/copypaste/lambda.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+
+// expected-no-diagnostics
+
+void foo1(int a, long b) {
+ auto l = [a, b](){};
+}
+
+void foo2(int a, long b) {
+ auto l = [&a, b](){};
+}
+
+void foo3(int a, long b) {
+ auto l = [a](){};
+}
+
+void foo4(int a, long b) {
+ auto l = [=](){};
+}
+
+void foo5(int a, long b) {
+ auto l = [&](){};
+}
+
OpenPOWER on IntegriCloud