aaron.ballman added a reviewer: majnemer. aaron.ballman added a comment. > I *think* the problem is that we gin up the function type for a > non-prototyped function based on the function call expression argument types, > and the literal `0` is getting the type `signed long long`.
I think this is because of `CodeGenFunction::getVarArgType()` and is specific to the Windows ABI. // System headers on Windows define NULL to 0 instead of 0LL on Win64. MSVC // implicitly widens null pointer constants that are arguments to varargs // functions to pointer-sized ints. This causes the 0 to be emit as a 64-bit value rather than a 32-bit value. Indeed, if you change your original example to pass `1` rather than `0` when calling `p`, you no longer get the UB: ; Function Attrs: noinline nounwind define void @f() #0 { entry: %0 = load void (...)*, void (...)** @p, align 8 %callee.knr.cast = bitcast void (...)* %0 to void (i32)* call void %callee.knr.cast(i32 1) ret void } However, when I test with MSVC 2015, I do not get the behavior that Clang produces. My test was: void h(int i, ...) {} void i(int i, int j, int k, int l, int m) {} void(*p)() = i; void f() { p(0, 1, 2, 3, 0); h(0, 1, 2, 3, 0); i(0, 1, 2, 3, 0); } MSVC outputs: ; 8 : p(0, 1, 2, 3, 0); mov DWORD PTR [rsp+32], 0 mov r9d, 3 mov r8d, 2 mov edx, 1 xor ecx, ecx call QWORD PTR p ; 9 : h(0, 1, 2, 3, 0); mov QWORD PTR [rsp+32], 0 mov r9d, 3 mov r8d, 2 mov edx, 1 xor ecx, ecx call h ; 10 : i(0, 1, 2, 3, 0); mov DWORD PTR [rsp+32], 0 mov r9d, 3 mov r8d, 2 mov edx, 1 xor ecx, ecx call i Clang outputs: %callee.knr.cast = bitcast void (...)* %0 to void (i64, i32, i32, i32, i64)* call void %callee.knr.cast(i64 0, i32 1, i32 2, i32 3, i64 0) call void (i32, ...) @h(i32 0, i32 1, i32 2, i32 3, i64 0) call void @i(i32 0, i32 1, i32 2, i32 3, i32 0) Note that the K&R call casts to i64 in Clang but uses a DWORD PTR in MSVC. Only the variadic call to `h()` uses the QWORD PTR. So I think the correct behavior is to only enable the vararg behavior when the function is variadic with an ellipsis rather than variadic due to a lack of prototype. Thoughts? https://reviews.llvm.org/D28166 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits