Skip to content

Commit 7327ce4

Browse files
committed
Stop abusing Twine in DiagnosticInfo
This switches the various DiagnosticInfo subclasses that store an un-owned string to use StringRef for this instead of Twine. Storing a `Twine &` like most of these were doing makes it very easy to introduce memory corruption bugs: ```c++ void f(std::string &Msg) { auto Diag = DiagnosticInfoGeneric(Msg); Ctx.diagnose(Diag); // Bug! We're referring to the temporary Twine! Ctx.diagnose(DiagnosticInfoGeneric(Msg); // this works, I guess... }; ``` This was sort of mitigated in DiagnosticInfoUnsupported, which actually copies the Twine, but copying Twines is always a questionable practice. Instead, we store a StringRef, which makes it much more explicit that ownership of the storage is the caller's problem.
1 parent 5dcfa61 commit 7327ce4

File tree

11 files changed

+137
-130
lines changed

11 files changed

+137
-130
lines changed

llvm/include/llvm/IR/DiagnosticInfo.h

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "llvm/ADT/ArrayRef.h"
1919
#include "llvm/ADT/SmallVector.h"
2020
#include "llvm/ADT/StringRef.h"
21-
#include "llvm/ADT/Twine.h"
2221
#include "llvm/IR/DebugLoc.h"
2322
#include "llvm/Support/CBindingWrapping.h"
2423
#include "llvm/Support/ErrorHandling.h"
@@ -139,22 +138,22 @@ class DiagnosticInfo {
139138
using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
140139

141140
class DiagnosticInfoGeneric : public DiagnosticInfo {
142-
const Twine &MsgStr;
141+
StringRef MsgStr;
143142
const Instruction *Inst = nullptr;
144143

145144
public:
146145
/// \p MsgStr is the message to be reported to the frontend.
147146
/// This class does not copy \p MsgStr, therefore the reference must be valid
148147
/// for the whole life time of the Diagnostic.
149-
DiagnosticInfoGeneric(const Twine &MsgStr,
148+
DiagnosticInfoGeneric(StringRef MsgStr,
150149
DiagnosticSeverity Severity = DS_Error)
151150
: DiagnosticInfo(DK_Generic, Severity), MsgStr(MsgStr) {}
152151

153-
DiagnosticInfoGeneric(const Instruction *I, const Twine &ErrMsg,
152+
DiagnosticInfoGeneric(const Instruction *I, StringRef ErrMsg,
154153
DiagnosticSeverity Severity = DS_Error)
155154
: DiagnosticInfo(DK_Generic, Severity), MsgStr(ErrMsg), Inst(I) {}
156155

157-
const Twine &getMsgStr() const { return MsgStr; }
156+
StringRef getMsgStr() const { return MsgStr; }
158157
const Instruction *getInstruction() const { return Inst; }
159158

160159
/// \see DiagnosticInfo::print.
@@ -172,7 +171,7 @@ class DiagnosticInfoInlineAsm : public DiagnosticInfo {
172171
/// Optional line information. 0 if not set.
173172
uint64_t LocCookie = 0;
174173
/// Message to be reported.
175-
const Twine &MsgStr;
174+
StringRef MsgStr;
176175
/// Optional origin of the problem.
177176
const Instruction *Instr = nullptr;
178177

@@ -181,19 +180,19 @@ class DiagnosticInfoInlineAsm : public DiagnosticInfo {
181180
/// \p MsgStr gives the message.
182181
/// This class does not copy \p MsgStr, therefore the reference must be valid
183182
/// for the whole life time of the Diagnostic.
184-
DiagnosticInfoInlineAsm(uint64_t LocCookie, const Twine &MsgStr,
183+
DiagnosticInfoInlineAsm(uint64_t LocCookie, StringRef MsgStr,
185184
DiagnosticSeverity Severity = DS_Error);
186185

187186
/// \p Instr gives the original instruction that triggered the diagnostic.
188187
/// \p MsgStr gives the message.
189188
/// This class does not copy \p MsgStr, therefore the reference must be valid
190189
/// for the whole life time of the Diagnostic.
191190
/// Same for \p I.
192-
DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
191+
DiagnosticInfoInlineAsm(const Instruction &I, StringRef MsgStr,
193192
DiagnosticSeverity Severity = DS_Error);
194193

195194
uint64_t getLocCookie() const { return LocCookie; }
196-
const Twine &getMsgStr() const { return MsgStr; }
195+
StringRef getMsgStr() const { return MsgStr; }
197196
const Instruction *getInstruction() const { return Instr; }
198197

199198
/// \see DiagnosticInfo::print.
@@ -258,15 +257,15 @@ class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
258257
class DiagnosticInfoSampleProfile : public DiagnosticInfo {
259258
public:
260259
DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
261-
const Twine &Msg,
260+
StringRef Msg,
262261
DiagnosticSeverity Severity = DS_Error)
263262
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
264263
LineNum(LineNum), Msg(Msg) {}
265-
DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
264+
DiagnosticInfoSampleProfile(StringRef FileName, StringRef Msg,
266265
DiagnosticSeverity Severity = DS_Error)
267266
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
268267
Msg(Msg) {}
269-
DiagnosticInfoSampleProfile(const Twine &Msg,
268+
DiagnosticInfoSampleProfile(StringRef Msg,
270269
DiagnosticSeverity Severity = DS_Error)
271270
: DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
272271

@@ -279,7 +278,7 @@ class DiagnosticInfoSampleProfile : public DiagnosticInfo {
279278

280279
StringRef getFileName() const { return FileName; }
281280
unsigned getLineNum() const { return LineNum; }
282-
const Twine &getMsg() const { return Msg; }
281+
StringRef getMsg() const { return Msg; }
283282

284283
private:
285284
/// Name of the input file associated with this diagnostic.
@@ -290,13 +289,13 @@ class DiagnosticInfoSampleProfile : public DiagnosticInfo {
290289
unsigned LineNum = 0;
291290

292291
/// Message to report.
293-
const Twine &Msg;
292+
StringRef Msg;
294293
};
295294

296295
/// Diagnostic information for the PGO profiler.
297296
class DiagnosticInfoPGOProfile : public DiagnosticInfo {
298297
public:
299-
DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
298+
DiagnosticInfoPGOProfile(const char *FileName, StringRef Msg,
300299
DiagnosticSeverity Severity = DS_Error)
301300
: DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
302301

@@ -308,14 +307,14 @@ class DiagnosticInfoPGOProfile : public DiagnosticInfo {
308307
}
309308

310309
const char *getFileName() const { return FileName; }
311-
const Twine &getMsg() const { return Msg; }
310+
StringRef getMsg() const { return Msg; }
312311

313312
private:
314313
/// Name of the input file associated with this diagnostic.
315314
const char *FileName;
316315

317316
/// Message to report.
318-
const Twine &Msg;
317+
StringRef Msg;
319318
};
320319

321320
class DiagnosticLocation {
@@ -364,7 +363,7 @@ class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
364363

365364
/// Return the absolute path tot the file.
366365
std::string getAbsolutePath() const;
367-
366+
368367
const Function &getFunction() const { return Fn; }
369368
DiagnosticLocation getLocation() const { return Loc; }
370369

@@ -379,19 +378,19 @@ class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
379378
class DiagnosticInfoGenericWithLoc : public DiagnosticInfoWithLocationBase {
380379
private:
381380
/// Message to be reported.
382-
const Twine &MsgStr;
381+
StringRef MsgStr;
383382

384383
public:
385384
/// \p MsgStr is the message to be reported to the frontend.
386385
/// This class does not copy \p MsgStr, therefore the reference must be valid
387386
/// for the whole life time of the Diagnostic.
388-
DiagnosticInfoGenericWithLoc(const Twine &MsgStr, const Function &Fn,
387+
DiagnosticInfoGenericWithLoc(StringRef MsgStr, const Function &Fn,
389388
const DiagnosticLocation &Loc,
390389
DiagnosticSeverity Severity = DS_Error)
391390
: DiagnosticInfoWithLocationBase(DK_GenericWithLoc, Severity, Fn, Loc),
392391
MsgStr(MsgStr) {}
393392

394-
const Twine &getMsgStr() const { return MsgStr; }
393+
StringRef getMsgStr() const { return MsgStr; }
395394

396395
/// \see DiagnosticInfo::print.
397396
void print(DiagnosticPrinter &DP) const override;
@@ -404,20 +403,20 @@ class DiagnosticInfoGenericWithLoc : public DiagnosticInfoWithLocationBase {
404403
class DiagnosticInfoRegAllocFailure : public DiagnosticInfoWithLocationBase {
405404
private:
406405
/// Message to be reported.
407-
const Twine &MsgStr;
406+
StringRef MsgStr;
408407

409408
public:
410409
/// \p MsgStr is the message to be reported to the frontend.
411410
/// This class does not copy \p MsgStr, therefore the reference must be valid
412411
/// for the whole life time of the Diagnostic.
413-
DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
412+
DiagnosticInfoRegAllocFailure(StringRef MsgStr, const Function &Fn,
414413
const DiagnosticLocation &DL,
415414
DiagnosticSeverity Severity = DS_Error);
416415

417-
DiagnosticInfoRegAllocFailure(const Twine &MsgStr, const Function &Fn,
416+
DiagnosticInfoRegAllocFailure(StringRef MsgStr, const Function &Fn,
418417
DiagnosticSeverity Severity = DS_Error);
419418

420-
const Twine &getMsgStr() const { return MsgStr; }
419+
StringRef getMsgStr() const { return MsgStr; }
421420

422421
/// \see DiagnosticInfo::print.
423422
void print(DiagnosticPrinter &DP) const override;
@@ -707,7 +706,7 @@ class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
707706
DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
708707
enum DiagnosticSeverity Severity,
709708
const char *PassName, const Function &Fn,
710-
const DiagnosticLocation &Loc, const Twine &Msg)
709+
const DiagnosticLocation &Loc, StringRef Msg)
711710
: DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
712711
*this << Msg.str();
713712
}
@@ -764,7 +763,7 @@ class OptimizationRemark : public DiagnosticInfoIROptimization {
764763
/// Note that this class does not copy this message, so this reference
765764
/// must be valid for the whole life time of the diagnostic.
766765
OptimizationRemark(const char *PassName, const Function &Fn,
767-
const DiagnosticLocation &Loc, const Twine &Msg)
766+
const DiagnosticLocation &Loc, StringRef Msg)
768767
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
769768
Fn, Loc, Msg) {}
770769
};
@@ -810,7 +809,7 @@ class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
810809
/// Note that this class does not copy this message, so this reference
811810
/// must be valid for the whole life time of the diagnostic.
812811
OptimizationRemarkMissed(const char *PassName, const Function &Fn,
813-
const DiagnosticLocation &Loc, const Twine &Msg)
812+
const DiagnosticLocation &Loc, StringRef Msg)
814813
: DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
815814
PassName, Fn, Loc, Msg) {}
816815
};
@@ -863,7 +862,7 @@ class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
863862
protected:
864863
OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
865864
const Function &Fn, const DiagnosticLocation &Loc,
866-
const Twine &Msg)
865+
StringRef Msg)
867866
: DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
868867

869868
OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
@@ -882,7 +881,7 @@ class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
882881
/// this class does not copy this message, so this reference must be valid for
883882
/// the whole life time of the diagnostic.
884883
OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
885-
const DiagnosticLocation &Loc, const Twine &Msg)
884+
const DiagnosticLocation &Loc, StringRef Msg)
886885
: DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
887886
PassName, Fn, Loc, Msg) {}
888887
};
@@ -924,7 +923,7 @@ class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
924923
/// diagnostic.
925924
OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
926925
const DiagnosticLocation &Loc,
927-
const Twine &Msg)
926+
StringRef Msg)
928927
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
929928
PassName, Fn, Loc, Msg) {}
930929
};
@@ -965,7 +964,7 @@ class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
965964
/// diagnostic.
966965
OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
967966
const DiagnosticLocation &Loc,
968-
const Twine &Msg)
967+
StringRef Msg)
969968
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
970969
PassName, Fn, Loc, Msg) {}
971970
};
@@ -991,10 +990,10 @@ class DiagnosticInfoMIRParser : public DiagnosticInfo {
991990

992991
/// Diagnostic information for IR instrumentation reporting.
993992
class DiagnosticInfoInstrumentation : public DiagnosticInfo {
994-
const Twine &Msg;
993+
StringRef Msg;
995994

996995
public:
997-
DiagnosticInfoInstrumentation(const Twine &DiagMsg,
996+
DiagnosticInfoInstrumentation(StringRef DiagMsg,
998997
DiagnosticSeverity Severity = DS_Warning)
999998
: DiagnosticInfo(DK_Instrumentation, Severity), Msg(DiagMsg) {}
1000999

@@ -1038,7 +1037,7 @@ class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
10381037
/// of the diagnostic.
10391038
DiagnosticInfoOptimizationFailure(const Function &Fn,
10401039
const DiagnosticLocation &Loc,
1041-
const Twine &Msg)
1040+
StringRef Msg)
10421041
: DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
10431042
nullptr, Fn, Loc, Msg) {}
10441043

@@ -1062,7 +1061,7 @@ class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
10621061
/// Diagnostic information for unsupported feature in backend.
10631062
class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
10641063
private:
1065-
Twine Msg;
1064+
StringRef Msg;
10661065

10671066
public:
10681067
/// \p Fn is the function where the diagnostic is being emitted. \p Loc is
@@ -1072,7 +1071,7 @@ class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
10721071
/// copy this message, so this reference must be valid for the whole life time
10731072
/// of the diagnostic.
10741073
DiagnosticInfoUnsupported(
1075-
const Function &Fn, const Twine &Msg,
1074+
const Function &Fn, StringRef Msg,
10761075
const DiagnosticLocation &Loc = DiagnosticLocation(),
10771076
DiagnosticSeverity Severity = DS_Error)
10781077
: DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
@@ -1082,15 +1081,15 @@ class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
10821081
return DI->getKind() == DK_Unsupported;
10831082
}
10841083

