168 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-gnu-linux -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INTEL2// RUN: %clang_cc1 -triple aarch64-gnu-linux -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH3// RUN: %clang_cc1 -triple x86_64-gnu-linux -x c++ -emit-llvm -fsanitize-memory-param-retval %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INTEL4// RUN: %clang_cc1 -triple aarch64-gnu-linux -x c++ -emit-llvm -fsanitize-memory-param-retval %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH5 6// no-sanitize-memory-param-retval does NOT conflict with enable-noundef-analysis7// RUN: %clang_cc1 -triple x86_64-gnu-linux -x c++ -emit-llvm -fno-sanitize-memory-param-retval %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-INTEL8 9//************ Passing structs by value10// TODO: No structs may currently be marked noundef11 12namespace check_structs {13struct Trivial {14 int a;15};16Trivial ret_trivial() { return {}; }17void pass_trivial(Trivial e) {}18// CHECK-INTEL: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial19// CHECK-AARCH: [[DEF:define( dso_local)?]] i32 @{{.*}}ret_trivial20// CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 %21// CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 %22 23struct NoCopy {24 int a;25 NoCopy(NoCopy &) = delete;26};27NoCopy ret_nocopy() { return {}; }28void pass_nocopy(NoCopy e) {}29// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %30// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr dead_on_return noundef %31 32struct Huge {33 int a[1024];34};35Huge ret_huge() { return {}; }36void pass_huge(Huge h) {}37// CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %38// CHECK-INTEL: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef39// CHECK-AARCH: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr dead_on_return noundef40} // namespace check_structs41 42//************ Passing unions by value43// No unions may be marked noundef44 45namespace check_unions {46union Trivial {47 int a;48};49Trivial ret_trivial() { return {}; }50void pass_trivial(Trivial e) {}51// CHECK-INTEL: [[DEF]] i32 @{{.*}}ret_trivial52// CHECK-AARCH: [[DEF]] i32 @{{.*}}ret_trivial53// CHECK-INTEL: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i32 %54// CHECK-AARCH: [[DEF]] void @{{.*}}pass_trivial{{.*}}(i64 %55 56union NoCopy {57 int a;58 NoCopy(NoCopy &) = delete;59};60NoCopy ret_nocopy() { return {}; }61void pass_nocopy(NoCopy e) {}62// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 %63// CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr dead_on_return noundef %64} // namespace check_unions65 66//************ Passing `this` pointers67// `this` pointer must always be defined68 69namespace check_this {70struct Object {71 int data[];72 73 Object() {74 this->data[0] = 0;75 }76 int getData() {77 return this->data[0];78 }79 Object *getThis() {80 return this;81 }82};83 84void use_object() {85 Object obj;86 obj.getData();87 obj.getThis();88}89// CHECK: define linkonce_odr void @{{.*}}Object{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) %90// CHECK: define linkonce_odr noundef i32 @{{.*}}Object{{.*}}getData{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) %91// CHECK: define linkonce_odr noundef ptr @{{.*}}Object{{.*}}getThis{{.*}}(ptr noundef nonnull align 4 dereferenceable(1) %92} // namespace check_this93 94//************ Passing vector types95 96namespace check_vecs {97typedef int __attribute__((vector_size(12))) i32x3;98i32x3 ret_vec() {99 return {};100}101void pass_vec(i32x3 v) {102}103 104// CHECK: [[DEF]] noundef <3 x i32> @{{.*}}ret_vec{{.*}}()105// CHECK-INTEL: [[DEF]] void @{{.*}}pass_vec{{.*}}(<3 x i32> noundef %106// CHECK-AARCH: [[DEF]] void @{{.*}}pass_vec{{.*}}(<4 x i32> %107} // namespace check_vecs108 109//************ Passing exotic types110// Function/Array pointers, Function member / Data member pointers, nullptr_t, ExtInt types111 112namespace check_exotic {113struct Object {114 int mfunc();115 int mdata;116};117typedef int Object::*mdptr;118typedef int (Object::*mfptr)();119typedef decltype(nullptr) nullptr_t;120typedef int (*arrptr)[32];121typedef int (*fnptr)(int);122 123arrptr ret_arrptr() {124 return nullptr;125}126fnptr ret_fnptr() {127 return nullptr;128}129mdptr ret_mdptr() {130 return nullptr;131}132mfptr ret_mfptr() {133 return nullptr;134}135nullptr_t ret_npt() {136 return nullptr;137}138void pass_npt(nullptr_t t) {139}140_BitInt(3) ret_BitInt() {141 return 0;142}143void pass_BitInt(_BitInt(3) e) {144}145void pass_large_BitInt(_BitInt(127) e) {146}147 148// Pointers to arrays/functions are always noundef149// CHECK: [[DEF]] noundef ptr @{{.*}}ret_arrptr{{.*}}()150// CHECK: [[DEF]] noundef ptr @{{.*}}ret_fnptr{{.*}}()151 152// Pointers to members are never noundef153// CHECK: [[DEF]] i64 @{{.*}}ret_mdptr{{.*}}()154// CHECK-INTEL: [[DEF]] { i64, i64 } @{{.*}}ret_mfptr{{.*}}()155// CHECK-AARCH: [[DEF]] [2 x i64] @{{.*}}ret_mfptr{{.*}}()156 157// nullptr_t is never noundef158// CHECK: [[DEF]] ptr @{{.*}}ret_npt{{.*}}()159// CHECK: [[DEF]] void @{{.*}}pass_npt{{.*}}(ptr %160 161// CHECK-INTEL: [[DEF]] noundef signext i3 @{{.*}}ret_BitInt{{.*}}()162// CHECK-AARCH: [[DEF]] noundef i3 @{{.*}}ret_BitInt{{.*}}()163// CHECK-INTEL: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef signext %164// CHECK-AARCH: [[DEF]] void @{{.*}}pass_BitInt{{.*}}(i3 noundef %165// CHECK-INTEL: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i64 noundef %{{.*}}, i64 noundef %166// CHECK-AARCH: [[DEF]] void @{{.*}}pass_large_BitInt{{.*}}(i127 noundef %167} // namespace check_exotic168