On Thu, 6 Oct 2022 at 13:39, Andres Freund <and...@anarazel.de> wrote:
> I attached a patch to add -Wshadow=compatible-local to our set of warnings.

Thanks for writing that and for looking at the patch.

FWIW, I'm +1 for having this part of our default compilation flags.  I
don't want to have to revisit this on a yearly basis. I imagine Justin
doesn't want to do that either.  I feel that since this work has
already uncovered 2 existing bugs that it's worth having this as a
default compilation flag.  Additionally, in the cases like in the
PLy_exec_trigger() trigger case below, I feel this has resulted in
slightly more simple code that's easier to follow. I feel having to be
slightly more inventive with variable names in a small number of cases
is worth the trouble.  I feel the cases where this could get annoying
are probably limited to variables declared in macros. Maybe that's
just a reason to consider static inline functions instead.  That
wouldn't work for macros such as PG_TRY(), but I think macros in that
category are rare.  I think switching it on does not mean we can never
switch it off again should we ever find something we're unable to work
around.  That just seems a little unlikely given that with the prior
commits plus the attached patch, we've managed to fix ~30 years worth
of opportunity to introduce shadowed local variables.

> > diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
> >  #define HS_FINALIZE(hsp_,count_,buf_,ptr_)                                 
> >                   \
> >       do {                                                                  
> >                                                   \
> > -             int buflen = (ptr_) - (buf_);                                 
> >                           \
> > +             int _buflen = (ptr_) - (buf_);                                
> >                           \
>
> Not pretty. Given that HS_FINALIZE already has multiple-eval hazards, perhaps
> we could just remove the local?

You're right. It's not that pretty, but I don't feel like making the
hazards any worse is a good idea. This is old code. I'd rather change
it as little as possible to minimise the risk of introducing any bugs.
I'm open to other names for the variable, but I just don't want to
widen the scope for multiple evaluation hazards.

> > --- a/src/interfaces/libpq/fe-secure-gssapi.c
> > +++ b/src/interfaces/libpq/fe-secure-gssapi.c
> > @@ -135,11 +135,11 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t 
> > len)
> > -                     ssize_t         ret;
> > +                     ssize_t         retval;
>
> That looks like it could easily lead to confusion further down the
> line. Wouldn't the better fix here be to remove the inner variable?

hmm. You're maybe able to see something I can't there, but to me, it
looks like reusing the outer variable could change the behaviour of
the function.  Note at the end of the function we set "ret" just
before the goto label.  It looks like it might be possible for the
goto to jump to the point after "ret = bytes_sent;", in which case we
should return -1, the default value for the outer "ret". If I go and
reuse the outer "ret" for something else then it'll return whatever
value it's left set to.  I could study the code more and perhaps work
out that that cannot happen, but if it can't then it's really not
obvious to me and if it's not obvious then I just don't feel the need
to take any undue risks by reusing the outer variable.  I'm open to
better names, but I'd just rather not reuse the outer scoped variable.

> > --- a/src/pl/plpython/plpy_exec.c
> > +++ b/src/pl/plpython/plpy_exec.c
> > @@ -375,11 +375,11 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, 
> > PLyProcedure *proc)
> > -                             TriggerData *tdata = (TriggerData *) 
> > fcinfo->context;
> > +                             TriggerData *trigdata = (TriggerData *) 
> > fcinfo->context;

> This doesn't strike me as a good fix either. Isn't the inner tdata exactly
> the same as the outer data?

Yeah, you're right. I've adjusted the patch to use the outer scoped
variable and get rid of the inner scoped one.

> > --- a/src/test/modules/test_integerset/test_integerset.c
> > +++ b/src/test/modules/test_integerset/test_integerset.c
> > @@ -585,26 +585,26 @@ test_huge_distances(void)
>
> This is one of the cases where our insistence on -Wdeclaration-after-statement
> really makes this unnecessary ugly... Declaring x at the start of the function
> just makes this harder to read.

Yeah, it's not pretty. Maybe one day we'll relax that rule. Until
then, I think it's not worth expending too much thought on a test
module.

