Including <atomic> breaks GCC's conversion-null diagnostic, and distcc fixes it. (Minimal examples included)

StackOverflow https://stackoverflow.com/questions/21918292

  •  14-10-2022
  •  | 
  •  

Question

This question actually consists of two observations.

First: The inclusion of <atomic> makes GCC not emit the conversion-null diagnostic in at least some cases where it otherwise does.
For example, consider the file noerror.cpp:

#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}

This file (error.cpp) is identical except for commenting out the include:

//#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}

If I attempt to compile error.cpp, I get an error as expected:

$ g++-4.8 -c -std=c++11 error.cpp
error.cpp: In function ‘int* foo()’:
error.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
 int * foo() {return false;}
                     ^
cc1plus: some warnings being treated as errors

I get the same results if I omit the #pragma and compile with -Werror instead. This is also expected: according to the GCC docs, the warning is enabled by default.

To my surprise, I can compile noerror.cpp with no errors. Even if the <atomic> header suppressed warnings and errors through #pragma GCC diagnostic ignore, the explicit pragma in my code should re-enable them, and yet it doesn't.

Incidentally, clang++ errors as expected regardless of whether the header is included:

error: cannot initialize return object of type 'int *' with an rvalue of type 'bool'

Second: Running with distcc restores proper behavior
I have multiple workstations. If I attempt to build locally on any of them, I encounter the above behavior. If, however, distcc attempts to built it on any remote machine, the error is emitted properly. (This is how I discovered this issue in the first place; our build would with high probability make distcc fallback to local compilation). In fact, even if I have distcc SSH to my own machine, the proper behavior (i.e. an error) is restored:

$ DISTCC_HOSTS='localhost' distcc g++-4.8 -c -std=c++11 noerror.cpp # no error
$ DISTCC_HOSTS='@[my_ip_address]' distcc g++-4.8 -c -std=c++11 noerror.cpp
noerror.cpp: In function ‘int* foo()’:
noerror.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
cc1plus: some warnings being treated as errors

It is not clear to me how distcc manages to restore the proper behavior.

Version information: I'm running Ubuntu 3.5.0-46-generic, GCC 4.8.1, and distcc 3.1.

Summary

Including <atomic> seems to break GCC's conversion-null diagnostic. And somehow, using distcc fixes it. I've searched but been unable to find any reference to a similar bug. Is this pilot error, a known issue, or should I file a GCC bug report?

[Edit: The code snippets were from when I made it a warning instead of an error. Pasted the corrected version]

Was it helpful?

Solution

I've further found that this only occurs when combining compilation and preprocessing in a single step. This accounts for the difference in behavior when using distcc: it preprocesses all the code on the local machine, and compiles it remotely.

Despite @user2485710's comments to the contrary, this is not a case of pilot error or using a poorly documented feature. This is a bona fide bug, and I've reported it as such:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60304

[As of now it's unresolved, but Harald van Dijk noted that GCC suppresses the warning because it (wrongly) thinks it's in a system header. The error/warning can be re-exposed by using -Wsystem-headers.]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top