Merging r257645:
authorDimitry Andric <dimitry@andric.com>
Wed, 13 Jan 2016 19:37:51 +0000 (19:37 +0000)
committerDimitry Andric <dimitry@andric.com>
Wed, 13 Jan 2016 19:37:51 +0000 (19:37 +0000)
------------------------------------------------------------------------
r257645 | dim | 2016-01-13 19:29:46 +0100 (Wed, 13 Jan 2016) | 22 lines

Avoid undefined behavior in LinkAllPasses.h

The LinkAllPasses.h file is included in several main programs, to force
a large number of passes to be linked in.  However, the ForcePassLinking
constructor uses undefined behavior, since it calls member functions on
`nullptr`, e.g.:

      ((llvm::Function*)nullptr)->viewCFGOnly();
      llvm::RGPassManager RGM;
      ((llvm::RegionPass*)nullptr)->runOnRegion((llvm::Region*)nullptr, RGM);

When the optimization level is -O2 or higher, the code below the first
nullptr dereference is optimized away, and replaced by `ud2` (on x86).

Therefore, the calls after that first dereference are never emitted.  In
my case, I noticed there was no call to `llvm::sys::RunningOnValgrind()`!

Replace instances of dereferencing `nullptr` with either objects on the
stack, or regular function calls.

Differential Revision: http://reviews.llvm.org/D15996

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@257660 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/LinkAllPasses.h

index d695d11..327faac 100644 (file)
@@ -160,9 +160,11 @@ namespace {
       (void) llvm::createPostOrderFunctionAttrsPass();
       (void) llvm::createReversePostOrderFunctionAttrsPass();
       (void) llvm::createMergeFunctionsPass();
       (void) llvm::createPostOrderFunctionAttrsPass();
       (void) llvm::createReversePostOrderFunctionAttrsPass();
       (void) llvm::createMergeFunctionsPass();
-      (void) llvm::createPrintModulePass(*(llvm::raw_ostream*)nullptr);
-      (void) llvm::createPrintFunctionPass(*(llvm::raw_ostream*)nullptr);
-      (void) llvm::createPrintBasicBlockPass(*(llvm::raw_ostream*)nullptr);
+      std::string buf;
+      llvm::raw_string_ostream os(buf);
+      (void) llvm::createPrintModulePass(os);
+      (void) llvm::createPrintFunctionPass(os);
+      (void) llvm::createPrintBasicBlockPass(os);
       (void) llvm::createModuleDebugInfoPrinterPass();
       (void) llvm::createPartialInliningPass();
       (void) llvm::createLintPass();
       (void) llvm::createModuleDebugInfoPrinterPass();
       (void) llvm::createPartialInliningPass();
       (void) llvm::createLintPass();
@@ -186,10 +188,10 @@ namespace {
 
       (void)new llvm::IntervalPartition();
       (void)new llvm::ScalarEvolutionWrapperPass();
 
       (void)new llvm::IntervalPartition();
       (void)new llvm::ScalarEvolutionWrapperPass();
-      ((llvm::Function*)nullptr)->viewCFGOnly();
+      llvm::Function::Create(nullptr, llvm::GlobalValue::ExternalLinkage)->viewCFGOnly();
       llvm::RGPassManager RGM;
       llvm::RGPassManager RGM;
-      ((llvm::RegionPass*)nullptr)->runOnRegion((llvm::Region*)nullptr, RGM);
-      llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)nullptr);
+      llvm::AliasAnalysis AA;
+      llvm::AliasSetTracker X(AA);
       X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets
       (void) llvm::AreStatisticsEnabled();
       (void) llvm::sys::RunningOnValgrind();
       X.add(nullptr, 0, llvm::AAMDNodes()); // for -print-alias-sets
       (void) llvm::AreStatisticsEnabled();
       (void) llvm::sys::RunningOnValgrind();