| // RUN: %clang -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-NO-STRICT %s |
| // RUN: %clang -fstrict-flex-arrays=0 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-0 %s |
| // RUN: %clang -fstrict-flex-arrays=1 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-1 %s |
| // RUN: %clang -fstrict-flex-arrays=2 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-2 %s |
| // RUN: %clang -fstrict-flex-arrays=3 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-3 %s |
| |
| #define OBJECT_SIZE_BUILTIN __builtin_object_size |
| |
| typedef struct { |
| float f; |
| double c[]; |
| } foo_t; |
| |
| typedef struct { |
| float f; |
| double c[0]; |
| } foo0_t; |
| |
| typedef struct { |
| float f; |
| double c[1]; |
| } foo1_t; |
| |
| typedef struct { |
| float f; |
| double c[2]; |
| } foo2_t; |
| |
| // CHECK-LABEL: @bar( |
| unsigned bar(foo_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 -1 |
| // CHECK-STRICT-3: ret i32 -1 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @bar0( |
| unsigned bar0(foo0_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 -1 |
| // CHECK-STRICT-3: ret i32 0 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @bar1( |
| unsigned bar1(foo1_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 8 |
| // CHECK-STRICT-3: ret i32 8 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @bar2( |
| unsigned bar2(foo2_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 16 |
| // CHECK-STRICT-2: ret i32 16 |
| // CHECK-STRICT-3: ret i32 16 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| #define DYNAMIC_OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size |
| |
| // CHECK-LABEL: @dyn_bar( |
| unsigned dyn_bar(foo_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 -1 |
| // CHECK-STRICT-3: ret i32 -1 |
| return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @dyn_bar0( |
| unsigned dyn_bar0(foo0_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 -1 |
| // CHECK-STRICT-3: ret i32 0 |
| return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @dyn_bar1( |
| unsigned dyn_bar1(foo1_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 -1 |
| // CHECK-STRICT-2: ret i32 8 |
| // CHECK-STRICT-3: ret i32 8 |
| return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @dyn_bar2( |
| unsigned dyn_bar2(foo2_t *f) { |
| // CHECK-NO-STRICT: ret i32 -1 |
| // CHECK-STRICT-0: ret i32 -1 |
| // CHECK-STRICT-1: ret i32 16 |
| // CHECK-STRICT-2: ret i32 16 |
| // CHECK-STRICT-3: ret i32 16 |
| return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // Also checks for non-trailing flex-array like members |
| |
| typedef struct { |
| double c[0]; |
| float f; |
| } foofoo0_t; |
| |
| typedef struct { |
| double c[1]; |
| float f; |
| } foofoo1_t; |
| |
| typedef struct { |
| double c[2]; |
| float f; |
| } foofoo2_t; |
| |
| // CHECK-LABEL: @babar0( |
| unsigned babar0(foofoo0_t *f) { |
| // CHECK-NO-STRICT: ret i32 0 |
| // CHECK-STRICT-0: ret i32 0 |
| // CHECK-STRICT-1: ret i32 0 |
| // CHECK-STRICT-2: ret i32 0 |
| // CHECK-STRICT-3: ret i32 0 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @babar1( |
| unsigned babar1(foofoo1_t *f) { |
| // CHECK-NO-STRICT: ret i32 8 |
| // CHECK-STRICT-0: ret i32 8 |
| // CHECK-STRICT-1: ret i32 8 |
| // CHECK-STRICT-2: ret i32 8 |
| // CHECK-STRICT-3: ret i32 8 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |
| |
| // CHECK-LABEL: @babar2( |
| unsigned babar2(foofoo2_t *f) { |
| // CHECK-NO-STRICT: ret i32 16 |
| // CHECK-STRICT-0: ret i32 16 |
| // CHECK-STRICT-1: ret i32 16 |
| // CHECK-STRICT-2: ret i32 16 |
| // CHECK-STRICT-3: ret i32 16 |
| return OBJECT_SIZE_BUILTIN(f->c, 1); |
| } |