clang on windows compiles functions with varargs incorrectly. osx is fine. #12290
Labels
bugzilla
Issues migrated from bugzilla
clang:codegen
IR generation bugs: mangling, exceptions, etc.
duplicate
Resolved as duplicate
Extended Description
clang (msvc10 cmake built) on trunk (as well as the 3.0 release) creates an invalid llvm program for the following wikipedia example of stdarg.h. (clang -emit-llvm -c test.c -o test.bc).
#include <stdio.h>
#include <stdarg.h>
/* print all non-negative args one at a time;
all args are assumed to be of int type */
void printargs(int arg1, ...)
{
va_list ap;
int i;
va_start(ap, arg1);
for (i = arg1; i >= 0; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}
int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return 0;
}
according to efriedma on irc, the generated llvm ir should always contain calls to @llvm.va_start. clang on osx creates these just fine. clang on windows however outputs the following program, whose output is incorrect, and contains no calls to @llvm.va_start()
ModuleID = '\temp\test.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
target triple = "i686-pc-win32"
@.str = private unnamed_addr constant [4 x i8] c"%d \00", align 1
define void @printargs(i32 %arg1, ...) nounwind {
%1 = alloca i32, align 4
%ap = alloca i8*, align 4
%i = alloca i32, align 4
store i32 %arg1, i32* %1, align 4
%2 = bitcast i32* %1 to i8*
%3 = getelementptr inbounds i8* %2, i32 4
store i8* %3, i8** %ap, align 4
%4 = load i32* %1, align 4
store i32 %4, i32* %i, align 4
br label %5
; :5 ; preds = %11, %0
%6 = load i32* %i, align 4
%7 = icmp sge i32 %6, 0
br i1 %7, label %8, label %17
; :8 ; preds = %5
%9 = load i32* %i, align 4
%10 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %9)
br label %11
; :11 ; preds = %8
%12 = load i8** %ap, align 4
%13 = getelementptr inbounds i8* %12, i32 4
store i8* %13, i8** %ap, align 4
%14 = getelementptr inbounds i8* %13, i32 -4
%15 = bitcast i8* %14 to i32*
%16 = load i32* %15
store i32 %16, i32* %i, align 4
br label %5
; :17 ; preds = %5
store i8* null, i8** %ap, align 4
%18 = call i32 @putchar(i32 10)
ret void
}
declare i32 @printf(i8*, ...)
declare i32 @putchar(i32)
define i32 @main() nounwind {
%1 = alloca i32, align 4
store i32 0, i32* %1
call void (i32, ...)* @printargs(i32 5, i32 2, i32 14, i32 84, i32 97, i32 15, i32 24, i32 48, i32 -1)
call void (i32, ...)* @printargs(i32 84, i32 51, i32 -1)
call void (i32, ...)* @printargs(i32 -1)
call void (i32, ...)* @printargs(i32 1, i32 -1)
ret i32 0
}
the incorrect output is: (ran with: lli test.bc)
5 22741095 5 2 14 84 97 15 24 48
84 22741123 84 51
1 22741155 1
the correct output is:
5 2 14 84 97 15 24 48
84 51
1
The text was updated successfully, but these errors were encountered: