Skip to content

Commit 09d8d11

Browse files
committed
Use FLEXIBLE_ARRAY_MEMBER in a bunch more places.
Replace some bogus "x[1]" declarations with "x[FLEXIBLE_ARRAY_MEMBER]". Aside from being more self-documenting, this should help prevent bogus warnings from static code analyzers and perhaps compiler misoptimizations. This patch is just a down payment on eliminating the whole problem, but it gets rid of a lot of easy-to-fix cases. Note that the main problem with doing this is that one must no longer rely on computing sizeof(the containing struct), since the result would be compiler-dependent. Instead use offsetof(struct, lastfield). Autoconf also warns against spelling that offsetof(struct, lastfield[0]). Michael Paquier, review and additional fixes by me.
1 parent 2fb7a75 commit 09d8d11

File tree

44 files changed

+109
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+109
-127
lines changed

contrib/cube/cubedata.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ typedef struct NDBOX
2323
unsigned int header;
2424

2525
/*
26-
* Variable length array. The lower left coordinates for each dimension
27-
* come first, followed by upper right coordinates unless the point flag
28-
* is set.
26+
* The lower left coordinates for each dimension come first, followed by
27+
* upper right coordinates unless the point flag is set.
2928
*/
30-
double x[1];
29+
double x[FLEXIBLE_ARRAY_MEMBER];
3130
} NDBOX;
3231

3332
#define POINT_BIT 0x80000000
@@ -41,9 +40,9 @@ typedef struct NDBOX
4140
#define LL_COORD(cube, i) ( (cube)->x[i] )
4241
#define UR_COORD(cube, i) ( IS_POINT(cube) ? (cube)->x[i] : (cube)->x[(i) + DIM(cube)] )
4342

44-
#define POINT_SIZE(_dim) (offsetof(NDBOX, x[0]) + sizeof(double)*(_dim))
45-
#define CUBE_SIZE(_dim) (offsetof(NDBOX, x[0]) + sizeof(double)*(_dim)*2)
43+
#define POINT_SIZE(_dim) (offsetof(NDBOX, x) + sizeof(double)*(_dim))
44+
#define CUBE_SIZE(_dim) (offsetof(NDBOX, x) + sizeof(double)*(_dim)*2)
4645

47-
#define DatumGetNDBOX(x) ((NDBOX*)DatumGetPointer(x))
48-
#define PG_GETARG_NDBOX(x) DatumGetNDBOX( PG_DETOAST_DATUM(PG_GETARG_DATUM(x)) )
46+
#define DatumGetNDBOX(x) ((NDBOX *) PG_DETOAST_DATUM(x))
47+
#define PG_GETARG_NDBOX(x) DatumGetNDBOX(PG_GETARG_DATUM(x))
4948
#define PG_RETURN_NDBOX(x) PG_RETURN_POINTER(x)

contrib/intarray/_int.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ typedef struct
7373
{
7474
int32 vl_len_; /* varlena header (do not touch directly!) */
7575
int32 flag;
76-
char data[1];
76+
char data[FLEXIBLE_ARRAY_MEMBER];
7777
} GISTTYPE;
7878

7979
#define ALLISTRUE 0x04
@@ -133,7 +133,7 @@ typedef struct QUERYTYPE
133133
{
134134
int32 vl_len_; /* varlena header (do not touch directly!) */
135135
int32 size; /* number of ITEMs */
136-
ITEM items[1]; /* variable length array */
136+
ITEM items[FLEXIBLE_ARRAY_MEMBER];
137137
} QUERYTYPE;
138138

139139
#define HDRSIZEQT offsetof(QUERYTYPE, items)

contrib/ltree/ltree.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
typedef struct
1111
{
1212
uint16 len;
13-
char name[1];
13+
char name[FLEXIBLE_ARRAY_MEMBER];
1414
} ltree_level;
1515

