@@ -1272,8 +1272,58 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
1272
1272
EmitCheck (std::make_pair (Check, CheckKind), CheckHandler, StaticData, Index);
1273
1273
}
1274
1274
1275
- void CodeGenFunction::EmitAllocTokenHint (llvm::CallBase *CB,
1276
- QualType AllocType) {
1275
+ static bool
1276
+ typeContainsPointer (QualType T,
1277
+ llvm::SmallPtrSet<const RecordDecl *, 4 > &VisitedRD,
1278
+ bool &IncompleteType) {
1279
+ QualType CanonicalType = T.getCanonicalType ();
1280
+ if (CanonicalType->isPointerType ())
1281
+ return true ; // base case
1282
+
1283
+ // Look through typedef chain to check for special types.
1284
+ for (QualType CurrentT = T; const auto *TT = CurrentT->getAs <TypedefType>();
1285
+ CurrentT = TT->getDecl ()->getUnderlyingType ()) {
1286
+ const IdentifierInfo *II = TT->getDecl ()->getIdentifier ();
1287
+ if (!II)
1288
+ continue ;
1289
+ // Special Case: Syntactically uintptr_t is not a pointer; semantically,
1290
+ // however, very likely used as such. Therefore, classify uintptr_t as a
1291
+ // pointer, too.
1292
+ if (II->isStr (" uintptr_t" ))
1293
+ return true ;
1294
+ }
1295
+
1296
+ // The type is an array; check the element type.
1297
+ if (const ArrayType *AT = CanonicalType->getAsArrayTypeUnsafe ())
1298
+ return typeContainsPointer (AT->getElementType (), VisitedRD, IncompleteType);
1299
+ // The type is a struct, class, or union.
1300
+ if (const RecordDecl *RD = CanonicalType->getAsRecordDecl ()) {
1301
+ if (!RD->isCompleteDefinition ()) {
1302
+ IncompleteType = true ;
1303
+ return false ;
1304
+ }
1305
+ if (!VisitedRD.insert (RD).second )
1306
+ return false ; // already visited
1307
+ // Check all fields.
1308
+ for (const FieldDecl *Field : RD->fields ()) {
1309
+ if (typeContainsPointer (Field->getType (), VisitedRD, IncompleteType))
1310
+ return true ;
1311
+ }
1312
+ // For C++ classes, also check base classes.
1313
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1314
+ // Polymorphic types require a vptr.
1315
+ if (CXXRD->isPolymorphic ())
1316
+ return true ;
1317
+ for (const CXXBaseSpecifier &Base : CXXRD->bases ()) {
1318
+ if (typeContainsPointer (Base.getType (), VisitedRD, IncompleteType))
1319
+ return true ;
1320
+ }
1321
+ }
1322
+ }
1323
+ return false ;
1324
+ }
1325
+
1326
+ void CodeGenFunction::EmitAllocToken (llvm::CallBase *CB, QualType AllocType) {
1277
1327
assert (SanOpts.has (SanitizerKind::AllocToken) &&
1278
1328
" Only needed with -fsanitize=alloc-token" );
1279
1329
@@ -1290,54 +1340,8 @@ void CodeGenFunction::EmitAllocTokenHint(llvm::CallBase *CB,
1290
1340
// recursively check if a type contains a pointer type.
1291
1341
llvm::SmallPtrSet<const RecordDecl *, 4 > VisitedRD;
1292
1342
bool IncompleteType = false ;
1293
- auto TypeContainsPtr = [&](auto &&self, QualType T) -> bool {
1294
- QualType CanonicalType = T.getCanonicalType ();
1295
- if (CanonicalType->isPointerType ())
1296
- return true ; // base case
1297
-
1298
- // Look through typedef chain to check for special types.
1299
- for (QualType CurrentT = T; const auto *TT = CurrentT->getAs <TypedefType>();
1300
- CurrentT = TT->getDecl ()->getUnderlyingType ()) {
1301
- const IdentifierInfo *II = TT->getDecl ()->getIdentifier ();
1302
- if (!II)
1303
- continue ;
1304
- // Special Case: Syntactically uintptr_t is not a pointer; semantically,
1305
- // however, very likely used as such. Therefore, classify uintptr_t as a
1306
- // pointer, too.
1307
- if (II->isStr (" uintptr_t" ))
1308
- return true ;
1309
- }
1310
-
1311
- // The type is an array; check the element type.
1312
- if (const ArrayType *AT = CanonicalType->getAsArrayTypeUnsafe ())
1313
- return self (self, AT->getElementType ());
1314
- // The type is a struct, class, or union.
1315
- if (const RecordDecl *RD = CanonicalType->getAsRecordDecl ()) {
1316
- if (!RD->isCompleteDefinition ()) {
1317
- IncompleteType = true ;
1318
- return false ;
1319
- }
1320
- if (!VisitedRD.insert (RD).second )
1321
- return false ; // already visited
1322
- // Check all fields.
1323
- for (const FieldDecl *Field : RD->fields ()) {
1324
- if (self (self, Field->getType ()))
1325
- return true ;
1326
- }
1327
- // For C++ classes, also check base classes.
1328
- if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
1329
- // Polymorphic types require a vptr.
1330
- if (CXXRD->isPolymorphic ())
1331
- return true ;
1332
- for (const CXXBaseSpecifier &Base : CXXRD->bases ()) {
1333
- if (self (self, Base.getType ()))
1334
- return true ;
1335
- }
1336
- }
1337
- }
1338
- return false ;
1339
- };
1340
- const bool ContainsPtr = TypeContainsPtr (TypeContainsPtr, AllocType);
1343
+ const bool ContainsPtr =
1344
+ typeContainsPointer (AllocType, VisitedRD, IncompleteType);
1341
1345
if (!ContainsPtr && IncompleteType)
1342
1346
return ;
1343
1347
auto *ContainsPtrC = Builder.getInt1 (ContainsPtr);
@@ -1346,7 +1350,7 @@ void CodeGenFunction::EmitAllocTokenHint(llvm::CallBase *CB,
1346
1350
// Format: !{<type-name>, <contains-pointer>}
1347
1351
auto *MDN =
1348
1352
llvm::MDNode::get (CGM.getLLVMContext (), {TypeNameMD, ContainsPtrMD});
1349
- CB->setMetadata (llvm::LLVMContext::MD_alloc_token_hint , MDN);
1353
+ CB->setMetadata (llvm::LLVMContext::MD_alloc_token , MDN);
1350
1354
}
1351
1355
1352
1356
CodeGenFunction::ComplexPairTy CodeGenFunction::
0 commit comments