/* * See the dyninst/COPYRIGHT file for copyright information. * * We provide the Paradyn Tools (below described as "Paradyn") * on an AS IS basis, and do not warrant its validity or performance. * We reserve the right to update, modify, or discontinue this * software at any time. We shall have no obligation to supply such * updates or modifications or any other form of support to you. * * By your use of Paradyn, you understand and agree that we (or any * other person or entity with proprietary rights in Paradyn) are * under no obligation to provide either maintenance services, * update services, notices of latent defects, or correction of * defects for Paradyn. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef COMPILER_DIAGNOSTICS_H #define COMPILER_DIAGNOSTICS_H // This file defines macros to suppress compiler diagnostics for a region of // code. They are used to suppress diagnostic that are due to 1) non-standard // code and 2) the compiler produced false positives. They expand to nothing // if not applicable with the current compiler. // // The macros to begin and end the region take the form: // // DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_ // DYNINST_DIAGNOSTIC_END_SUPPRESS_ // // They should be place on a lines of their own without trailing '()' or ';'. // // Currently defined value for are // // FLEX_ARRAY // warning about C flexible arrays in C++ // VLA // warning about C VLAs (variable length arrays) in C++ // VLA_EXTENSION // clang warning about C VLAs in C++ if VLA is suppressed // VLA_ALL` // both of the above // VLA_GCC_PRAGMA_BUG // gcc <9, 11.0, and 11.1 workaround macro // LOGICAL_OP // warning about duplicate subexpressions in a logical expression // Is a false positive due compiler checks after macro/constant // propagation (eg. (x == a && x == b) if a and b are distinct // constants with the same physical value. Only gcc 6-8. // DUPLICATED_BRANCHES // similar to LOGICAL_OP except the expressions are the // conditionals of a chain of if/then/else's. Only gcc 7-8. // UNUSED_VARIABLE // clang <10 warns about variables defined solely for RIAA (locks) // MAYBE_UNINITIALIZED // gcc 12 warns that dyncompat::optional::value_or may use an // unitialized value when value_or checks if it is initialized. // // Macros to silence unused variable warnings // // DYNINST_SUPPRESS_UNUSED_VARIABLE(var) // indicate that variable var OK to be unused // // Define DYNINST_DIAGNOSTIC_NO_SUPPRESSIONS to prevents suppressions. // Define compiler specific suppression codes, an undefined value represents no // suppression required. Suppression code macro names have the form // // DYNINST_SUPPRESS_CODE_ // #if defined(__GNUC__) && !defined(__clang__) #define DYNINST_SUPPRESS_CODE_FLEX_ARRAY "-Wpedantic" #define DYNINST_SUPPRESS_CODE_VLA "-Wvla" #if __GNUC__ < 9 #define DYNINST_SUPPRESS_CODE_LOGICAL_OP "-Wlogical-op" #endif #if __GNUC__ >= 7 && __GNUC__ < 9 #define DYNINST_SUPPRESS_CODE_DUPLICATED_BRANCHES "-Wduplicated-branches" #endif #if __GNUC__ == 12 #define DYNINST_SUPPRESS_CODE_MAYBE_UNINITIALIZED "-Wmaybe-uninitialized" #endif #elif defined(__clang__) #define DYNINST_SUPPRESS_CODE_FLEX_ARRAY "-Wpedantic" #define DYNINST_SUPPRESS_CODE_VLA "-Wvla" #define DYNINST_SUPPRESS_CODE_VLA_EXTENSION "-Wvla-extension" #if __clang_major__ < 10 #define DYNINST_SUPPRESS_CODE_UNUSED_VARIABLE "-Wunused-variable" #endif #elif defined(_MSC_VER) #define DYNINST_SUPPRESS_CODE_FLEX_ARRAY 4200 #endif // Define DYNISNT_DIAGNOSTIC_BEGIN/END macros, expands to nothing if code undefined #ifdef DYNINST_SUPPRESS_CODE_FLEX_ARRAY #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_FLEX_ARRAY DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(FLEX_ARRAY) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_FLEX_ARRAY DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_FLEX_ARRAY #define DYNINST_DIAGNOSTIC_END_SUPPRESS_FLEX_ARRAY #endif #ifdef DYNINST_SUPPRESS_CODE_VLA #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(VLA) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA #endif #ifdef DYNINST_SUPPRESS_CODE_VLA_EXTENSION #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_EXTENSION DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(VLA_EXTENSION) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_EXTENSION DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_EXTENSION #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_EXTENSION #endif #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_ALL DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_EXTENSION #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_ALL DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_EXTENSION // Suppressions to work around compiler specific diagnostic bugs #ifdef DYNINST_SUPPRESS_CODE_LOGICAL_OP #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_LOGICAL_OP DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(LOGICAL_OP) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_LOGICAL_OP DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_LOGICAL_OP #define DYNINST_DIAGNOSTIC_END_SUPPRESS_LOGICAL_OP #endif #ifdef DYNINST_SUPPRESS_CODE_DUPLICATED_BRANCHES #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_DUPLICATED_BRANCHES DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(DUPLICATED_BRANCHES) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_DUPLICATED_BRANCHES DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_DUPLICATED_BRANCHES #define DYNINST_DIAGNOSTIC_END_SUPPRESS_DUPLICATED_BRANCHES #endif #ifdef DYNINST_SUPPRESS_CODE_UNUSED_VARIABLE #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_UNUSED_VARIABLE DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(UNUSED_VARIABLE) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_UNUSED_VARIABLE DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_UNUSED_VARIABLE #define DYNINST_DIAGNOSTIC_END_SUPPRESS_UNUSED_VARIABLE #endif #ifdef DYNINST_SUPPRESS_CODE_MAYBE_UNINITIALIZED #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_MAYBE_UNINITIALIZED DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(MAYBE_UNINITIALIZED) #define DYNINST_DIAGNOSTIC_END_SUPPRESS_MAYBE_UNINITIALIZED DYNINST_DIAGNOSTIC_POP #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_MAYBE_UNINITIALIZED #define DYNINST_DIAGNOSTIC_END_SUPPRESS_MAYBE_UNINITIALIZED #endif // gcc <9, 11.0 and 11.1 (there may be others) have a bug where 'pragma // diagnostic ignores' do not take affect until the next line, so this is a // workaround for the suppression and VLA are in the same macro #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 9 || __GNUC__ == 11 && __GNUC_MINOR__ < 2) #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_GCC_PRAGMA_BUG DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_GCC_PRAGMA_BUG DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA #else #define DYNINST_DIAGNOSTIC_BEGIN_SUPPRESS_VLA_GCC_PRAGMA_BUG #define DYNINST_DIAGNOSTIC_END_SUPPRESS_VLA_GCC_PRAGMA_BUG #endif // Create pragma from parameters #define DYNINST_Pragma(x) _Pragma(#x) // Create compiler specific macros // // DYNINST_DIAGNOSTIC_Pragma(x) - diagnostic pragma for x which is unquoted // DYNINST_DIAGNOSTIC_SUPPRESS(x) - diagnostic pragma to suppress warning x: // quoted string (gcc), number (MSVC) #ifndef DYNINST_DIAGNOSTIC_NO_SUPPRESSIONS #if defined(__GNUC__) #define DYNINST_DIAGNOSTIC_Pragma(x) DYNINST_Pragma(GCC diagnostic x) #define DYNINST_DIAGNOSTIC_SUPPRESS(x) DYNINST_DIAGNOSTIC_Pragma(ignored x) #elif defined(_MSC_VER) #define DYNINST_DIAGNOSTIC_Pragma(x) DYNINST_Pragma(warning(x)) #define DYNINST_DIAGNOSTIC_SUPPRESS(x) DYNINST_DIAGNOSTIC_Pragma(disable:x) #endif #endif // if not defined, expand to nothing #ifndef DYNINST_DIAGNOSTIC_Pragma #define DYNINST_DIAGNOSTIC_Pragma(x) #endif #ifndef DYNINST_DIAGNOSTIC_SUPPRESS #define DYNINST_DIAGNOSTIC_SUPPRESS(x) #endif // Define macros in terms of compiler specific macros // // DYNINST_DIAGNOSTIC_POP - pop stack of pushed diagnostic state // DYNINST_DIAGNOSTIC_PUSH - push current diagnostic state on stack // DYNINST_DIAGNOSTIC_PUSH_SUPPRESS(x) - push diagnostic state and add suppression x #define DYNINST_DIAGNOSTIC_POP DYNINST_DIAGNOSTIC_Pragma(pop) #define DYNINST_DIAGNOSTIC_PUSH DYNINST_DIAGNOSTIC_Pragma(push) #define DYNINST_DIAGNOSTIC_PUSH_SUPPRESS(x) DYNINST_DIAGNOSTIC_PUSH \ DYNINST_DIAGNOSTIC_SUPPRESS(x) #define DYNINST_DIAGNOSTIC_PUSH_SUPPRESS_CODE(x) DYNINST_DIAGNOSTIC_PUSH_SUPPRESS(DYNINST_SUPPRESS_CODE_##x) // use the variable in a void expression to indicate use #ifndef DYNINST_DIAGNOSTIC_NO_SUPPRESSIONS #define DYNINST_SUPPRESS_UNUSED_VARIABLE(var) (void)(var) #endif // if not defined, expand to nothing #ifndef DYNINST_SUPPRESS_UNUSED_VARIABLE #define DYNINST_SUPPRESS_UNUSED_VARIABLE(var) #endif #endif /* COMPILER_DIAGNOSTICS_H */