Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ErrorHandling] Add reportFatalInternalError + reportFatalUsageError (NFC) #138251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/AST/ExternalASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
// FIXME: Only bump the generation counter if the current generation number
// has been observed?
if (!++CurrentGeneration)
llvm::report_fatal_error("generation counter overflowed", false);
llvm::reportFatalUsageError("generation counter overflowed");
}

return OldGeneration;
Expand Down
2 changes: 1 addition & 1 deletion clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ int main(int Argc, char **Argv) {
PassPlugins.setCallback([&](const std::string &PluginPath) {
auto Plugin = PassPlugin::Load(PluginPath);
if (!Plugin)
report_fatal_error(Plugin.takeError(), /*gen_crash_diag=*/false);
reportFatalUsageError(Plugin.takeError());
PluginList.emplace_back(Plugin.get());
});
cl::ParseCommandLineOptions(NewArgv.size(), &NewArgv[0]);
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/CodeGen/CodeGenTargetMachineImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ getEffectiveCodeModel(std::optional<CodeModel::Model> CM,
if (CM) {
// By default, targets do not support the tiny and kernel models.
if (*CM == CodeModel::Tiny)
report_fatal_error("Target does not support the tiny CodeModel", false);
reportFatalUsageError("Target does not support the tiny CodeModel");
if (*CM == CodeModel::Kernel)
report_fatal_error("Target does not support the kernel CodeModel", false);
reportFatalUsageError("Target does not support the kernel CodeModel");
return *CM;
}
return Default;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Passes/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
addPass(RAGreedyPass());
break;
default:
report_fatal_error("register allocator not supported yet", false);
reportFatalUsageError("register allocator not supported yet");
}
return;
}
Expand Down
11 changes: 9 additions & 2 deletions llvm/include/llvm/Support/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,10 +735,17 @@ template <class T> class [[nodiscard]] Expected {
#endif
};

/// Report a serious error, calling any installed error handler. See
/// ErrorHandling.h.
/// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
/// instead.
[[noreturn]] void report_fatal_error(Error Err, bool gen_crash_diag = true);

/// Report a fatal error that indicates a bug in LLVM.
/// See ErrorHandling.h for details.
[[noreturn]] void reportFatalInternalError(Error Err);
/// Report a fatal error that does not indicate a bug in LLVM.
/// See ErrorHandling.h for details.
[[noreturn]] void reportFatalUsageError(Error Err);

/// Report a fatal error if Err is a failure value.
///
/// This function can be used to wrap calls to fallible functions ONLY when it
Expand Down
40 changes: 31 additions & 9 deletions llvm/include/llvm/Support/ErrorHandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,44 @@ namespace llvm {
~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
};

/// Reports a serious error, calling any installed error handler. These
/// functions are intended to be used for error conditions which are outside
/// the control of the compiler (I/O errors, invalid user input, etc.)
///
/// If no error handler is installed the default is to print the message to
/// standard error, followed by a newline.
/// After the error handler is called this function will call abort(), it
/// does not return.
/// NOTE: The std::string variant was removed to avoid a <string> dependency.
/// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
/// instead.
[[noreturn]] void report_fatal_error(const char *reason,
bool gen_crash_diag = true);
[[noreturn]] void report_fatal_error(StringRef reason,
bool gen_crash_diag = true);
[[noreturn]] void report_fatal_error(const Twine &reason,
bool gen_crash_diag = true);

/// Report a fatal error that likely indicates a bug in LLVM. It serves a
/// similar purpose as an assertion, but is always enabled, regardless of the
/// value of NDEBUG.
///
/// This will call installed error handlers (or print the message by default)
/// and then abort. This will produce a crash trace and *will* ask users to
/// report an LLVM bug.
[[noreturn]] void reportFatalInternalError(const char *reason);
[[noreturn]] void reportFatalInternalError(StringRef reason);
[[noreturn]] void reportFatalInternalError(const Twine &reason);

