Open 9bd1cfd0-e1a1-415b-82a2-89ef9b1b5fcb opened 5 years ago
I've created a smaller reproduction:
first_file.cpp
extern void my_extern_fn();
void first_fn() {
my_extern_fn();
}
second_file.cpp
void second_fn(int my_arg, ...) {
__builtin_va_list args;
__builtin_va_start(args, my_arg);
__builtin_va_arg(args, int);
__builtin_va_end(args);
}
Running clang-tidy-12 first_file.cpp second_file.cpp
results in the following output:
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "first_file.cpp"
No compilation database found in /home/aaron/repos/tidy-bug or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 warning generated.
/home/aaron/repos/tidy-bug/second_file.cpp:5:5: warning: va_arg() is called on an uninitialized va_list [clang-analyzer-valist.Uninitialized]
__builtin_va_arg(args, int);
^
/home/aaron/repos/tidy-bug/second_file.cpp:5:5: note: va_arg() is called on an uninitialized va_list
Running clang-tidy first_file.cpp
or clang-tidy second_file.cpp
does not produce any warnings.
I'm happy to help debug if you're still having trouble reproducing this.
tmp.i Here is the pre-processed C file. The original was
#include<stdarg.h>
#include<stdio.h>
int g(char *format, ...) {
int len;
va_list args;
va_start(args, format);
len = va_arg(args, int);
va_end(args);
return len;
}
I can reproduce locally with cp tmp.c main.c && clang-tidy tmp.c main.c
.
I still can't reproduce with multiple files.
Please send us a preprocessed file because different implementations of standard headers on different systems may affect analysis results.
As a work-around, you can run clang-tidy on only one file at a time:
$ parallel clang-tidy -- main.c tmp.c # parallel from `moreutils`, not GNU parallel
That avoids the false positive. (Yes, I'm still running into this a year later.)
Not sure what the compile_commands file is, but I have the same problem if I run clang-tidy with more than one source file:
$ cat tmp.c
#include<stdarg.h>
#include<stdio.h>
int f(char *format, ...) {
int len;
va_list args;
va_start(args, format);
len = vsnprintf((void*)0, 0, format, args);
va_end(args);
return len;
}
$ clang-tidy main.c tmp.c
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "main.c"
No compilation database found in /home/joshua/src/c/threaded/src or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 warning generated.
/home/joshua/src/c/threaded/src/tmp.c:7:11: error: Function 'vsnprintf' is called with an uninitialized va_list argument [clang-analyzer-valist.Uninitialized,-warnings-as-errors]
len = vsnprintf((void*)0, 0, format, args);
^
/home/joshua/src/c/threaded/src/tmp.c:7:11: note: Function 'vsnprintf' is called with an uninitialized va_list argument
I have a similar issue. The warning only arises when there are multiple copies of the source file in the "compile_commands.json" file.
$ cat main.c
#include <stdio.h>
#include <stdarg.h>
void my_fun(int a, const char* fmt, ...) {
char buf[100];
va_list args;
va_start(args, fmt);
vsnprintf(buf, 100, fmt, args);
va_end(args);
printf("%s", buf);
}
int main(void) {
my_fun(42, "%d\n", 1);
return 0;
}
$ cat compile_commands.json
[
{ "directory": "/home/niklas/projects/c-examples/vprintf",
"command": "gcc -o main main.c",
"file": "/home/niklas/projects/c-examples/vprintf/main.c"},
{ "directory": "/home/niklas/projects/c-examples/vprintf",
"command": "gcc -o main main.c",
"file": "/home/niklas/projects/c-examples/vprintf/main.c"}
]
$ clang-tidy-8 main.c
1 warning generated.
main.c:8:5: warning: Function 'vsnprintf' is called with an uninitialized va_list argument [clang-analyzer-valist.Uninitialized]
vsnprintf(buf, 100, fmt, args);
^
main.c:8:5: note: Function 'vsnprintf' is called with an uninitialized va_list argument
I hope you can reproduce the issue!
I also cannot reproduce, but this is because in my case builtins aren't recognized at all. I guess we need to make a more consistent solution for recognizing all the builtins.
Hi!
I unfortunately could not reproduce this problem. What architecture are you using? What standard libraries? Could you also attach a preprocessed file?
As far as I remember, for different target architectures the va_lists have different representation. My suspicion is that, probably not all of the possible representations are handled by the checker currently.
Thanks, Gabor
Gabor, do you know what is this about? :)
assigned to @Xazax-hun
I can reproduce this with clang-tidy 14 (installed today from deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main
on Ubuntu 20.04)
The file a.c
:
#include <stdio.h>
void a(void)
{
printf("");
}
The file b.c
:
#include <stdio.h>
void b(const char *c, ...)
{
va_list va;
va_start(va, c);
vprintf(c, va);
va_end(va);
}
The command:
clang-tidy-14 a.c b.c
Produces output:
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "a.c"
No compilation database found in /home/pbliss or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
1 warning generated.
/home/pbliss/b.c:8:5: warning: Function 'vprintf' is called with an uninitialized va_list argument [clang-analyzer-valist.Uninitialized]
vprintf(c, va);
^~~~~~~~~~~~~~
/home/pbliss/b.c:8:5: note: Function 'vprintf' is called with an uninitialized va_list argument
vprintf(c, va);
^~~~~~~~~~~~~~
Extended Description
When running the clang-analyzer checks under clang-tidy, the clang-analyzer-valist.Uninitialized warning is firing on a valist copied using va_copy().
Command: clang-tidy --checks="-,clang-analyzer-" example.cpp
Minimal example.cpp:
include
include
void StringVPrintf(const char* format, va_list ap) { char stack_buf[1024u]; va_list ap_copy; va_copy(ap_copy, ap); vsnprintf(stack_buf, 1024u, format, ap_copy); va_end(ap_copy); }
Clang-tidy warning:
example.cpp:8:5: warning: Function 'vsnprintf' is called with an uninitialized va_list argument [clang-analyzer-valist.Uninitialized] vsnprintf(stack_buf, 1024u, format, ap_copy); ^ example.cpp:8:5: note: Function 'vsnprintf' is called with an uninitialized va_list argument