1616
#define LEVEL_HDRSIZE (offsetof(ltree_level,name))
@@ -20,7 +20,7 @@ typedef struct
2020
{
2121
int32 vl_len_; /* varlena header (do not touch directly!) */
2222
uint16 numlevel;
23-
char data[1];
23+
char data[FLEXIBLE_ARRAY_MEMBER];
2424
} ltree;
2525

2626
#define LTREE_HDRSIZE MAXALIGN( offsetof(ltree, data) )
@@ -34,7 +34,7 @@ typedef struct
3434
int32 val;
3535
uint16 len;
3636
uint8 flag;
37-
char name[1];
37+
char name[FLEXIBLE_ARRAY_MEMBER];
3838
} lquery_variant;
3939

4040
#define LVAR_HDRSIZE MAXALIGN(offsetof(lquery_variant, name))
@@ -51,7 +51,7 @@ typedef struct
5151
uint16 numvar;
5252
uint16 low;
5353
uint16 high;
54-
char variants[1];
54+
char variants[FLEXIBLE_ARRAY_MEMBER];
5555
} lquery_level;
5656

5757
#define LQL_HDRSIZE MAXALIGN( offsetof(lquery_level,variants) )
@@ -72,7 +72,7 @@ typedef struct
7272
uint16 numlevel;
7373
uint16 firstgood;
7474
uint16 flag;
75-
char data[1];
75+
char data[FLEXIBLE_ARRAY_MEMBER];
7676
} lquery;
7777

7878
#define LQUERY_HDRSIZE MAXALIGN( offsetof(lquery, data) )
@@ -107,7 +107,7 @@ typedef struct
107107
{
108108
int32 vl_len_; /* varlena header (do not touch directly!) */
109109
int32 size;
110-
char data[1];
110+
char data[FLEXIBLE_ARRAY_MEMBER];
111111
} ltxtquery;
112112

113113
#define HDRSIZEQT MAXALIGN(VARHDRSZ + sizeof(int32))
@@ -208,7 +208,7 @@ typedef struct
208208
{
209209
int32 vl_len_; /* varlena header (do not touch directly!) */
210210
uint32 flag;
211-
char data[1];
211+
char data[FLEXIBLE_ARRAY_MEMBER];
212212
} ltree_gist;
213213

214214
#define LTG_ONENODE 0x01

contrib/pageinspect/rawpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ page_header(PG_FUNCTION_ARGS)
192192
* Check that enough data was supplied, so that we don't try to access
193193
* fields outside the supplied buffer.
194194
*/
195-
if (raw_page_size < sizeof(PageHeaderData))
195+
if (raw_page_size < SizeOfPageHeaderData)
196196
ereport(ERROR,
197197
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
198198
errmsg("input page too small (%d bytes)", raw_page_size)));

contrib/pg_trgm/trgm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ typedef struct
6363
{
6464
int32 vl_len_; /* varlena header (do not touch directly!) */
6565
uint8 flag;
66-
char data[1];
66+
char data[FLEXIBLE_ARRAY_MEMBER];
6767
} TRGM;
6868

6969
#define TRGMHDRSIZE (VARHDRSZ + sizeof(uint8))

src/backend/catalog/namespace.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
261261
* with the answer changing under them, or that they already hold some
262262
* appropriate lock, and therefore return the first answer we get without
263263
* checking for invalidation messages. Also, if the requested lock is
264-
* already held, LockRelationOid will not AcceptInvalidationMessages,
265-
* so we may fail to notice a change. We could protect against that case
266-
* by calling AcceptInvalidationMessages() before beginning this loop, but
264+
* already held, LockRelationOid will not AcceptInvalidationMessages, so
265+
* we may fail to notice a change. We could protect against that case by
266+
* calling AcceptInvalidationMessages() before beginning this loop, but
267267
* that would add a significant amount overhead, so for now we don't.
268268
*/
269269
for (;;)
@@ -1075,8 +1075,8 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames,
10751075
*/
10761076
effective_nargs = Max(pronargs, nargs);
10771077
newResult = (FuncCandidateList)
1078-
palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
1079-
+ effective_nargs * sizeof(Oid));
1078+
palloc(offsetof(struct _FuncCandidateList, args) +
1079+
effective_nargs * sizeof(Oid));
10801080
newResult->pathpos = pathpos;
10811081
newResult->oid = HeapTupleGetOid(proctup);
10821082
newResult->nargs = effective_nargs;
@@ -1597,7 +1597,8 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
15971597
* separate palloc for each operator, but profiling revealed that the
15981598
* pallocs used an unreasonably large fraction of parsing time.
15991599
*/
1600-
#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))
1600+
#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
1601+
2 * sizeof(Oid))
16011602

