diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-22 23:51:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-22 23:51:40 +0000 |
commit | db655905913a680db86b31ec1edaed847eaf0f97 (patch) | |
tree | bcaba8dc6a4ee0fac40d88c4658cd0294557b83e /test/Misc | |
parent | c81676aad8483f90dda0d463eb46c565a03ccd25 (diff) |
Add option to include multiple lines in snippets.
When a diagnostic includes a highlighted range spanning multiple lines, clang
now supports printing out multiple lines of context if necessary to show the
highlighted ranges. This is not yet exposed in the driver, but can be enabled
by "-Xclang -fcaret-diagnostics-max-lines -Xclang N".
This is experimental until we can find out whether it works well in practice,
and if so, what a good default for the maximum number of lines is.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303589 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Misc')
-rw-r--r-- | test/Misc/caret-diags-multiline.cpp | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/test/Misc/caret-diags-multiline.cpp b/test/Misc/caret-diags-multiline.cpp new file mode 100644 index 0000000000..4826d9beaa --- /dev/null +++ b/test/Misc/caret-diags-multiline.cpp @@ -0,0 +1,234 @@ +// RUN: not %clang_cc1 -std=c++11 -fcaret-diagnostics-max-lines 5 -Wsometimes-uninitialized %s 2>&1 | FileCheck %s --strict-whitespace + +void line(int); + +// Check we expand the range as much as possible within the limit. + +// CHECK: warning: variable 'a' is used uninitialized whenever 'if' condition is true +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~{{$}} +// CHECK-NEXT: note: uninitialized use occurs here +// CHECK-NEXT: {{^}} return a; +// CHECK-NEXT: {{^}} ^ +// CHECK-NEXT: note: remove the 'if' if its condition is always false +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(1); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} } else { +// CHECK-NEXT: {{^}}~~~~~~~~~{{$}} +// CHECK-NEXT: note: initialize the variable +int f1(int cond) { + int a; + if (cond) { + line(1); + } else { + a = 3; + } + return a; +} + +// CHECK: warning: variable 'a' is used uninitialized whenever 'if' condition is true +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~{{$}} +// CHECK-NEXT: note: uninitialized use occurs here +// CHECK-NEXT: {{^}} return a; +// CHECK-NEXT: {{^}} ^ +// CHECK-NEXT: note: remove the 'if' if its condition is always false +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(1); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(2); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} } else { +// CHECK-NEXT: {{^}}~~~~~~~~~{{$}} +// CHECK-NEXT: note: initialize the variable +int f2(int cond) { + int a; + if (cond) { + line(1); + line(2); + } else { + a = 3; + } + return a; +} + +// CHECK: warning: variable 'a' is used uninitialized whenever 'if' condition is true +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~{{$}} +// CHECK-NEXT: note: uninitialized use occurs here +// CHECK-NEXT: {{^}} return a; +// CHECK-NEXT: {{^}} ^ +// CHECK-NEXT: note: remove the 'if' if its condition is always false +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(1); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(2); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(3); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} } else { +// CHECK-NEXT: {{^}}~~~~~~~~~{{$}} +// CHECK-NEXT: note: initialize the variable +int f3(int cond) { + int a; + if (cond) { + line(1); + line(2); + line(3); + } else { + a = 3; + } + return a; +} + +// CHECK: warning: variable 'a' is used uninitialized whenever 'if' condition is true +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~{{$}} +// CHECK-NEXT: note: uninitialized use occurs here +// CHECK-NEXT: {{^}} return a; +// CHECK-NEXT: {{^}} ^ +// CHECK-NEXT: note: remove the 'if' if its condition is always false +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(1); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(2); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(3); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(4); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: note: initialize the variable +int f4(int cond) { + int a; + if (cond) { + line(1); + line(2); + line(3); + line(4); + } else { + a = 3; + } + return a; +} + +// CHECK: warning: variable 'a' is used uninitialized whenever 'if' condition is true +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~{{$}} +// CHECK-NEXT: note: uninitialized use occurs here +// CHECK-NEXT: {{^}} return a; +// CHECK-NEXT: {{^}} ^ +// CHECK-NEXT: note: remove the 'if' if its condition is always false +// CHECK-NEXT: {{^}} if (cond) { +// CHECK-NEXT: {{^}} ^~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(1); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(2); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(3); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: {{^}} line(4); +// CHECK-NEXT: {{^}}~~~~~~~~~~~~{{$}} +// CHECK-NEXT: note: initialize the variable +int f5(int cond) { + int a; + if (cond) { + line(1); + line(2); + line(3); + line(4); + line(5); + } else { + a = 3; + } + return a; +} + + +// Check that we don't include lines with no interesting code if we can't reach +// the interesting part within the line limit. + +// CHECK: error: no matching function for call to 'g + +// CHECK: note: candidate template ignored: substitution failure +// CHECK-NEXT: {{^}}decltype(T() +// CHECK-NEXT: {{^}} ~{{$}} +// CHECK-NEXT: {{^}} + 1 +// CHECK-NEXT: {{^}} + 2 +// CHECK-NEXT: {{^}} + 3 +// CHECK-NEXT: {{^}}void g(); +// CHECK-NEXT: {{^}} ^{{$}} +template<typename T> +decltype(T() + + 1 + + 2 + + 3) +void g(); + +// CHECK: note: candidate template ignored: substitution failure +// CHECK-NEXT: {{^}}void g(); +// CHECK-NEXT: {{^}} ^{{$}} +template<typename T> +decltype(T() + + 1 + + 2 + + 3 + + 4) +void g(); + +void h() { g<int()>(); } + + +void multiple_ranges(int a, int b) { + // CHECK: error: invalid operands + // CHECK-NEXT: &(a) + // CHECK-NEXT: ~~~~ + // CHECK-NEXT: + + // CHECK-NEXT: ^ + // CHECK-NEXT: &(b) + // CHECK-NEXT: ~~~~ + &(a) + + + &(b); + + // CHECK-NEXT: error: invalid operands + // CHECK-NEXT: &( + // CHECK-NEXT: ~~ + // CHECK-NEXT: a + // CHECK-NEXT: ~ + // CHECK-NEXT: ) + // CHECK-NEXT: ~ + // CHECK-NEXT: + + // CHECK-NEXT: ^ + // CHECK-NEXT: &( + // CHECK-NEXT: ~~ + &( + a + ) + + + &( + b + ); + + // CHECK-NEXT: error: invalid operands + // CHECK-NEXT: &(a + // CHECK-NEXT: ~~ + // CHECK-NEXT: ) + // CHECK-NEXT: ~ + // CHECK-NEXT: + + // CHECK-NEXT: ^ + // CHECK-NEXT: &( + // CHECK-NEXT: ~~ + // CHECK-NEXT: b + // CHECK-NEXT: ~ + &(a + ) + + + &( + b + ); +} |