/// Report a fatal error that does not indicate a bug in LLVM.
///
/// This can be used in contexts where a proper error reporting mechanism
/// (such as Error/Expected or DiagnosticInfo) is currently not supported, and
/// would be too involved to introduce at the moment.
///
/// Examples where this function should be used instead of
/// reportFatalInternalError() include invalid inputs or options, but also
/// environment error conditions outside LLVM's control. It should also be used
/// for known unsupported/unimplemented functionality.
///
/// This will call installed error handlers (or print the message by default)
/// and then exit with code 1. It will not produce a crash trace and will
/// *not* ask users to report an LLVM bug.
[[noreturn]] void reportFatalUsageError(const char *reason);
[[noreturn]] void reportFatalUsageError(StringRef reason);
[[noreturn]] void reportFatalUsageError(const Twine &reason);

/// Installs a new bad alloc error handler that should be used whenever a
/// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM.
///
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/LTO/LTOBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins,
for (auto &PluginFN : PassPlugins) {
auto PassPlugin = PassPlugin::Load(PluginFN);
if (!PassPlugin)
report_fatal_error(PassPlugin.takeError(), /*gen_crash_diag=*/false);
reportFatalUsageError(PassPlugin.takeError());
PassPlugin->registerPassBuilderCallbacks(PB);
}
}
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Support/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ void report_fatal_error(Error Err, bool GenCrashDiag) {
report_fatal_error(Twine(ErrMsg), GenCrashDiag);
}

void reportFatalInternalError(Error Err) {
report_fatal_error(std::move(Err), /*GenCrashDiag=*/true);
}
void reportFatalUsageError(Error Err) {
report_fatal_error(std::move(Err), /*GenCrashDiag=*/false);
}

} // end namespace llvm

LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err) {
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/Support/ErrorHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
exit(1);
}

void llvm::reportFatalInternalError(const char *reason) {
report_fatal_error(reason, /*GenCrashDiag=*/true);
}
void llvm::reportFatalInternalError(StringRef reason) {
report_fatal_error(reason, /*GenCrashDiag=*/true);
}
void llvm::reportFatalInternalError(const Twine &reason) {
report_fatal_error(reason, /*GenCrashDiag=*/true);
}
void llvm::reportFatalUsageError(const char *reason) {
report_fatal_error(reason, /*GenCrashDiag=*/false);
}
void llvm::reportFatalUsageError(StringRef reason) {
report_fatal_error(reason, /*GenCrashDiag=*/false);
}
void llvm::reportFatalUsageError(const Twine &reason) {
report_fatal_error(reason, /*GenCrashDiag=*/false);
}