1085-
const Twine &getMessage() const { return Msg; }
1084+
const StringRef getMessage() const { return Msg; }
10861085

10871086
void print(DiagnosticPrinter &DP) const override;
10881087
};
10891088

10901089
/// Diagnostic information for MisExpect analysis.
10911090
class DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase {
10921091
public:
1093-
DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg);
1092+
DiagnosticInfoMisExpect(const Instruction *Inst, StringRef Msg);
10941093

10951094
/// \see DiagnosticInfo::print.
10961095
void print(DiagnosticPrinter &DP) const override;
@@ -1099,11 +1098,11 @@ class DiagnosticInfoMisExpect : public DiagnosticInfoWithLocationBase {
10991098
return DI->getKind() == DK_MisExpect;
11001099
}
11011100

1102-
const Twine &getMsg() const { return Msg; }
1101+
StringRef getMsg() const { return Msg; }
11031102

11041103
private:
11051104
/// Message to report.
1106-
const Twine &Msg;
1105+
StringRef Msg;
11071106
};
11081107

11091108
static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {

llvm/include/llvm/ProfileData/SampleProfReader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,9 @@ class SampleProfileReader {
449449

450450
/// Report a parse error message.
451451
void reportError(int64_t LineNumber, const Twine &Msg) const {
452-
Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(),
453-
LineNumber, Msg));
452+
SmallString<128> Storage;
453+
Ctx.diagnose(DiagnosticInfoSampleProfile(
454+
Buffer->getBufferIdentifier(), LineNumber, Msg.toStringRef(Storage)));
454455
}
455456

456457
/// Create a sample profile reader appropriate to the file format.

0 commit comments

Comments
 (0)