> 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. So you don't need to 
redefine anything, just don't use MDEPKG_NDEBUG. That will give you the same 
path as VC++ and clang (assuming LTO is enabled). 

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)

Note you only get the dead stripping if DebugPrintEnabled() or 
DebugCodeEnabled() resolve to a constant value at link time. The dead stripping 
of sets of strings is controller by PcdFixedDebugPrintErrorLevel.

Thanks,

Andrew Fish

> Michael

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to