Skip to content

Commit c7f0fa4

Browse files
mkindahlCommitfest Bot
authored and
Commitfest Bot
committed
Semantic patch for palloc_array and palloc_object
Macros were added to the palloc API in commit 2016055 to improve type-safety, but very few instances were replaced. This adds a cocci script to do that replacement. The semantic patch deliberately do not replace instances where the type of the variable and the type used in the macro does not match.
1 parent cebab18 commit c7f0fa4

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

cocci/palloc_array.cocci

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Since PG16 there are array versions of common palloc operations, so
2+
// we can use those instead.
3+
//
4+
// We ignore cases where we have a anonymous struct and also when the
5+
// type of the variable being assigned to is different from the
6+
// inferred type.
7+
//
8+
// Options: --no-includes --include-headers
9+
10+
virtual patch
11+
virtual report
12+
virtual context
13+
14+
// These rules (soN) are needed to rewrite types of the form
15+
// sizeof(T[C]) to C * sizeof(T) since Cocci cannot (currently) handle
16+
// it.
17+
@initialize:python@
18+
@@
19+
import re
20+
21+
CRE = re.compile(r'(.*)\s+\[\s+(\d+)\s+\]$')
22+
23+
def is_array_type(s):
24+
mre = CRE.match(s)
25+
return (mre is not None)
26+
27+
@so1 depends on patch@
28+
type T : script:python() { is_array_type(T) };
29+
@@
30+
palloc(sizeof(T))
31+
32+
@script:python so2 depends on patch@
33+
T << so1.T;
34+
T2;
35+
E;
36+
@@
37+
mre = CRE.match(T)
38+
coccinelle.T2 = cocci.make_type(mre.group(1))
39+
coccinelle.E = cocci.make_expr(mre.group(2))
40+
41+
@depends on patch@
42+
type so1.T;
43+
type so2.T2;
44+
expression so2.E;
45+
@@
46+
- palloc(sizeof(T))
47+
+ palloc(E * sizeof(T2))
48+
49+
@r1 depends on report || context@
50+
type T !~ "^struct {";
51+
expression E;
52+
position p;
53+
idexpression T *I;
54+
identifier alloc = {palloc0, palloc};
55+
@@
56+
* I = alloc@p(E * sizeof(T))
57+
58+
@script:python depends on report@
59+
p << r1.p;
60+
alloc << r1.alloc;
61+
@@
62+
coccilib.report.print_report(p[0], f"this {alloc} can be replaced with {alloc}_array")
63+
64+
@depends on patch@
65+
type T !~ "^struct {";
66+
expression E;
67+
T *P;
68+
idexpression T* I;
69+
constant C;
70+
identifier alloc = {palloc0, palloc};
71+
fresh identifier alloc_array = alloc ## "_array";
72+
@@
73+
(
74+
- I = (T*) alloc(E * sizeof( \( *P \| P[C] \) ))
75+
+ I = alloc_array(T, E)
76+
|
77+
- I = (T*) alloc(E * sizeof(T))
78+
+ I = alloc_array(T, E)
79+
|
80+
- I = alloc(E * sizeof( \( *P \| P[C] \) ))
81+
+ I = alloc_array(T, E)
82+
|
83+
- I = alloc(E * sizeof(T))
84+
+ I = alloc_array(T, E)
85+
)
86+
87+
@r3 depends on report || context@
88+
type T !~ "^struct {";
89+
expression E;
90+
idexpression T *P;
91+
idexpression T *I;
92+
position p;
93+
@@
94+
* I = repalloc@p(P, E * sizeof(T))
95+
96+
@script:python depends on report@
97+
p << r3.p;
98+
@@
99+
coccilib.report.print_report(p[0], "this repalloc can be replaced with repalloc_array")
100+
101+
@depends on patch@
102+
type T !~ "^struct {";
103+
expression E;
104+
idexpression T *P1;
105+
idexpression T *P2;
106+
idexpression T *I;
107+
constant C;
108+
@@
109+
(
110+
- I = (T*) repalloc(P1, E * sizeof( \( *P2 \| P2[C] \) ))
111+
+ I = repalloc_array(P1, T, E)
112+
|
113+
- I = (T*) repalloc(P1, E * sizeof(T))
114+
+ I = repalloc_array(P1, T, E)
115+
|
116+
- I = repalloc(P1, E * sizeof( \( *P2 \| P2[C] \) ))
117+
+ I = repalloc_array(P1, T, E)
118+
|
119+
- I = repalloc(P1, E * sizeof(T))
120+
+ I = repalloc_array(P1, T, E)
121+
)
122+
123+
@r4 depends on report || context@
124+
type T !~ "^struct {";
125+
position p;
126+
idexpression T* I;
127+
identifier alloc = {palloc, palloc0};
128+
@@
129+
* I = alloc@p(sizeof(T))
130+
131+
@script:python depends on report@
132+
p << r4.p;
133+
alloc << r4.alloc;
134+
@@
135+
coccilib.report.print_report(p[0], f"this {alloc} can be replaced with {alloc}_object")
136+
137+
@depends on patch@
138+
type T !~ "^struct {";
139+
T* P;
140+
idexpression T *I;
141+
constant C;
142+
identifier alloc = {palloc, palloc0};
143+
fresh identifier alloc_object = alloc ## "_object";
144+
@@
145+
(
146+
- I = (T*) alloc(sizeof( \( *P \| P[C] \) ))
147+
+ I = alloc_object(T)
148+
|
149+
- I = (T*) alloc(sizeof(T))
150+
+ I = alloc_object(T)
151+
|
152+
- I = alloc(sizeof( \( *P \| P[C] \) ))
153+
+ I = alloc_object(T)
154+
|
155+
- I = alloc(sizeof(T))
156+
+ I = alloc_object(T)
157+
)

0 commit comments

Comments
 (0)