16021603
if (catlist->n_members > 0)
16031604
resultSpace = palloc(catlist->n_members * SPACE_PER_OP);

src/backend/commands/prepare.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,9 @@ EvaluateParams(PreparedStatement *pstmt, List *params,
383383
/* Prepare the expressions for execution */
384384
exprstates = (List *) ExecPrepareExpr((Expr *) params, estate);
385385

386-
/* sizeof(ParamListInfoData) includes the first array element */
387386
paramLI = (ParamListInfo)
388-
palloc(sizeof(ParamListInfoData) +
389-
(num_params - 1) * sizeof(ParamExternData));
387+
palloc(offsetof(ParamListInfoData, params) +
388+
num_params * sizeof(ParamExternData));
390389
/* we have static list of params, so no hooks needed */
391390
paramLI->paramFetch = NULL;
392391
paramLI->paramFetchArg = NULL;

src/backend/executor/functions.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -896,9 +896,9 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
896896

897897
if (fcache->paramLI == NULL)
898898
{
899-
/* sizeof(ParamListInfoData) includes the first array element */
900-
paramLI = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
901-
(nargs - 1) * sizeof(ParamExternData));
899+
paramLI = (ParamListInfo)
900+
palloc(offsetof(ParamListInfoData, params) +
901+
nargs * sizeof(ParamExternData));
902902
/* we have static list of params, so no hooks needed */
903903
paramLI->paramFetch = NULL;
904904
paramLI->paramFetchArg = NULL;

src/backend/executor/spi.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,9 +2290,8 @@ _SPI_convert_params(int nargs, Oid *argtypes,
22902290
{
22912291
int i;
22922292

2293-
/* sizeof(ParamListInfoData) includes the first array element */
2294-
paramLI = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
2295-
(nargs - 1) * sizeof(ParamExternData));
2293+
paramLI = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) +
2294+
nargs * sizeof(ParamExternData));
22962295
/* we have static list of params, so no hooks needed */
22972296
paramLI->paramFetch = NULL;
22982297
paramLI->paramFetchArg = NULL;

src/backend/nodes/params.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ copyParamList(ParamListInfo from)
4040
if (from == NULL || from->numParams <= 0)
4141
return NULL;
4242

43-
/* sizeof(ParamListInfoData) includes the first array element */
44-
size = sizeof(ParamListInfoData) +
45-
(from->numParams - 1) * sizeof(ParamExternData);
43+
size = offsetof(ParamListInfoData, params) +
44+
from->numParams * sizeof(ParamExternData);
4645

4746
retval = (ParamListInfo) palloc(size);
4847
retval->paramFetch = NULL;

src/backend/postmaster/syslogger.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,13 +785,13 @@ process_pipe_input(char *logbuffer, int *bytes_in_logbuffer)
785785
int dest = LOG_DESTINATION_STDERR;
786786

