[llvm] [llvm][Support] Create llvm::formatv variant of llvm::createStringError (PR #176407)
Michael Buch via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 16 07:55:58 PST 2026
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/176407
>From 823144669e583f38cfcb66b4c8d04b2ec523dea4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 16 Jan 2026 15:26:58 +0000
Subject: [PATCH 1/3] [llvm][Support] Create llvm::formatv variant of
llvm::createStringError
Currently `llvm::createStringError` only supports printf format specifiers because it forwards to `llvm::format`.
In LLDB we've been using `llvm::createStringError(llvm::formatv(...),
...` to work around this. It would be convenient to have a version of
the API that takes LLVM format specifiers, so we benefit from the
advantages that come with those.
This patch adds a new `llvm::createStringErrorV` which forwards to
`llvm::formatv` (hence the `V` suffix in the name). I only implemented
`V` variants for the `llvm::createStringError` APIs that take a format
string argument.
As a side-note, `llvm/lib/Frontend/Offloading/PropertySet.cpp`
implements it's own variant of this function (and also calls it
`createStringErrorV`). This patch would allow us to clean that up as
well.
---
llvm/include/llvm/Support/Error.h | 17 +++++++++++++++++
llvm/unittests/Support/ErrorTest.cpp | 21 +++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index c9fd16fdb7c2b..4e2753272514b 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -21,6 +21,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
@@ -1335,6 +1336,22 @@ inline Error createStringError(std::errc EC, char const *Fmt,
return createStringError(std::make_error_code(EC), Fmt, Vals...);
}
+// LLVM formatv versions of llvm::createStringError
+
+template <typename... Ts>
+inline Error createStringErrorV(std::error_code EC, char const *Fmt,
+ Ts &&...Vals) {
+ std::string Buffer;
+ raw_string_ostream(Buffer) << formatv(Fmt, std::forward<Ts>(Vals)...);
+ return make_error<StringError>(std::move(Buffer), EC, true);
+}
+
+template <typename... Ts>
+inline Error createStringErrorV(char const *Fmt, Ts &&...Vals) {
+ return createStringErrorV(llvm::inconvertibleErrorCode(), Fmt,
+ std::forward<Ts>(Vals)...);
+}
+
/// This class wraps a filename and another Error.
///
/// In some cases, an error needs to live along a 'source' name, in order to
diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp
index 00c562ecc059d..8454bae666fcb 100644
--- a/llvm/unittests/Support/ErrorTest.cpp
+++ b/llvm/unittests/Support/ErrorTest.cpp
@@ -471,6 +471,27 @@ TEST(Error, createStringError) {
<< "Failed to convert createStringError() result to error_code.";
}
+TEST(Error, createStringErrorV) {
+ static const char *Bar = "bar";
+ static const std::error_code EC = errc::invalid_argument;
+ std::string Msg;
+ raw_string_ostream S(Msg);
+ logAllUnhandledErrors(createStringErrorV(EC, "foo{0}{1}{2:x}", Bar, 1, 0xff),
+ S);
+ EXPECT_EQ(Msg, "foobar10xff\n")
+ << "Unexpected createStringError() log result";
+
+ Msg.clear();
+ auto Res = errorToErrorCode(createStringError(EC, "foo{0}", Bar));
+ EXPECT_EQ(Res, EC)
+ << "Failed to convert createStringError() result to error_code.";
+
+ Msg.clear();
+ logAllUnhandledErrors(createStringErrorV("foo{0}{1}{2:x}", Bar, 1, 0xff), S);
+ EXPECT_EQ(Msg, "foobar10xff\n")
+ << "Unexpected createStringError() (no EC overload) log result";
+}
+
// Test that the ExitOnError utility works as expected.
TEST(ErrorDeathTest, ExitOnError) {
ExitOnError ExitOnErr;
>From 6d8b45d6c030ccceccd4a78eab7bcdd7566d5a97 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 16 Jan 2026 15:51:54 +0000
Subject: [PATCH 2/3] fixup! don't use intermediate std::string buffer
Co-authored-by: Jakub Kuderski <kubakuderski at gmail.com>
---
llvm/include/llvm/Support/Error.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index 4e2753272514b..828d1075c99f2 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -1341,9 +1341,7 @@ inline Error createStringError(std::errc EC, char const *Fmt,
template <typename... Ts>
inline Error createStringErrorV(std::error_code EC, char const *Fmt,
Ts &&...Vals) {
- std::string Buffer;
- raw_string_ostream(Buffer) << formatv(Fmt, std::forward<Ts>(Vals)...);
- return make_error<StringError>(std::move(Buffer), EC, true);
+ return make_error<StringError>(formatv(Fmt, std::forward<Ts>(Vals)...).str(), EC, true);
}
template <typename... Ts>
>From 07e384291719af6ddd80654e2491762c636d09d5 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 16 Jan 2026 15:55:45 +0000
Subject: [PATCH 3/3] fixup! clang-format
---
llvm/include/llvm/Support/Error.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index 828d1075c99f2..6638c919e2965 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -1341,7 +1341,8 @@ inline Error createStringError(std::errc EC, char const *Fmt,
template <typename... Ts>
inline Error createStringErrorV(std::error_code EC, char const *Fmt,
Ts &&...Vals) {
- return make_error<StringError>(formatv(Fmt, std::forward<Ts>(Vals)...).str(), EC, true);
+ return make_error<StringError>(formatv(Fmt, std::forward<Ts>(Vals)...).str(),
+ EC, true);
}
template <typename... Ts>
More information about the llvm-commits
mailing list