Skip to content

Instantly share code, notes, and snippets.

@lucasmeijer
Created February 2, 2012 21:46
Show Gist options
  • Save lucasmeijer/1725972 to your computer and use it in GitHub Desktop.
Save lucasmeijer/1725972 to your computer and use it in GitHub Desktop.
invoking clang3.0 like this:
clang -emit-llvm test.c -o test.bc -c
on the wikipedia example program of stdarg.h (http://en.wikipedia.org/wiki/Stdarg.h)
----------------
#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;
}
---------------
produces this incorrect output: (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 generated program looks like this:
--------------;
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
}
-----------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment