xref: /llvm-project/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-span-overload.cpp (revision de8b2f0c69c8bc13a248691ef9ad9a1c10d81392)
1 // RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -fdiagnostics-parseable-fixits -fsafe-buffer-usage-suggestions %s 2>&1 | FileCheck %s
2 
3 // We cannot deal with overload conflicts for now so NO fix-it to
4 // function parameters will be emitted if there are overloads for that
5 // function.
6 
7 #include "warn-unsafe-buffer-usage-fixits-parm-span-overload.h"
8 
9 void foo(int *p, int * q);
10 
11 void foo(int *p);
12 
foo(int * p)13 void foo(int *p) {
14   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
15   int tmp;
16   tmp = p[5];
17 }
18 
19 // an overload declaration of `bar(int *)` appears after it
bar(int * p)20 void bar(int *p) {
21   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
22   int tmp;
23   tmp = p[5];
24 }
25 
26 void bar();
27 
28 // an overload declaration of `baz(int)` appears is in the included header
baz(int * p)29 void baz(int *p) {
30   // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:
31   int tmp;
32   tmp = p[5];
33 }
34 
35 namespace NS {
36   // `NS::foo` is a distinct function from `foo`, so it has no
37   // overload and shall be fixed.
foo(int * p)38   void foo(int *p) {
39     // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:12-[[@LINE-1]]:18}:"std::span<int> p"
40     int tmp;
41     tmp = p[5];
42   }
43   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:4}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void foo(int *p) {return foo(std::span<int>(p, <# size #>));}\n"
44 
45   // Similarly, `NS::bar` is distinct from `bar`:
46   void bar(int *p);
47   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:3}:"{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} "
48   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:19-[[@LINE-2]]:19}:";\nvoid bar(std::span<int> p)"
49 } // end of namespace NS
50 
51 // This is the implementation of `NS::bar`, which shall be fixed.
bar(int * p)52 void NS::bar(int *p) {
53   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:14-[[@LINE-1]]:20}:"std::span<int> p"
54   int tmp;
55   tmp = p[5];
56 }
57 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:2-[[@LINE-1]]:2}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void NS::bar(int *p) {return NS::bar(std::span<int>(p, <# size #>));}\n"
58 
59 namespace NESTED {
60   void alpha(int);
61   void beta(int *, int *);
62 
63   namespace INNER {
64     // `NESTED::INNER::alpha` is distinct from `NESTED::alpha`, so it
65     // has no overload and shall be fixed.
alpha(int * p)66     void alpha(int *p) {
67       // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:22}:"std::span<int> p"
68       int tmp;
69       tmp = p[5];
70     }
71     // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:6}:"\n{{\[}}{{\[}}clang::unsafe_buffer_usage{{\]}}{{\]}} void alpha(int *p) {return alpha(std::span<int>(p, <# size #>));}\n"
72   }
73 }
74 
75 namespace NESTED {
76   // There is an `NESTED::beta(int *, int *)` declared above, so this
77   // unsafe function will not be fixed.
beta(int * p)78   void beta(int *p) {
79     // CHECK-NOT: fix-it:"{{.*}}":[[@LINE-1]]:
80     int tmp;
81     tmp = p[5];
82   }
83 
84   namespace INNER {
85     void delta(int);  // No fix for `NESTED::INNER::delta`
86     void delta(int*);
87   }
88 }
89 
90 // There is an `NESTED::beta(int *)` declared above, so this unsafe
91 // function will not be fixed.
beta(int * p,int * q)92 void NESTED::beta(int *p, int *q) {
93   // CHECK-NOT: fix-it:"{{.*}}":[[@LINE-1]]:
94   int tmp;
95   tmp = p[5];
96   tmp = q[5];
97 }
98 
delta(int * p)99 void NESTED::INNER::delta(int * p) {
100   // CHECK-NOT: fix-it:"{{.*}}":[[@LINE-1]]:
101   int tmp;
102   tmp = p[5];
103 }
104