David
diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c
index e64291e049..dd26d6ac29 100644
--- a/contrib/bloom/blinsert.c
+++ b/contrib/bloom/blinsert.c
@@ -232,8 +232,6 @@ blinsert(Relation index, Datum *values, bool *isnull,
 
        if (metaData->nEnd > metaData->nStart)
        {
-               Page            page;
-
                blkno = metaData->notFullPage[metaData->nStart];
                Assert(blkno != InvalidBlockNumber);
 
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index de0b9a109c..67821cd25b 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -450,15 +450,15 @@ get_file_fdw_attribute_options(Oid relid)
        for (attnum = 1; attnum <= natts; attnum++)
        {
                Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum - 1);
-               List       *options;
+               List       *column_options;
                ListCell   *lc;
 
                /* Skip dropped attributes. */
                if (attr->attisdropped)
                        continue;
 
-               options = GetForeignColumnOptions(relid, attnum);
-               foreach(lc, options)
+               column_options = GetForeignColumnOptions(relid, attnum);
+               foreach(lc, column_options)
                {
                        DefElem    *def = (DefElem *) lfirst(lc);
 
@@ -480,7 +480,7 @@ get_file_fdw_attribute_options(Oid relid)
                                        fncolumns = lappend(fncolumns, 
makeString(attname));
                                }
                        }
-                       /* maybe in future handle other options here */
+                       /* maybe in future handle other column options here */
                }
        }
 
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
index 4713e6ea7a..897af244a4 100644
--- a/contrib/hstore/hstore.h
+++ b/contrib/hstore/hstore.h
@@ -128,15 +128,15 @@ typedef struct
 /* finalize a newly-constructed hstore */
 #define HS_FINALIZE(hsp_,count_,buf_,ptr_)                                     
                \
        do {                                                                    
                                                \
-               int buflen = (ptr_) - (buf_);                                   
                        \
+               int _buflen = (ptr_) - (buf_);                                  
                        \
                if ((count_))                                                   
                                        \
                        ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST;                
                \
                if ((count_) != HS_COUNT((hsp_)))                               
                        \
                {                                                               
                                                        \
                        HS_SETCOUNT((hsp_),(count_));                           
                        \
-                       memmove(STRPTR(hsp_), (buf_), buflen);                  
                \
+                       memmove(STRPTR(hsp_), (buf_), _buflen);                 
                \
                }                                                               
                                                        \
-               SET_VARSIZE((hsp_), CALCDATASIZE((count_), buflen));            
\
+               SET_VARSIZE((hsp_), CALCDATASIZE((count_), _buflen));           
\
        } while (0)
 
 /* ensure the varlena size of an existing hstore is correct */
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index 09f37fb77a..9524765650 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -943,8 +943,6 @@ foreign_expr_walker(Node *node,
                                 */
                                if (agg->aggorder)
                                {
-                                       ListCell   *lc;
-
                                        foreach(lc, agg->aggorder)
                                        {
                                                SortGroupClause *srt = 
(SortGroupClause *) lfirst(lc);
diff --git a/contrib/postgres_fdw/postgres_fdw.c 
b/contrib/postgres_fdw/postgres_fdw.c
index dd858aba03..8d013f5b1a 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -1341,8 +1341,6 @@ postgresGetForeignPlan(PlannerInfo *root,
                 */
                if (outer_plan)
                {
-                       ListCell   *lc;
-
                        /*
                         * Right now, we only consider grouping and aggregation 
beyond
                         * joins. Queries involving aggregates or grouping do 
not require
@@ -6272,10 +6270,10 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo 
*grouped_rel,
                                 */
                                foreach(l, aggvars)
                                {
-                                       Expr       *expr = (Expr *) lfirst(l);
+                                       Expr       *aggref = (Expr *) lfirst(l);
 
-                                       if (IsA(expr, Aggref))
-                                               tlist = 
add_to_flat_tlist(tlist, list_make1(expr));
+                                       if (IsA(aggref, Aggref))
+                                               tlist = 
add_to_flat_tlist(tlist, list_make1(aggref));
                                }
                        }
                }
@@ -6289,8 +6287,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo 
*grouped_rel,
         */
        if (havingQual)
        {
-               ListCell   *lc;
-
                foreach(lc, (List *) havingQual)
                {
                        Expr       *expr = (Expr *) lfirst(lc);
@@ -6324,7 +6320,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo 
*grouped_rel,
        if (fpinfo->local_conds)
        {
                List       *aggvars = NIL;
-               ListCell   *lc;
 
                foreach(lc, fpinfo->local_conds)
                {
diff --git a/src/interfaces/libpq/fe-secure-gssapi.c 
b/src/interfaces/libpq/fe-secure-gssapi.c
index 6ea52ed866..dee0982eba 100644
--- a/src/interfaces/libpq/fe-secure-gssapi.c
+++ b/src/interfaces/libpq/fe-secure-gssapi.c
@@ -135,11 +135,11 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
                 */
                if (PqGSSSendLength)
                {
-                       ssize_t         ret;
+                       ssize_t         retval;
                        ssize_t         amount = PqGSSSendLength - 
PqGSSSendNext;
 
-                       ret = pqsecure_raw_write(conn, PqGSSSendBuffer + 
PqGSSSendNext, amount);
-                       if (ret <= 0)
+                       retval = pqsecure_raw_write(conn, PqGSSSendBuffer + 
PqGSSSendNext, amount);
+                       if (retval <= 0)
                        {
                                /*
                                 * Report any previously-sent data; if there 
was none, reflect
@@ -149,16 +149,16 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
                                 */
                                if (bytes_sent)
                                        return bytes_sent;
-                               return ret;
+                               return retval;
                        }
 
                        /*
                         * Check if this was a partial write, and if so, move 
forward that
                         * far in our buffer and try again.
                         */
-                       if (ret != amount)
+                       if (retval != amount)
                        {
-                               PqGSSSendNext += ret;
+                               PqGSSSendNext += retval;
                                continue;
                        }
 
diff --git a/src/pl/plpython/plpy_cursorobject.c 
b/src/pl/plpython/plpy_cursorobject.c
index 6b6e743345..57e8f8ec21 100644
--- a/src/pl/plpython/plpy_cursorobject.c
+++ b/src/pl/plpython/plpy_cursorobject.c
@@ -215,18 +215,18 @@ PLy_cursor_plan(PyObject *ob, PyObject *args)
                        PyObject   *elem;
 
                        elem = PySequence_GetItem(args, j);
-                       PG_TRY();
+                       PG_TRY(2);
                        {
                                bool            isnull;
 
                                plan->values[j] = PLy_output_convert(arg, elem, 
&isnull);
                                nulls[j] = isnull ? 'n' : ' ';
                        }
-                       PG_FINALLY();
+                       PG_FINALLY(2);
                        {
                                Py_DECREF(elem);
                        }
-                       PG_END_TRY();
+                       PG_END_TRY(2);
                }
 
                portal = SPI_cursor_open(NULL, plan->plan, plan->values, nulls,
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index 150b3a5977..923703535a 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -375,8 +375,6 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure 
*proc)
                                rv = NULL;
                        else if (pg_strcasecmp(srv, "MODIFY") == 0)
                        {
-                               TriggerData *tdata = (TriggerData *) 
fcinfo->context;
-
                                if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event) ||
                                        
TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
                                        rv = PLy_modify_tuple(proc, plargs, 
tdata, rv);
diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c
index 9a71a42c15..6b9f8d5b43 100644
--- a/src/pl/plpython/plpy_spi.c
+++ b/src/pl/plpython/plpy_spi.c
@@ -236,18 +236,18 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long 
limit)
                        PyObject   *elem;
 
                        elem = PySequence_GetItem(list, j);
-                       PG_TRY();
+                       PG_TRY(2);
                        {
                                bool            isnull;
 
                                plan->values[j] = PLy_output_convert(arg, elem, 
&isnull);
                                nulls[j] = isnull ? 'n' : ' ';
                        }
-                       PG_FINALLY();
+                       PG_FINALLY(2);
                        {
                                Py_DECREF(elem);
                        }
-                       PG_END_TRY();
+                       PG_END_TRY(2);
                }
 
                rv = SPI_execute_plan(plan->plan, plan->values, nulls,
diff --git a/src/test/modules/test_integerset/test_integerset.c 
b/src/test/modules/test_integerset/test_integerset.c
index 578d2e8aec..813ca4ba6b 100644
--- a/src/test/modules/test_integerset/test_integerset.c
+++ b/src/test/modules/test_integerset/test_integerset.c
@@ -585,26 +585,26 @@ test_huge_distances(void)
         */
        for (int i = 0; i < num_values; i++)
        {
-               uint64          x = values[i];
+               uint64          y = values[i];
                bool            expected;
                bool            result;
 
-               if (x > 0)
+               if (y > 0)
                {
-                       expected = (values[i - 1] == x - 1);
-                       result = intset_is_member(intset, x - 1);
+                       expected = (values[i - 1] == y - 1);
+                       result = intset_is_member(intset, y - 1);
                        if (result != expected)
-                               elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, x - 1);
+                               elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, y - 1);
                }
 
-               result = intset_is_member(intset, x);
+               result = intset_is_member(intset, y);
                if (result != true)
-                       elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, x);
+                       elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, y);
 
-               expected = (i != num_values - 1) ? (values[i + 1] == x + 1) : 
false;
-               result = intset_is_member(intset, x + 1);
+               expected = (i != num_values - 1) ? (values[i + 1] == y + 1) : 
false;
+               result = intset_is_member(intset, y + 1);
                if (result != expected)
-                       elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, x + 1);
+                       elog(ERROR, "intset_is_member failed for " 
UINT64_FORMAT, y + 1);
        }
 
        /*

Reply via email to