Add a static_assert to enforce that parameters to llvm::format() are not totally...
authorMehdi Amini <mehdi.amini@apple.com>
Thu, 6 Oct 2016 23:26:29 +0000 (23:26 +0000)
committerMehdi Amini <mehdi.amini@apple.com>
Thu, 6 Oct 2016 23:26:29 +0000 (23:26 +0000)
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

llvm/include/llvm/Support/Format.h
llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp

index d5c301c..026488c 100644 (file)
@@ -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...>());
index d53c8e3..8197285 100644 (file)
@@ -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 ");