[PATCH] Add noinline attribute to sanitizer-blacklisted functions

Evgeniy Stepanov eugenis at google.com
Tue Jun 25 03:28:59 PDT 2013


  This new version does not add noinline if the function already has always_inline.

Hi samsonov, kcc,

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

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1034?vs=2552&id=2554#toc

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

Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -414,6 +414,8 @@
 
   llvm::BlackList SanitizerBlacklist;
 
+  bool ModuleInSanitizerBlacklist;
+
   const SanitizerOptions &SanOpts;
 
   /// @}
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -84,8 +84,9 @@
     BlockDescriptorType(0), GenericBlockLiteralType(0),
     LifetimeStartFn(0), LifetimeEndFn(0),
     SanitizerBlacklist(CGO.SanitizerBlacklistFile),
-    SanOpts(SanitizerBlacklist.isIn(M) ?
-            SanitizerOptions::Disabled : LangOpts.Sanitize) {
+    ModuleInSanitizerBlacklist(SanitizerBlacklist.isIn(M)),
+    SanOpts(ModuleInSanitizerBlacklist ? SanitizerOptions::Disabled
+                                       : LangOpts.Sanitize) {
 
   // Initialize the type cache.
   llvm::LLVMContext &LLVMContext = M.getContext();
@@ -644,18 +645,41 @@
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   // Add sanitizer attributes if function is not blacklisted.
-  if (!SanitizerBlacklist.isIn(*F)) {
+  // Add noinline attribute if function is blacklisted and sanitizer is active.
+  // The latter needs to happen even if the entire module is blacklisted, hence
+  // the use of LangOpts.Sanitize.*.
+  if (LangOpts.Sanitize.Address || LangOpts.Sanitize.Thread ||
+      LangOpts.Sanitize.Memory) {
+    bool InSanitizerBlacklist =
+        ModuleInSanitizerBlacklist || SanitizerBlacklist.isIn(*F);
+
     // 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 (LangOpts.Sanitize.Address) {
+      if (!D->hasAttr<NoSanitizeAddressAttr>() && !InSanitizerBlacklist)
+        B.addAttribute(llvm::Attribute::SanitizeAddress);
+      else if (!B.contains(llvm::Attribute::AlwaysInline))
+        B.addAttribute(llvm::Attribute::NoInline);
+    }
+
     // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
-    if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
-      B.addAttribute(llvm::Attribute::SanitizeThread);
+    if (LangOpts.Sanitize.Thread) {
+      if (!D->hasAttr<NoSanitizeThreadAttr>() && !InSanitizerBlacklist)
+        B.addAttribute(llvm::Attribute::SanitizeThread);
+      else if (!B.contains(llvm::Attribute::AlwaysInline))
+        B.addAttribute(llvm::Attribute::NoInline);
     }
+
     // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
-    if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
-      B.addAttribute(llvm::Attribute::SanitizeMemory);
+    if (LangOpts.Sanitize.Memory) {
+      if (!D->hasAttr<NoSanitizeMemoryAttr>() && !InSanitizerBlacklist)
+        B.addAttribute(llvm::Attribute::SanitizeMemory);
+      else if (!B.contains(llvm::Attribute::AlwaysInline))
+        B.addAttribute(llvm::Attribute::NoInline);
+    }
   }
 
   F->addAttributes(llvm::AttributeSet::FunctionIndex,
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: 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-memory-attr.cpp
===================================================================
--- test/CodeGen/sanitize-memory-attr.cpp
+++ test/CodeGen/sanitize-memory-attr.cpp
@@ -0,0 +1,79 @@
+// 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:  NoMSANAA{{.*}}) [[NOATTR_AA:#[0-9]+]]
+// BL:  NoMSANAA{{.*}}) [[NOATTR_AA:#[0-9]+]]
+// MSAN: NoMSANAA{{.*}}) [[NOATTR_AA:#[0-9]+]]
+__attribute__((always_inline))
+__attribute__((no_sanitize_memory))
+int NoMSANAA(int *a) { return *a; }
+
+// WITHOUT:  MSANOkAA{{.*}}) [[NOATTR_AA]]
+// BL:  MSANOkAA{{.*}}) [[NOATTR_AA]]
+// MSAN: MSANOkAA{{.*}}) [[WITH_AA:#[0-9]+]]
+__attribute__((always_inline))
+int MSANOkAA(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_AA]] = { alwaysinline nounwind{{.*}} }
+// WITHOUT: attributes [[NOATTR_NO_TF]] = { nounwind }
+
+// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
+// BL: attributes [[NOATTR_AA]] = { alwaysinline nounwind{{.*}} }
+// BL: attributes [[NOATTR_NO_TF]] = { nounwind{{.*}} }
+
+// MSAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
+// MSAN: attributes [[WITH]] = { nounwind sanitize_memory{{.*}} }
+// MSAN: attributes [[NOATTR_AA]] = { alwaysinline nounwind{{.*}} }
+// MSAN: attributes [[WITH_AA]] = { alwaysinline nounwind sanitize_memory{{.*}} }
+// MSAN: attributes [[WITH_NO_TF]] = { nounwind sanitize_memory }
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1034.2.patch
Type: text/x-patch
Size: 8512 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130625/4df74dfa/attachment.bin>


More information about the cfe-commits mailing list