False clang warning w/o line number

Hello,

I gave clang a try on a large source tree that is built using gcc.
Warnings are treated as errors, so the compilation stopped early, with
plenty of the same message:

warning: format string is not a string literal (potentially insecure)
[-Wformat-security]

And no file/line info! I reduced the problem to the following test case:

----8<----8<----8<----8<----8<----8<----
#define ASSERT(expr, args...) if (expr) { } else {
my_assert(__FILE__, __LINE__, #expr, ## args); }

void my_assert(const char* file, int line, const char* expr = nullptr,
const char* fmt = nullptr, ...) __attribute__((format (printf, 4,
5)));

class Foo
{
        void Bar(int i)
        {
                ASSERT(i != 0);
        }
        void Baz(int i)
        {
                ASSERT(i == 0, "i is %d", i);
        }
};
----8<----8<----8<----8<----8<----8<----

When reducing the test case, I peppered the code with #error's to see
where the warning comes from. It is not printed when processing Bar(),
but when the closing }; of the class is seen. If I comment out the
first assert, where there is only the expression, but not the optional
format string, it compiles fine. I suspect the null format string
causes the warning. I think the format string being null should be
legal if there are no arguments for it, or print specifically that it
is null. But most importantly, print the exact file/line where the
problem is. It was really time consuming to find the cause of the
warning.

Writing an overloaded my_assert() without the fmt and ... args would
work, but this is not the only case in the code base where this
warning fires, and I don't really have the time to narrow down each
case with #error's. I don't want to turn off this warning either,
since it is quite useful otherwise.

In the bottom there is the detailed output of the compiler, I hope it
helps. Please CC me any replies, I'm not subscribed.

Kind regards, Peter

$ clang++ --std=c++0x -v -c clang-fmt-bug.cpp
Debian clang version 3.0-6 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
"/usr/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj
-mrelax-all -disable-free -disable-llvm-verifier -main-file-name
clang-fmt-bug.cpp -mrelocation-model static -mdisable-fp-elim
-masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64
-target-linker-version 2.22 -momit-leaf-frame-pointer -v
-coverage-file clang-fmt-bug.o -resource-dir /usr/bin/../lib/clang/3.0
-fmodule-cache-path /tmp/clang-module-cache -internal-isystem
/usr/include/c++/4.6 -internal-isystem
/usr/include/c++/4.6/x86_64-linux-gnu -internal-isystem
/usr/include/c++/4.6/backward -internal-isystem /usr/local/include
-internal-isystem /usr/bin/../lib/clang/3.0/include
-internal-externc-isystem /usr/include/x86_64-linux-gnu
-internal-externc-isystem /usr/include -std=c++0x -fdeprecated-macro
-ferror-limit 19 -fmessage-length 271 -fgnu-runtime
-fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi
-fcxx-exceptions -fexceptions -fdiagnostics-show-option
-fcolor-diagnostics -o clang-fmt-bug.o -x c++ clang-fmt-bug.cpp
clang -cc1 version 3.0 based upon llvm 3.0 hosted on x86_64-pc-linux-gnu
ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
ignoring nonexistent directory "/usr/include/c++/4.6//x86_64-linux-gnu/64"
ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
ignoring duplicate directory "/usr/include/c++/4.6"
ignoring duplicate directory "/usr/include/c++/4.6/backward"
ignoring duplicate directory "/usr/include/c++/4.6"
ignoring duplicate directory "/usr/include/c++/4.6/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include/c++/4.6/backward"
ignoring duplicate directory "/usr/include/c++/4.6"
ignoring duplicate directory "/usr/include/c++/4.6/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include/c++/4.6/backward"
ignoring duplicate directory "/usr/local/include"
ignoring duplicate directory "/usr/include/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/4.6
/usr/include/c++/4.6/x86_64-linux-gnu
/usr/include/c++/4.6/backward
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
/usr/include/clang/3.0/include/
/usr/lib/gcc/x86_64-linux-gnu/4.6/include/
/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed/
End of search list.
warning: format string is not a string literal (potentially insecure)
[-Wformat-security]
1 warning generated.

I can't reproduce this with ToT clang. It's likely been fixed in the
impending 3.1 release.

-Matt

I checked it with the current svn version (clang version 3.2 (trunk
157048)) and the issue is indeed fixed.

Thanks, Peter