Search code examples
c++gccclangcompiler-warningssuppress-warnings

#pragma(* diagnostic) when mixing Clang analyzers with a GCC compiler


I'm compiling on with GCC on Linux, but CMake is kind enough to produce a Clang compatible compilation database. This means that I can run fancy, modern Clang based tools on my codebase and those tools have perfect knowledge of how each file is to be built (flags, defines, include paths, etc.) So far so good.

But today the Clang based static analysis in my IDE started showing a Clang specific warning. I don't think it particularly matters for my question which warning it is, but it was warning: disabled expansion of recursive macro, generated by -Wdisabled-macro-expansion. This particular macro is provided by a third party, so fixing the warning isn't an option, but I would like to suppress it as it occurs several times in the file in question.

What I'm struggling with is how to suppress the warning in Clang based analysis tools without causing new warnings in the GCC build.

  • Adding #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" suppresses the warning for Clang tools, but causes GCC to issue warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas].
  • Similarly, adding #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" suppresses the Clang warning (because Clang tries to be compatible with GCC diagnostics), but causes GCC to issue warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas].
  • Wrapping either of the above with #ifdef __clang__ makes GCC happy, but doesn't suppress the Clang warning because the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead.

Is there a way to make a diagnostic #pragma visible to Clang tooling, but not to GCC?


Solution

  • the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead

    If it's reporting a clang-only warning, but does not think that __clang__ is defined, that sounds like a problem with the tooling. If it's trying to be that clever about misrepresenting itself, you may be up a creek... but also you should be complaining to the tool author for creating this situation in the first place.

    That said, you could try:

    #if defined(__has_warning)
    #  if __has_warning("-Wdisabled-macro-expansion")
    #    pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
    #  endif
    #endif
    

    I'm not sure if this will work... it depends on how hard the tooling is pretending to not be clang (__has_warning is a clang-only extension).