787787
/* While we have enough for a header, process data... */
788-
while (count >= (int) sizeof(PipeProtoHeader))
788+
while (count >= (int) (offsetof(PipeProtoHeader, data) +1))
789789
{
790790
PipeProtoHeader p;
791791
int chunklen;
792792

793793
/* Do we have a valid header? */
794-
memcpy(&p, cursor, sizeof(PipeProtoHeader));
794+
memcpy(&p, cursor, offsetof(PipeProtoHeader, data));
795795
if (p.nuls[0] == '\0' && p.nuls[1] == '\0' &&
796796
p.len > 0 && p.len <= PIPE_MAX_PAYLOAD &&
797797
p.pid != 0 &&

src/backend/tcop/postgres.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,9 +1619,8 @@ exec_bind_message(StringInfo input_message)
16191619
{
16201620
int paramno;
16211621

1622-
/* sizeof(ParamListInfoData) includes the first array element */
1623-
params = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
1624-
(numParams - 1) * sizeof(ParamExternData));
1622+
params = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) +
1623+
numParams * sizeof(ParamExternData));
16251624
/* we have static list of params, so no hooks needed */
16261625
params->paramFetch = NULL;
16271626
params->paramFetchArg = NULL;

src/backend/utils/adt/geo_ops.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ path_in(PG_FUNCTION_ARGS)
13901390
}
13911391

13921392
base_size = sizeof(path->p[0]) * npts;
1393-
size = offsetof(PATH, p[0]) +base_size;
1393+
size = offsetof(PATH, p) +base_size;
13941394

13951395
/* Check for integer overflow */
13961396
if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
@@ -1443,12 +1443,12 @@ path_recv(PG_FUNCTION_ARGS)
14431443

14441444
closed = pq_getmsgbyte(buf);
14451445
npts = pq_getmsgint(buf, sizeof(int32));
1446-
if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p[0])) / sizeof(Point)))
1446+
if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p)) / sizeof(Point)))
14471447
ereport(ERROR,
14481448
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
14491449
errmsg("invalid number of points in external \"path\" value")));
14501450

1451-
size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
1451+
size = offsetof(PATH, p) +sizeof(path->p[0]) * npts;
14521452
path = (PATH *) palloc(size);
14531453

14541454
SET_VARSIZE(path, size);
@@ -3476,7 +3476,7 @@ poly_in(PG_FUNCTION_ARGS)
34763476
errmsg("invalid input syntax for type polygon: \"%s\"", str)));
34773477

34783478
base_size = sizeof(poly->p[0]) * npts;
3479-
size = offsetof(POLYGON, p[0]) +base_size;
3479+
size = offsetof(POLYGON, p) +base_size;
34803480

34813481
/* Check for integer overflow */
34823482
if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
@@ -3530,12 +3530,12 @@ poly_recv(PG_FUNCTION_ARGS)
35303530
int size;
35313531

35323532
npts = pq_getmsgint(buf, sizeof(int32));
3533-
if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p[0])) / sizeof(Point)))
3533+
if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p)) / sizeof(Point)))
35343534
ereport(ERROR,
35353535
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
35363536
errmsg("invalid number of points in external \"polygon\" value")));
35373537

3538-
size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
3538+
size = offsetof(POLYGON, p) +sizeof(poly->p[0]) * npts;
35393539
poly = (POLYGON *) palloc0(size); /* zero any holes */
35403540

35413541
SET_VARSIZE(poly, size);
@@ -4251,7 +4251,7 @@ path_add(PG_FUNCTION_ARGS)
42514251
PG_RETURN_NULL();
42524252

42534253
base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
4254-
size = offsetof(PATH, p[0]) +base_size;
4254+
size = offsetof(PATH, p) +base_size;
42554255

42564256
/* Check for integer overflow */
42574257
if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
@@ -4393,7 +4393,7 @@ path_poly(PG_FUNCTION_ARGS)
43934393
* Never overflows: the old size fit in MaxAllocSize, and the new size is
43944394
* just a small constant larger.
43954395
*/
4396-
size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * path->npts;
4396+
size = offsetof(POLYGON, p) +sizeof(poly->p[0]) * path->npts;
43974397
poly = (POLYGON *) palloc(size);
43984398

