Skip to content

Commit b0a3167

Browse files
committed
[move-only] Restructure move only diagnostics so that we can properly emit diagnostics for ref_element_addr and global_addr.
1 parent 910ca17 commit b0a3167

File tree

1 file changed

+81
-26
lines changed

1 file changed

+81
-26
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -59,30 +59,76 @@ static void diagnose(ASTContext &context, SILInstruction *inst, Diag<T...> diag,
5959
context.Diags.diagnose(loc.getSourceLoc(), diag, std::forward<U>(args)...);
6060
}
6161

62-
static StringRef getVariableNameForValue(MarkMustCheckInst *mmci) {
63-
if (auto *allocInst = dyn_cast<AllocationInst>(mmci->getOperand())) {
64-
DebugVarCarryingInst debugVar(allocInst);
65-
if (auto varInfo = debugVar.getVarInfo()) {
66-
return varInfo->Name;
67-
} else {
68-
if (auto *decl = debugVar.getDecl()) {
69-
return decl->getBaseName().userFacingName();
70-
}
62+
static void getVariableNameForValue(MarkMustCheckInst *mmci,
63+
SmallString<64> &resultingString) {
64+
// Before we do anything, lets see if we have an exact debug_value on our
65+
// mmci. In such a case, we can end early and are done.
66+
if (auto *use = getSingleDebugUse(mmci)) {
67+
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
68+
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
69+
resultingString += debugVar.getName();
70+
return;
7171
}
7272
}
7373

74-
if (auto *use = getSingleDebugUse(mmci)) {
75-
DebugVarCarryingInst debugVar(use->getUser());
76-
if (auto varInfo = debugVar.getVarInfo()) {
77-
return varInfo->Name;
78-
} else {
79-
if (auto *decl = debugVar.getDecl()) {
80-
return decl->getBaseName().userFacingName();
74+
// Otherwise, we need to look at our mark_must_check's operand.
75+
StackList<SILInstruction *> variableNamePath(mmci->getFunction());
76+
SILValue value = mmci->getOperand();
77+
while (true) {
78+
if (auto *allocInst = dyn_cast<AllocationInst>(value)) {
79+
variableNamePath.push_back(allocInst);
80+
break;
81+
}
82+
83+
if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(value)) {
84+
variableNamePath.push_back(globalAddrInst);
85+
break;
86+
}
87+
88+
if (auto *rei = dyn_cast<RefElementAddrInst>(value)) {
89+
variableNamePath.push_back(rei);
90+
value = rei->getOperand();
91+
continue;
92+
}
93+
94+
// Single value instructions we should look through.
95+
if (isa<BeginBorrowInst>(value) || isa<LoadInst>(value) ||
96+
isa<BeginAccessInst>(value) || isa<MarkMustCheckInst>(value)) {
97+
value = cast<SingleValueInstruction>(value)->getOperand(0);
98+
continue;
99+
}
100+
101+
// If we do not do an exact match, see if we can find a debug_var inst. If
102+
// we do, we always break since we have a root value.
103+
if (auto *use = getSingleDebugUse(value)) {
104+
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
105+
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
106+
variableNamePath.push_back(use->getUser());
107+
break;
81108
}
82109
}
110+
111+
// If we do not pattern match successfully, just set resulting string to
112+
// unknown and return early.
113+
resultingString += "unknown";
114+
return;
83115
}
84116

85-
return "unknown";
117+
// Walk backwards, constructing our string.
118+
while (true) {
119+
auto *next = variableNamePath.pop_back_val();
120+
121+
if (auto i = DebugVarCarryingInst(next)) {
122+
resultingString += i.getName();
123+
} else if (auto i = VarDeclCarryingInst(next)) {
124+
resultingString += i.getName();
125+
}
126+
127+
if (variableNamePath.empty())
128+
return;
129+
130+
resultingString += '.';
131+
}
86132
}
87133

88134
//===----------------------------------------------------------------------===//
@@ -113,7 +159,8 @@ void DiagnosticEmitter::emitCheckerDoesntUnderstandDiagnostic(
113159
void DiagnosticEmitter::emitObjectGuaranteedDiagnostic(
114160
MarkMustCheckInst *markedValue) {
115161
auto &astContext = fn->getASTContext();
116-
StringRef varName = getVariableNameForValue(markedValue);
162+
SmallString<64> varName;
163+
getVariableNameForValue(markedValue, varName);
117164

118165
// See if we have any closure capture uses and emit a better diagnostic.
119166
if (getCanonicalizer().hasPartialApplyConsumingUse()) {
@@ -153,7 +200,8 @@ void DiagnosticEmitter::emitObjectGuaranteedDiagnostic(
153200
void DiagnosticEmitter::emitObjectOwnedDiagnostic(
154201
MarkMustCheckInst *markedValue) {
155202
auto &astContext = fn->getASTContext();
156-
StringRef varName = getVariableNameForValue(markedValue);
203+
SmallString<64> varName;
204+
getVariableNameForValue(markedValue, varName);
157205

158206
// Ok we know that we are going to emit an error. Lets use a little more
159207
// compile time to emit a nice error.
@@ -323,7 +371,8 @@ void DiagnosticEmitter::emitAddressExclusivityHazardDiagnostic(
323371
registerDiagnosticEmitted(markedValue);
324372

325373
auto &astContext = markedValue->getFunction()->getASTContext();
326-
StringRef varName = getVariableNameForValue(markedValue);
374+
SmallString<64> varName;
375+
getVariableNameForValue(markedValue, varName);
327376

328377
LLVM_DEBUG(llvm::dbgs() << "Emitting error for exclusivity!\n");
329378
LLVM_DEBUG(llvm::dbgs() << " Mark: " << *markedValue);
@@ -345,7 +394,8 @@ void DiagnosticEmitter::emitAddressDiagnostic(MarkMustCheckInst *markedValue,
345394
registerDiagnosticEmitted(markedValue);
346395

347396
auto &astContext = markedValue->getFunction()->getASTContext();
348-
StringRef varName = getVariableNameForValue(markedValue);
397+
SmallString<64> varName;
398+
getVariableNameForValue(markedValue, varName);
349399

350400
LLVM_DEBUG(llvm::dbgs() << "Emitting error!\n");
351401
LLVM_DEBUG(llvm::dbgs() << " Mark: " << *markedValue);
@@ -434,7 +484,8 @@ void DiagnosticEmitter::emitInOutEndOfFunctionDiagnostic(
434484
"Expected markedValue to be on an inout");
435485

436486
auto &astContext = markedValue->getFunction()->getASTContext();
437-
StringRef varName = getVariableNameForValue(markedValue);
487+
SmallString<64> varName;
488+
getVariableNameForValue(markedValue, varName);
438489

439490
LLVM_DEBUG(llvm::dbgs() << "Emitting inout error error!\n");
440491
LLVM_DEBUG(llvm::dbgs() << " Mark: " << *markedValue);
@@ -468,7 +519,8 @@ void DiagnosticEmitter::emitAddressDiagnosticNoCopy(
468519
return;
469520

470521
auto &astContext = markedValue->getFunction()->getASTContext();
471-
StringRef varName = getVariableNameForValue(markedValue);
522+
SmallString<64> varName;
523+
getVariableNameForValue(markedValue, varName);
472524

473525
LLVM_DEBUG(llvm::dbgs() << "Emitting no copy error!\n");
474526
LLVM_DEBUG(llvm::dbgs() << " Mark: " << *markedValue);
@@ -491,7 +543,8 @@ void DiagnosticEmitter::emitObjectDestructureNeededWithinBorrowBoundary(
491543
return;
492544

493545
auto &astContext = markedValue->getFunction()->getASTContext();
494-
StringRef varName = getVariableNameForValue(markedValue);
546+
SmallString<64> varName;
547+
getVariableNameForValue(markedValue, varName);
495548

496549
LLVM_DEBUG(llvm::dbgs() << "Emitting destructure can't be created error!\n");
497550
LLVM_DEBUG(llvm::dbgs() << " Mark: " << *markedValue);
@@ -531,7 +584,8 @@ void DiagnosticEmitter::emitObjectInstConsumesValueTwice(
531584
<< secondUse->getOperandNumber() << '\n');
532585

533586
auto &astContext = markedValue->getModule().getASTContext();
534-
StringRef varName = getVariableNameForValue(markedValue);
587+
SmallString<64> varName;
588+
getVariableNameForValue(markedValue, varName);
535589
diagnose(astContext, markedValue,
536590
diag::sil_moveonlychecker_owned_value_consumed_more_than_once,
537591
varName);
@@ -556,7 +610,8 @@ void DiagnosticEmitter::emitObjectInstConsumesAndUsesValue(
556610
<< nonConsumingUse->getOperandNumber() << '\n');
557611

558612
auto &astContext = markedValue->getModule().getASTContext();
559-
StringRef varName = getVariableNameForValue(markedValue);
613+
SmallString<64> varName;
614+
getVariableNameForValue(markedValue, varName);
560615
diagnose(astContext, markedValue,
561616
diag::sil_moveonlychecker_owned_value_consumed_and_used_at_same_time,
562617
varName);

0 commit comments

Comments
 (0)