Fix statically allocated struct with FLEXIBLE_ARRAY_MEMBER member.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Feb 2015 22:50:18 +0000 (17:50 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Feb 2015 22:50:18 +0000 (17:50 -0500)
clang complains about this, not unreasonably, so define another struct
that's explicitly for a WordEntryPos with exactly one element.

While at it, get rid of pretty dubious use of a static variable for
more than one purpose --- if it were being treated as const maybe
I'd be okay with this, but it isn't.

src/backend/utils/adt/tsrank.c
src/include/tsearch/ts_type.h

index 8952d7f0b61099e2815409c3098fbef4f3e3358d..733203ec7b52422f6df5de2abc1ebbbc3b776055 100644 (file)
@@ -195,16 +195,12 @@ SortAndUniqItems(TSQuery q, int *size)
        return res;
 }
 
-/* A dummy WordEntryPos array to use when haspos is false */
-static WordEntryPosVector POSNULL = {
-       1,                                                      /* Number of elements that follow */
-       {0}
-};
-
 static float
 calc_rank_and(const float *w, TSVector t, TSQuery q)
 {
        WordEntryPosVector **pos;
+       WordEntryPosVector1 posnull;
+       WordEntryPosVector *POSNULL;
        int                     i,
                                k,
                                l,
@@ -228,7 +224,12 @@ calc_rank_and(const float *w, TSVector t, TSQuery q)
                return calc_rank_or(w, t, q);
        }
        pos = (WordEntryPosVector **) palloc0(sizeof(WordEntryPosVector *) * q->size);
-       WEP_SETPOS(POSNULL.pos[0], MAXENTRYPOS - 1);
+
+       /* A dummy WordEntryPos array to use when haspos is false */
+       posnull.npos = 1;
+       posnull.pos[0] = 0;
+       WEP_SETPOS(posnull.pos[0], MAXENTRYPOS - 1);
+       POSNULL = (WordEntryPosVector *) &posnull;
 
        for (i = 0; i < size; i++)
        {
@@ -241,7 +242,7 @@ calc_rank_and(const float *w, TSVector t, TSQuery q)
                        if (entry->haspos)
                                pos[i] = _POSVECPTR(t, entry);
                        else
-                               pos[i] = &POSNULL;
+                               pos[i] = POSNULL;
 
                        dimt = pos[i]->npos;
                        post = pos[i]->pos;
@@ -256,7 +257,7 @@ calc_rank_and(const float *w, TSVector t, TSQuery q)
                                        for (p = 0; p < lenct; p++)
                                        {
                                                dist = Abs((int) WEP_GETPOS(post[l]) - (int) WEP_GETPOS(ct[p]));
-                                               if (dist || (dist == 0 && (pos[i] == &POSNULL || pos[k] == &POSNULL)))
+                                               if (dist || (dist == 0 && (pos[i] == POSNULL || pos[k] == POSNULL)))
                                                {
                                                        float           curw;
 
@@ -282,6 +283,7 @@ calc_rank_or(const float *w, TSVector t, TSQuery q)
 {
        WordEntry  *entry,
                           *firstentry;
+       WordEntryPosVector1 posnull;
        WordEntryPos *post;
        int32           dimt,
                                j,
@@ -291,6 +293,10 @@ calc_rank_or(const float *w, TSVector t, TSQuery q)
        QueryOperand **item;
        int                     size = q->size;
 
+       /* A dummy WordEntryPos array to use when haspos is false */
+       posnull.npos = 1;
+       posnull.pos[0] = 0;
+
        item = SortAndUniqItems(q, &size);
 
        for (i = 0; i < size; i++)
@@ -312,8 +318,8 @@ calc_rank_or(const float *w, TSVector t, TSQuery q)
                        }
                        else
                        {
-                               dimt = POSNULL.npos;
-                               post = POSNULL.pos;
+                               dimt = posnull.npos;
+                               post = posnull.pos;
                        }
 
                        resj = 0.0;
index ce919a2c66530e0a628d530f0f49735ecb11668c..281cdd6c2633463689579107fb6c9362504959ee 100644 (file)
@@ -66,6 +66,13 @@ typedef struct
        WordEntryPos pos[FLEXIBLE_ARRAY_MEMBER];
 } WordEntryPosVector;
 
+/* WordEntryPosVector with exactly 1 entry */
+typedef struct
+{
+       uint16          npos;
+       WordEntryPos pos[1];
+} WordEntryPosVector1;
+
 
 #define WEP_GETWEIGHT(x)       ( (x) >> 14 )
 #define WEP_GETPOS(x)          ( (x) & 0x3fff )