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
?
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.