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/Path.h"
     16 #include "llvm/Support/Program.h"
     17 #include "llvm/Support/raw_ostream.h"
     18 using namespace llvm;
     19 
     20 int main(int argc, const char **argv) {
     21   bool ExpectCrash = false;
     22 
     23   ++argv;
     24   --argc;
     25 
     26   if (argc > 0 && StringRef(argv[0]) == "--crash") {
     27     ++argv;
     28     --argc;
     29     ExpectCrash = true;
     30   }
     31 
     32   if (argc == 0)
     33     return 1;
     34 
     35   auto Program = sys::findProgramByName(argv[0]);
     36   if (!Program) {
     37     errs() << "Error: Unable to find `" << argv[0]
     38            << "' in PATH: " << Program.getError().message() << "\n";
     39     return 1;
     40   }
     41 
     42   std::string ErrMsg;
     43   int Result = sys::ExecuteAndWait(*Program, argv, nullptr, nullptr, 0, 0,
     44                                    &ErrMsg);
     45 #ifdef _WIN32
     46   // Handle abort() in msvcrt -- It has exit code as 3.  abort(), aka
     47   // unreachable, should be recognized as a crash.  However, some binaries use
     48   // exit code 3 on non-crash failure paths, so only do this if we expect a
     49   // crash.
     50   if (ExpectCrash && Result == 3)
     51     Result = -3;
     52 #endif
     53   if (Result < 0) {
     54     errs() << "Error: " << ErrMsg << "\n";
     55     if (ExpectCrash)
     56       return 0;
     57     return 1;
     58   }
     59 
     60   if (ExpectCrash)
     61     return 1;
     62 
     63   return Result == 0;
     64 }
     65