@@ -1852,3 +1852,57 @@ struct annotated_struct_array {
18521852void test29 (struct annotated_struct_array * ann , int idx1 , int idx2 ) {
18531853 ann -> ann_array [idx1 ]-> array [idx2 ] = __builtin_dynamic_object_size (ann -> ann_array [idx1 ]-> array , 1 );
18541854}
1855+
1856+ typedef struct {
1857+ char __padding [0 ];
1858+ } test30_spinlock_t ;
1859+
1860+ struct test30_struct {
1861+ struct test30_decl * name_node ;
1862+ int priv_len ;
1863+ test30_spinlock_t pcpu_refcnt ;
1864+ char priv [] __counted_by (priv_len );
1865+ };
1866+
1867+ // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30(
1868+ // SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR5]] {
1869+ // SANITIZE-WITH-ATTR-NEXT: entry:
1870+ // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META2]]
1871+ // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR10]], !nosanitize [[META2]]
1872+ // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
1873+ //
1874+ // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30(
1875+ // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] {
1876+ // NO-SANITIZE-WITH-ATTR-NEXT: entry:
1877+ // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 8
1878+ // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4
1879+ // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 4)
1880+ // NO-SANITIZE-WITH-ATTR-NEXT: [[DOTINV:%.*]] = icmp slt i32 [[DOT_COUNTED_BY_LOAD]], 0
1881+ // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8
1882+ // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], 12
1883+ // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[DOTINV]], i8 0, i8 [[TMP2]]
1884+ // NO-SANITIZE-WITH-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12
1885+ // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
1886+ // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]]
1887+ // NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]]
1888+ // NO-SANITIZE-WITH-ATTR-NEXT: ret void
1889+ //
1890+ // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30(
1891+ // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] {
1892+ // SANITIZE-WITHOUT-ATTR-NEXT: entry:
1893+ // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META9]]
1894+ // SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META9]]
1895+ // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]]
1896+ //
1897+ // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30(
1898+ // NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] {
1899+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry:
1900+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[PCPU_REFCNT:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 12
1901+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
1902+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[PCPU_REFCNT]], i64 0, i64 [[IDXPROM]]
1903+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]]
1904+ // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void
1905+ //
1906+ void test30 (struct test30_struct * ptr , int idx ) {
1907+ ptr -> pcpu_refcnt .__padding [idx ] = __builtin_dynamic_object_size (ptr , 1 );
1908+ }
0 commit comments