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