[PATCH] Add noinline attribute to sanitizer-blacklisted functions

Evgeniy Stepanov eugenis at google.com
Tue Jun 25 00:42:05 PDT 2013


Hi samsonov, kcc,

ATM sanitizer attributes are useless at -O2, because they are lost when a function is inlined. This change adds a noinline attribute to functions that are either blacklisted or annotated with the attribute when building with sanitizer.

http://llvm-reviews.chandlerc.com/D1034

Files:
  test/CodeGen/sanitize-memory-attr.cpp
  test/CodeGen/address-safety-attr.cpp
  test/CodeGen/sanitize-thread-attr.cpp
  lib/CodeGen/CodeGenModule.cpp

Index: test/CodeGen/sanitize-memory-attr.cpp
===================================================================
--- test/CodeGen/sanitize-memory-attr.cpp
+++ test/CodeGen/sanitize-memory-attr.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=memory | FileCheck -check-prefix=MSAN %s
+// RUN: echo "src:%s" > %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s -fsanitize=memory -fsanitize-blacklist=%t | FileCheck -check-prefix=BL %s
+
+// REQUIRES: shell
+
+// The sanitize_memory attribute should be attached to functions
+// when MemorySanitizer is enabled, unless no_sanitize_memory attribute
+// is present.
+
+// WITHOUT:  NoMSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// BL:  NoMSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+// MSAN:  NoMSAN1{{.*}}) [[NOATTR:#[0-9]+]]
+__attribute__((no_sanitize_memory))
+int NoMSAN1(int *a) { return *a; }
+
+// WITHOUT:  NoMSAN2{{.*}}) [[NOATTR]]
+// BL:  NoMSAN2{{.*}}) [[NOATTR]]
+// MSAN:  NoMSAN2{{.*}}) [[NOATTR]]
+__attribute__((no_sanitize_memory))
+int NoMSAN2(int *a);
+int NoMSAN2(int *a) { return *a; }
+
+// WITHOUT:  MSANOk{{.*}}) [[NOATTR]]
+// BL:  MSANOk{{.*}}) [[NOATTR]]
+// MSAN: MSANOk{{.*}}) [[WITH:#[0-9]+]]
+int MSANOk(int *a) { return *a; }
+
+// WITHOUT:  TemplateMSANOk{{.*}}) [[NOATTR]]
+// BL:  TemplateMSANOk{{.*}}) [[NOATTR]]
+// MSAN: TemplateMSANOk{{.*}}) [[WITH]]
+template<int i>
+int TemplateMSANOk() { return i; }
+
+// WITHOUT:  TemplateNoMSAN{{.*}}) [[NOATTR]]
+// BL:  TemplateNoMSAN{{.*}}) [[NOATTR]]
+// MSAN: TemplateNoMSAN{{.*}}) [[NOATTR]]
+template<int i>
+__attribute__((no_sanitize_memory))
+int TemplateNoMSAN() { return i; }
+
+int force_instance = TemplateMSANOk<42>()
+                   + TemplateNoMSAN<42>();
+
+// Check that __cxx_global_var_init* get the sanitize_memory attribute.
+int global1 = 0;
+int global2 = *(int*)((char*)&global1+1);
+// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// BL: @__cxx_global_var_init{{.*}}[[NOATTR_NO_TF:#[0-9]+]]
+// MSAN: @__cxx_global_var_init{{.*}}[[WITH_NO_TF:#[0-9]+]]
+
+// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
+
+// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
+// BL: attributes [[NOATTR_NO_TF]] = { nounwind{{.*}} }
+
+// MSAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
+// MSAN: attributes [[WITH]] = { nounwind sanitize_memory{{.*}} }
+// MSAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_memory }
Index: test/CodeGen/address-safety-attr.cpp
===================================================================
--- test/CodeGen/address-safety-attr.cpp
+++ test/CodeGen/address-safety-attr.cpp
@@ -68,13 +68,13 @@
 // WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
 // WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
 
-// BLFILE: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFILE: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 // BLFILE: attributes [[NOATTR_NO_TF]] = { nounwind }
 
-// BLFUNC: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BLFUNC: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 // BLFUNC: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
 // BLFUNC: attributes [[WITH_NO_TF]] = { nounwind sanitize_address }
 
-// ASAN: attributes [[NOATTR]] = { nounwind{{.*}} }
+// ASAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 // ASAN: attributes [[WITH]] = { nounwind sanitize_address{{.*}} }
 // ASAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_address }
Index: test/CodeGen/sanitize-thread-attr.cpp
===================================================================
--- test/CodeGen/sanitize-thread-attr.cpp
+++ test/CodeGen/sanitize-thread-attr.cpp
@@ -53,9 +53,9 @@
 // WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} }
 // WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
 
-// BL: attributes [[NOATTR]] = { nounwind{{.*}} }
+// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 // BL: attributes [[NOATTR_NO_TF]] = { nounwind{{.*}} }
 
-// TSAN: attributes [[NOATTR]] = { nounwind{{.*}} }
+// TSAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
 // TSAN: attributes [[WITH]] = { nounwind sanitize_thread{{.*}} }
 // TSAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_thread }
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -644,18 +644,28 @@
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   // Add sanitizer attributes if function is not blacklisted.
-  if (!SanitizerBlacklist.isIn(*F)) {
+  if (SanitizerBlacklist.isIn(*F)) {
+      B.addAttribute(llvm::Attribute::NoInline);
+  } else {
     // When AddressSanitizer is enabled, set SanitizeAddress attribute
     // unless __attribute__((no_sanitize_address)) is used.
-    if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>())
-      B.addAttribute(llvm::Attribute::SanitizeAddress);
+    // If __attribute__((no_sanitize_address)) is used, set NoInline instead
+    // to avoid false positives in case a blacklisted function is inlined into a
+    // non-blacklisted one.
+    if (SanOpts.Address)
+      B.addAttribute(D->hasAttr<NoSanitizeAddressAttr>()
+                         ? llvm::Attribute::NoInline
+                         : llvm::Attribute::SanitizeAddress);
     // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
-    if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
-      B.addAttribute(llvm::Attribute::SanitizeThread);
-    }
+    if (SanOpts.Thread)
+      B.addAttribute(D->hasAttr<NoSanitizeThreadAttr>()
+                         ? llvm::Attribute::NoInline
+                         : llvm::Attribute::SanitizeThread);
     // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
-    if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
-      B.addAttribute(llvm::Attribute::SanitizeMemory);
+    if (SanOpts.Memory)
+      B.addAttribute(D->hasAttr<NoSanitizeMemoryAttr>()
+                         ? llvm::Attribute::NoInline
+                         : llvm::Attribute::SanitizeMemory);
   }
 
   F->addAttributes(llvm::AttributeSet::FunctionIndex,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1034.1.patch
Type: text/x-patch
Size: 6326 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130625/a0cc416c/attachment.bin>


More information about the cfe-commits mailing list