Controlling Clang Warnings - llvm

I've compiled the SQLite amalgamation source into my iOS project, and clang throws a warning on this line
mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff;
with the following warning:
Implicit conversion from 'long long' to 'long' changes value from
9223372036854775807 to -1
[warn_impcast_integer_precision_constant]
I've enabled -fdiagnostics-show-name to show the name (warn_impcast_integer_precision_constant).
I certainly don't want to change anything in the SQLite source, since I don't want to introduce unforseen side effects, so I'd like to disable this specific warning just for that one line. The warning is certainly valid, but cannot occur anyway with the sizeof check in place.
To make this process reproducible for other warnings and diagnostics, is there a method to find out the specific warning class and disable them for one line? Unfortunately I can't find anything in the so called clang/llvm "documentation".

Any remotely recent version of clang should be printing the flag associated with a given warning along with the warning (in this case -Wconstant-conversion); not sure why you are not seeing this. And to turn it off, you can use #pragma clang diagnostic ignored "-Wconstant-conversion".

as quoted from the user manual lined by sir Chris Lattner:
In the below example -Wmultichar is ignored for only a single line of code, after which the diagnostics return to whatever state had previously existed.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmultichar"
char b = 'df'; // no warning.
#pragma clang diagnostic pop
But more importantly, would it not be more prudent to consider the type of variable that 'mask' is, and what 'mask' represents?
Since you're doing something depending on whether the size of long is 8, should it perhaps be of type uint64_t?
What if sizeof(long) is actually 16 instead of 8 or 4 (which I guess you expect it to be when it is not 8)? Is 0x7fffffff then still the mask you need? Or perhaps you really want to assign it LONG_MAX from limits.h rather then the current construction.

The clang user manual is here:
http://clang.llvm.org/docs/UsersManual.html
It discusses various topics related to diagnostics. There are other useful documents in the sidebar of http://clang.llvm.org/

Related

How to silence Xcode warning: "variable length arrays are a C99 feature [-Wvla-extension]"?

I am very confused by the format of Xcode, and have tried to look around to by advice: "invert the flag" that shows up when we get these warnings. If someone could walk me through how to get to that page to silence this warning. I would be VERY grateful :)
You shouldn't use variable-length arrays. They are not a part of standard c++, and you should use a std::vector instead.
However, if you want to turn off a specific warning such as -Wvla-extension then you can explicitly suppress this warning by adding the -Wno-vla-extension flag when compiling the program.
You can add this flag to wherever you would normally put such flags in Xcode.
I advise you to NOT use VLAs (variable Length Arrays) because they are out of the standard and unsafe, but if you know what you are doing, you can use
#pragma clang diagnostic ignored "-Wwarning-name"
Replace warning-name with the warning name to silence
I assume you are using clang, but if you are using GCC, replace clang with GCC.
Here is a link may also help:
https://davedelong.com/blog/2018/12/15/silencing-specific-build-warnings/

error C4146: unary minus operator applied to unsigned type, result still unsigned

I try to build CRF++ in Visual Studio 2013 and get this error in the last line:
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-siblings[i].left-1);
error C4146: unary minus operator applied to unsigned type, result
still unsigned
Specifically, it is in darts.h, line 189.
I built again in Visual Studio 2015 then there is no error.
How can I fix this in Visual Studio 2013?
C4146 is not supposed to be an error. It is a mere warning. If you see it as an error in your case, it means that someone has configured it this way, most likely unintentionally. This makes no sense.
Find and undo the changes that turned it into an error. Then you can disable it if you wish.
For others I wanted to add another answer in case they stumble into that bug like me.
Even if "Threat warning as error" was off in my compiler, I had to compile my project with #pragma warning(disable:4146) in my header's file that was showing me the error. For you it would had been inside darts.h
Please note disabling the warning globally in my project was not working (compiler /wd4146), the pragma line was needed in the header's file directly.
the siblings variable also has unary minus applied to it, maybe that is the culprit? Also if it's templated code you cannot really be sure value_ is going to be be short, int or long unless that is asserted via static_assert or so. We can only guess as you don't provide information about what types are actually used or something reproducable. Also did you use the exact same project for compilation in VS2015? If not, the warning might just have been disabled there.
Anyway, suppose it is a bug in VS2013, it likely won't ever get fixed anymore so you can try to find a workaround. Start by breaking that statement down into smaller ones until you know exactly which part is the problem (or maybe, by then the problem is gone already as it goes with compiler bugs). Then suppress the warning with #pragma warning ( disable : 4146 ), wrapped in a conditional directive so it only has effect for VS2013 #if _MSC_VER > 1800 && _MSC_VER < 1900 should do fine. Enable the warning again after the statement. Add a comment as to why the warning is disabled and submit the changes as a patch to CRF++.
Try this:
int tmp = static_cast<int>(siblings[i].left);
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-tmp - 1);
For anyone running into the really confusing part of this:
This isn't supposed to be an error. In fact, there are a bunch of warnings that Visual Studio incorrectly turns into errors by default. Compilers can add warnings for whatever they want, but throwing errors for valid code is just a bug.
The culprit is the "SDL checks" option. It's known for adding things like runtime stack checking, which is fine, but they snuck a bit of nastiness in: "and enables extra security-relevant warnings as errors". That needs to be turned off to have something slightly closer to a standard C++ compiler.

