// 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); }