2

I am not sure if I am the only person or this is the problem of so many other people.

What I suffer from is that for an even simple code that includes LLVM headers regardless of what ever I write in my main function, I get too many warnings when I compile my codes with extra warnings:

#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Instructions.h>

int main()
{
    return 0;
}

I cat get these warnings by using either gcc or clang:

g++-9 -std=c++17 main.cpp -Wall -Wextra -I/usr/lib/llvm-9/include -c -o main.o

clang++-9 -std=c++17 main.cpp -Wall -Wextra -I/usr/lib/llvm-9/include -c -o main.o

They are mainly unused parameters:

In file included from /usr/lib/llvm-9/include/llvm/IR/ConstantFolder.h:20,
                 from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:24,
                 from main.cpp:1:
/usr/lib/llvm-9/include/llvm/IR/Constants.h: In member function ‘llvm::Value* llvm::ConstantData::handleOperandChangeImpl(llvm::Value*, llvm::Value*)’:
/usr/lib/llvm-9/include/llvm/IR/Constants.h:60:41: warning: unused parameter ‘From’ [-Wunused-parameter]
   60 |   Value *handleOperandChangeImpl(Value *From, Value *To) {
      |                                  ~~~~~~~^~~~
/usr/lib/llvm-9/include/llvm/IR/Constants.h:60:54: warning: unused parameter ‘To’ [-Wunused-parameter]
   60 |   Value *handleOperandChangeImpl(Value *From, Value *To) {
      |                                               ~~~~~~~^~
In file included from /usr/lib/llvm-9/include/llvm/IR/ConstantFolder.h:21,
                 from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:24,
                 from main.cpp:1:
/usr/lib/llvm-9/include/llvm/IR/InstrTypes.h: In member function ‘bool llvm::CallBase::isFnAttrDisallowedByOpBundle(llvm::StringRef) const’:
/usr/lib/llvm-9/include/llvm/IR/InstrTypes.h:1913:47: warning: unused parameter ‘S’ [-Wunused-parameter]
 1913 |   bool isFnAttrDisallowedByOpBundle(StringRef S) const {
      |                                     ~~~~~~~~~~^
In file included from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:33,
                 from main.cpp:1:
/usr/lib/llvm-9/include/llvm/IR/Instructions.h: In member function ‘llvm::BasicBlock* llvm::ReturnInst::getSuccessor(unsigned int) const’:
/usr/lib/llvm-9/include/llvm/IR/Instructions.h:2943:37: warning: unused parameter ‘idx’ [-Wunused-parameter]
 2943 |   BasicBlock *getSuccessor(unsigned idx) const {
      |                            ~~~~~~~~~^~~
...

I just truncate these warnings. They are too many. When I turn on the -Wconversion the problem becomes even worse:

In file included from /usr/lib/llvm-9/include/llvm/Support/MathExtras.h:17,
                 from /usr/lib/llvm-9/include/llvm/ADT/SmallVector.h:19,
                 from /usr/lib/llvm-9/include/llvm/ADT/STLExtras.h:20,
                 from /usr/lib/llvm-9/include/llvm/ADT/StringRef.h:12,
                 from /usr/lib/llvm-9/include/llvm/ADT/StringMap.h:16,
                 from /usr/lib/llvm-9/include/llvm/Support/Host.h:16,
                 from /usr/lib/llvm-9/include/llvm/ADT/Hashing.h:48,
                 from /usr/lib/llvm-9/include/llvm/ADT/ArrayRef.h:12,
                 from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:18,
                 from main.cpp:1:
/usr/lib/llvm-9/include/llvm/Support/SwapByteOrder.h: In function ‘uint16_t llvm::sys::SwapByteOrder_16(uint16_t)’:
/usr/lib/llvm-9/include/llvm/Support/SwapByteOrder.h:36:23: warning: conversion from ‘int’ to ‘uint16_t’ {aka ‘short unsigned int’} may change value [-Wconversion]
   36 |   uint16_t Hi = value << 8;
      |                 ~~~~~~^~~~
/usr/lib/llvm-9/include/llvm/Support/SwapByteOrder.h:37:23: warning: conversion from ‘int’ to ‘uint16_t’ {aka ‘short unsigned int’} may change value [-Wconversion]
   37 |   uint16_t Lo = value >> 8;
      |                 ~~~~~~^~~~
In file included from /usr/lib/llvm-9/include/llvm/ADT/STLExtras.h:20,
                 from /usr/lib/llvm-9/include/llvm/ADT/StringRef.h:12,
                 from /usr/lib/llvm-9/include/llvm/ADT/StringMap.h:16,
                 from /usr/lib/llvm-9/include/llvm/Support/Host.h:16,
                 from /usr/lib/llvm-9/include/llvm/ADT/Hashing.h:48,
                 from /usr/lib/llvm-9/include/llvm/ADT/ArrayRef.h:12,
                 from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:18,
                 from main.cpp:1:
/usr/lib/llvm-9/include/llvm/ADT/SmallVector.h: In constructor ‘llvm::SmallVectorBase::SmallVectorBase(void*, size_t)’:
/usr/lib/llvm-9/include/llvm/ADT/SmallVector.h:45:35: warning: conversion from ‘size_t’ {aka ‘long unsigned int’} to ‘unsigned int’ may change value [-Wconversion]
   45 |       : BeginX(FirstEl), Capacity(TotalCapacity) {}
      |                                   ^~~~~~~~~~~~~
...

I get these warnings by clang too:

...
In file included from main.cpp:1:
In file included from /usr/lib/llvm-9/include/llvm/IR/IRBuilder.h:18:
In file included from /usr/lib/llvm-9/include/llvm/ADT/ArrayRef.h:12:
/usr/lib/llvm-9/include/llvm/ADT/Hashing.h:190:15: warning: implicit conversion changes signedness: 'const char' to 'uint8_t' (aka 'unsigned char') [-Wsign-conversion]
  uint8_t a = s[0];
          ~   ^~~~
/usr/lib/llvm-9/include/llvm/ADT/Hashing.h:191:15: warning: implicit conversion changes signedness: 'const char' to 'uint8_t' (aka 'unsigned char') [-Wsign-conversion]
  uint8_t b = s[len >> 1];
          ~   ^~~~~~~~~~~
/usr/lib/llvm-9/include/llvm/ADT/Hashing.h:192:15: warning: implicit conversion changes signedness: 'const char' to 'uint8_t' (aka 'unsigned char') [-Wsign-conversion]
  uint8_t c = s[len - 1];
          ~   ^~~~~~~~~~
...

This is just a MWE. Adding more headers, I can get other types of warnings such as

/usr/lib/llvm-9/include/llvm/ADT/Twine.h:232:16: warning: ‘<anonymous>.llvm::Twine::RHS.llvm::Twine::Child::twine’ may be used uninitialized in this function [-Wmaybe-uninitialized]
           !RHS.twine->isBinary())
            ~~~~^~~~~

Now, I am wondering whether LLVM is written carelessly? I always turn on all warnings and make sure my application compiles with 0 warnings. When I do this while using LLVM all warnings of my code are burried under LLVM ones. I cannot easily see them. Usually the first advise from people is to turn off those warnings switches. I strictly resist that. I want to find them for my application. The alternative solution comes to my mind is to turn off these warnings only for LLVM but not for my application. Is this possible especially when using CMake?

ar2015
  • 5,558
  • 8
  • 53
  • 110

2 Answers2

3

The issue of system header files causing warnings is a common one. It is not really for me to judge whether the authors of those headers were "careless" or not, but there is a relatively simple way to disable specific warnings before including the 'offending' headers, then restore your 'full' warnings once they have been included.

For clang you can do this with various #pragma diagnostic ... lines, as shown in the following code snippet:

#if defined (__clang__)
#pragma clang diagnostic push // Saves current diagnostic settings
#pragma clang diagnostic ignored "-Wsign-conversion" // Ignore this warning
#pragma clang diagnostic ignored "-Wunused-parameter" // and this one...
    // ... Add similar lines for other warnings you wish to disable
#endif

// Now include the 'offending' headers ...
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Instructions.h>

#if defined(__clang__)
#pragma clang diagnostic pop // Restores the saved settings
#endif

I don't have access to a GCC compiler but I believe very similar directives can be used: just substitute GCC for clang in the lines where that occurs. More information on such #pragma directives (for the GCC versions) can be found here.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • This got me on the right track to solve it with the GCC compiler. https://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code – Brambor Jun 14 '23 at 01:58
1

It is dependent on your GCC/clang/OS installation. On Fedora 32 it works as expected out of the box with system gcc-10.2.1-1.fc32.x86_64 + system clang-10.0.0-2.fc32.x86_64:

#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Instructions.h>

static void func(int val) {}

int main()
{
    func(42);
    return 0;
}

For GCC:

$ g++ -o stackoverflowllvmwarnings stackoverflowllvmwarnings.C $(llvm-config --cflags --libs) -std=c++17 -Wall -Wextra
stackoverflowllvmwarnings.C: In function ‘void func(int)’:
stackoverflowllvmwarnings.C:7:22: warning: unused parameter ‘val’ [-Wunused-parameter]
    7 | static void func(int val) {}
      |                  ~~~~^~~
$ _

For clang:

$ clang++ -o stackoverflowllvmwarnings stackoverflowllvmwarnings.C $(llvm-config --cflags --libs) -std=c++17 -Wall -Wextra
stackoverflowllvmwarnings.C:7:22: warning: unused parameter 'val' [-Wunused-parameter]
static void func(int val) {}
                     ^
1 warning generated.
$ _

If you really want (you do not) the warnings even for system headers use Wsystem-headers (it works similar way both for gcc and clang):

$ clang++ -o stackoverflowllvmwarnings stackoverflowllvmwarnings.C $(llvm-config --cflags --libs) -std=c++17 -Wall -Wextra -Wsystem-headers
In file included from stackoverflowllvmwarnings.C:1:
In file included from /usr/include/llvm/IR/IRBuilder.h:17:
In file included from /usr/include/llvm-c/Types.h:17:
In file included from /usr/include/llvm-c/DataTypes.h:28:
In file included from /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/cmath:42:
/usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/bits/cpp_type_traits.h:110:12: warning: keyword '__is_void' will be made available as an identifier for the remainder of the translation unit [-Wkeyword-compat]
    struct __is_void
           ^
...
Jan Kratochvil
  • 387
  • 3
  • 11
  • Thank you very much for proposing system headers. You probably mean `-isystem`. The problem is that I have some `-I./my-local-folder` and their related warning will be ignored too. But, maybe for some others, this will not be a problem. – ar2015 Aug 29 '20 at 19:11
  • One can be experimenting with -isystem etc. but that is a job of system integrators. I have shown it just works. One can also cross-compile to W32/W64 by MinGW or what other targets are needed. – Jan Kratochvil Aug 29 '20 at 19:18