Disable GCC "may be used uninitialized" on a particular variable

I'm getting this warning on a stack variable:
warning: object.member may be used uninitialized in this function
In this case I do not wish to force initialization to just to get rid of the warning as it consumes CPU cycles. The variable is a POD structure so a memset on it is not zero cost. I can verify that the variable is never used uninitialized, so I'd just like to suppress the warning for it.
In general I do want the warning, just not on this particular variable in this particular scenario. How can I suppress the warning?
Looks like the pragma diagnostics are the correct way to go but they require quite a recent version of GCC (4.6)
No acceptable solution prior that version is known.
Try doing this:
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
This pragma comes in three interesting and helpful flavors : warning, error, ignored. See 6.56.10 Diagnostic Pragmas for their usages. The link says,
GCC allows the user to selectively
enable or disable certain types of
diagnostics, and change the kind of
the diagnostic. For example, a
project's policy might require that
all sources compile with -Werror but
certain files might have exceptions
allowing specific types of warnings.
Or, a project might selectively enable
diagnostics and treat them as errors
depending on which preprocessor macros
are defined.
The accepted answer has two big problems that requires more than a comment.
First, it deactivates the warning for the whole file. If that pragma resides in a header, probably for more. Warnings are useful and if it is indeed a false positive, one should disable the warning for a bunch of code as small as possible.
Then the warning in the OP is "maybe uninitialized" which is deactivated by -Wmaybe-uninitialized, as opposed to -Wuninitialized.
#pragma GCC diagnostic push // save the actual diag context
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // disable maybe warnings
function() or int variable; // impacted section of code
#pragma GCC diagnostic pop // restore previous diag context
GCC differentiates between uninitalised and self initalized, e.g. compiling:
int main() {
int i = i;
return i;
}
With gcc -Wall -Wextra gives no warnings, unless you explicitly added -Winit-self as well, yet it gets completely optimized out by my quick testing.
#Nawaz has answered the question as specifically asked, but have you considered that the fact that you need this may indicate you're declaring your struct too early/at a less nested scope than appropriate? It would generally be much preferred if you could declare your struct at a point where you can actually initialize it rather than declaring it earlier and filling it in various locations.
Also, even though you can verify that it's never used uninitialized right now, what if someone else adds a new code path in the future and it's not initialized properly? If you disable the warning then it'll silently compile and probably break in an unexpected way. Unless you can prove that the initialization is taking a measurable amount of your program's CPU it's probably better to just do the initialization up front.
Selectively disable GCC warnings for only part of a translation unit?

Forcing an error when a function doesn't explicitly return a value on the deafult return path?

Is there a way, in VC++ (VSTS 2008), to froce a compiler error for functions that do not explicitly return a value on the default return path (Or any other quick way to locate them)?
On the same issue, is there any gaurentee as to what such functions actually return?
I don't know exactly the warning number, but you can use #pragma warning for enforcing a specific warning to be treated as error:
Example:
#pragma warning( error: 4001)
will treat warning 4001 as error
If you enable max warning level, and treat warnings as errors, you'll surely find what you're looking for. A guess as to what will be returned otherwise: A default-constructed object of the function's return type.
VC will warn about many instances of this problem, but fails to detect some. I've repeatedly caught it missing this problem in function templates, but I've seen int in some plain functions, too. Treating warnings as errors (compiler switch for all warnings or pragma for specifc ones) will make it impossible to overlook those it finds.
For those VC overlooks you have to use more thorough tools. AFAIK in VSTS you can also throw an /analyze switch for the compiler and have it find even more problems.
There's also many versions of lint-like programs.
Using some other compiler helps, too. Porting a VS project to GCC for the first time can be quite hard, but I think Intel's compiler can be used as a drop-in replacement for VC and compile VC projects right away. Comeau C++, too, has switches for being quite VC-compatible and has incredibly good errors messages.

Assignment across data types in C++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Make VS compiler catch signed/unsigned assignments?
I've compiled the following snippet of code in VC++ 2005/2008:
unsigned long ul = ...;
signed long l = ...;
l = ul;
and was expecting to see a compiler warning (Warning Level set to 4), but none was generated. Am I missing something obvious here?
Thanks
If the omitted initializers are compile-time constants, the static analyzer may be able to determine that no overflow can occur and let it slide without a warning. Try initializing ul to something > 2^31 -1 and see what happens (assuming you're on a 32-bit platform).
I think it's a duplicate (here).
Quoting the accepted answer:
You need to enable warning 4365 to catch the assignment.
That might be tricky - you need to enable ALL warnings - use /Wall which enables lots of warnings, so you may have some trouble seeing the warning occur, but it does. (quamrana)
You could also use #pragma warning(default: 4365) to enable. (ChrisN)
Warnings are compiler specific. You "should" see a warning in the sense that "it would help you" to see one, but the Visual C++ team did not choose to display one by default.