Showing posts with label Clang. Show all posts
Showing posts with label Clang. Show all posts

Wednesday, March 21, 2012

PostgreSQL and compiler warnings

Recently, I did some work on backpatching a few commits from PostgreSQL master, and I noticed that with the current tools, the old branches create tons of compiler warnings. In PostgreSQL 8.3, the oldest currently supported branch, a make all with GCC 4.6.3 produces 231 warnings! (Also note that there are only 751 .c files, so that's a warning every three files.) We do a lot of work cleaning up any and all compiler warnings, at least those issued by the latest GCC. These kinds of noisy builds are quite troublesome to work with, because it is more difficult to check whether your changes introduced any new, more serious warnings.

Let's take a look at the current number of compiler warnings in different PostgreSQL branches with different compilers:

gcc 4.4gcc 4.5gcc 4.6gcc 4.7clang
8.317351231207665
8.41217201201673
9.013138989780
9.12424404025
master11111

Obviously, GCC 4.6 introduced many new warnings. If you use the compiler that was current around the time the branch was originally released, you'll be better off. But even then, you should expect a few surprises. (8.3 would probably require gcc 4.3, but I don't have that available anymore.)

Fortunately, it looks as though GCC 4.7, which is currently in release candidate state, will spare us of new warnings. Also note that clang (version 3.0) is now as good as GCC, as far as noise is concerned.

Thursday, September 15, 2011

ccache and clang, part 2

There's more funny business when using ccache in combination with clang. Last time I suggested that you use the invocation
./configure CC='ccache clang -Qunused-arguments -fcolor-diagnostics'
to get rid of the "argument unused during compilation" warnings.

But you still might get loads of warnings that you wouldn't normally get without ccache, such as this example (from the PostgreSQL source code):

extension.c:382:35: warning: equality comparison with extraneous parentheses [-Wparentheses]
 if (( (((control->directory)[0]) == '/') ))
        ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
extension.c:382:35: note: use '=' to turn this equality comparison into an assignment
(This is the opposite of the warning that tells you to put two pairs of parentheses around an assignment used as a truth value.) Or:
path.c:727:7: warning: explicitly assigning a variable of type 'char *' to itself [-Wself-assign]
 path = (path);
 ~~~~ ^  ~~~~
The problem is, these come from macro expansions, so wouldn't normally see them, because (I guess) the compiler driver is smart enough not to warn about such things when they come from macro expansions.

The way ccache works is approximately

  1. preprocess the input file
  2. look for it in the cache
  3. if not found, compile the preprocessed file
What would be better in this situation is
  1. preprocess the input file
  2. look for it in the cache
  3. if not found, compile the original file
And indeed you can turn on that second behavior by setting the obscure environment variable CCACHE_CPP2 (as in, run cpp twice):
export CCACHE_CPP2=yes
Then all these extra warnings disappear.

(The ccache man page is worth a read. There are a few interesting settings to play with.)

I'm currently playing around with a shell script ccache-clang that looks like this:

CCACHE_CPP2=yes exec ccache clang -Qunused-arguments `test -t 2 && echo -fcolor-diagnostics` "$@"

Thursday, May 5, 2011

ccache and clang

Just a note for the Internet: When you use ccache and clang together, you will probably get a lot of warnings like these:
clang: warning: argument unused during compilation: '-c'
clang: warning: argument unused during compilation: '-I .'
These are harmless, but if you want to get rid of them, use the clang option -Qunused-arguments, which will hide them. (The first one is already fixed in ccache.)

The reason for this is that ccache splits the compilation into separate calls to the preprocessor and the compiler proper, and it tries to sort out which of the options that you called it with go with which call. But since gcc doesn't complain about passing -c to the preprocessor or -I to the compiler, ccache doesn't bother about sorting this out (bug). That's why you don't lose any information relative to using gcc if you use the -Qunused-arguments option.

Also, if you like clang's colored diagnostics messages, you'll have to turn them on explicitly with -fcolor-diagnostics, because when running through ccache, clang doesn't think it's printing to a terminal and turns off the color by default.

So a complete invocation might look like this:
./configure CC='ccache clang -Qunused-arguments -fcolor-diagnostics'