Skip to content

Commit 555eacf

Browse files
committed
[clangd] Fix undefined behavior when generating error message at rename with an invalid name
`Message()` lambda uses `Reason.Details` as an input parameter for `llvm::formatv()`, but `Reason` in `Message()` is a local object. Return value of `llvm::formatv()` contains references to its input arguments, thus `Message()` returns an object which contains a reference to `Details` field of the local object `Reason`. This patch fixes this behavior by passing `Reason` as a reference to `Message()` to ensure that return value of `Message()` contains references to alive object and also prevents copying of `InvalidName` structure at passing it to `makeError()`. Provided test passes on Linux+GCC with or without this patch, but fails on Windows+VisualStudio without this patch. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D115959
1 parent 1965cc4 commit 555eacf

File tree

2 files changed

+7
-2
lines changed

2 files changed

+7
-2
lines changed

clang-tools-extra/clangd/refactor/Rename.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ std::string toString(InvalidName::Kind K) {
455455
}
456456

457457
llvm::Error makeError(InvalidName Reason) {
458-
auto Message = [](InvalidName Reason) {
458+
auto Message = [](const InvalidName &Reason) {
459459
switch (Reason.K) {
460460
case InvalidName::Keywords:
461461
return llvm::formatv("the chosen name \"{0}\" is a keyword",
@@ -733,7 +733,7 @@ llvm::Expected<RenameResult> rename(const RenameInputs &RInputs) {
733733
return makeError(ReasonToReject::SameName);
734734
auto Invalid = checkName(RenameDecl, RInputs.NewName);
735735
if (Invalid)
736-
return makeError(*Invalid);
736+
return makeError(std::move(*Invalid));
737737

738738
auto Reject = renameable(RenameDecl, RInputs.MainFilePath, RInputs.Index);
739739
if (Reject)

clang-tools-extra/clangd/unittests/RenameTests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,11 @@ TEST(RenameTest, Renameable) {
10601060
)cpp",
10611061
"conflict", !HeaderFile, "Conflict"},
10621062

1063+
{R"cpp(
1064+
int V^ar;
1065+
)cpp",
1066+
"\"const\" is a keyword", !HeaderFile, "const"},
1067+
10631068
{R"cpp(// Trying to rename into the same name, SameName == SameName.
10641069
void func() {
10651070
int S^ameName;

0 commit comments

Comments
 (0)