@@ -313,21 +313,57 @@ void CodeGenModule::applyGlobalValReplacements() {
313
313
// This is only used in aliases that we created and we know they have a
314
314
// linear structure.
315
315
static const llvm::GlobalValue *getAliasedGlobal (const llvm::GlobalValue *GV) {
316
- llvm::SmallPtrSet<const llvm::GlobalValue *, 4 > Visited;
317
- for (;;) {
318
- if (!GV || !Visited.insert (GV).second )
319
- return nullptr ;
320
-
321
- const llvm::Constant *C;
322
- if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV))
323
- C = GA->getAliasee ();
324
- else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV))
325
- C = GI->getResolver ();
326
- else
327
- return GV;
316
+ const llvm::Constant *C;
317
+ if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV))
318
+ C = GA->getAliasee ();
319
+ else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV))
320
+ C = GI->getResolver ();
321
+ else
322
+ return GV;
323
+
324
+ const auto *AliaseeGV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts ());
325
+ if (!AliaseeGV)
326
+ return nullptr ;
327
+
328
+ const llvm::GlobalValue *FinalGV = AliaseeGV->getAliaseeObject ();
329
+ if (FinalGV == GV)
330
+ return nullptr ;
331
+
332
+ return FinalGV;
333
+ }
334
+
335
+ static bool checkAliasedGlobal (DiagnosticsEngine &Diags,
336
+ SourceLocation Location, bool IsIFunc,
337
+ const llvm::GlobalValue *Alias,
338
+ const llvm::GlobalValue *&GV) {
339
+ GV = getAliasedGlobal (Alias);
340
+ if (!GV) {
341
+ Diags.Report (Location, diag::err_cyclic_alias) << IsIFunc;
342
+ return false ;
343
+ }
344
+
345
+ if (GV->isDeclaration ()) {
346
+ Diags.Report (Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc;
347
+ return false ;
348
+ }
349
+
350
+ if (IsIFunc) {
351
+ // Check resolver function type.
352
+ const auto *F = dyn_cast<llvm::Function>(GV);
353
+ if (!F) {
354
+ Diags.Report (Location, diag::err_alias_to_undefined)
355
+ << IsIFunc << IsIFunc;
356
+ return false ;
357
+ }
328
358
329
- GV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts ());
359
+ llvm::FunctionType *FTy = F->getFunctionType ();
360
+ if (!FTy->getReturnType ()->isPointerTy ()) {
361
+ Diags.Report (Location, diag::err_ifunc_resolver_return);
362
+ return false ;
363
+ }
330
364
}
365
+
366
+ return true ;
331
367
}
332
368
333
369
void CodeGenModule::checkAliases () {
@@ -344,23 +380,13 @@ void CodeGenModule::checkAliases() {
344
380
Location = A->getLocation ();
345
381
else
346
382
llvm_unreachable (" Not an alias or ifunc?" );
383
+
347
384
StringRef MangledName = getMangledName (GD);
348
385
llvm::GlobalValue *Alias = GetGlobalValue (MangledName);
349
- const llvm::GlobalValue *GV = getAliasedGlobal (Alias);
350
- if (!GV) {
351
- Error = true ;
352
- Diags.Report (Location, diag::err_cyclic_alias) << IsIFunc;
353
- } else if (GV->isDeclaration ()) {
386
+ const llvm::GlobalValue *GV = nullptr ;
387
+ if (!checkAliasedGlobal (Diags, Location, IsIFunc, Alias, GV)) {
354
388
Error = true ;
355
- Diags.Report (Location, diag::err_alias_to_undefined)
356
- << IsIFunc << IsIFunc;
357
- } else if (IsIFunc) {
358
- // Check resolver function type.
359
- llvm::FunctionType *FTy = dyn_cast<llvm::FunctionType>(
360
- GV->getType ()->getPointerElementType ());
361
- assert (FTy);
362
- if (!FTy->getReturnType ()->isPointerTy ())
363
- Diags.Report (Location, diag::err_ifunc_resolver_return);
389
+ continue ;
364
390
}
365
391
366
392
llvm::Constant *Aliasee =
0 commit comments