================
@@ -0,0 +1,182 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O2 -emit-llvm -o - %s | 
FileCheck %s --check-prefix=X86_64
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O2 -emit-llvm -o - %s | 
FileCheck %s --check-prefix=I386
+
+struct a {
+  char x;
+  short count;
+  int array[] __attribute__((counted_by(count)));
+};
+
+// X86_64-LABEL: define dso_local noalias noundef ptr @test1(
+// X86_64-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] 
{
+// X86_64-NEXT:  [[ENTRY:.*:]]
+// X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[SIZE]] to i64
+// X86_64-NEXT:    [[MUL:%.*]] = shl nsw i64 [[CONV]], 2
+// X86_64-NEXT:    [[ADD:%.*]] = add nsw i64 [[MUL]], 4
+// X86_64-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i64 noundef [[ADD]]) 
#[[ATTR3:[0-9]+]]
+// X86_64-NEXT:    [[CONV1:%.*]] = trunc i32 [[SIZE]] to i16
+// X86_64-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i64 2
+// X86_64-NEXT:    store i16 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 2, 
!tbaa [[TBAA2:![0-9]+]]
+// X86_64-NEXT:    ret ptr [[CALL]]
+//
+// I386-LABEL: define dso_local noalias noundef ptr @test1(
+// I386-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// I386-NEXT:  [[ENTRY:.*:]]
+// I386-NEXT:    [[MUL:%.*]] = shl i32 [[SIZE]], 2
+// I386-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 4
+// I386-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i32 noundef [[ADD]]) 
#[[ATTR3:[0-9]+]]
+// I386-NEXT:    [[CONV:%.*]] = trunc i32 [[SIZE]] to i16
+// I386-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i32 2
+// I386-NEXT:    store i16 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 2, 
!tbaa [[TBAA3:![0-9]+]]
+// I386-NEXT:    ret ptr [[CALL]]
+//
+struct a *test1(int size) {
+  struct a *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size);
+
+  *__builtin_counted_by_ref(p->array) = size;
+  *__builtin_counted_by_ref(&p->array[0]) = size;
+  return p;
+}
+
+struct b {
+  int _filler;
+  struct {
+    int __filler;
+    struct {
+      int ___filler;
+      struct {
+        char count;
+      };
+    };
+  };
+  struct {
+    int filler_;
+    struct {
+      int filler__;
+      struct {
+        long array[] __attribute__((counted_by(count)));
+      };
+    };
+  };
+};
+
+// X86_64-LABEL: define dso_local noalias noundef ptr @test2(
+// X86_64-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// X86_64-NEXT:  [[ENTRY:.*:]]
+// X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[SIZE]] to i64
+// X86_64-NEXT:    [[MUL:%.*]] = shl nsw i64 [[CONV]], 2
+// X86_64-NEXT:    [[ADD:%.*]] = add nsw i64 [[MUL]], 4
+// X86_64-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i64 noundef [[ADD]]) 
#[[ATTR3]]
+// X86_64-NEXT:    [[CONV1:%.*]] = trunc i32 [[SIZE]] to i8
+// X86_64-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i64 12
+// X86_64-NEXT:    store i8 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 1, 
!tbaa [[TBAA6:![0-9]+]]
+// X86_64-NEXT:    ret ptr [[CALL]]
+//
+// I386-LABEL: define dso_local noalias noundef ptr @test2(
+// I386-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// I386-NEXT:  [[ENTRY:.*:]]
+// I386-NEXT:    [[MUL:%.*]] = shl i32 [[SIZE]], 2
+// I386-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 4
+// I386-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i32 noundef [[ADD]]) 
#[[ATTR3]]
+// I386-NEXT:    [[CONV:%.*]] = trunc i32 [[SIZE]] to i8
+// I386-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i32 12
+// I386-NEXT:    store i8 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 1, !tbaa 
[[TBAA7:![0-9]+]]
+// I386-NEXT:    ret ptr [[CALL]]
+//
+struct b *test2(int size) {
+  struct b *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size);
+
+  *__builtin_counted_by_ref(p->array) = size;
+  *__builtin_counted_by_ref(&p->array[0]) = size;
+  return p;
+}
+
+struct c {
+  char x;
+  short count;
+  int array[];
+};
+
+// X86_64-LABEL: define dso_local noalias noundef ptr @test3(
+// X86_64-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] 
{
+// X86_64-NEXT:  [[ENTRY:.*:]]
+// X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[SIZE]] to i64
+// X86_64-NEXT:    [[MUL:%.*]] = shl nsw i64 [[CONV]], 2
+// X86_64-NEXT:    [[ADD:%.*]] = add nsw i64 [[MUL]], 4
+// X86_64-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i64 noundef [[ADD]]) 
#[[ATTR3]]
+// X86_64-NEXT:    ret ptr [[CALL]]
+//
+// I386-LABEL: define dso_local noalias noundef ptr @test3(
+// I386-SAME: i32 noundef [[SIZE:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+// I386-NEXT:  [[ENTRY:.*:]]
+// I386-NEXT:    [[MUL:%.*]] = shl i32 [[SIZE]], 2
+// I386-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 4
+// I386-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i32 noundef [[ADD]]) 
#[[ATTR3]]
+// I386-NEXT:    ret ptr [[CALL]]
+//
+struct c *test3(int size) {
+  struct c *p = __builtin_malloc(sizeof(struct c) + sizeof(int) * size);
+  unsigned long int __ignored;
+
+  *_Generic(
+    __builtin_counted_by_ref(&p->array[0]),
+      void *: &__ignored,
+      default: __builtin_counted_by_ref(&p->array[0])) = size;
+
+  return p;
+}
+
+struct d {
+  char x;
+  short count;
+  int array[] __attribute__((counted_by(count)));
+};
+
+// X86_64-LABEL: define dso_local noalias noundef ptr @test4(
+// X86_64-SAME: i32 noundef [[SIZE:%.*]], i32 noundef [[IDX:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// X86_64-NEXT:  [[ENTRY:.*:]]
+// X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[SIZE]] to i64
+// X86_64-NEXT:    [[MUL:%.*]] = shl nsw i64 [[CONV]], 2
+// X86_64-NEXT:    [[ADD:%.*]] = add nsw i64 [[MUL]], 4
+// X86_64-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i64 noundef [[ADD]]) 
#[[ATTR3]]
+// X86_64-NEXT:    [[CONV1:%.*]] = trunc i32 [[SIZE]] to i16
+// X86_64-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i64 2
+// X86_64-NEXT:    store i16 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 2, 
!tbaa [[TBAA2]]
+// X86_64-NEXT:    ret ptr [[CALL]]
+//
+// I386-LABEL: define dso_local noalias noundef ptr @test4(
+// I386-SAME: i32 noundef [[SIZE:%.*]], i32 noundef [[IDX:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// I386-NEXT:  [[ENTRY:.*:]]
+// I386-NEXT:    [[MUL:%.*]] = shl i32 [[SIZE]], 2
+// I386-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], 4
+// I386-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i32 noundef [[ADD]]) 
#[[ATTR3]]
+// I386-NEXT:    [[CONV:%.*]] = trunc i32 [[SIZE]] to i16
+// I386-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr 
[[CALL]], i32 2
+// I386-NEXT:    store i16 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 2, 
!tbaa [[TBAA3]]
+// I386-NEXT:    ret ptr [[CALL]]
+//
+struct d *test4(int size, int idx) {
+  struct d *p = __builtin_malloc(sizeof(struct d) + sizeof(int) * size);
+  unsigned long int __ignored;
+
+  *_Generic(
+    __builtin_counted_by_ref(&p->array[0]),
+      void *: &__ignored,
+      default: __builtin_counted_by_ref(&p->array[idx++])) = size;
----------------
rapidsna wrote:

Yes, upgrading to an error sounds good to me! Also, the message might need to 
be updated (since the side effect is not actually ignored).

https://github.com/llvm/llvm-project/pull/114495
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to