SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
- const Function *Personality; // Personality function.
std::vector<int> TypeIds; // List of type ids (filters negative).
int WinEHState; // WinEH specific state number.
explicit LandingPadInfo(MachineBasicBlock *MBB)
- : LandingPadBlock(MBB), LandingPadLabel(nullptr), Personality(nullptr),
+ : LandingPadBlock(MBB), LandingPadLabel(nullptr),
WinEHState(-1) {}
};
/// addPersonality - Provide the personality function for the exception
/// information.
- void addPersonality(MachineBasicBlock *LandingPad,
- const Function *Personality);
void addPersonality(const Function *Personality);
void addWinEHState(MachineBasicBlock *LandingPad, int State);
- /// getPersonalityIndex - Get index of the current personality function inside
- /// Personalitites array
- unsigned getPersonalityIndex() const;
-
/// getPersonalities - Return array of personality functions ever seen.
const std::vector<const Function *>& getPersonalities() const {
return Personalities;
return FilterIds;
}
- /// getPersonality - Return a personality function if available. The presence
- /// of one is required to emit exception handling info.
- const Function *getPersonality() const;
-
- /// Classify the personality function amongst known EH styles.
- EHPersonality getPersonalityType();
-
/// setVariableDbgInfo - Collect information used to emit debugging
/// information of a variable.
void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
/// See if the given exception handling personality function is one that we
/// understand. If so, return a description of it; otherwise return Unknown.
EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
- const Function *F = dyn_cast<Function>(Pers->stripPointerCasts());
+ const Function *F =
+ Pers ? dyn_cast<Function>(Pers->stripPointerCasts()) : nullptr;
if (!F)
return EHPersonality::Unknown;
return StringSwitch<EHPersonality>(F->getName())
const Function *Per = nullptr;
if (F->hasPersonalityFn())
Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
- assert(!MMI->getPersonality() || Per == MMI->getPersonality());
bool forceEmitPersonality =
F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
F->needsUnwindTableEntry();
return;
// Emit references to all used personality functions
- const std::vector<const Function*> &Personalities = MMI->getPersonalities();
- for (size_t i = 0, e = Personalities.size(); i != e; ++i) {
- if (!Personalities[i])
+ for (const Function *Personality : MMI->getPersonalities()) {
+ if (!Personality)
continue;
- MCSymbol *Sym = Asm->getSymbol(Personalities[i]);
+ MCSymbol *Sym = Asm->getSymbol(Personality);
TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
}
}
const Function *Per = nullptr;
if (F->hasPersonalityFn())
Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
- assert(!MMI->getPersonality() || Per == MMI->getPersonality());
// Emit a personality function even when there are no landing pads
bool forceEmitPersonality =
CallsUnwindInit = false;
HasEHFunclets = false;
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
- // Always emit some info, by default "no personality" info.
- Personalities.push_back(nullptr);
PersonalityTypeCache = EHPersonality::Unknown;
AddrLabelSymbols = nullptr;
TheModule = nullptr;
return LandingPadLabel;
}
-/// addPersonality - Provide the personality function for the exception
-/// information.
-void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
- const Function *Personality) {
- LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
- LP.Personality = Personality;
- addPersonality(Personality);
-}
-
void MachineModuleInfo::addPersonality(const Function *Personality) {
for (unsigned i = 0; i < Personalities.size(); ++i)
if (Personalities[i] == Personality)
return;
-
- // If this is the first personality we're adding go
- // ahead and add it at the beginning.
- if (!Personalities[0])
- Personalities[0] = Personality;
- else
- Personalities.push_back(Personality);
+ Personalities.push_back(Personality);
}
void MachineModuleInfo::addWinEHState(MachineBasicBlock *LandingPad,
return FilterID;
}
-/// getPersonality - Return the personality function for the current function.
-const Function *MachineModuleInfo::getPersonality() const {
- for (const LandingPadInfo &LPI : LandingPads)
- if (LPI.Personality)
- return LPI.Personality;
- return nullptr;
-}
-
-EHPersonality MachineModuleInfo::getPersonalityType() {
- if (PersonalityTypeCache == EHPersonality::Unknown) {
- if (const Function *F = getPersonality())
- PersonalityTypeCache = classifyEHPersonality(F);
- }
- return PersonalityTypeCache;
-}
-
-/// getPersonalityIndex - Return unique index for current personality
-/// function. NULL/first personality function should always get zero index.
-unsigned MachineModuleInfo::getPersonalityIndex() const {
- const Function* Personality = nullptr;
-
- // Scan landing pads. If there is at least one non-NULL personality - use it.
- for (unsigned i = 0, e = LandingPads.size(); i != e; ++i)
- if (LandingPads[i].Personality) {
- Personality = LandingPads[i].Personality;
- break;
- }
-
- for (unsigned i = 0, e = Personalities.size(); i < e; ++i) {
- if (Personalities[i] == Personality)
- return i;
- }
-
- // This will happen if the current personality function is
- // in the zero index.
- return 0;
-}
-
const Function *MachineModuleInfo::getWinEHParent(const Function *F) const {
StringRef WinEHParentName =
F->getFnAttribute("wineh-parent").getValueAsString();
/// landingpad instruction and add them to the specified machine module info.
void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
MachineBasicBlock *MBB) {
- MMI.addPersonality(
- MBB,
- cast<Function>(
- I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()));
+ if (const auto *PF = dyn_cast<Function>(
+ I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
+ MMI.addPersonality(PF);
if (I.isCleanup())
MMI.addCleanup(MBB);
// If this is an MSVC-style personality function, we need to split the landing
// pad into several BBs.
const BasicBlock *LLVMBB = MBB->getBasicBlock();
- const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst();
- MF->getMMI().addPersonality(MBB, cast<Function>(LPadInst->getParent()
- ->getParent()
- ->getPersonalityFn()
- ->stripPointerCasts()));
- EHPersonality Personality = MF->getMMI().getPersonalityType();
-
- if (isMSVCEHPersonality(Personality)) {
+ const Constant *Personality = MF->getFunction()->getPersonalityFn();
+ if (const auto *PF = dyn_cast<Function>(Personality->stripPointerCasts()))
+ MF->getMMI().addPersonality(PF);
+ EHPersonality PersonalityType = classifyEHPersonality(Personality);
+
+ if (isMSVCEHPersonality(PersonalityType)) {
SmallVector<MachineBasicBlock *, 4> ClauseBBs;
const IntrinsicInst *ActionsCall =
dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());
if (MAI->doesSupportExceptionHandling() && MMI) {
// Add the (possibly multiple) personalities to the set of global values.
// Only referenced functions get into the Personalities list.
- const std::vector<const Function*> &Personalities = MMI->getPersonalities();
- for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
- E = Personalities.end(); I != E; ++I) {
- if (*I) {
- MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
+ for (const Function *Personality : MMI->getPersonalities()) {
+ if (Personality) {
+ MCSymbol *NLPSym =
+ getSymbolWithGlobalValueBase(Personality, "$non_lazy_ptr");
MachineModuleInfoImpl::StubValueTy &StubSym =
- MMIMacho.getGVStubEntry(NLPSym);
- StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true);
+ MMIMacho.getGVStubEntry(NLPSym);
+ StubSym =
+ MachineModuleInfoImpl::StubValueTy(getSymbol(Personality), true);
}
}
}
--- /dev/null
+; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
+
+; We should treat non-Function personalities as the unknown personality, which
+; is usually Itanium.
+
+declare void @g()
+declare void @terminate(i8*)
+
+define void @f() personality i8* null {
+ invoke void @g()
+ to label %ret unwind label %lpad
+ret:
+ ret void
+lpad:
+ %vals = landingpad { i8*, i32 } catch i8* null
+ %ptr = extractvalue { i8*, i32 } %vals, 0
+ call void @terminate(i8* %ptr)
+ unreachable
+}
+
+; CHECK: f:
+; CHECK: callq g
+; CHECK: retq
+; CHECK: movq %rax, %rdi
+; CHECK: callq terminate