Skip to content

Warn on misuse of DiagnosticInfo classes that hold Twines #137397

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 1 commit into from
May 28, 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
30 changes: 18 additions & 12 deletions llvm/include/llvm/IR/DiagnosticInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,12 @@ class DiagnosticInfoGeneric : public DiagnosticInfo {
/// \p MsgStr is the message to be reported to the frontend.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
DiagnosticInfoGeneric(const Twine &MsgStr,
DiagnosticInfoGeneric(const Twine &MsgStr LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_Generic, Severity), MsgStr(MsgStr) {}

DiagnosticInfoGeneric(const Instruction *I, const Twine &ErrMsg,
DiagnosticInfoGeneric(const Instruction *I,
const Twine &ErrMsg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_Generic, Severity), MsgStr(ErrMsg), Inst(I) {}

Expand Down Expand Up @@ -181,15 +182,17 @@ class DiagnosticInfoInlineAsm : public DiagnosticInfo {
/// \p MsgStr gives the message.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr,
DiagnosticInfoInlineAsm(uint64_t LocCookie,
const Twine &MsgStr LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error);

/// \p Instr gives the original instruction that triggered the diagnostic.
/// \p MsgStr gives the message.
/// This class does not copy \p MsgStr, therefore the reference must be valid
/// for the whole life time of the Diagnostic.
/// Same for \p I.
DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
DiagnosticInfoInlineAsm(const Instruction &I,
const Twine &MsgStr LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error);

uint64_t getLocCookie() const { return LocCookie; }
Expand Down Expand Up @@ -258,15 +261,16 @@ class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
class DiagnosticInfoSampleProfile : public DiagnosticInfo {
public:
DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
const Twine &Msg,
const Twine &Msg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
LineNum(LineNum), Msg(Msg) {}
DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
DiagnosticInfoSampleProfile(StringRef FileName,
const Twine &Msg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
Msg(Msg) {}
DiagnosticInfoSampleProfile(const Twine &Msg,
DiagnosticInfoSampleProfile(const Twine &Msg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}

Expand Down Expand Up @@ -296,7 +300,8 @@ class DiagnosticInfoSampleProfile : public DiagnosticInfo {
/// Diagnostic information for the PGO profiler.
class DiagnosticInfoPGOProfile : public DiagnosticInfo {
public:
DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
DiagnosticInfoPGOProfile(const char *FileName,
const Twine &Msg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}

Expand Down Expand Up @@ -364,7 +369,7 @@ class DiagnosticInfoWithLocationBase : public DiagnosticInfo {

/// Return the absolute path tot the file.
std::string getAbsolutePath() const;

const Function &getFunction() const { return Fn; }
DiagnosticLocation getLocation() const { return Loc; }

Expand Down Expand Up @@ -1062,7 +1067,7 @@ class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
/// Diagnostic information for unsupported feature in backend.
class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
private:
Twine Msg;
const Twine &Msg;

public:
/// \p Fn is the function where the diagnostic is being emitted. \p Loc is
Expand All @@ -1072,7 +1077,7 @@ class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
/// copy this message, so this reference must be valid for the whole life time
/// of the diagnostic.
DiagnosticInfoUnsupported(
const Function &Fn, const Twine &Msg,
const Function &Fn, const Twine &Msg LLVM_LIFETIME_BOUND,
const DiagnosticLocation &Loc = DiagnosticLocation(),
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
Expand All @@ -1090,7 +1095,8 @@ class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
/// Diagnostic information for MisExpect analysis.
class DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase {
public:
DiagnosticInfoMisExpect(const Instruction *Inst, const Twine &Msg);
DiagnosticInfoMisExpect(const Instruction *Inst,
const Twine &Msg LLVM_LIFETIME_BOUND);

/// \see DiagnosticInfo::print.
void print(DiagnosticPrinter &DP) const override;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ class LoweringDiagnosticInfo : public DiagnosticInfo {
const Twine &Msg;

public:
LoweringDiagnosticInfo(const Twine &DiagMsg,
LoweringDiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {}
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/LTO/LTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,8 @@ namespace {
class LTODiagnosticInfo : public DiagnosticInfo {
const Twine &Msg;
public:
LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error)
LTODiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
};
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/LTO/ThinLTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ namespace {
class ThinLTODiagnosticInfo : public DiagnosticInfo {
const Twine &Msg;
public:
ThinLTODiagnosticInfo(const Twine &DiagMsg,
ThinLTODiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,
DiagnosticSeverity Severity = DS_Error)
: DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Linker/LinkDiagnosticInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class LinkDiagnosticInfo : public DiagnosticInfo {
const Twine &Msg;

public:
LinkDiagnosticInfo(DiagnosticSeverity Severity, const Twine &Msg);
LinkDiagnosticInfo(DiagnosticSeverity Severity,
const Twine &Msg LLVM_LIFETIME_BOUND);
void print(DiagnosticPrinter &DP) const override;
};
}
Expand Down
17 changes: 7 additions & 10 deletions llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1389,9 +1389,8 @@ SDValue AMDGPUTargetLowering::lowerUnhandledCall(CallLoweringInfo &CLI,
else if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
FuncName = G->getGlobal()->getName();

DiagnosticInfoUnsupported NoCalls(
Fn, Reason + FuncName, CLI.DL.getDebugLoc());
DAG.getContext()->diagnose(NoCalls);
DAG.getContext()->diagnose(
DiagnosticInfoUnsupported(Fn, Reason + FuncName, CLI.DL.getDebugLoc()));

if (!CLI.IsTailCall) {
for (ISD::InputArg &Arg : CLI.Ins)
Expand All @@ -1410,9 +1409,8 @@ SDValue AMDGPUTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const {
const Function &Fn = DAG.getMachineFunction().getFunction();

DiagnosticInfoUnsupported NoDynamicAlloca(Fn, "unsupported dynamic alloca",
SDLoc(Op).getDebugLoc());
DAG.getContext()->diagnose(NoDynamicAlloca);
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
Fn, "unsupported dynamic alloca", SDLoc(Op).getDebugLoc()));
auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
return DAG.getMergeValues(Ops, SDLoc());
}
Expand Down Expand Up @@ -1527,10 +1525,9 @@ SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
!AMDGPU::isNamedBarrier(*cast<GlobalVariable>(GV))) {
SDLoc DL(Op);
const Function &Fn = DAG.getMachineFunction().getFunction();
DiagnosticInfoUnsupported BadLDSDecl(
Fn, "local memory global used by non-kernel function",
DL.getDebugLoc(), DS_Warning);
DAG.getContext()->diagnose(BadLDSDecl);
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
Fn, "local memory global used by non-kernel function",
DL.getDebugLoc(), DS_Warning));

// We currently don't have a way to correctly allocate LDS objects that
// aren't directly associated with a kernel. We do force inlining of
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2339,9 +2339,9 @@ bool AMDGPUInstructionSelector::selectG_INTRINSIC_W_SIDE_EFFECTS(
case Intrinsic::amdgcn_exp_compr:
if (!STI.hasCompressedExport()) {
Function &F = I.getMF()->getFunction();
DiagnosticInfoUnsupported NoFpRet(
F, "intrinsic not supported on subtarget", I.getDebugLoc(), DS_Error);
F.getContext().diagnose(NoFpRet);
F.getContext().diagnose(
DiagnosticInfoUnsupported(F, "intrinsic not supported on subtarget",
I.getDebugLoc(), DS_Error));
return false;
}
break;
Expand Down
29 changes: 12 additions & 17 deletions llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3014,10 +3014,9 @@ bool AMDGPULegalizerInfo::legalizeGlobalValue(
GV->getName() != "llvm.amdgcn.module.lds" &&
!AMDGPU::isNamedBarrier(*cast<GlobalVariable>(GV))) {
const Function &Fn = MF.getFunction();
DiagnosticInfoUnsupported BadLDSDecl(
Fn, "local memory global used by non-kernel function", MI.getDebugLoc(),
DS_Warning);
Fn.getContext().diagnose(BadLDSDecl);
Fn.getContext().diagnose(DiagnosticInfoUnsupported(
Fn, "local memory global used by non-kernel function",
MI.getDebugLoc(), DS_Warning));

// We currently don't have a way to correctly allocate LDS objects that
// aren't directly associated with a kernel. We do force inlining of
Expand Down Expand Up @@ -7046,11 +7045,9 @@ bool AMDGPULegalizerInfo::legalizeDebugTrap(MachineInstr &MI,
// accordingly
if (!ST.isTrapHandlerEnabled() ||
ST.getTrapHandlerAbi() != GCNSubtarget::TrapHandlerAbi::AMDHSA) {
DiagnosticInfoUnsupported NoTrap(B.getMF().getFunction(),
"debugtrap handler not supported",
MI.getDebugLoc(), DS_Warning);
LLVMContext &Ctx = B.getMF().getFunction().getContext();
Ctx.diagnose(NoTrap);
Function &Fn = B.getMF().getFunction();
Fn.getContext().diagnose(DiagnosticInfoUnsupported(
Fn, "debugtrap handler not supported", MI.getDebugLoc(), DS_Warning));
} else {
// Insert debug-trap instruction
B.buildInstr(AMDGPU::S_TRAP)
Expand Down Expand Up @@ -7078,10 +7075,9 @@ bool AMDGPULegalizerInfo::legalizeBVHIntersectRayIntrinsic(
Register TDescr = MI.getOperand(7).getReg();

if (!ST.hasGFX10_AEncoding()) {
DiagnosticInfoUnsupported BadIntrin(B.getMF().getFunction(),
"intrinsic not supported on subtarget",
MI.getDebugLoc());
B.getMF().getFunction().getContext().diagnose(BadIntrin);
Function &Fn = B.getMF().getFunction();
Fn.getContext().diagnose(DiagnosticInfoUnsupported(
Fn, "intrinsic not supported on subtarget", MI.getDebugLoc()));
return false;
}

Expand Down Expand Up @@ -7231,10 +7227,9 @@ bool AMDGPULegalizerInfo::legalizeBVHDualOrBVH8IntersectRayIntrinsic(
Register TDescr = MI.getOperand(10).getReg();

if (!ST.hasBVHDualAndBVH8Insts()) {
DiagnosticInfoUnsupported BadIntrin(B.getMF().getFunction(),
"intrinsic not supported on subtarget",
MI.getDebugLoc());
B.getMF().getFunction().getContext().diagnose(BadIntrin);
Function &Fn = B.getMF().getFunction();
Fn.getContext().diagnose(DiagnosticInfoUnsupported(
Fn, "intrinsic not supported on subtarget", MI.getDebugLoc()));
return false;
}

Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,11 @@ static StringRef getAsConstantStr(Value *V) {
}

static void diagnoseInvalidFormatString(const CallBase *CI) {
DiagnosticInfoUnsupported UnsupportedFormatStr(
CI->getContext().diagnose(DiagnosticInfoUnsupported(
*CI->getParent()->getParent(),
"printf format string must be a trivially resolved constant string "
"global variable",
CI->getDebugLoc());
CI->getContext().diagnose(UnsupportedFormatStr);
CI->getDebugLoc()));
}

bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) {
Expand Down
41 changes: 17 additions & 24 deletions llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2860,9 +2860,8 @@ SDValue SITargetLowering::LowerFormalArguments(
bool IsError = false;

if (Subtarget->isAmdHsaOS() && AMDGPU::isGraphics(CallConv)) {
DiagnosticInfoUnsupported NoGraphicsHSA(
Fn, "unsupported non-compute shaders with HSA", DL.getDebugLoc());
DAG.getContext()->diagnose(NoGraphicsHSA);
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
Fn, "unsupported non-compute shaders with HSA", DL.getDebugLoc()));
IsError = true;
}

Expand Down Expand Up @@ -3086,11 +3085,10 @@ SDValue SITargetLowering::LowerFormalArguments(
if (Arg.isOrigArg()) {
Argument *OrigArg = Fn.getArg(Arg.getOrigArgIndex());
if (OrigArg->hasAttribute("amdgpu-hidden-argument")) {
DiagnosticInfoUnsupported NonPreloadHiddenArg(
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
*OrigArg->getParent(),
"hidden argument in kernel signature was not preloaded",
DL.getDebugLoc());
DAG.getContext()->diagnose(NonPreloadHiddenArg);
DL.getDebugLoc()));
}
}

Expand Down Expand Up @@ -7315,11 +7313,10 @@ SDValue SITargetLowering::lowerDEBUGTRAP(SDValue Op, SelectionDAG &DAG) const {

if (!Subtarget->isTrapHandlerEnabled() ||
Subtarget->getTrapHandlerAbi() != GCNSubtarget::TrapHandlerAbi::AMDHSA) {
DiagnosticInfoUnsupported NoTrap(MF.getFunction(),
"debugtrap handler not supported",
Op.getDebugLoc(), DS_Warning);
LLVMContext &Ctx = MF.getFunction().getContext();
Ctx.diagnose(NoTrap);
Ctx.diagnose(DiagnosticInfoUnsupported(MF.getFunction(),
"debugtrap handler not supported",
Op.getDebugLoc(), DS_Warning));
return Chain;
}

Expand Down Expand Up @@ -8092,19 +8089,17 @@ SDValue SITargetLowering::lowerImplicitZextParam(SelectionDAG &DAG, SDValue Op,

static SDValue emitNonHSAIntrinsicError(SelectionDAG &DAG, const SDLoc &DL,
EVT VT) {
DiagnosticInfoUnsupported BadIntrin(DAG.getMachineFunction().getFunction(),
"non-hsa intrinsic with hsa target",
DL.getDebugLoc());
DAG.getContext()->diagnose(BadIntrin);
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
DAG.getMachineFunction().getFunction(),
"non-hsa intrinsic with hsa target", DL.getDebugLoc()));
return DAG.getPOISON(VT);
}

static SDValue emitRemovedIntrinsicError(SelectionDAG &DAG, const SDLoc &DL,
EVT VT) {
DiagnosticInfoUnsupported BadIntrin(DAG.getMachineFunction().getFunction(),
"intrinsic not supported on subtarget",
DL.getDebugLoc());
DAG.getContext()->diagnose(BadIntrin);
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
DAG.getMachineFunction().getFunction(),
"intrinsic not supported on subtarget", DL.getDebugLoc()));
return DAG.getPOISON(VT);
}

Expand Down Expand Up @@ -8813,10 +8808,9 @@ SDValue SITargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::amdgcn_dispatch_ptr:
case Intrinsic::amdgcn_queue_ptr: {
if (!Subtarget->isAmdHsaOrMesa(MF.getFunction())) {
DiagnosticInfoUnsupported BadIntrin(
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
MF.getFunction(), "unsupported hsa intrinsic without hsa target",
DL.getDebugLoc());
DAG.getContext()->diagnose(BadIntrin);
DL.getDebugLoc()));
return DAG.getPOISON(VT);
}

Expand Down Expand Up @@ -9925,10 +9919,9 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
switch (IntrinsicID) {
case Intrinsic::amdgcn_exp_compr: {
if (!Subtarget->hasCompressedExport()) {
DiagnosticInfoUnsupported BadIntrin(
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
DAG.getMachineFunction().getFunction(),
"intrinsic not supported on subtarget", DL.getDebugLoc());
DAG.getContext()->diagnose(BadIntrin);
"intrinsic not supported on subtarget", DL.getDebugLoc()));
}
SDValue Src0 = Op.getOperand(4);
SDValue Src1 = Op.getOperand(5);
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,12 +623,12 @@ static void reportIllegalCopy(const SIInstrInfo *TII, MachineBasicBlock &MBB,
MCRegister SrcReg, bool KillSrc,
const char *Msg = "illegal VGPR to SGPR copy") {
MachineFunction *MF = MBB.getParent();
DiagnosticInfoUnsupported IllegalCopy(MF->getFunction(), Msg, DL, DS_Error);

LLVMContext &C = MF->getFunction().getContext();
C.diagnose(IllegalCopy);
C.diagnose(DiagnosticInfoUnsupported(MF->getFunction(), Msg, DL, DS_Error));

BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_ILLEGAL_COPY), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
.addReg(SrcReg, getKillRegState(KillSrc));
}

/// Handle copying from SGPR to AGPR, or from AGPR to AGPR on GFX908. It is not
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,8 @@ void diagnoseUnknownMMRAASName(const MachineInstr &MI, StringRef AS) {
ListSeparator LS;
for (const auto &[Name, Val] : ASNames)
OS << LS << '\'' << Name << '\'';
DiagnosticInfoUnsupported BadTag(Fn, Str.str(), MI.getDebugLoc(), DS_Warning);
Fn.getContext().diagnose(BadTag);
Fn.getContext().diagnose(
DiagnosticInfoUnsupported(Fn, Str.str(), MI.getDebugLoc(), DS_Warning));
}

/// Reads \p MI's MMRAs to parse the "amdgpu-as" MMRA.
Expand Down Expand Up @@ -734,8 +734,8 @@ static SIAtomicAddrSpace getFenceAddrSpaceMMRA(const MachineInstr &MI,
void SIMemOpAccess::reportUnsupported(const MachineBasicBlock::iterator &MI,
const char *Msg) const {
const Function &Func = MI->getParent()->getParent()->getFunction();
DiagnosticInfoUnsupported Diag(Func, Msg, MI->getDebugLoc());
Func.getContext().diagnose(Diag);
Func.getContext().diagnose(
DiagnosticInfoUnsupported(Func, Msg, MI->getDebugLoc()));
}

std::optional<std::tuple<SIAtomicScope, SIAtomicAddrSpace, bool>>
Expand Down
Loading
Loading