-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Support] Fix bugs in formatv automatic index assignment #108384
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
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-llvm-support Author: Rahul Joshi (jurahul) ChangesFix bugs found when actually trying to use formatv() automatic index assignment in IntrinsicEmitter.cpp:
Full diff: https://github.com/llvm/llvm-project/pull/108384.diff 2 Files Affected:
diff --git a/llvm/lib/Support/FormatVariadic.cpp b/llvm/lib/Support/FormatVariadic.cpp
index 3240b1c0f4e413..7c4b265b2ee228 100644
--- a/llvm/lib/Support/FormatVariadic.cpp
+++ b/llvm/lib/Support/FormatVariadic.cpp
@@ -144,6 +144,7 @@ formatv_object_base::parseFormatString(StringRef Fmt, size_t NumArgs,
bool Validate) {
SmallVector<ReplacementItem, 2> Replacements;
unsigned NextAutomaticIndex = 0;
+ bool HasExplicitIndex = false;
#if ENABLE_VALIDATION
const StringRef SavedFmtStr = Fmt;
@@ -155,14 +156,17 @@ formatv_object_base::parseFormatString(StringRef Fmt, size_t NumArgs,
std::tie(I, Fmt) = splitLiteralAndReplacement(Fmt);
if (!I)
continue;
- if (I->Index == ~0U)
- I->Index = NextAutomaticIndex++;
-
- Replacements.emplace_back(*I);
+ if (I->Type == ReplacementType::Format) {
+ if (I->Index == ~0U)
+ I->Index = NextAutomaticIndex++;
+ else
+ HasExplicitIndex = true;
#if ENABLE_VALIDATION
- if (I->Type == ReplacementType::Format)
NumExpectedArgs = std::max(NumExpectedArgs, I->Index + 1);
#endif
+ }
+
+ Replacements.emplace_back(*I);
}
#if ENABLE_VALIDATION
@@ -208,9 +212,8 @@ formatv_object_base::parseFormatString(StringRef Fmt, size_t NumArgs,
return getErrorReplacements("Replacement indices have holes");
}
- // If we had automatic numbering of replacement indices, verify that all
- // indices used automatic numbering.
- if (NextAutomaticIndex != 0 && NextAutomaticIndex != Count) {
+ // Fail validation if we see both automatic index and explicit index.
+ if (NextAutomaticIndex != 0 && HasExplicitIndex) {
errs() << formatv(
"Cannot mix automatic and explicit indices for format string '{}'\n",
SavedFmtStr);
diff --git a/llvm/unittests/Support/FormatVariadicTest.cpp b/llvm/unittests/Support/FormatVariadicTest.cpp
index 68938480ecfe20..34bfbd16bd08dd 100644
--- a/llvm/unittests/Support/FormatVariadicTest.cpp
+++ b/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -283,6 +283,15 @@ TEST(FormatVariadicTest, AutomaticIndices) {
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
+ Replacements = parseFormatString("{}bar{}");
+ ASSERT_EQ(3u, Replacements.size());
+ EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+ EXPECT_EQ(0u, Replacements[0].Index);
+ EXPECT_EQ(ReplacementType::Literal, Replacements[1].Type);
+ EXPECT_EQ("bar", Replacements[1].Spec);
+ EXPECT_EQ(ReplacementType::Format, Replacements[2].Type);
+ EXPECT_EQ(1u, Replacements[2].Index);
+
Replacements = parseFormatString("{}{}");
ASSERT_EQ(2u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -761,6 +770,8 @@ TEST(FormatVariadicTest, Validate) {
"Replacement field indices cannot have holes");
EXPECT_DEATH(formatv("{}{1}", 0, 1).str(),
"Cannot mix automatic and explicit indices");
+ EXPECT_DEATH(formatv("{}{0}{}", 0, 1).str(),
+ "Cannot mix automatic and explicit indices");
#else // GTEST_HAS_DEATH_TEST
GTEST_SKIP() << "No support for EXPECT_DEATH";
#endif // GTEST_HAS_DEATH_TEST
@@ -769,6 +780,7 @@ TEST(FormatVariadicTest, Validate) {
EXPECT_EQ(formatv("{0}", 1, 2).str(), "1");
EXPECT_EQ(formatv("{0} {2}", 1, 2, 3).str(), "1 3");
EXPECT_EQ(formatv("{}{1}", 0, 1).str(), "01");
+ EXPECT_EQ(formatv("{}{0}{}", 0, 1).str(), "001");
#endif // NDEBUG
}
|
Fix bugs found when actually trying to use formatv() automatic index assignment in IntrinsicEmitter.cpp: - Assign automatic index only for `ReplacementType::Format`. - Make the check for all replacement indices being either automatic or explicit more accurate. The existing check fails for format formatv("{}{0}{}", 0, 1) (added as a unit test). Explicitly track if we have seen any explicit and any automatic index instead.
82bafe9
to
3505bca
Compare
Friendly ping @River707 |
River707
approved these changes
Sep 17, 2024
Thanks! |
tmsri
pushed a commit
to tmsri/llvm-project
that referenced
this pull request
Sep 19, 2024
Fix bugs found when actually trying to use formatv() automatic index assignment in IntrinsicEmitter.cpp: - Assign automatic index only for `ReplacementType::Format`. - Make the check for all replacement indices being either automatic orexplicit more accurate. The existing check fails for formatv("{}{0}{}", 0, 1) (added as a unit test). Explicitly track if we have seen any explicit and any automatic index instead.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix bugs found when actually trying to use formatv() automatic index assignment in IntrinsicEmitter.cpp:
ReplacementType::Format
.The existing check fails for formatv("{}{0}{}", 0, 1) (added as a unit test). Explicitly track if we
have seen any explicit and any automatic index instead.