Created
February 2, 2012 21:46
-
-
Save lucasmeijer/1725972 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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