@@ -102,20 +102,10 @@ static tysan_type_descriptor *getRootTD(tysan_type_descriptor *TD) {
102102 return RootTD;
103103}
104104
105- static bool isAliasingLegalUp (tysan_type_descriptor *TDA,
106- tysan_type_descriptor *TDB, int TDAOffset) {
107- // Walk up the tree starting with TDA to see if we reach TDB.
108- uptr OffsetA = 0 , OffsetB = 0 ;
109- if (TDB->Tag == TYSAN_MEMBER_TD) {
110- OffsetB = TDB->Member .Offset ;
111- TDB = TDB->Member .Base ;
112- }
113-
114- if (TDA->Tag == TYSAN_MEMBER_TD) {
115- OffsetA = TDA->Member .Offset - TDAOffset;
116- TDA = TDA->Member .Base ;
117- }
118-
105+ // Walk up TDA to see if it reaches TDB.
106+ static bool walkAliasTree (tysan_type_descriptor *TDA,
107+ tysan_type_descriptor *TDB, uptr OffsetA,
108+ uptr OffsetB) {
119109 do {
120110 if (TDA == TDB)
121111 return OffsetA == OffsetB;
@@ -153,8 +143,50 @@ static bool isAliasingLegalUp(tysan_type_descriptor *TDA,
153143 return false ;
154144}
155145
146+ // Walk up the tree starting with TDA to see if we reach TDB.
147+ static bool isAliasingLegalUp (tysan_type_descriptor *TDA,
148+ tysan_type_descriptor *TDB) {
149+ uptr OffsetA = 0 , OffsetB = 0 ;
150+ if (TDB->Tag == TYSAN_MEMBER_TD) {
151+ OffsetB = TDB->Member .Offset ;
152+ TDB = TDB->Member .Base ;
153+ }
154+
155+ if (TDA->Tag == TYSAN_MEMBER_TD) {
156+ OffsetA = TDA->Member .Offset ;
157+ TDA = TDA->Member .Base ;
158+ }
159+
160+ return walkAliasTree (TDA, TDB, OffsetA, OffsetB);
161+ }
162+
163+ static bool isAliasingLegalWithOffset (tysan_type_descriptor *TDA,
164+ tysan_type_descriptor *TDB,
165+ uptr OffsetB) {
166+ // This is handled by calls to isAliasingLegalUp.
167+ if (OffsetB == 0 )
168+ return false ;
169+
170+ // You can't have an offset into a member.
171+ if (TDB->Tag == TYSAN_MEMBER_TD)
172+ return false ;
173+
174+ uptr OffsetA = 0 ;
175+ if (TDA->Tag == TYSAN_MEMBER_TD) {
176+ OffsetA = TDA->Member .Offset ;
177+ TDA = TDA->Member .Base ;
178+ }
179+
180+ // Since the access was partially inside TDB (the shadow), it can be assumed
181+ // that we are accessing a member in an object. This means that rather than
182+ // walk up the scalar access TDA to reach an object, we should walk up the
183+ // object TBD to reach the scalar we are accessing it with. The offsets will
184+ // still be checked at the end to make sure this alias is legal.
185+ return walkAliasTree (TDB, TDA, OffsetB, OffsetA);
186+ }
187+
156188static bool isAliasingLegal (tysan_type_descriptor *TDA,
157- tysan_type_descriptor *TDB, int TDAOffset = 0 ) {
189+ tysan_type_descriptor *TDB, uptr OffsetB = 0 ) {
158190 if (TDA == TDB || !TDB || !TDA)
159191 return true ;
160192
@@ -165,8 +197,8 @@ static bool isAliasingLegal(tysan_type_descriptor *TDA,
165197 // TDB may have been adjusted by offset TDAOffset in the caller to point to
166198 // the outer type. Check for aliasing with and without adjusting for this
167199 // offset.
168- return isAliasingLegalUp (TDA, TDB, 0 ) || isAliasingLegalUp (TDB, TDA, 0 ) ||
169- isAliasingLegalUp (TDA, TDB, TDAOffset );
200+ return isAliasingLegalUp (TDA, TDB) || isAliasingLegalUp (TDB, TDA) ||
201+ isAliasingLegalWithOffset (TDA, TDB, OffsetB );
170202}
171203
172204namespace __tysan {
0 commit comments