void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
void *user_data) {
#if LLVM_ENABLE_THREADS == 1
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Support/raw_ostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,8 @@ raw_fd_ostream::~raw_fd_ostream() {
// has_error() and clear the error flag with clear_error() before
// destructing raw_ostream objects which may have errors.
if (has_error())
report_fatal_error(Twine("IO failure on output stream: ") +
error().message(),
/*gen_crash_diag=*/false);
reportFatalUsageError(Twine("IO failure on output stream: ") +
error().message());
}

#if defined(_WIN32)
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,8 @@ void AMDGPUAsmPrinter::emitFunctionBodyStart() {

// TODO: We're checking this late, would be nice to check it earlier.
if (STM.requiresCodeObjectV6() && CodeObjectVersion < AMDGPU::AMDHSA_COV6) {
report_fatal_error(
STM.getCPU() + " is only available on code object version 6 or better",
/*gen_crash_diag*/ false);
reportFatalUsageError(
STM.getCPU() + " is only available on code object version 6 or better");
}

// TODO: Which one is called first, emitStartOfAsmFile or
Expand Down
14 changes: 5 additions & 9 deletions llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ static Value *expandCrossIntrinsic(CallInst *Orig) {

VectorType *VT = cast<VectorType>(Orig->getType());
if (cast<FixedVectorType>(VT)->getNumElements() != 3)
report_fatal_error(Twine("return vector must have exactly 3 elements"),
/* gen_crash_diag=*/false);
reportFatalUsageError("return vector must have exactly 3 elements");

Value *op0 = Orig->getOperand(0);
Value *op1 = Orig->getOperand(1);
Expand Down Expand Up @@ -197,9 +196,8 @@ static Value *expandFloatDotIntrinsic(CallInst *Orig, Value *A, Value *B) {
DotIntrinsic = Intrinsic::dx_dot4;
break;
default:
report_fatal_error(
Twine("Invalid dot product input vector: length is outside 2-4"),
/* gen_crash_diag=*/false);
reportFatalUsageError(
"Invalid dot product input vector: length is outside 2-4");
return nullptr;
}

Expand Down Expand Up @@ -359,8 +357,7 @@ static Value *expandNormalizeIntrinsic(CallInst *Orig) {
if (auto *constantFP = dyn_cast<ConstantFP>(X)) {
const APFloat &fpVal = constantFP->getValueAPF();
if (fpVal.isZero())
report_fatal_error(Twine("Invalid input scalar: length is zero"),
/* gen_crash_diag=*/false);
reportFatalUsageError("Invalid input scalar: length is zero");
}
return Builder.CreateFDiv(X, X);
}
Expand All @@ -372,8 +369,7 @@ static Value *expandNormalizeIntrinsic(CallInst *Orig) {
if (auto *constantFP = dyn_cast<ConstantFP>(DotProduct)) {
const APFloat &fpVal = constantFP->getValueAPF();
if (fpVal.isZero())
report_fatal_error(Twine("Invalid input vector: length is zero"),
/* gen_crash_diag=*/false);
reportFatalUsageError("Invalid input vector: length is zero");
}

Value *Multiplicand = Builder.CreateIntrinsic(EltTy, Intrinsic::dx_rsqrt,
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Target/DirectX/DXILOpBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,9 @@ DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) {
ShaderStage = TT.getEnvironment();
// Ensure Environment type is known
if (ShaderStage == Triple::UnknownEnvironment) {
report_fatal_error(
reportFatalUsageError(
Twine(DXILVersion.getAsString()) +
": Unknown Compilation Target Shader Stage specified ",
/*gen_crash_diag*/ false);
": Unknown Compilation Target Shader Stage specified ");
}
}

Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/DirectX/DXILResourceAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI,
case dxil::ResourceKind::TextureCubeArray:
case dxil::ResourceKind::FeedbackTexture2D:
case dxil::ResourceKind::FeedbackTexture2DArray:
report_fatal_error("DXIL Load not implemented yet",
/*gen_crash_diag=*/false);
reportFatalUsageError("DXIL Load not implemented yet");
return;
case dxil::ResourceKind::CBuffer:
case dxil::ResourceKind::Sampler:
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2486,8 +2486,7 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
assert(N->getOffset() == 0 && "unexpected offset in global node");

if (DAG.getTarget().useEmulatedTLS())
report_fatal_error("the emulated TLS is prohibited",
/*GenCrashDiag=*/false);
reportFatalUsageError("the emulated TLS is prohibited");

bool IsDesc = DAG.getTarget().useTLSDESC();

Expand Down Expand Up @@ -7122,4 +7121,4 @@ LoongArchTargetLowering::getPreferredVectorAction(MVT VT) const {
return TypeWidenVector;

return TargetLoweringBase::getPreferredVectorAction(VT);
}
}
5 changes: 3 additions & 2 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ namespace RISCV {
} // namespace RISCV

// Report an error but don't ask the user to report a bug.
// TODO: Remove these wrappers.
[[noreturn]] static void reportError(const char *Reason) {
report_fatal_error(Reason, /*gen_crash_diag=*/false);
reportFatalUsageError(Reason);
}
[[noreturn]] static void reportError(Error Err) {
report_fatal_error(std::move(Err), /*gen_crash_diag=*/false);
reportFatalUsageError(std::move(Err));
}

namespace RISCVABI {
Expand Down
10 changes: 4 additions & 6 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21465,15 +21465,13 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
report_fatal_error("'qci-*' interrupt kinds require Xqciint extension");

if (Kind.starts_with("SiFive-CLIC-") && !Subtarget.hasVendorXSfmclic())
report_fatal_error(
"'SiFive-CLIC-*' interrupt kinds require XSfmclic extension",
/*gen_crash_diag=*/false);
reportFatalUsageError(
"'SiFive-CLIC-*' interrupt kinds require XSfmclic extension");

const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
if (Kind.starts_with("SiFive-CLIC-preemptible") && TFI->hasFP(MF))
report_fatal_error("'SiFive-CLIC-preemptible' interrupt kinds cannot "
"have a frame pointer",
/*gen_crash_diag=*/false);
reportFatalUsageError("'SiFive-CLIC-preemptible' interrupt kinds cannot "
"have a frame pointer");
}

EVT PtrVT = getPointerTy(DAG.getDataLayout());
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static unsigned typeToAddressSpace(const Type *Ty) {
if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
ExtTy && isTypedPointerWrapper(ExtTy))
return ExtTy->getIntParameter(0);
report_fatal_error("Unable to convert LLVM type to SPIRVType", true);
reportFatalInternalError("Unable to convert LLVM type to SPIRVType");
}

#ifndef NDEBUG
Expand Down
13 changes: 6 additions & 7 deletions llvm/lib/Transforms/IPO/BlockExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ void BlockExtractor::loadFile() {
if (LineSplit.empty())
continue;
if (LineSplit.size()!=2)
report_fatal_error("Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'",
/*GenCrashDiag=*/false);
reportFatalUsageError(
"Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'");
SmallVector<StringRef, 4> BBNames;
LineSplit[1].split(BBNames, ';', /*MaxSplit=*/-1,
/*KeepEmpty=*/false);
Expand Down Expand Up @@ -139,14 +139,13 @@ bool BlockExtractor::runOnModule(Module &M) {
for (const auto &BInfo : BlocksByName) {
Function *F = M.getFunction(BInfo.first);
if (!F)
report_fatal_error("Invalid function name specified in the input file",
/*GenCrashDiag=*/false);
reportFatalUsageError(
"Invalid function name specified in the input file");
for (const auto &BBInfo : BInfo.second) {
auto Res = llvm::find_if(
*F, [&](const BasicBlock &BB) { return BB.getName() == BBInfo; });
if (Res == F->end())
report_fatal_error("Invalid block name specified in the input file",
/*GenCrashDiag=*/false);
reportFatalUsageError("Invalid block name specified in the input file");
GroupsOfBlocks[NextGroupIdx].push_back(&*Res);
}
++NextGroupIdx;
Expand All @@ -158,7 +157,7 @@ bool BlockExtractor::runOnModule(Module &M) {
for (BasicBlock *BB : BBs) {
// Check if the module contains BB.
if (BB->getParent()->getParent() != &M)
report_fatal_error("Invalid basic block", /*GenCrashDiag=*/false);
reportFatalUsageError("Invalid basic block");
LLVM_DEBUG(dbgs() << "BlockExtractor: Extracting "
<< BB->getParent()->getName() << ":" << BB->getName()
<< "\n");
Expand Down
8 changes: 3 additions & 5 deletions llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ using namespace llvm;

PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
if (M.getGlobalVariable("llvm.embedded.module", /*AllowInternal=*/true))
report_fatal_error("Can only embed the module once",
/*gen_crash_diag=*/false);
reportFatalUsageError("Can only embed the module once");

Triple T(M.getTargetTriple());
if (T.getObjectFormat() != Triple::ELF)
report_fatal_error(
"EmbedBitcode pass currently only supports ELF object format",
/*gen_crash_diag=*/false);
reportFatalUsageError(
"EmbedBitcode pass currently only supports ELF object format");

std::string Data;
raw_string_ostream OS(Data);
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5647,13 +5647,12 @@ static bool combineInstructionsOverFunction(

MadeIRChange = true;
if (Iteration > Opts.MaxIterations) {
report_fatal_error(
reportFatalUsageError(
"Instruction Combining on " + Twine(F.getName()) +
" did not reach a fixpoint after " + Twine(Opts.MaxIterations) +
" iterations. " +
"Use 'instcombine<no-verify-fixpoint>' or function attribute "
"'instcombine-no-verify-fixpoint' to suppress this error.",
/*GenCrashDiag=*/false);
" did not reach a fixpoint after " + Twine(Opts.MaxIterations) +
" iterations. " +
"Use 'instcombine<no-verify-fixpoint>' or function attribute "
"'instcombine-no-verify-fixpoint' to suppress this error.");
}
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ GCOVOptions GCOVOptions::getDefault() {
Options.Atomic = AtomicCounter;

if (DefaultGCOVVersion.size() != 4) {
llvm::report_fatal_error(Twine("Invalid -default-gcov-version: ") +
DefaultGCOVVersion, /*GenCrashDiag=*/false);
reportFatalUsageError(Twine("Invalid -default-gcov-version: ") +
DefaultGCOVVersion);
}
memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
return Options;
Expand Down
Loading
Loading