1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s 2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type | FileCheck -check-prefix=TYSAN %s 3 // RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t 4 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type -fsanitize-blacklist=%t | FileCheck -check-prefix=BL %s 5 6 // The sanitize_type attribute should be attached to functions 7 // when TypeSanitizer is enabled, unless no_sanitize("type") attribute 8 // is present. 9 10 // WITHOUT: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] 11 // BL: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] 12 // TYSAN: NoTYSAN1{{.*}}) [[NOATTR:#[0-9]+]] 13 __attribute__((no_sanitize("type"))) int NoTYSAN1(int *a) { return *a; } 14 15 // WITHOUT: NoTYSAN2{{.*}}) [[NOATTR]] 16 // BL: NoTYSAN2{{.*}}) [[NOATTR]] 17 // TYSAN: NoTYSAN2{{.*}}) [[NOATTR]] 18 __attribute__((no_sanitize("type"))) int NoTYSAN2(int *a); 19 int NoTYSAN2(int *a) { return *a; } 20 21 // WITHOUT: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] 22 // BL: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] 23 // TYSAN: NoTYSAN3{{.*}}) [[NOATTR:#[0-9]+]] 24 __attribute__((no_sanitize("type"))) int NoTYSAN3(int *a) { return *a; } 25 26 // WITHOUT: TYSANOk{{.*}}) [[NOATTR]] 27 // BL: TYSANOk{{.*}}) [[NOATTR]] 28 // TYSAN: TYSANOk{{.*}}) [[WITH:#[0-9]+]] 29 int TYSANOk(int *a) { return *a; } 30 31 // WITHOUT: TemplateTYSANOk{{.*}}) [[NOATTR]] 32 // BL: TemplateTYSANOk{{.*}}) [[NOATTR]] 33 // TYSAN: TemplateTYSANOk{{.*}}) [[WITH]] 34 template <int i> 35 int TemplateTYSANOk() { return i; } 36 37 // WITHOUT: TemplateNoTYSAN{{.*}}) [[NOATTR]] 38 // BL: TemplateNoTYSAN{{.*}}) [[NOATTR]] 39 // TYSAN: TemplateNoTYSAN{{.*}}) [[NOATTR]] 40 template <int i> 41 __attribute__((no_sanitize("type"))) int TemplateNoTYSAN() { return i; } 42 43 int force_instance = TemplateTYSANOk<42>() + TemplateNoTYSAN<42>(); 44 45 // Check that __cxx_global_var_init* get the sanitize_type attribute. 46 int global1 = 0; 47 int global2 = *(int *)((char *)&global1 + 1); 48 // WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]] 49 // BL: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]] 50 // TYSAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]] 51 52 // Make sure that we don't add globals to the list for which we don't have a 53 // specific type description. 54 // FIXME: We now have a type description for this type and a global is added. Should it? 55 struct SX { 56 int a, b; 57 }; 58 SX sx; 59 60 void consumer(const char *); 61 62 void char_caller() { 63 // TYSAN: void @_Z11char_callerv() 64 // TYSAN-NEXT: entry: 65 // TYSAN-NEXT: call void @_Z8consumerPKc(ptr noundef @.str) 66 // TYSAN-NEXT: ret void 67 68 consumer("foo"); 69 } 70 71 // WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} } 72 73 // BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} } 74 75 // TYSAN: attributes [[NOATTR]] = { mustprogress noinline nounwind{{.*}} } 76 // TYSAN: attributes [[WITH]] = { noinline nounwind sanitize_type{{.*}} } 77 78 // TYSAN-DAG: !llvm.tysan.globals = !{[[G1MD:![0-9]+]], [[G2MD:![0-9]+]], [[G3MD:![0-9]+]], [[SXMD:![0-9]+]]} 79 // TYSAN-DAG: [[G1MD]] = !{ptr @force_instance, [[INTMD:![0-9]+]]} 80 // TYSAN-DAG: [[INTMD]] = !{!"int", 81 // TYSAN-DAG: [[G2MD]] = !{ptr @global1, [[INTMD]]} 82 // TYSAN-DAG: [[G3MD]] = !{ptr @global2, [[INTMD]]} 83 // TYSAN-DAG: [[SXMD]] = !{ptr @sx, [[SXTYMD:![0-9]+]]} 84 // TYSAN-DAG: [[SXTYMD]] = !{!"_ZTS2SX", [[INTMD]], i64 0, !1, i64 4} 85 // TYSAN-DAG: Simple C++ TBAA 86