forked from OSchip/llvm-project
Add a static_assert to enforce that parameters to llvm::format() are not totally unsafe
Summary: I had for the second time today a bug where llvm::format("%s", Str) was called with Str being a StringRef. The Linux and MacOS bots were fine, but windows having different calling convention, it printed garbage. Instead we can catch this at compile-time: it is never expected to call a C vararg printf-like function with non scalar type I believe. Reviewers: bogner, Bigcheese, dexonsmith Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D25266 llvm-svn: 283509
This commit is contained in:
parent
e15a370084
commit
a7e893f638
|
@ -75,6 +75,16 @@ public:
|
|||
/// printed, this synthesizes the string into a temporary buffer provided and
|
||||
/// returns whether or not it is big enough.
|
||||
|
||||
// Helper to validate that format() parameters are scalars or pointers.
|
||||
template <typename... Args> struct validate_format_parameters;
|
||||
template <typename Arg, typename... Args>
|
||||
struct validate_format_parameters<Arg, Args...> {
|
||||
static_assert(std::is_scalar<Arg>::value,
|
||||
"format can't be used with non fundamental / non pointer type");
|
||||
validate_format_parameters() { validate_format_parameters<Args...>(); }
|
||||
};
|
||||
template <> struct validate_format_parameters<> {};
|
||||
|
||||
template <typename... Ts>
|
||||
class format_object final : public format_object_base {
|
||||
std::tuple<Ts...> Vals;
|
||||
|
@ -91,7 +101,9 @@ class format_object final : public format_object_base {
|
|||
|
||||
public:
|
||||
format_object(const char *fmt, const Ts &... vals)
|
||||
: format_object_base(fmt), Vals(vals...) {}
|
||||
: format_object_base(fmt), Vals(vals...) {
|
||||
validate_format_parameters<Ts...>();
|
||||
}
|
||||
|
||||
int snprint(char *Buffer, unsigned BufferSize) const override {
|
||||
return snprint_tuple(Buffer, BufferSize, index_sequence_for<Ts...>());
|
||||
|
|
|
@ -962,7 +962,8 @@ void PPCVSXSwapRemoval::dumpSwapVector() {
|
|||
DEBUG(dbgs() << format("%6d", ID));
|
||||
DEBUG(dbgs() << format("%6d", EC->getLeaderValue(ID)));
|
||||
DEBUG(dbgs() << format(" BB#%3d", MI->getParent()->getNumber()));
|
||||
DEBUG(dbgs() << format(" %14s ", TII->getName(MI->getOpcode())));
|
||||
DEBUG(dbgs() << format(" %14s ",
|
||||
TII->getName(MI->getOpcode()).str().c_str()));
|
||||
|
||||
if (SwapVector[EntryIdx].IsLoad)
|
||||
DEBUG(dbgs() << "load ");
|
||||
|
|
Loading…
Reference in New Issue