Add optional parameter to PG_TRY() macros

This optional parameter can be specified in cases where there are nested
PG_TRY() statements within a function in order to stop the compiler from
issuing warnings about shadowed local variables when compiling with
-Wshadow.  The optional parameter is used as a suffix on the variable
names declared within the PG_TRY(), PG_CATCH(), PG_FINALLY() and
PG_END_TRY() macros.  The parameter, if specified, must be the same in
each component macro of the given PG_TRY() block.

This also adjusts the single case where we have nested PG_TRY() statements
to add a parameter to the inner-most PG_TRY().

This reduces the number of compiler warnings when compiling with
-Wshadow=compatible-local from 5 down to 1.

Author: David Rowley
Discussion: https://postgr.es/m/CAApHDvqWGMdB_pATeUqE=JCtNqNxObPOJ00jFEa2_sZ20j_Wvg@mail.gmail.com
This commit is contained in:
David Rowley 2022-10-06 10:08:31 +13:00
parent 23f3989d92
commit 112f0225db
2 changed files with 29 additions and 21 deletions

View file

@ -1678,16 +1678,16 @@ ProcessUtilitySlow(ParseState *pstate,
* command itself is queued, which is enough.
*/
EventTriggerInhibitCommandCollection();
PG_TRY();
PG_TRY(2);
{
address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
queryString, params, qc);
}
PG_FINALLY();
PG_FINALLY(2);
{
EventTriggerUndoInhibitCommandCollection();
}
PG_END_TRY();
PG_END_TRY(2);
break;
case T_CreateTrigStmt:

View file

@ -310,39 +310,47 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
* pedantry; we have seen bugs from compilers improperly optimizing code
* away when such a variable was not marked. Beware that gcc's -Wclobbered
* warnings are just about entirely useless for catching such oversights.
*
* Each of these macros accepts an optional argument which can be specified
* to apply a suffix to the variables declared within the macros. This suffix
* can be used to avoid the compiler emitting warnings about shadowed
* variables when compiling with -Wshadow in situations where nested PG_TRY()
* statements are required. The optional suffix may contain any character
* that's allowed in a variable name. The suffix, if specified, must be the
* same within each component macro of the given PG_TRY() statement.
*----------
*/
#define PG_TRY() \
#define PG_TRY(...) \
do { \
sigjmp_buf *_save_exception_stack = PG_exception_stack; \
ErrorContextCallback *_save_context_stack = error_context_stack; \
sigjmp_buf _local_sigjmp_buf; \
bool _do_rethrow = false; \
if (sigsetjmp(_local_sigjmp_buf, 0) == 0) \
sigjmp_buf *_save_exception_stack##__VA_ARGS__ = PG_exception_stack; \
ErrorContextCallback *_save_context_stack##__VA_ARGS__ = error_context_stack; \
sigjmp_buf _local_sigjmp_buf##__VA_ARGS__; \
bool _do_rethrow##__VA_ARGS__ = false; \
if (sigsetjmp(_local_sigjmp_buf##__VA_ARGS__, 0) == 0) \
{ \
PG_exception_stack = &_local_sigjmp_buf
PG_exception_stack = &_local_sigjmp_buf##__VA_ARGS__
#define PG_CATCH() \
#define PG_CATCH(...) \
} \
else \
{ \
PG_exception_stack = _save_exception_stack; \
error_context_stack = _save_context_stack
PG_exception_stack = _save_exception_stack##__VA_ARGS__; \
error_context_stack = _save_context_stack##__VA_ARGS__
#define PG_FINALLY() \
#define PG_FINALLY(...) \
} \
else \
_do_rethrow = true; \
_do_rethrow##__VA_ARGS__ = true; \
{ \
PG_exception_stack = _save_exception_stack; \
error_context_stack = _save_context_stack
PG_exception_stack = _save_exception_stack##__VA_ARGS__; \
error_context_stack = _save_context_stack##__VA_ARGS__
#define PG_END_TRY() \
#define PG_END_TRY(...) \
} \
if (_do_rethrow) \
if (_do_rethrow##__VA_ARGS__) \
PG_RE_THROW(); \
PG_exception_stack = _save_exception_stack; \
error_context_stack = _save_context_stack; \
PG_exception_stack = _save_exception_stack##__VA_ARGS__; \
error_context_stack = _save_context_stack##__VA_ARGS__; \
} while (0)
/*