@@ -820,6 +820,11 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
820
820
// / fix this for each of its uses.
821
821
llvm::DenseSet<std::pair<SILValue, const Operand *>> isOperandInValueUsesCache;
822
822
823
+ // / Used for checking all equivalent variables have the same type
824
+ using VarID = std::tuple<const SILDebugScope *, llvm::StringRef, SILLocation>;
825
+ llvm::DenseMap<VarID, SILType> DebugVarTypes;
826
+ llvm::StringSet<> VarNames;
827
+
823
828
// / Check that this operand appears in the use-chain of the value it uses.
824
829
bool isOperandInValueUses (const Operand *operand) {
825
830
SILValue value = operand->get ();
@@ -1520,6 +1525,26 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1520
1525
" Scope of the debug variable should have the same parent function"
1521
1526
" as that of instruction." );
1522
1527
1528
+ // Check that every var info with the same name, scope and location, refer
1529
+ // to a variable of the same type
1530
+ llvm::StringRef UniqueName = VarNames.insert (varInfo->Name ).first ->getKey ();
1531
+ if (!varInfo->Loc )
1532
+ varInfo->Loc = inst->getLoc ();
1533
+ if (!varInfo->Loc )
1534
+ varInfo->Loc = SILLocation::invalid ();
1535
+ VarID Key (varInfo->Scope ? varInfo->Scope : debugScope,
1536
+ UniqueName, *varInfo->Loc );
1537
+ auto CachedVar = DebugVarTypes.insert ({Key, DebugVarTy});
1538
+ if (!CachedVar.second ) {
1539
+ auto lhs = CachedVar.first ->second .removingMoveOnlyWrapper ();
1540
+ auto rhs = DebugVarTy.removingMoveOnlyWrapper ();
1541
+
1542
+ require (lhs == rhs ||
1543
+ (lhs.isAddress () && lhs.getObjectType () == rhs) ||
1544
+ (DebugVarTy.isAddress () && lhs == rhs.getObjectType ()),
1545
+ " Two variables with different type but same scope!" );
1546
+ }
1547
+
1523
1548
// Check debug info expression
1524
1549
if (const auto &DIExpr = varInfo->DIExpr ) {
1525
1550
bool HasFragment = false ;
0 commit comments