On 03/19/16 00:27, Andrew Fish wrote: > >> On Mar 18, 2016, at 3:46 PM, Michael Brown <[email protected]> wrote: >> >> On 18/03/16 22:30, Laszlo Ersek wrote: >>> Unfortunately, I've run into a big issue: the DEBUG(()) macro. (To a >>> smaller extent, the ASSERT_EFI_ERROR() macro as well.) These macros >>> expand to the null replacement string when MDEPKG_NDEBUG is defined >>> (which is occasionally the case for RELEASE builds). If those macro >>> invocations constitute the only read accesses to some local variables, >>> then the MDEPKG_NDEBUG build triggers "-Wunused-but-set-variable". >>> >>> For ASSERT_EFI_ERROR(), I could work it around like this: >>> >>> ((VOID)(TRUE ? 0 : (StatusParameter))) >>> >>> but I have no clue how to do the same with DEBUG(), which can receive >>> any number of arguments (of any type too). >> >> With the caveat that I haven't looked at how DEBUG() is implemented in EDK2: >> >> Could this rely upon dead code elimination? At least gcc will happily >> accept something which expands to >> >> if ( 0 ) { >> do_something_with ( a_variable ); >> } >> >> and treat that as being a "use" of a_variable (for the purposes of >> -Wunused-but-set-variable). >> > > All the DEBUG macros work this way all ready. MDEPKG_NDEBUG was a > hack-a-round for compilers that don't do link time optimization.
Like, all versions of gcc that are currently supported? :) > So you don't need to redefine anything, just don't use MDEPKG_NDEBUG. That sounds like good advice, but reality would have to catch up: $ git grep MDEPKG_NDEBUG -- '*.dsc' ArmPkg/ArmPkg.dsc: RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc: GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc: GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc: INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc: MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc: GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc: GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc: INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc: MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32.dsc: GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32.dsc: GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32.dsc: INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32.dsc: MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32X64.dsc: GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32X64.dsc: GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32X64.dsc: INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgIa32X64.dsc: MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgX64.dsc: GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgX64.dsc: GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG OvmfPkg/OvmfPkgX64.dsc: INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG OvmfPkg/OvmfPkgX64.dsc: MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc: ICC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc: GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgIA32.dsc: ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgIA32.dsc: GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgX64.dsc: ICC:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG Vlv2TbltDevicePkg/PlatformPkgX64.dsc: GCC:*_*_*_CC_FLAGS = -D MDEPKG_NDEBUG > That will give you the same path as VC++ and clang (assuming LTO is enabled). Well, LTO is unusable in edk2 with the supported GCC toolchains, to my knowledge. > https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/DebugLib.h > > #if !defined(MDEPKG_NDEBUG) > #define DEBUG(Expression) \ > do { \ > if (DebugPrintEnabled ()) { \ > _DEBUG (Expression); \ > } \ > } while (FALSE) > #else > #define DEBUG(Expression) > #endif > > > If you have code that only exists in DEBUG builds you can use these macros to > isolate it. > > /** > Macro that marks the beginning of debug source code. > If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, > then this macro marks the beginning of source code that is included in a > module. > Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() > are not included in a module. > **/ > #define DEBUG_CODE_BEGIN() do { if (DebugCodeEnabled ()) { UINT8 > __DebugCodeLocal > > > /** > The macro that marks the end of debug source code. > If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, > then this macro marks the end of source code that is included in a module. > Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() > are not included in a module. > **/ > #define DEBUG_CODE_END() __DebugCodeLocal = 0; __DebugCodeLocal++; } } > while (FALSE) Right, but the code that triggers the problem is more like: CHAR8 *Message; Message = ""; if (whatever) { // do some real logic Message = "blah\n"; // do some more real logic } DEBUG ((EFI_D_INFO, "%a\n", Message)); I.e., it's hard to find a common, tight scope for all uses of the variable in question. Thanks Laszlo _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

