summaryrefslogtreecommitdiff
path: root/test/Misc
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-05-22 23:51:40 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-05-22 23:51:40 +0000
commitdb655905913a680db86b31ec1edaed847eaf0f97 (patch)
treebcaba8dc6a4ee0fac40d88c4658cd0294557b83e /test/Misc
parentc81676aad8483f90dda0d463eb46c565a03ccd25 (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.cpp234
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
+ );
+}