brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.3 KiB · e3e5093 Raw
308 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fdiagnostics-parseable-fixits -fblocks -fsafe-buffer-usage-suggestions -verify %s2// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fdiagnostics-parseable-fixits -fblocks -fsafe-buffer-usage-suggestions \3// RUN:            %s 2>&1 | FileCheck %s4 5// FIXME: what about possible diagnostic message non-determinism?6 7// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:8void parmsNoFix(int *p, int *q) {9  int * a = new int[10];10  int * b = new int[10]; //expected-warning{{'b' is an unsafe pointer used for buffer access}} \11			   expected-note{{change type of 'b' to 'std::span' to preserve bounds information}}12 13  a = p;14  a = q;15  b[5] = 5; // expected-note{{used in buffer access here}}16}17 18// CHECK: fix-it:{{.*}}:{[[@LINE+2]]:21-[[@LINE+2]]:27}:"std::span<int> p"19// CHECK: fix-it:{{.*}}:{[[@LINE+14]]:2-[[@LINE+14]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void parmsSingleton(int *p) {return parmsSingleton(std::span<int>(p, <# size #>));}\n"20void parmsSingleton(int *p) { //expected-warning{{'p' is an unsafe pointer used for buffer access}} \21			        expected-note{{change type of 'p' to 'std::span' to preserve bounds information}}22  // CHECK: fix-it:{{.*}}:{[[@LINE+3]]:3-[[@LINE+3]]:8}:"std::span<int>"23  // CHECK: fix-it:{{.*}}:{[[@LINE+2]]:13-[[@LINE+2]]:13}:"{"24  // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:24-[[@LINE+1]]:24}:", 10}"25  int * a = new int[10];26  // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:8}:"std::span<int>"27  int * b; //expected-warning{{'b' is an unsafe pointer used for buffer access}} \28	     expected-note{{change type of 'b' to 'std::span' to preserve bounds information, and change 'a' to 'std::span' to propagate bounds information between them}}29 30  b = a;31  b[5] = 5; // expected-note{{used in buffer access here}}32  p[5] = 5; // expected-note{{used in buffer access here}}33}34 35 36// Parameters other than `r` all will be fixed37// CHECK: fix-it:{{.*}}:{[[@LINE+15]]:24-[[@LINE+15]]:30}:"std::span<int> p"38// CHECK  fix-it:{{.*}}:{[[@LINE+14]]:32-[[@LINE+14]]:39}:"std::span<int *> q"39// CHECK: fix-it:{{.*}}:{[[@LINE+13]]:41-[[@LINE+13]]:48}:"std::span<int> a"40// CHECK: fix-it:{{.*}}:{[[@LINE+23]]:2-[[@LINE+23]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void * multiParmAllFix(int *p, int **q, int a[], int * r) {return multiParmAllFix(std::span<int>(p, <# size #>), std::span<int *>(q, <# size #>), std::span<int>(a, <# size #>), r);}\n"41 42// repeat 2 more times as each of the 3 fixing parameters generates the set of fix-its above.43 44// CHECK: fix-it:{{.*}}:{[[@LINE+8]]:24-[[@LINE+8]]:30}:"std::span<int> p"45// CHECK  fix-it:{{.*}}:{[[@LINE+7]]:32-[[@LINE+7]]:39}:"std::span<int *> q"46// CHECK: fix-it:{{.*}}:{[[@LINE+6]]:41-[[@LINE+6]]:48}:"std::span<int> a"47// CHECK: fix-it:{{.*}}:{[[@LINE+16]]:2-[[@LINE+16]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void * multiParmAllFix(int *p, int **q, int a[], int * r) {return multiParmAllFix(std::span<int>(p, <# size #>), std::span<int *>(q, <# size #>), std::span<int>(a, <# size #>), r);}\n"48// CHECK: fix-it:{{.*}}:{[[@LINE+4]]:24-[[@LINE+4]]:30}:"std::span<int> p"49// CHECK  fix-it:{{.*}}:{[[@LINE+3]]:32-[[@LINE+3]]:39}:"std::span<int *> q"50// CHECK: fix-it:{{.*}}:{[[@LINE+2]]:41-[[@LINE+2]]:48}:"std::span<int> a"51// CHECK: fix-it:{{.*}}:{[[@LINE+12]]:2-[[@LINE+12]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void * multiParmAllFix(int *p, int **q, int a[], int * r) {return multiParmAllFix(std::span<int>(p, <# size #>), std::span<int *>(q, <# size #>), std::span<int>(a, <# size #>), r);}\n"52void * multiParmAllFix(int *p, int **q, int a[], int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}}   expected-warning{{'q' is an unsafe pointer used for buffer access}} \53   expected-warning{{'a' is an unsafe pointer used for buffer access}} \54   expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'a' to safe types to make function 'multiParmAllFix' bounds-safe}} \55   expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'a' to safe types to make function 'multiParmAllFix' bounds-safe}} \56   expected-note{{change type of 'a' to 'std::span' to preserve bounds information, and change 'p' and 'q' to safe types to make function 'multiParmAllFix' bounds-safe}}57  int tmp;58 59  tmp = p[5]; // expected-note{{used in buffer access here}}60  tmp = a[5]; // expected-note{{used in buffer access here}}61  if (++q) {} // expected-note{{used in pointer arithmetic here}}62  return r;63}64 65void * multiParmAllFix(int *p, int **q, int a[], int * r);66// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} "67// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:58-[[@LINE-2]]:58}:";\nvoid * multiParmAllFix(std::span<int> p, std::span<int *> q, std::span<int> a, int * r)"68 69// Fixing local variables implicates fixing parameters70void  multiParmLocalAllFix(int *p, int * r) {71  // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:72  // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:73  int * x; // expected-warning{{'x' is an unsafe pointer used for buffer access}}74  // CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:75  int * z; // expected-warning{{'z' is an unsafe pointer used for buffer access}}76  int * y;77 78  x = p;79  y = x; // FIXME: we do not fix `y = x` here as the `.data()` fix-it is not generally correct80  // `x` needs to be fixed so does the pointer assigned to `x`, i.e.,`p`81  x[5] = 5; // expected-note{{used in buffer access here}}82  z = r;83  // `z` needs to be fixed so does the pointer assigned to `z`, i.e.,`r`84  z[5] = 5; // expected-note{{used in buffer access here}}85  // Since `p` and `r` are parameters need to be fixed together,86  // fixing `x` involves fixing all `p`, `r` and `z`. Similar for87  // fixing `z`.88}89// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:90 91 92// Fixing parameters implicates fixing local variables93// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]:94void  multiParmLocalAllFix2(int *p, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \95                                                  expected-warning{{'r' is an unsafe pointer used for buffer access}}96  int * x = new int[10];97  // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:98  int * z = new int[10];99  // CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:100  int * y;101 102  p = x;103  y = x;    // FIXME: we do not fix `y = x` here as the `.data()` fix-it is not generally correct104  p[5] = 5; // expected-note{{used in buffer access here}}105  r = z;106  r[5] = 5; // expected-note{{used in buffer access here}}107}108// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]:109 110 111// No fix emitted for any of the parameter since parameter `r` cannot be fixed112// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]113void noneParmFix(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \114					         expected-warning{{'q' is an unsafe pointer used for buffer access}} \115					         expected-warning{{'r' is an unsafe pointer used for buffer access}}116  int tmp = p[5]; // expected-note{{used in buffer access here}}117  tmp = q[5];     // expected-note{{used in buffer access here}}118  r++;            // expected-note{{used in pointer arithmetic here}}119  tmp = r[5];     // expected-note{{used in buffer access here}}120}121// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]122 123// To show what if the `r` in `noneParmFix` can be fixed:124void noneParmFix_control(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \125						         expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q' and 'r' to safe types to make function 'noneParmFix_control' bounds-safe}} \126					                 expected-warning{{'q' is an unsafe pointer used for buffer access}} \127						         expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p' and 'r' to safe types to make function 'noneParmFix_control' bounds-safe}} \128					                 expected-warning{{'r' is an unsafe pointer used for buffer access}} \129						         expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p' and 'q' to safe types to make function 'noneParmFix_control' bounds-safe}}130  int tmp = p[5]; // expected-note{{used in buffer access here}}131  tmp = q[5];     // expected-note{{used in buffer access here}}132  if (++r) {}     // expected-note{{used in pointer arithmetic here}}133  tmp = r[5];     // expected-note{{used in buffer access here}}134}135 136 137// No fix emitted for any of the parameter since local variable `l` cannot be fixed.138// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]139void noneParmOrLocalFix(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \140						        expected-warning{{'q' is an unsafe pointer used for buffer access}} \141						        expected-warning{{'r' is an unsafe pointer used for buffer access}}142  int tmp = p[5];  // expected-note{{used in buffer access here}}143  tmp = q[5];      // expected-note{{used in buffer access here}}144  tmp = r[5];      // expected-note{{used in buffer access here}}145  // `l` and `r` must be fixed together while all parameters must be fixed together as well:146  int * l; l = r;     // expected-warning{{'l' is an unsafe pointer used for buffer access}}147 148  l++;             // expected-note{{used in pointer arithmetic here}}149}150// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]151 152// To show what if the `l` can be fixed in `noneParmOrLocalFix`:153void noneParmOrLocalFix_control(int * p, int * q, int * r) {// \154  expected-warning{{'p' is an unsafe pointer used for buffer access}} \155  expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q', 'r', and 'l' to safe types to make function 'noneParmOrLocalFix_control' bounds-safe}} \156  expected-warning{{'q' is an unsafe pointer used for buffer access}} \157  expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p', 'r', and 'l' to safe types to make function 'noneParmOrLocalFix_control' bounds-safe}} \158  expected-warning{{'r' is an unsafe pointer used for buffer access}} \159  expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p', 'q', and 'l' to safe types to make function 'noneParmOrLocalFix_control' bounds-safe}}160  int tmp = p[5];  // expected-note{{used in buffer access here}}161  tmp = q[5];      // expected-note{{used in buffer access here}}162  tmp = r[5];      // expected-note{{used in buffer access here}}163  int * l;         // expected-warning{{'l' is an unsafe pointer used for buffer access}} \164		      expected-note{{change type of 'l' to 'std::span' to preserve bounds information, and change 'p', 'q', and 'r' to safe types to make function 'noneParmOrLocalFix_control' bounds-safe}}165  l = r;166  if (++l){};         // expected-note{{used in pointer arithmetic here}}167}168 169 170// No fix emitted for any of the parameter since local variable `l` cannot be fixed.171// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]172void noneParmOrLocalFix2(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \173						         expected-warning{{'q' is an unsafe pointer used for buffer access}} \174						         expected-warning{{'r' is an unsafe pointer used for buffer access}}175  int tmp = p[5]; // expected-note{{used in buffer access here}}176  tmp = q[5];     // expected-note{{used in buffer access here}}177  tmp = r[5];     // expected-note{{used in buffer access here}}178 179  int * a; a = r;180  int * b; b = a;181  int * l; l = b;    // expected-warning{{'l' is an unsafe pointer used for buffer access}}182 183  // `a, b, l` and parameters must be fixed together but `l` can't be fixed:184  l++;               // expected-note{{used in pointer arithmetic here}}185}186// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]187 188// To show what if the `l` can be fixed in `noneParmOrLocalFix2`:189void noneParmOrLocalFix2_control(int * p, int * q, int * r) { // \190  expected-warning{{'p' is an unsafe pointer used for buffer access}} \191  expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'q', 'r', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix2_control' bounds-safe}}                 \192  expected-warning{{'q' is an unsafe pointer used for buffer access}} \193  expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p', 'r', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix2_control' bounds-safe}}                 \194  expected-warning{{'r' is an unsafe pointer used for buffer access}} \195  expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p', 'q', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix2_control' bounds-safe}}196  int tmp = p[5]; // expected-note{{used in buffer access here}}197  tmp = q[5];     // expected-note{{used in buffer access here}}198  tmp = r[5];     // expected-note{{used in buffer access here}}199 200  int * a; a = r;201  int * b; b = a;202  int * l;  // expected-warning{{'l' is an unsafe pointer used for buffer access}} \203	       expected-note{{change type of 'l' to 'std::span' to preserve bounds information, and change 'p', 'q', 'r', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix2_control' bounds-safe}}204 205  l = b;206  if(++l){} // expected-note{{used in pointer arithmetic here}}207}208 209// No fix emitted for any of the parameter since local variable `l` cannot be fixed210// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]211void noneParmOrLocalFix3(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \212						         expected-warning{{'q' is an unsafe pointer used for buffer access}} \213						         expected-warning{{'r' is an unsafe pointer used for buffer access}}214  int tmp = p[5];  // expected-note{{used in buffer access here}}215  tmp = q[5];      // expected-note{{used in buffer access here}}216  tmp = r[5];      // expected-note{{used in buffer access here}}217 218  int * a; a = r;219  int * b; b = a;220  int * l; l = b;     // expected-warning{{'l' is an unsafe pointer used for buffer access}}221 222  l++;             // expected-note{{used in pointer arithmetic here}}223 224  int * x; x = p; // expected-warning{{'x' is an unsafe pointer used for buffer access}}225  tmp = x[5];  // expected-note{{used in buffer access here}}226}227// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]228 229void noneParmOrLocalFix3_control(int * p, int * q, int * r) { // \230     expected-warning{{'p' is an unsafe pointer used for buffer access}} \231     expected-note{{change type of 'p' to 'std::span' to preserve bounds information, and change 'x', 'q', 'r', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix3_control' bounds-safe}}            \232     expected-warning{{'q' is an unsafe pointer used for buffer access}} \233     expected-note{{change type of 'q' to 'std::span' to preserve bounds information, and change 'p', 'x', 'r', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix3_control' bounds-safe}}            \234     expected-warning{{'r' is an unsafe pointer used for buffer access}} \235     expected-note{{change type of 'r' to 'std::span' to preserve bounds information, and change 'p', 'x', 'q', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix3_control' bounds-safe}}236  int tmp = p[5];  // expected-note{{used in buffer access here}}237  tmp = q[5];      // expected-note{{used in buffer access here}}238  tmp = r[5];      // expected-note{{used in buffer access here}}239 240  int * a; a = r;241  int * b; b = a;242  int * l;         // expected-warning{{'l' is an unsafe pointer used for buffer access}}   \243		      expected-note{{change type of 'l' to 'std::span' to preserve bounds information, and change 'p', 'x', 'q', 'r', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix3_control' bounds-safe}}244 245  l = b;246  if (++l){};         // expected-note{{used in pointer arithmetic here}}247 248  int * x;            // expected-warning{{'x' is an unsafe pointer used for buffer access}} \249		         expected-note{{change type of 'x' to 'std::span' to preserve bounds information, and change 'p', 'q', 'r', 'l', 'b', and 'a' to safe types to make function 'noneParmOrLocalFix3_control' bounds-safe}}250  x = p;251  tmp = x[5];  // expected-note{{used in buffer access here}}252}253 254 255// No fix emitted for any of the parameter but some local variables will get fixed256// CHECK-NOT: fix-it:{{.*}}:{[[@LINE+1]]257void noneParmSomeLocalFix(int * p, int * q, int * r) { // expected-warning{{'p' is an unsafe pointer used for buffer access}} \258						          expected-warning{{'q' is an unsafe pointer used for buffer access}} \259						          expected-warning{{'r' is an unsafe pointer used for buffer access}}260  int tmp = p[5];  // expected-note{{used in buffer access here}}261  tmp = q[5];      // expected-note{{used in buffer access here}}262  tmp = r[5];      // expected-note{{used in buffer access here}}263 264  int * a; a = r;265  int * b; b = a;266  int * l; l = b; // expected-warning{{'l' is an unsafe pointer used for buffer access}}267 268  l++; // expected-note{{used in pointer arithmetic here}}269 270  //`x` and `y` can be fixed271  int * x = new int[10];272  // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:8}:"std::span<int>"273  // CHECK: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"274  // CHECK: fix-it:{{.*}}:{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"275  // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:8}:"std::span<int>"276  int * y;   // expected-warning{{'y' is an unsafe pointer used for buffer access}} \277	        expected-note{{change type of 'y' to 'std::span' to preserve bounds information, and change 'x' to 'std::span' to propagate bounds information between them}}278  y = x;279  tmp = y[5];  // expected-note{{used in buffer access here}}280}281// CHECK-NOT: fix-it:{{.*}}:{[[@LINE-1]]282 283// Test that other parameters of (lambdas and blocks) do not interfere284// the grouping of variables of the function.285// CHECK: fix-it:{{.*}}:{[[@LINE+3]]:30-[[@LINE+3]]:37}:"std::span<int> p"286// CHECK: fix-it:{{.*}}:{[[@LINE+2]]:39-[[@LINE+2]]:46}:"std::span<int> q"287// CHECK: fix-it:{{.*}}:{[[@LINE+20]]:2-[[@LINE+20]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void parmsFromLambdaAndBlock(int * p, int * q) {return parmsFromLambdaAndBlock(std::span<int>(p, <# size #>), std::span<int>(q, <# size #>));}\n"288void parmsFromLambdaAndBlock(int * p, int * q) {289  // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:8}:"std::span<int>"290  int * a; // expected-warning{{'a' is an unsafe pointer used for buffer access}} \291	      expected-note{{change type of 'a' to 'std::span' to preserve bounds information, and change 'p', 'b', and 'q' to safe types to make function 'parmsFromLambdaAndBlock' bounds-safe}}292  // CHECK: fix-it:{{.*}}:{[[@LINE+1]]:3-[[@LINE+1]]:8}:"std::span<int>"293  int * b; // expected-warning{{'b' is an unsafe pointer used for buffer access}} \294              expected-note{{change type of 'b' to 'std::span' to preserve bounds information, and change 'a', 'p', and 'q' to safe types to make function 'parmsFromLambdaAndBlock' bounds-safe}}295  auto Lamb = [](int * x) -> void { // expected-warning{{'x' is an unsafe pointer used for buffer access}}296    x[5] = 5;                       // expected-note{{used in buffer access here}}297  };298 299  void (^Blk)(int*) = ^(int * y) {  // expected-warning{{'y' is an unsafe pointer used for buffer access}}300    y[5] = 5;                       // expected-note{{used in buffer access here}}301  };302 303  a = p;304  b = q;305  a[5] = 5; // expected-note{{used in buffer access here}}306  b[5] = 5; // expected-note{{used in buffer access here}}307}308