@@ -102,20 +102,10 @@ static tysan_type_descriptor *getRootTD(tysan_type_descriptor *TD) {
102
102
return RootTD;
103
103
}
104
104
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
+ bool walkAliasTree (
106
+ tysan_type_descriptor* TDA, tysan_type_descriptor* TDB,
107
+ uptr OffsetA, uptr OffsetB
108
+ ){
119
109
do {
120
110
if (TDA == TDB)
121
111
return OffsetA == OffsetB;
@@ -153,8 +143,43 @@ static bool isAliasingLegalUp(tysan_type_descriptor *TDA,
153
143
return false ;
154
144
}
155
145
146
+ static bool isAliasingLegalUp (tysan_type_descriptor *TDA,
147
+ tysan_type_descriptor *TDB) {
148
+ // Walk up the tree starting with TDA to see if we reach 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 *AccessTD, tysan_type_descriptor *ShadowTD, int OffsetInShadow){
164
+ // This is handled in the other cases
165
+ if (OffsetInShadow == 0 )
166
+ return false ;
167
+
168
+ // You can't have an offset into a member
169
+ if (ShadowTD->Tag == TYSAN_MEMBER_TD)
170
+ return false ;
171
+
172
+ int OffsetInAccess = 0 ;
173
+ if (AccessTD->Tag == TYSAN_MEMBER_TD){
174
+ OffsetInAccess = AccessTD->Member .Offset ;
175
+ AccessTD = AccessTD->Member .Base ;
176
+ }
177
+
178
+ return walkAliasTree (ShadowTD, AccessTD, OffsetInShadow, OffsetInAccess);
179
+ }
180
+
156
181
static bool isAliasingLegal (tysan_type_descriptor *TDA,
157
- tysan_type_descriptor *TDB, int TDAOffset = 0 ) {
182
+ tysan_type_descriptor *TDB) {
158
183
if (TDA == TDB || !TDB || !TDA)
159
184
return true ;
160
185
@@ -165,8 +190,7 @@ static bool isAliasingLegal(tysan_type_descriptor *TDA,
165
190
// TDB may have been adjusted by offset TDAOffset in the caller to point to
166
191
// the outer type. Check for aliasing with and without adjusting for this
167
192
// offset.
168
- return isAliasingLegalUp (TDA, TDB, 0 ) || isAliasingLegalUp (TDB, TDA, 0 ) ||
169
- isAliasingLegalUp (TDA, TDB, TDAOffset);
193
+ return isAliasingLegalUp (TDA, TDB) || isAliasingLegalUp (TDB, TDA);
170
194
}
171
195
172
196
namespace __tysan {
@@ -243,7 +267,7 @@ __tysan_check(void *addr, int size, tysan_type_descriptor *td, int flags) {
243
267
OldTDPtr -= i;
244
268
OldTD = *OldTDPtr;
245
269
246
- if (!isAliasingLegal (td, OldTD, i))
270
+ if (!isAliasingLegal (td, OldTD) && ! isAliasingLegalWithOffset (td, OldTD , i))
247
271
reportError (addr, size, td, OldTD, AccessStr,
248
272
" accesses part of an existing object" , -i, pc, bp, sp);
249
273
0 commit comments