Bug#747123: Clang mistakenly removes an if check
Carlos Martín Nieto
cmn at dwim.me
Mon May 5 19:12:56 UTC 2014
Package: clang-3.4
Hello,
We had an odd problem in our CI servers, where some builds would
mysteriously make a bunch of files read-only. After some wrangling, I
managed to track this down to the create mode being set to 0 when it
shouldn't be.
We have a function which wraps the system's open(2) for portability and
convenience, which needs to check if the flags include O_CREAT which
means that it should grab a third argument, to pass the file create mode
along.
We found that on release mode (which passes -O3 to clang, though it
seems that any optimisation mode triggers this bug), the check for the
'if' is skipped. Looking at the disassembly, it looks like the code for
inside the if-block is there, but the actual check for the flag is
skipped.
There is an issue on [1] with a description of what I found in the
context of trying to debug this in the project, but I have managed to
reduce it to a much simpler example, at the end of this message. If you
compile with `clang -O3 main.c` and run the code, you'll see that it
prints a mode of 0. Compiling without any optimisation options returns
the correct result.
This does not happen with clang-3.5 installed. I've also been unable to
reproduce this with a clang 3.4 built from svn (from the release tag).
[1] https://github.com/libgit2/libgit2/pull/2321#issuecomment-42039673
----8<----8<----
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
int p_open(const char *path, int flags, ...)
{
mode_t mode = 0;
if (flags & O_CREAT) {
va_list arg_list;
va_start(arg_list, flags);
mode = (mode_t)va_arg(arg_list, int);
va_end(arg_list);
}
return mode;
}
int main(int argc, char **argv)
{
int mode;
mode = p_open("foo", O_CREAT, 0666);
printf("mode %4o\n", mode);
return 0;
}
More information about the Pkg-llvm-team
mailing list