[LLVMbugs] [Bug 8398] New: Struct padding is not accounted for when passing structs to VA functions.

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Oct 17 12:01:30 PDT 2010


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

           Summary: Struct padding is not accounted for when passing
                    structs to VA functions.
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: bigcheesegs at gmail.com
                CC: llvmbugs at cs.uiuc.edu


While debugging test-suite/SingleSource/UnitTests/2003-08-11-VaListArg.c I
reduced it to incorrect passing of structs with padding.

The VA code has GEPs with offsets that include padding, however, no padding is
passed to the function.

To reproduce (on Windows):
% clang -O3 va.c -o va.exe
% va.exe
QuadWord { 19, 0.000000 }

Expected Output:
QuadWord { 19, 20.000000 }

Changing the following in va.ll fixes the problem:
-  tail call void (...)* @testVaArg(i32 19, double 2.000000e+001)
+  tail call void (...)* @testVaArg(i32 19, i32 0, double 2.000000e+001)

=============================================================================
file: va.c
=============================================================================
#include <stdio.h>
#include <stdarg.h>

/* 12 bytes if d is 4-byte aligned; 16 bytes if d is 8-byte aligned. */
typedef struct QuadWordS_struct { int i; double d; } QuadWordS;

static void testVaArg(char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  QuadWordS qw;
  qw = va_arg(ap, QuadWordS);
  printf("QuadWord { %d, %f }\n", qw.i, qw.d);
  va_end(ap);
}

int main() {
  QuadWordS qw = { 19, 20.0 };

  /* test passing structs by value to varargs */
  testVaArg("Q", qw);

  return sizeof(qw);
}
=============================================================================

=============================================================================
file: va.ll
=============================================================================
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"
target triple = "i686-pc-win32"

%struct.QuadWordS_struct = type { i32, double }

@.str1 = private constant [21 x i8] c"QuadWord { %d, %f }\0A\00"

define i32 @main() nounwind {
entry:
  tail call void (...)* @testVaArg(i32 19, double 2.000000e+001)
  ret i32 16
}

define internal void @testVaArg(...) nounwind {
entry:
  %ap = alloca i8*, align 4
  %ap1 = bitcast i8** %ap to i8*
  call void @llvm.va_start(i8* %ap1)
  %ap.cur = load i8** %ap, align 4
  %ap.next = getelementptr i8* %ap.cur, i32 16
  store i8* %ap.next, i8** %ap, align 4
  %ap.cur8.0 = bitcast i8* %ap.cur to i32*
  %tmp9 = load i32* %ap.cur8.0, align 8
  %ap.cur8.1 = getelementptr inbounds i8* %ap.cur, i32 8
  %0 = bitcast i8* %ap.cur8.1 to double*
  %tmp10 = load double* %0, align 8
  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([21 x i8]*
@.str1, i32 0, i32 0), i32 %tmp9, double %tmp10) nounwind
  call void @llvm.va_end(i8* %ap1)
  ret void
}

declare void @llvm.va_start(i8*) nounwind

declare i32 @printf(i8* nocapture, ...) nounwind

declare void @llvm.va_end(i8*) nounwind
=============================================================================

-- 
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