@@ -792,6 +792,32 @@ static void checkAddressWalkerCanVisitAllTransitiveUses(SILValue address) {
792
792
llvm::report_fatal_error (" invoking standard assertion failure" );
793
793
}
794
794
795
+ } // end anonymous namespace
796
+
797
+ namespace llvm {
798
+
799
+ template <>
800
+ struct DenseMapInfo <SILLocation> {
801
+ static inline SILLocation getEmptyKey () {
802
+ return SILLocation::invalid ();
803
+ }
804
+ static inline SILLocation getTombstoneKey () {
805
+ return SILLocation::invalid ().asAutoGenerated ();
806
+ }
807
+ static inline unsigned getHashValue (SILLocation id) {
808
+ if (id.isFilenameAndLocation ())
809
+ return hash_value (id);
810
+ return 0 ;
811
+ }
812
+ static bool isEqual (SILLocation a, SILLocation b) {
813
+ return a == b;
814
+ }
815
+ };
816
+
817
+ } // end namespace llvm
818
+
819
+ namespace {
820
+
795
821
// / The SIL verifier walks over a SIL function / basic block / instruction,
796
822
// / checking and enforcing its invariants.
797
823
class SILVerifier : public SILVerifierBase <SILVerifier> {
@@ -820,6 +846,11 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
820
846
// / fix this for each of its uses.
821
847
llvm::DenseSet<std::pair<SILValue, const Operand *>> isOperandInValueUsesCache;
822
848
849
+ // / Used for checking all equivalent variables have the same type
850
+ using VarID = std::tuple<const SILDebugScope *, llvm::StringRef, SILLocation>;
851
+ llvm::DenseMap<VarID, SILType> DebugVarTypes;
852
+ llvm::StringSet<> VarNames;
853
+
823
854
// / Check that this operand appears in the use-chain of the value it uses.
824
855
bool isOperandInValueUses (const Operand *operand) {
825
856
SILValue value = operand->get ();
@@ -1520,6 +1551,26 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1520
1551
" Scope of the debug variable should have the same parent function"
1521
1552
" as that of instruction." );
1522
1553
1554
+ // Check that every var info with the same name, scope and location, refer
1555
+ // to a variable of the same type
1556
+ llvm::StringRef UniqueName = VarNames.insert (varInfo->Name ).first ->getKey ();
1557
+ if (!varInfo->Loc )
1558
+ varInfo->Loc = inst->getLoc ();
1559
+ if (!varInfo->Loc )
1560
+ varInfo->Loc = SILLocation::invalid ();
1561
+ VarID Key (varInfo->Scope ? varInfo->Scope : debugScope,
1562
+ UniqueName, *varInfo->Loc );
1563
+ auto CachedVar = DebugVarTypes.insert ({Key, DebugVarTy});
1564
+ if (!CachedVar.second ) {
1565
+ auto lhs = CachedVar.first ->second .removingMoveOnlyWrapper ();
1566
+ auto rhs = DebugVarTy.removingMoveOnlyWrapper ();
1567
+
1568
+ require (lhs == rhs ||
1569
+ (lhs.isAddress () && lhs.getObjectType () == rhs) ||
1570
+ (DebugVarTy.isAddress () && lhs == rhs.getObjectType ()),
1571
+ " Two variables with different type but same scope!" );
1572
+ }
1573
+
1523
1574
// Check debug info expression
1524
1575
if (const auto &DIExpr = varInfo->DIExpr ) {
1525
1576
bool HasFragment = false ;
0 commit comments