not.cpp 1.7 KB

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