The x86_64 and aarch64 vararg helpers in memorysanitizer pass currently assume no non-vararg argument ends up in the overflow area - if that's not true, the data stored to __msan_va_arg_tls will be misaligned with the overflow pointer computed by va_start. Here's a testcase for x86_64: #include <stdio.h> #include <stdarg.h> int passarg(int a, int b, int c, int d, int e, int f, int g, ...) { va_list v; va_start(v, g); int res = va_arg(v, int); va_end(v); return res; } int main() { int undef; int res = passarg(undef, undef, undef, undef, undef, undef, undef, 2); if (res) printf("%d\n", res); return 0; } Compiling with -fsanitize=memory and running results in: ==22438==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x4889ef in main (/home/mwk/llvm/llvm/a.out+0x4889ef) #1 0x7f78129fe70f in __libc_start_main (/usr/lib/libc.so.6+0x2070f) #2 0x418e38 in _start (/home/mwk/llvm/llvm/a.out+0x418e38) This is because va_arg effectively reads the shadow belonging to argument g. aarch64 should be suspectible to the same issue, but I haven't checked it. mips64 is even worse, since it assumes there's exactly one non-vararg argument.
aarch64 has the same issue, but you have to add one more non-vararg parameter (it passes 7 ints in registers, as opposed to x86_64's 6).
Scratch that, you have to add *two* more non-vararg parameters to trigger the bug for AArch64 - if you pass 8 non-varargs, the first one is ignored, due to code copied from mips64 helper (two wrongs make a right, apparently).
Fixed in 268673, 268783, 268967.