-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Not Applicable
-
None
-
Storage Engines - Persistence
-
607.592
-
SE Persistence backlog
-
None
Problem
The WT_RET_MSG_CHK macro introduced in WT-17565 (PR #13821) fails to compile when used in a function because it internally calls WT_RET_MSG, which declares its own int _ret = (v). This creates a nested declaration that shadows the outer _ret from WT_RET_MSG_CHK's own do { } while(0) block, triggering -Werror,-Wshadow and -Werror,-Wuninitialized:
error: declaration shadows a local variable [-Werror,-Wshadow]
error: variable '__ret' is uninitialized when used within its own initialization [-Werror,-Wuninitialized]
The self-initialization happens because when WT_RET_MSG(session, _ret, ...) is expanded, the inner int __ret = (ret) refers to itself rather than the outer _ret (which was shadowed at the point of declaration).
The analogous WT_ERR_MSG_CHK macro does not have this problem because WT_ERR_MSG does not declare a new __ret variable — it uses the existing ret in scope and jumps to err:.
Fix
Inline the body of WT_RET_MSG directly inside WT_RET_MSG_CHK instead of calling the macro, so there is only one __ret declaration:
#define WT_RET_MSG_CHK(session, v, ...) \ do { \ int __ret = (v); \ if (__ret != 0) { \ __wt_error_log_add_helper(#v, __ret, WT_NONE); \ __wt_err(session, __ret, __VA_ARGS__); \ __wt_session_set_last_error(session, __ret, WT_NONE, __VA_ARGS__); \ return (__ret); \ } \ } while (0)
Discovery
Found while adding the first callsite of WT_RET_MSG_CHK in WT-17550.