[cfe-commits] [PATCH] Add three new sanitizers depending on ASan.
Alexey Samsonov
samsonov at google.com
Thu Nov 29 13:11:35 PST 2012
Addressed comments by gribozavr and rsmith.
Hi kcc, rsmith,
http://llvm-reviews.chandlerc.com/D142
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D142?vs=371&id=372#toc
Files:
test/Driver/fsanitize.c
include/clang/Basic/Sanitizers.def
docs/UsersManual.html
lib/Driver/SanitizerArgs.h
lib/Driver/Tools.cpp
lib/CodeGen/BackendUtil.cpp
Index: test/Driver/fsanitize.c
===================================================================
--- test/Driver/fsanitize.c
+++ test/Driver/fsanitize.c
@@ -10,6 +10,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-thread-sanitizer -fno-sanitize=float-cast-overflow,vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
// CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|object-size|bounds),?){11}"}}
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL
+// CHECK-ASAN-FULL: "-fsanitize={{((address|init-order|use-after-return|use-after-scope),?){4}"}}
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fno-rtti %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-NO-RTTI
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fno-rtti %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-NO-RTTI
// CHECK-VPTR-NO-RTTI: '-fsanitize=vptr' not allowed with '-fno-rtti'
@@ -20,6 +23,9 @@
// RUN: %clang -target x86_64-linux-gnu -faddress-sanitizer -fthread-sanitizer -fno-rtti %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TSAN
// CHECK-ASAN-TSAN: '-faddress-sanitizer' not allowed with '-fthread-sanitizer'
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=init-order %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-EXTRA-ASAN
+// CHECK-ONLY-EXTRA-ASAN: argument '-fsanitize=init-order' only allowed with '-fsanitize=address'
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize=alignment -fsanitize=vptr -fno-sanitize=vptr %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-ASAN
// CHECK-UBSAN-ASAN: '-fsanitize=address' not allowed with '-fsanitize=alignment'
Index: include/clang/Basic/Sanitizers.def
===================================================================
--- include/clang/Basic/Sanitizers.def
+++ include/clang/Basic/Sanitizers.def
@@ -40,6 +40,13 @@
// AddressSanitizer
SANITIZER("address", Address)
+// More features of AddressSanitizer that should be turned on explicitly.
+SANITIZER("init-order", InitOrder)
+SANITIZER("use-after-return", UseAfterReturn)
+SANITIZER("use-after-scope", UseAfterScope)
+
+SANITIZER_GROUP("address-full", AddressFull,
+ Address | InitOrder | UseAfterReturn | UseAfterScope)
// ThreadSanitizer
SANITIZER("thread", Thread)
Index: docs/UsersManual.html
===================================================================
--- docs/UsersManual.html
+++ docs/UsersManual.html
@@ -886,6 +886,8 @@
<li id="opt_fsanitize_address"><tt>-fsanitize=address</tt>:
<a href="AddressSanitizer.html">AddressSanitizer</a>, a memory error
detector.</li>
+<li id="opt_fsanitize_address_full"><tt>-fsanitize=address-full</tt>:
+ AddressSanitizer with all the experimental features listed below.
<li id="opt_fsanitize_integer"><tt>-fsanitize=integer</tt>:
Enables checks for undefined or suspicious integer behavior.</li>
<li id="opt_fsanitize_thread"><tt>-fsanitize=thread</tt>:
@@ -941,6 +943,20 @@
<tt>-fno-rtti</tt>.</li>
</ul>
+Experimental features of AddressSanitizer (not ready for widespread use,
+require explicit <tt>-fsanitize=address</tt>):
+
+<ul>
+<li id="opt_fsanitize_init_order"><tt>-fsanitize=init-order</tt>:
+Check for dynamic initialization order problems.</li>
+<li id="opt_fsanitize_use_after_return"><tt>-fsanitize=use-after-return</tt>:
+Check for use-after-return errors (accessing local variable after the function
+exit).
+<li id="opt_fsanitize_use_after_scope"><tt>-fsanitize=use-after-scope</tt>:
+Check for use-after-scope errors (accesing local variable after it went out of
+scope).
+</ul>
+
The <tt>-fsanitize=</tt> argument must also be provided when linking, in order
to link to the appropriate runtime library. It is not possible to combine the
<tt>-fsanitize=address</tt> and <tt>-fsanitize=thread</tt> checkers in the same
Index: lib/Driver/SanitizerArgs.h
===================================================================
--- lib/Driver/SanitizerArgs.h
+++ lib/Driver/SanitizerArgs.h
@@ -28,7 +28,7 @@
#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
#include "clang/Basic/Sanitizers.def"
- NeedsAsanRt = Address,
+ NeedsAsanRt = AddressFull,
NeedsTsanRt = Thread,
NeedsUbsanRt = (Undefined & ~Bounds) | Integer
};
@@ -44,7 +44,7 @@
bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
bool sanitizesVptr() const { return Kind & Vptr; }
-
+
void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
if (!Kind)
return;
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1474,6 +1474,13 @@
D.Diag(diag::err_drv_argument_not_allowed_with)
<< lastArgumentForKind(D, Args, NeedsAsan ? NeedsAsanRt : NeedsTsanRt)
<< lastArgumentForKind(D, Args, NeedsUbsan ? NeedsUbsanRt : NeedsTsanRt);
+
+ // If -fsanitize contains extra features of ASan, it should also
+ // explicitly contain -fsanitize=address.
+ if (NeedsAsan && ((Kind & Address) == 0))
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << lastArgumentForKind(D, Args, NeedsAsanRt)
+ << "-fsanitize=address";
}
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -135,6 +135,17 @@
void EmitAssembly(BackendAction Action, raw_ostream *OS);
};
+// We need this wrapper to access LangOpts from extension functions that
+// we add to the PassManagerBuilder.
+class PassManagerBuilderWrapper : public PassManagerBuilder {
+public:
+ PassManagerBuilderWrapper(const LangOptions &LangOpts)
+ : PassManagerBuilder(), LangOpts(LangOpts) {}
+ const LangOptions &getLangOpts() const { return LangOpts; }
+private:
+ const LangOptions &LangOpts;
+};
+
}
static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
@@ -157,10 +168,15 @@
PM.add(createBoundsCheckingPass());
}
-static void addAddressSanitizerPass(const PassManagerBuilder &Builder,
- PassManagerBase &PM) {
- PM.add(createAddressSanitizerFunctionPass());
- PM.add(createAddressSanitizerModulePass());
+static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
+ PassManagerBase &PM) {
+ const PassManagerBuilderWrapper &BuilderWrapper =
+ static_cast<const PassManagerBuilderWrapper&>(Builder);
+ const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
+ PM.add(createAddressSanitizerFunctionPass(LangOpts.SanitizeInitOrder,
+ LangOpts.SanitizeUseAfterReturn,
+ LangOpts.SanitizeUseAfterScope));
+ PM.add(createAddressSanitizerModulePass(LangOpts.SanitizeInitOrder));
}
static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
@@ -178,8 +194,8 @@
OptLevel = 0;
Inlining = CodeGenOpts.NoInlining;
}
-
- PassManagerBuilder PMBuilder;
+
+ PassManagerBuilderWrapper PMBuilder(LangOpts);
PMBuilder.OptLevel = OptLevel;
PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
@@ -206,9 +222,9 @@
if (LangOpts.SanitizeAddress) {
PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
- addAddressSanitizerPass);
+ addAddressSanitizerPasses);
PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
- addAddressSanitizerPass);
+ addAddressSanitizerPasses);
}
if (LangOpts.SanitizeThread) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142.3.patch
Type: text/x-patch
Size: 8033 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121129/08cb43b2/attachment.bin>
More information about the cfe-commits
mailing list