148f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//===- not.cpp - The 'not' testing tool -----------------------------------===//
248f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//
348f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//                     The LLVM Compiler Infrastructure
448f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//
548f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar// This file is distributed under the University of Illinois Open Source
648f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar// License. See LICENSE.TXT for details.
748f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//
848f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar//===----------------------------------------------------------------------===//
9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Usage:
10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//   not cmd
11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//     Will return true if cmd doesn't crash and returns false.
12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//   not --crash cmd
13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//     Will return true if cmd crashes (e.g. for testing crash reporting).
1448f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar
151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h"
161f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Program.h"
179dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman#include "llvm/Support/raw_ostream.h"
1848f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbarusing namespace llvm;
1948f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar
2048f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbarint main(int argc, const char **argv) {
21a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  bool ExpectCrash = false;
22a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola
23a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  ++argv;
24a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  --argc;
25a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola
26a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  if (argc > 0 && StringRef(argv[0]) == "--crash") {
27a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    ++argv;
28a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    --argc;
29a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    ExpectCrash = true;
30a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  }
31a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola
32a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  if (argc == 0)
33a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    return 1;
34a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto Program = sys::findProgramByName(argv[0]);
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Program) {
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "Error: Unable to find `" << argv[0]
3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "' in PATH: " << Program.getError().message() << "\n";
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 1;
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
419dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman
429dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman  std::string ErrMsg;
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int Result = sys::ExecuteAndWait(*Program, argv, nullptr, nullptr, 0, 0,
44c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                   &ErrMsg);
45c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#ifdef _WIN32
46c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Handle abort() in msvcrt -- It has exit code as 3.  abort(), aka
47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // unreachable, should be recognized as a crash.  However, some binaries use
48c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // exit code 3 on non-crash failure paths, so only do this if we expect a
49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // crash.
50c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (ExpectCrash && Result == 3)
51c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Result = -3;
52c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#endif
539dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman  if (Result < 0) {
549dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman    errs() << "Error: " << ErrMsg << "\n";
55a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    if (ExpectCrash)
56a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola      return 0;
579dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman    return 1;
589dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman  }
599dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman
60a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola  if (ExpectCrash)
61a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola    return 1;
62a5db79d5148d3972b90390f526fd35d707729c5aRafael Espindola
639dbb79aaac8dc2a94b13ddd4c8fdc659f0167716Dan Gohman  return Result == 0;
6448f7ce88a6040c12d4c7d0a5bd208cf1e0bda9d1Daniel Dunbar}
65