diff --git a/flang/include/flang/Optimizer/Builder/Todo.h b/flang/include/flang/Optimizer/Builder/Todo.h --- a/flang/include/flang/Optimizer/Builder/Todo.h +++ b/flang/include/flang/Optimizer/Builder/Todo.h @@ -29,48 +29,40 @@ #undef TODOQUOTE #define TODOQUOTE(X) #X +// Give backtrace only in debug builds. +#undef GEN_TRACE #ifdef NDEBUG - -// In a release build, just give a message and exit. -#define TODO_NOLOC(ToDoMsg) \ - do { \ - llvm::errs() << __FILE__ << ':' << __LINE__ \ - << ": not yet implemented: " << ToDoMsg << '\n'; \ - std::exit(1); \ - } while (false) - -#undef TODO_DEFN -#define TODO_DEFN(MlirLoc, ToDoMsg, ToDoFile, ToDoLine) \ - do { \ - mlir::emitError(MlirLoc, ToDoFile ":" TODOQUOTE( \ - ToDoLine) ": not yet implemented: " ToDoMsg); \ - std::exit(1); \ - } while (false) - -#define TODO(MlirLoc, ToDoMsg) TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__) - +#define GEN_TRACE false #else +#define GEN_TRACE true +#endif -// In a developer build, print a message and give a backtrace. #undef TODO_NOLOCDEFN -#define TODO_NOLOCDEFN(ToDoMsg, ToDoFile, ToDoLine) \ +#define TODO_NOLOCDEFN(ToDoMsg, ToDoFile, ToDoLine, GenTrace) \ do { \ - llvm::report_fatal_error( \ - ToDoFile ":" TODOQUOTE(ToDoLine) ": not yet implemented: " ToDoMsg); \ + llvm::report_fatal_error(llvm::Twine(ToDoFile ":" TODOQUOTE( \ + ToDoLine) ": not yet implemented: ") + \ + llvm::Twine(ToDoMsg), \ + GenTrace); \ } while (false) -#define TODO_NOLOC(ToDoMsg) TODO_NOLOCDEFN(ToDoMsg, __FILE__, __LINE__) +#define TODO_NOLOC(ToDoMsg) TODO_NOLOCDEFN(ToDoMsg, __FILE__, __LINE__, false) +#define TODO_NOLOC_TRACE(ToDoMsg) \ + TODO_NOLOCDEFN(ToDoMsg, __FILE__, __LINE__, GENTRACE) #undef TODO_DEFN -#define TODO_DEFN(MlirLoc, ToDoMsg, ToDoFile, ToDoLine) \ +#define TODO_DEFN(MlirLoc, ToDoMsg, ToDoFile, ToDoLine, GenTrace) \ do { \ - fir::emitFatalError( \ - MlirLoc, \ - ToDoFile ":" TODOQUOTE(ToDoLine) ": not yet implemented: " ToDoMsg); \ + fir::emitFatalError(MlirLoc, \ + llvm::Twine(ToDoFile ":" TODOQUOTE( \ + ToDoLine) ": not yet implemented: ") + \ + llvm::Twine(ToDoMsg), \ + GenTrace); \ } while (false) -#define TODO(MlirLoc, ToDoMsg) TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__) - -#endif +#define TODO(MlirLoc, ToDoMsg) \ + TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__, false) +#define TODO_TRACE(MlirLoc, ToDoMsg) \ + TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__, GEN_TRACE) #endif // FORTRAN_LOWER_TODO_H diff --git a/flang/include/flang/Optimizer/Support/FatalError.h b/flang/include/flang/Optimizer/Support/FatalError.h --- a/flang/include/flang/Optimizer/Support/FatalError.h +++ b/flang/include/flang/Optimizer/Support/FatalError.h @@ -19,11 +19,14 @@ namespace fir { /// Fatal error reporting helper. Report a fatal error with a source location -/// and immediately abort flang. +/// and immediately interrupt flang. If `genCrashDiag` is true, then +/// the execution is aborted and the backtrace is printed, otherwise, +/// flang exits with non-zero exit code and without backtrace printout. [[noreturn]] inline void emitFatalError(mlir::Location loc, - const llvm::Twine &message) { + const llvm::Twine &message, + bool genCrashDiag = true) { mlir::emitError(loc, message); - llvm::report_fatal_error("aborting"); + llvm::report_fatal_error("aborting", genCrashDiag); } } // namespace fir diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py --- a/flang/test/lit.cfg.py +++ b/flang/test/lit.cfg.py @@ -94,14 +94,17 @@ ToolSubst('%flang_fc1', command=FindTool('flang-new'), extra_args=['-fc1'], unresolved='fatal')] -# Flang has several unimplemented features. TODO messages are used to mark and fail if these -# features are exercised. TODOs exit with an error in non-assert builds but in assert builds -# it aborts. To catch aborts, the `--crash` option for the `not` command has to be used. +# Flang has several unimplemented features. TODO messages are used to mark +# and fail if these features are exercised. Some TODOs exit with a non-zero +# exit code, but others abort the execution in assert builds. +# To catch aborts, the `--crash` option for the `not` command has to be used. +tools.append(ToolSubst('%not_todo_cmd', command=FindTool('not'), unresolved='fatal')) if 'asserts' in config.available_features: - tools.append(ToolSubst('%not_todo_cmd', command=FindTool('not'), extra_args=['--crash'], - unresolved='fatal')) + tools.append(ToolSubst('%not_todo_abort_cmd', command=FindTool('not'), + extra_args=['--crash'], unresolved='fatal')) else: - tools.append(ToolSubst('%not_todo_cmd', command=FindTool('not'), unresolved='fatal')) + tools.append(ToolSubst('%not_todo_abort_cmd', command=FindTool('not'), + unresolved='fatal')) # Define some variables to help us test that the flang runtime doesn't depend on # the C++ runtime libraries. For this we need a C compiler. If for some reason