|
| 1 | +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 |
| 2 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s |
| 3 | + |
| 4 | +// See #110385 |
| 5 | +// Based on reproducer from Kees Cook: |
| 6 | +// https://lore.kernel.org/all/202409170436.C3C6E7F7A@keescook/ |
| 7 | + |
| 8 | +struct variable { |
| 9 | + int a; |
| 10 | + int b; |
| 11 | + int length; |
| 12 | + short array[] __attribute__((counted_by(length))); |
| 13 | +}; |
| 14 | + |
| 15 | +struct bucket { |
| 16 | + int a; |
| 17 | + struct variable *growable; |
| 18 | + int b; |
| 19 | +}; |
| 20 | + |
| 21 | +void init(void * __attribute__((pass_dynamic_object_size(0)))); |
| 22 | + |
| 23 | +// CHECK-LABEL: define dso_local void @test1( |
| 24 | +// CHECK-SAME: ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { |
| 25 | +// CHECK-NEXT: entry: |
| 26 | +// CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 |
| 27 | +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] |
| 28 | +// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 |
| 29 | +// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 |
| 30 | +// CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 |
| 31 | +// CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 |
| 32 | +// CHECK-NEXT: [[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 |
| 33 | +// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 |
| 34 | +// CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 |
| 35 | +// CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP4]]) #[[ATTR2:[0-9]+]] |
| 36 | +// CHECK-NEXT: ret void |
| 37 | +// |
| 38 | +void test1(struct bucket *foo) { |
| 39 | + init(foo->growable->array); |
| 40 | +} |
0 commit comments