Home | History | Annotate | Download | only in not
      1 //===- not.cpp - The 'not' testing tool -----------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 // Usage:
     10 //   not cmd
     11 //     Will return true if cmd doesn't crash and returns false.
     12 //   not --crash cmd
     13 //     Will return true if cmd crashes (e.g. for testing crash reporting).
     14 
     15 #include "llvm/Support/Program.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 using namespace llvm;
     18 
     19 int main(int argc, const char **argv) {
     20   bool ExpectCrash = false;
     21 
     22   ++argv;
     23   --argc;
     24 
     25   if (argc > 0 && StringRef(argv[0]) == "--crash") {
     26     ++argv;
     27     --argc;
     28     ExpectCrash = true;
     29   }
     30 
     31   if (argc == 0)
     32     return 1;
     33 
     34   auto Program = sys::findProgramByName(argv[0]);
     35   if (!Program) {
     36     errs() << "Error: Unable to find `" << argv[0]
     37            << "' in PATH: " << Program.getError().message() << "\n";
     38     return 1;
     39   }
     40 
     41   std::vector<StringRef> Argv;
     42   Argv.reserve(argc);
     43   for (int i = 0; i < argc; ++i)
     44     Argv.push_back(argv[i]);
     45   std::string ErrMsg;
     46   int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg);
     47 #ifdef _WIN32
     48   // Handle abort() in msvcrt -- It has exit code as 3.  abort(), aka
     49   // unreachable, should be recognized as a crash.  However, some binaries use
     50   // exit code 3 on non-crash failure paths, so only do this if we expect a
     51   // crash.
     52   if (ExpectCrash && Result == 3)
     53     Result = -3;
     54 #endif
     55   if (Result < 0) {
     56     errs() << "Error: " << ErrMsg << "\n";
     57     if (ExpectCrash)
     58       return 0;
     59     return 1;
     60   }
     61 
     62   if (ExpectCrash)
     63     return 1;
     64 
     65   return Result == 0;
     66 }
     67