diff options
author | Kostya Serebryany <kcc@google.com> | 2012-01-24 19:25:38 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-01-24 19:25:38 +0000 |
commit | 588d6abf7d38fd7e7d189dbff79f16e995c2c79d (patch) | |
tree | 1dfed8ab3f27af5a5dee6a703f56ccd8d9122a88 | |
parent | 64cee06504b9f8fd6821f16a84512b372cb29414 (diff) | |
download | bcm5719-llvm-588d6abf7d38fd7e7d189dbff79f16e995c2c79d.tar.gz bcm5719-llvm-588d6abf7d38fd7e7d189dbff79f16e995c2c79d.zip |
The following patch adds __attribute__((no_address_safety_analysis)) which will allow to disable
address safety analysis (such as e.g. AddressSanitizer or SAFECode) for a specific function.
When building with AddressSanitizer, add AddressSafety function attribute to every generated function
except for those that have __attribute__((no_address_safety_analysis)).
With this patch we will be able to
1. disable AddressSanitizer for a particular function
2. disable AddressSanitizer-hostile optimizations (such as some cases of load widening) when AddressSanitizer is on.
llvm-svn: 148842
-rw-r--r-- | clang/docs/LanguageExtensions.html | 4 | ||||
-rw-r--r-- | clang/include/clang/Basic/Attr.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Sema/AttributeList.h | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/AttributeList.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 20 | ||||
-rw-r--r-- | clang/test/CodeGen/address-safety-attr.cpp | 35 |
7 files changed, 73 insertions, 0 deletions
diff --git a/clang/docs/LanguageExtensions.html b/clang/docs/LanguageExtensions.html index 7b832bab927..7693d241540 100644 --- a/clang/docs/LanguageExtensions.html +++ b/clang/docs/LanguageExtensions.html @@ -1453,6 +1453,10 @@ balance in some way.</p> to check if the code is being built with <a href="AddressSanitizer.html">AddressSanitizer</a>. </p> +<p>Use <tt>__attribute__((no_address_safety_analysis))</tt> on a function +declaration to specify that address safety instrumentation (e.g. +AddressSanitizer) should not be applied to that function. +</p> <!-- ======================================================================= --> <h2 id="threadsafety">Thread-Safety Annotation Checking</h2> diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 292c9a396f5..a7680bbb52f 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -576,6 +576,10 @@ def X86ForceAlignArgPointer : InheritableAttr { let Spellings = []; } +// AddressSafety attribute (e.g. for AddressSanitizer) +def NoAddressSafetyAnalysis : InheritableAttr { + let Spellings = ["no_address_safety_analysis"]; +} // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h index a54c1828aef..545350f9ef9 100644 --- a/clang/include/clang/Sema/AttributeList.h +++ b/clang/include/clang/Sema/AttributeList.h @@ -218,6 +218,7 @@ public: AT_naked, AT_neon_polyvector_type, // Clang-specific. AT_neon_vector_type, // Clang-specific. + AT_no_address_safety_analysis, AT_no_instrument_function, AT_no_thread_safety_analysis, AT_nocommon, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c54b904abcb..67059016f7d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1019,6 +1019,14 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName, if (ExtraAttrs != llvm::Attribute::None) F->addFnAttr(ExtraAttrs); + if (Features.AddressSanitizer) { + // When AddressSanitizer is enabled, set AddressSafety attribute + // unless __attribute__((no_address_safety_analysis)) is used. + const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl()); + if (!FD || !FD->hasAttr<NoAddressSafetyAnalysisAttr>()) + F->addFnAttr(llvm::Attribute::AddressSafety); + } + // This is the first use or definition of a mangled name. If there is a // deferred decl with this name, remember that we need to emit it at the end // of the file. diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index c184676b9e5..a3791dedf73 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/lib/Sema/AttributeList.cpp @@ -218,6 +218,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { .Case("pt_guarded_var", AT_pt_guarded_var) .Case("scoped_lockable", AT_scoped_lockable) .Case("lockable", AT_lockable) + .Case("no_address_safety_analysis", AT_no_address_safety_analysis) .Case("no_thread_safety_analysis", AT_no_thread_safety_analysis) .Case("guarded_by", AT_guarded_by) .Case("pt_guarded_by", AT_pt_guarded_by) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index e06d637eeb7..b15ad0ddd15 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -444,6 +444,23 @@ static void handleNoThreadSafetyAttr(Sema &S, Decl *D, S.Context)); } +static void handleNoAddressSafetyAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + assert(!Attr.isInvalid()); + + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << Attr.getName() << ExpectedFunctionOrMethod; + return; + } + + D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), + S.Context)); +} + static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, bool before) { assert(!Attr.isInvalid()); @@ -3678,6 +3695,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_scoped_lockable: handleLockableAttr(S, D, Attr, /*scoped = */true); break; + case AttributeList::AT_no_address_safety_analysis: + handleNoAddressSafetyAttr(S, D, Attr); + break; case AttributeList::AT_no_thread_safety_analysis: handleNoThreadSafetyAttr(S, D, Attr); break; diff --git a/clang/test/CodeGen/address-safety-attr.cpp b/clang/test/CodeGen/address-safety-attr.cpp new file mode 100644 index 00000000000..9d0fb959633 --- /dev/null +++ b/clang/test/CodeGen/address-safety-attr.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - %s -faddress-sanitizer | FileCheck -check-prefix ASAN %s + +// The address_safety attribute should be attached to functions +// when AddressSanitizer is enabled, unless no_address_safety_analysis attribute +// is present. + +// CHECK-NOT: NoAddressSafety1{{.*}} address_safety +// ASAN-NOT: NoAddressSafety1{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety1(int *a) { return *a; } + +// CHECK-NOT: NoAddressSafety2{{.*}} address_safety +// ASAN-NOT: NoAddressSafety2{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety2(int *a); +int NoAddressSafety2(int *a) { return *a; } + +// CHECK-NOT: AddressSafetyOk{{.*}} address_safety +// ASAN: AddressSafetyOk{{.*}} address_safety +int AddressSafetyOk(int *a) { return *a; } + +// CHECK-NOT: TemplateNoAddressSafety{{.*}} address_safety +// ASAN-NOT: TemplateNoAddressSafety{{.*}} address_safety +template<int i> +__attribute__((no_address_safety_analysis)) +int TemplateNoAddressSafety() { return i; } + +// CHECK-NOT: TemplateAddressSafetyOk{{.*}} address_safety +// ASAN: TemplateAddressSafetyOk{{.*}} address_safety +template<int i> +int TemplateAddressSafetyOk() { return i; } + +int force_instance = TemplateAddressSafetyOk<42>() + + TemplateNoAddressSafety<42>(); |