This patch exposes to Clang users three more sanitizers are experimental features of ASan:
1) init-order sanitizer: initialization-order checker.
Status: usable, but may produce false positives w/o proper blacklisting.
2) use-after-return sanitizer
Status: implemented, but heavily understed.
Should be optional, as it significanlty slows program down.
3) use-after-scope sanitizer
Status: in progress.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168950 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index d54ed22..a5cc2ea 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/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) {