43994399
SET_VARSIZE(poly, size);
@@ -4468,7 +4468,7 @@ box_poly(PG_FUNCTION_ARGS)
44684468
int size;
44694469

44704470
/* map four corners of the box to a polygon */
4471-
size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * 4;
4471+
size = offsetof(POLYGON, p) +sizeof(poly->p[0]) * 4;
44724472
poly = (POLYGON *) palloc(size);
44734473

44744474
SET_VARSIZE(poly, size);
@@ -4502,7 +4502,7 @@ poly_path(PG_FUNCTION_ARGS)
45024502
* Never overflows: the old size fit in MaxAllocSize, and the new size is
45034503
* smaller by a small constant.
45044504
*/
4505-
size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * poly->npts;
4505+
size = offsetof(PATH, p) +sizeof(path->p[0]) * poly->npts;
45064506
path = (PATH *) palloc(size);
45074507

45084508
SET_VARSIZE(path, size);
@@ -5181,7 +5181,7 @@ circle_poly(PG_FUNCTION_ARGS)
51815181
errmsg("must request at least 2 points")));
51825182

51835183
base_size = sizeof(poly->p[0]) * npts;
5184-
size = offsetof(POLYGON, p[0]) +base_size;
5184+
size = offsetof(POLYGON, p) +base_size;
51855185

51865186
/* Check for integer overflow */
51875187
if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)

src/backend/utils/cache/catcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ SearchCatCacheList(CatCache *cache,
15901590
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
15911591
nmembers = list_length(ctlist);
15921592
cl = (CatCList *)
1593-
palloc(sizeof(CatCList) + nmembers * sizeof(CatCTup *));
1593+
palloc(offsetof(CatCList, members) +nmembers * sizeof(CatCTup *));
15941594
heap_copytuple_with_tuple(ntp, &cl->tuple);
15951595
MemoryContextSwitchTo(oldcxt);
15961596
heap_freetuple(ntp);

src/bin/pg_dump/dumputils.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,9 +1216,8 @@ simple_string_list_append(SimpleStringList *list, const char *val)
12161216
{
12171217
SimpleStringListCell *cell;
12181218

1219-
/* this calculation correctly accounts for the null trailing byte */
12201219
cell = (SimpleStringListCell *)
1221-
pg_malloc(sizeof(SimpleStringListCell) + strlen(val));
1220+
pg_malloc(offsetof(SimpleStringListCell, val) +strlen(val) + 1);
12221221

12231222
cell->next = NULL;
12241223
strcpy(cell->val, val);

src/bin/pg_dump/dumputils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ typedef struct SimpleOidList
3838
typedef struct SimpleStringListCell
3939
{
4040
struct SimpleStringListCell *next;
41-
char val[1]; /* VARIABLE LENGTH FIELD */
41+
char val[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string here */
4242
} SimpleStringListCell;
4343

4444
typedef struct SimpleStringList

src/include/access/gin_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ typedef struct GinOptions
322322
{
323323
int32 vl_len_; /* varlena header (do not touch directly!) */
324324
bool useFastUpdate; /* use fast updates? */
325-
int pendingListCleanupSize; /* maximum size of pending list */
325+
int pendingListCleanupSize; /* maximum size of pending list */
326326
} GinOptions;
327327

328328
#define GIN_DEFAULT_USE_FASTUPDATE true
@@ -389,7 +389,7 @@ typedef struct
389389
{
390390
ItemPointerData first; /* first item in this posting list (unpacked) */
391391
uint16 nbytes; /* number of bytes that follow */
392-
unsigned char bytes[1]; /* varbyte encoded items (variable length) */
392+
unsigned char bytes[FLEXIBLE_ARRAY_MEMBER]; /* varbyte encoded items */
393393
} GinPostingList;
394394

395395
#define SizeOfGinPostingList(plist) (offsetof(GinPostingList, bytes) + SHORTALIGN((plist)->nbytes) )

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy