[LLVMbugs] [Bug 11918] New: clang on windows compiles functions with varargs incorrectly. osx is fine.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Feb 3 14:06:06 PST 2012


http://llvm.org/bugs/show_bug.cgi?id=11918

             Bug #: 11918
           Summary: clang on windows compiles functions with varargs
                    incorrectly.  osx is fine.
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: other
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: lucas.meijer at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


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

; <label>:5 ; preds = %11, %0
  %6 = load i32* %i, align 4
  %7 = icmp sge i32 %6, 0
  br i1 %7, label %8, label %17

; <label>: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

; <label>: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

; <label>: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
---------

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list