gcc: suppress [enabled by default] warning from c++ code - c++

We build our project using gcc with -Wall -Werror options.
Warnings from external headers are suppressed by pragmas, like this:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <somelib/component/settings.h>
#pragma GCC diagnostic pop
After upgrading externals to new version we got new type of warnings to suppress:
error: inline function ‘...’ given attribute noinline [-Werror]
Or warning without -Werror:
warning: inline function ‘...’ given attribute noinline [enabled by default]
In seems there is no way to ignore it via #pragma GCC diagnostic ignored.
What can be done in this case under following conditions?
External headers cannot be modified. Patching local copy at build time is acceptable as a last resort.
Problematic header is widely used.
-Werror is on for our code

Finally we have chosen to patch at build time. It's a bit hacky but it allows to leave our project intact.
Patching was added to cmake build:
execute_process(COMMAND "patch" "-N" "header_to_patch.h" "header_to_patch.h.patch")
Patch file was prepared with:
diff -u "original/header_to_patch.h" "fixed/header_to_patch.h" > header_to_patch.h.patch

Related

Error: Initializer provided for function, __THROW __asm

I am trying to port an ARM-C library to be compiled with x86_64 C++, and I am getting the following error:
In file included from /usr/include/c++/5/cwchar:44:0,
from /usr/include/c++/5/bits/postypes.h:40,
from /usr/include/c++/5/bits/char_traits.h:40,
from /usr/include/c++/5/string:40,
from MyFile.h:19,
/usr/include/wchar.h:226:20: error: initializer provided for function
__THROW __asm ("wcschr") __attribute_pure__;
^
where MyFile.h has the following structure
// comments
#pragma once
// comments
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string> //<<< line 19
…
Initially, instead of it used to be which gave me a similar error:
In file included from MyFile.h:19:
/usr/include/string.h:73:21: error: initializer provided for function
__THROW __asm ("memchr") __attribute_pure__ __nonnull ((1));
^
Compiler version:
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.11) version 5.4.0 20160609 (x86_64-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3
ldd (Ubuntu GLIBC 2.23-0ubuntu11) 2.23
Compilation flags:
#g++ -O3 -std=c++14 -fpermissive -Wno-system-headers -w
UPDATE 1:
I've been modifying the Makefile, and the original version contains $#.via. For instance:
#$(COMPILE) -M -MF $(subst .o,.d.tmp,$#) -MT $# -E $(C_FLAGS) $#.via $< -o $#.preprocessed.c
and I changed the $#.via for #$#.via because I saw that in an older project they did it like that. However, if I leave as $#.via I just get:
SomeFile.c:1:1 fatal error: OneHeader.h: No such file or directory
I am starting to think that my Makefile is somewhere wrong...
I misunderstood the compiler option... Few lines above, my makefile creates the #.via files passing DEFINES and INCLUDES
#echo $(patsubst %, '%', $(C_DEFINES)) > $#.via
#echo $(C_INCLUDE) >> $#.via
and those #.via files are passed as additional arguments for the compilation. While for armcc the --via is supported see here, I found that for g++ -according to the gcc doc- the syntax is #<your_file>. Thus, what #$#.via does is simply to parse the $#.via to <your_file>.via.
Now I am still getting the initializer provided for function error message.
UPDATE 2:
I found the problem and I explained what happened in the answer section. See below.
Root cause
The problem was originated because I redefined __asm to be replaced by nothing (e.g. #define __asm) since I didn't want to touch the assembly code yet. Remember that I said I am porting ARM to x86, so I thought that easiest way to get rid of the compile errors was to remove all those __asm instructions, but not considering the effects of doing such a thing.
In other words, when I included the string.h header, the header itself uses assembly call as the error messaged pointed out:
/usr/include/wchar.h:226:20: error: initializer provided for function
__THROW __asm ("wcschr") __attribute_pure__;
and when the preprocessor changed the __asm("wcschr") for ("wcschr") the compiler hits the error -- which makes sense.
Moral of the history
Do not redefine qualifiers since it will also affect other modules that you are not seeing directly and prefer creating a macro to just change them (e.g. __asm for /*__asm*/) or just run sed in you code base.

How can I suppress a "-fpermissive" error using modern GCC?

I am trying to compile some nonconforming code in C++17, but I am stuck with the following issue.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-fpermissive"
Some code that compiles only when with -fpermissive flag is set:
#pragma GCC diagnostic pop
It compiles fine on GCC version 4.6.4 through 4.7.4, but all later versions of GCC are giving me the following warning and don't suppress the error.
warning: ‘-fpermissive’ is not an option that controls warnings [-Wpragmas]
#pragma GCC diagnostic ignored "-fpermissive"
When I write (out of desperation)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-fpermissive"
Some code that compiles only when with -fpermissive flag is set:
#pragma GCC diagnostic pop
I am back at square one. Currently I'd like to continue using GCC 7.1 for the project. I can compile the entire project with -fpermissive flag set as a compile option, but this means that some other section of code causing a -fpermissive error could compile.
Condensed example https://godbolt.org/g/KFd5Ke
This question is not a duplicate of In GCC, how can I mute the '-fpermissive' warning? as this is directed toward newer versions of GCC where the solution provided in the aforementioned Stack Overflow question does not work. I even included an example.

cc1plus: unrecognized command line option warning on any other warning

I have a strange behavior of g++ that it shows a warning about unrecognized command line option, when any other warning is shown.
Example:
struct Foo{virtual int bar() = 0;};
struct Bar:public Foo{int bar() {return 0;} };
int main(){}
Compiling with g++-5 -Wsuggest-override -Wno-c99-extensions -std=c++11 a.cpp or even g++-5 -Wsuggest-override -Wno-c99-extensions a.cpp shows:
a.cpp:2:27: warning: ‘virtual int Bar::bar()’ can be marked override [-Wsuggest-override]
struct Bar:public Foo{int bar() {return 0;} };
^
cc1plus: warning: unrecognized command line option ‘-Wno-c99-extensions’
ADDITION: There is no warning/error when I compile with g++-5 -Wno-c99-extensions a.cpp hence that option passes CMAKEs check using CHECK_CXX_COMPILER_FLAG
This bothers me quite a lot, as we use Werror but with exceptions via Wno-error=... It then bails out when any of the (non-error) warnings is shown with the "unrecognized command line option"
Is this known/expected? How can it be prevented?
If you don't want warnings about unrecognised command-line options, don't use unrecognised command-line options: -Wno-c99-extensions has never been a valid GCC option (I believe it's a clangism). Simply remove it from your build command.
As for why the warning is only emitted when you have another warning present, this behaviour seems counter-intuitive but it is actually deliberate and documented:
The warning "unrecognized command-line option" is not given for -Wno-foo
Since GCC 4.4, and as explained in the GCC manual: when an unrecognized warning option is requested (-Wunknown-warning), GCC emits a diagnostic stating that the option is not recognized. However, if the -Wno- form is used, the behavior is slightly different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are being produced. This allows the use of new -Wno- options with old compilers, but if something goes wrong, the compiler warns that an unrecognized option is present. (See PR28322 for the history of this change)
This might break configure tests that check for -Wno-foo options. The solution is to either test for the positive form (-Wfoo) or test using a testcase that triggers some other warning.
There are in fact a few results on Google of mailing list threads where software developers have faced this "problem", specifically with CMake, and made trivial fixes to their build scripts to "fix" it.

Can't suppress GCC -Wextra warning

I use Boost.Log v2 in one of my projects and I get the following warning when I build it:
C:\boost-1.55\include\boost\log\utility\setup\common_attributes.hpp:22: In file included from C:\boost-1.55\include/boost/log/utility/setup/common_attributes.hpp:22:0,
PROJECT_PATH\PROJECT_NAME\main.cpp:12: from ..\PROJECT_NAME\main.cpp:12:
C:\boost-1.55\include\boost\log\attributes\counter.hpp:-1: In instantiation of 'boost::log::v2_mt_nt5::attribute_value boost::log::v2_mt_nt5::attributes::counter<T>::impl_generic::get_value() [with T = unsigned int]':
PROJECT_PATH\PROJECT_NAME\main.cpp:44: required from here
C:\boost-1.55\include\boost\log\attributes\counter.hpp:133: avertissement : address requested for 'next', which is declared 'register' [-Wextra]
return make_attribute_value(next);
^
I'd like to remove this warning since I can't fix it as it's part of the Boost library. However, I did not find any -Wno-xxx option to remove it (-Wno-extra doesn't work). I'm using GCC 4.8.2.
How can I suppress this warning?
You may disable the warning when you include boost library
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra" // address requested for 'next', which is declared 'register'
//#include "boost/header_you_want.h"
#pragma GCC diagnostic pop

why is "cc1plus: warning: unrecognized command line option" for "no-" options only flagged by g++ when there is another warning?

> cat warning.cpp
#pragma foobar
> cat no_warning.cpp
#pragma message "foobar"
> g++ -Wall -Wno-foobar -c warning.cpp
warning.cpp:1:0: warning: ignoring #pragma foobar [-Wunknown-pragmas]
cc1plus: warning: unrecognized command line option "-Wno-foobar" [enabled by default]
> g++ -Wall -Wno-foobar -c no_warning.cpp
no_warning.cpp:1:17: note: #pragma message: foobar
This is by design, explained here:
When an unrecognized warning option is requested (e.g., -Wunknown-warning),
GCC emits a diagnostic stating that the option is not recognized.
However, if the -Wno- form is used, the behavior is slightly different:
no diagnostic is produced for -Wno-unknown-warning unless other diagnostics
are being produced.
This allows the use of new -Wno- options with old compilers, but if something
goes wrong, the compiler warns that an unrecognized option is present.
In other words, suppose you have foo.cc, and GCC-4.9 warns about something (let's call it foobar) in it, but you believe that your use of foobar is safe.
Since you want to treat all warnings as errors (with -Werror), you dutifully add -Wno-foobar to your Makefile.
Now someone else tries to build your code with GCC-4.8. As stated above, this produces no warning and he succeeds.
If this did produce a warning, you'd be unable to both use the foobar construct and have a single Makefile that worked with both GCC-4.8 and GCC-4.9.