diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2016-08-20 10:06:59 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2016-08-20 10:06:59 +0000 |
commit | 51b9a0e8e8ab7b6ad0458163248035afef08d5b4 (patch) | |
tree | 323bd2abb093df828eddc32b8541d71ae1996845 /clang/test/Analysis/copypaste/macros.cpp | |
parent | 51838888131bdeadbd998c50a141efeb67d73751 (diff) | |
download | bcm5719-llvm-51b9a0e8e8ab7b6ad0458163248035afef08d5b4.tar.gz bcm5719-llvm-51b9a0e8e8ab7b6ad0458163248035afef08d5b4.zip |
[analyzer] Make CloneDetector consider macro expansions.
So far macro-generated code was treated by the CloneDetector as normal code.
This caused that some macros where reported as false-positive clones because
large chunks of code coming from otherwise concise macro expansions were treated
as copy-pasted code.
This patch ensures that macros are treated in the same way as literals/function
calls. This prevents macros that expand into multiple statements
from being reported as clones.
Patch by Raphael Isemann!
Differential Revision: https://reviews.llvm.org/D23316
llvm-svn: 279367
Diffstat (limited to 'clang/test/Analysis/copypaste/macros.cpp')
-rw-r--r-- | clang/test/Analysis/copypaste/macros.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/clang/test/Analysis/copypaste/macros.cpp b/clang/test/Analysis/copypaste/macros.cpp new file mode 100644 index 00000000000..170e034095d --- /dev/null +++ b/clang/test/Analysis/copypaste/macros.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s + +// Tests that macros and non-macro clones aren't mixed into the same hash +// group. This is currently necessary as all clones in a hash group need +// to have the same complexity value. Macros have smaller complexity values +// and need to be in their own hash group. + +int foo(int a) { // expected-warning{{Detected code clone.}} + a = a + 1; + a = a + 1 / 1; + a = a + 1 + 1 + 1; + a = a + 1 - 1 + 1 + 1; + a = a + 1 * 1 + 1 + 1 + 1; + a = a + 1 / 1 + 1 + 1 + 1; + return a; +} + +int fooClone(int a) { // expected-note{{Related code clone is here.}} + a = a + 1; + a = a + 1 / 1; + a = a + 1 + 1 + 1; + a = a + 1 - 1 + 1 + 1; + a = a + 1 * 1 + 1 + 1 + 1; + a = a + 1 / 1 + 1 + 1 + 1; + return a; +} + +// Below is the same AST as above but this time generated with macros. The +// clones below should land in their own hash group for the reasons given above. + +#define ASSIGN(T, V) T = T + V + +int macro(int a) { // expected-warning{{Detected code clone.}} + ASSIGN(a, 1); + ASSIGN(a, 1 / 1); + ASSIGN(a, 1 + 1 + 1); + ASSIGN(a, 1 - 1 + 1 + 1); + ASSIGN(a, 1 * 1 + 1 + 1 + 1); + ASSIGN(a, 1 / 1 + 1 + 1 + 1); + return a; +} + +int macroClone(int a) { // expected-note{{Related code clone is here.}} + ASSIGN(a, 1); + ASSIGN(a, 1 / 1); + ASSIGN(a, 1 + 1 + 1); + ASSIGN(a, 1 - 1 + 1 + 1); + ASSIGN(a, 1 * 1 + 1 + 1 + 1); + ASSIGN(a, 1 / 1 + 1 + 1 + 1); + return a; +} + +// FIXME: Macros with empty definitions in the AST are currently ignored. + +#define EMPTY + +int fooFalsePositiveClone(int a) { // expected-note{{Related code clone is here.}} + a = EMPTY a + 1; + a = a + 1 / 1; + a = a + 1 + 1 + 1; + a = a + 1 - 1 + 1 + 1; + a = a + 1 * 1 + 1 + 1 + 1; + a = a + 1 / 1 + 1 + 1 + 1; + return a; +} + + |