summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/pointer-signext.c
blob: e809effb2b10086b8327e59937c7ca4e0d2be3d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm -O2 -o - %s | FileCheck %s

// Under Windows 64, int and long are 32-bits.  Make sure pointer math doesn't
// cause any sign extensions.

// CHECK:      [[P:%.*]] = add i64 %param, -8
// CHECK-NEXT: [[Q:%.*]] = inttoptr i64 [[P]] to [[R:%.*\*]]
// CHECK-NEXT: {{%.*}} = getelementptr inbounds [[R]] [[Q]], i64 0, i32 0

#define CR(Record, TYPE, Field) \
  ((TYPE *) ((unsigned char *) (Record) - (unsigned char *) &(((TYPE *) 0)->Field)))

typedef struct _LIST_ENTRY {
  struct _LIST_ENTRY  *ForwardLink;
  struct _LIST_ENTRY  *BackLink;
} LIST_ENTRY;

typedef struct {
  unsigned long long    Signature;
  LIST_ENTRY            Link;
} MEMORY_MAP;

int test(unsigned long long param)
{
  LIST_ENTRY      *Link;
  MEMORY_MAP      *Entry;

  Link = (LIST_ENTRY *) param;

  Entry = CR (Link, MEMORY_MAP, Link);
  return (int) Entry->Signature;
}