summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/InlineCost.cpp2
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp184
-rw-r--r--llvm/lib/AsmParser/LLParser.h25
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp154
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp10
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp7
-rw-r--r--llvm/lib/IR/AsmWriter.cpp22
-rw-r--r--llvm/lib/IR/Instruction.cpp2
-rw-r--r--llvm/lib/IR/Instructions.cpp102
-rw-r--r--llvm/lib/IR/Verifier.cpp47
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp12
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp3
12 files changed, 334 insertions, 236 deletions
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index 40bfac56719..32dc50ae62c 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -913,7 +913,7 @@ bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
// FIXME: It's not clear that a single instruction is an accurate model for
- // the inline cost of a cleanupret instruction.
+ // the inline cost of a catchret instruction.
return false;
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index fc7fceb2a26..082637bf0b8 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2237,8 +2237,8 @@ bool LLParser::PerFunctionState::FinishFunction() {
/// GetVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
-Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
- Type *Ty, LocTy Loc) {
+Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty,
+ LocTy Loc, OperatorConstraint OC) {
// Look this name up in the normal function symbol table.
Value *Val = F.getValueSymbolTable().lookup(Name);
@@ -2253,6 +2253,24 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
// If we have the value in the symbol table or fwd-ref table, return it.
if (Val) {
+ // Check operator constraints.
+ switch (OC) {
+ case OC_None:
+ // no constraint
+ break;
+ case OC_CatchPad:
+ if (!isa<CatchPadInst>(Val)) {
+ P.Error(Loc, "'%" + Name + "' is not a catchpad");
+ return nullptr;
+ }
+ break;
+ case OC_CleanupPad:
+ if (!isa<CleanupPadInst>(Val)) {
+ P.Error(Loc, "'%" + Name + "' is not a cleanuppad");
+ return nullptr;
+ }
+ break;
+ }
if (Val->getType() == Ty) return Val;
if (Ty->isLabelTy())
P.Error(Loc, "'%" + Name + "' is not a basic block");
@@ -2270,17 +2288,31 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
// Otherwise, create a new forward reference for this value and remember it.
Value *FwdVal;
- if (Ty->isLabelTy())
+ if (Ty->isLabelTy()) {
+ assert(!OC);
FwdVal = BasicBlock::Create(F.getContext(), Name, &F);
- else
+ } else if (!OC) {
FwdVal = new Argument(Ty, Name);
+ } else {
+ switch (OC) {
+ case OC_CatchPad:
+ FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {},
+ Name);
+ break;
+ case OC_CleanupPad:
+ FwdVal = CleanupPadInst::Create(F.getContext(), {}, Name);
+ break;
+ default:
+ llvm_unreachable("unexpected constraint");
+ }
+ }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
-Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
- LocTy Loc) {
+Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc,
+ OperatorConstraint OC) {
// Look this name up in the normal function symbol table.
Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
@@ -2295,6 +2327,24 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
// If we have the value in the symbol table or fwd-ref table, return it.
if (Val) {
+ // Check operator constraint.
+ switch (OC) {
+ case OC_None:
+ // no constraint
+ break;
+ case OC_CatchPad:
+ if (!isa<CatchPadInst>(Val)) {
+ P.Error(Loc, "'%" + Twine(ID) + "' is not a catchpad");
+ return nullptr;
+ }
+ break;
+ case OC_CleanupPad:
+ if (!isa<CleanupPadInst>(Val)) {
+ P.Error(Loc, "'%" + Twine(ID) + "' is not a cleanuppad");
+ return nullptr;
+ }
+ break;
+ }
if (Val->getType() == Ty) return Val;
if (Ty->isLabelTy())
P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block");
@@ -2311,10 +2361,23 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
// Otherwise, create a new forward reference for this value and remember it.
Value *FwdVal;
- if (Ty->isLabelTy())
+ if (Ty->isLabelTy()) {
+ assert(!OC);
FwdVal = BasicBlock::Create(F.getContext(), "", &F);
- else
+ } else if (!OC) {
FwdVal = new Argument(Ty);
+ } else {
+ switch (OC) {
+ case OC_CatchPad:
+ FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {});
+ break;
+ case OC_CleanupPad:
+ FwdVal = CleanupPadInst::Create(F.getContext(), {});
+ break;
+ default:
+ llvm_unreachable("unexpected constraint");
+ }
+ }
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -2346,11 +2409,24 @@ bool LLParser::PerFunctionState::SetInstName(int NameID,
std::map<unsigned, std::pair<Value*, LocTy> >::iterator FI =
ForwardRefValIDs.find(NameID);
if (FI != ForwardRefValIDs.end()) {
- if (FI->second.first->getType() != Inst->getType())
+ Value *Sentinel = FI->second.first;
+ if (Sentinel->getType() != Inst->getType())
return P.Error(NameLoc, "instruction forward referenced with type '" +
getTypeString(FI->second.first->getType()) + "'");
- FI->second.first->replaceAllUsesWith(Inst);
- delete FI->second.first;
+ // Check operator constraints. We only put cleanuppads or catchpads in
+ // the forward value map if the value is constrained to match.
+ if (isa<CatchPadInst>(Sentinel)) {
+ if (!isa<CatchPadInst>(Inst))
+ return P.Error(FI->second.second,
+ "'%" + Twine(NameID) + "' is not a catchpad");
+ } else if (isa<CleanupPadInst>(Sentinel)) {
+ if (!isa<CleanupPadInst>(Inst))
+ return P.Error(FI->second.second,
+ "'%" + Twine(NameID) + "' is not a cleanuppad");
+ }
+
+ Sentinel->replaceAllUsesWith(Inst);
+ delete Sentinel;
ForwardRefValIDs.erase(FI);
}
@@ -2362,11 +2438,24 @@ bool LLParser::PerFunctionState::SetInstName(int NameID,
std::map<std::string, std::pair<Value*, LocTy> >::iterator
FI = ForwardRefVals.find(NameStr);
if (FI != ForwardRefVals.end()) {
- if (FI->second.first->getType() != Inst->getType())
+ Value *Sentinel = FI->second.first;
+ if (Sentinel->getType() != Inst->getType())
return P.Error(NameLoc, "instruction forward referenced with type '" +
getTypeString(FI->second.first->getType()) + "'");
- FI->second.first->replaceAllUsesWith(Inst);
- delete FI->second.first;
+ // Check operator constraints. We only put cleanuppads or catchpads in
+ // the forward value map if the value is constrained to match.
+ if (isa<CatchPadInst>(Sentinel)) {
+ if (!isa<CatchPadInst>(Inst))
+ return P.Error(FI->second.second,
+ "'%" + NameStr + "' is not a catchpad");
+ } else if (isa<CleanupPadInst>(Sentinel)) {
+ if (!isa<CleanupPadInst>(Inst))
+ return P.Error(FI->second.second,
+ "'%" + NameStr + "' is not a cleanuppad");
+ }
+
+ Sentinel->replaceAllUsesWith(Inst);
+ delete Sentinel;
ForwardRefVals.erase(FI);
}
@@ -4007,18 +4096,30 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
//===----------------------------------------------------------------------===//
bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
- PerFunctionState *PFS) {
+ PerFunctionState *PFS,
+ OperatorConstraint OC) {
if (Ty->isFunctionTy())
return Error(ID.Loc, "functions are not values, refer to them as pointers");
+ if (OC && ID.Kind != ValID::t_LocalID && ID.Kind != ValID::t_LocalName) {
+ switch (OC) {
+ case OC_CatchPad:
+ return Error(ID.Loc, "Catchpad value required in this position");
+ case OC_CleanupPad:
+ return Error(ID.Loc, "Cleanuppad value required in this position");
+ default:
+ llvm_unreachable("Unexpected constraint kind");
+ }
+ }
+
switch (ID.Kind) {
case ValID::t_LocalID:
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
- V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
+ V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, OC);
return V == nullptr;
case ValID::t_LocalName:
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
- V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
+ V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, OC);
return V == nullptr;
case ValID::t_InlineAsm: {
assert(ID.FTy);
@@ -4140,11 +4241,11 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
}
}
-bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
+bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS,
+ OperatorConstraint OC) {
V = nullptr;
ValID ID;
- return ParseValID(ID, PFS) ||
- ConvertValIDToValue(Ty, ID, V, PFS);
+ return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS, OC);
}
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
@@ -4985,7 +5086,7 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
PerFunctionState &PFS) {
- if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad"))
+ if (ParseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad"))
return true;
while (Lex.getKind() != lltok::rsquare) {
@@ -5016,16 +5117,12 @@ bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
}
/// ParseCleanupRet
-/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue)
+/// ::= 'cleanupret' Value unwind ('to' 'caller' | TypeAndValue)
bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
- Type *RetTy = nullptr;
- Value *RetVal = nullptr;
- if (ParseType(RetTy, /*AllowVoid=*/true))
- return true;
+ Value *CleanupPad = nullptr;
- if (!RetTy->isVoidTy())
- if (ParseValue(RetTy, RetVal, PFS))
- return true;
+ if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad))
+ return true;
if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
return true;
@@ -5041,39 +5138,32 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
}
}
- Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB);
+ Inst = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad), UnwindBB);
return false;
}
/// ParseCatchRet
-/// ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue
+/// ::= 'catchret' Value 'to' TypeAndValue
bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
- Type *RetTy = nullptr;
- Value *RetVal = nullptr;
+ Value *CatchPad = nullptr;
- if (ParseType(RetTy, /*AllowVoid=*/true))
+ if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS, OC_CatchPad))
return true;
- if (!RetTy->isVoidTy())
- if (ParseValue(RetTy, RetVal, PFS))
- return true;
-
BasicBlock *BB;
if (ParseToken(lltok::kw_to, "expected 'to' in catchret") ||
ParseTypeAndBasicBlock(BB, PFS))
return true;
- Inst = CatchReturnInst::Create(BB, RetVal);
+ Inst = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB);
return false;
}
/// ParseCatchPad
-/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
+/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
- Type *RetType = nullptr;
-
SmallVector<Value *, 8> Args;
- if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ if (ParseExceptionArgs(Args, PFS))
return true;
BasicBlock *NormalBB, *UnwindBB;
@@ -5083,7 +5173,7 @@ bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
ParseTypeAndBasicBlock(UnwindBB, PFS))
return true;
- Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args);
+ Inst = CatchPadInst::Create(NormalBB, UnwindBB, Args);
return false;
}
@@ -5115,13 +5205,11 @@ bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) {
/// ParseCleanupPad
/// ::= 'cleanuppad' ParamList
bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
- Type *RetType = nullptr;
-
SmallVector<Value *, 8> Args;
- if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ if (ParseExceptionArgs(Args, PFS))
return true;
- Inst = CleanupPadInst::Create(RetType, Args);
+ Inst = CleanupPadInst::Create(Context, Args);
return false;
}
diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
index 96fb06a1f29..8b7e9560a69 100644
--- a/llvm/lib/AsmParser/LLParser.h
+++ b/llvm/lib/AsmParser/LLParser.h
@@ -108,6 +108,14 @@ namespace llvm {
unsigned MDKind, MDSlot;
};
+ /// Indicates which operator an operand allows (for the few operands that
+ /// may only reference a certain operator).
+ enum OperatorConstraint {
+ OC_None = 0, // No constraint
+ OC_CatchPad, // Must be CatchPadInst
+ OC_CleanupPad // Must be CleanupPadInst
+ };
+
SmallVector<Instruction*, 64> InstsWithTBAATag;
// Type resolution handling data structures. The location is set when we
@@ -329,8 +337,10 @@ namespace llvm {
/// GetVal - Get a value with the specified name or ID, creating a
/// forward reference record if needed. This can return null if the value
/// exists but does not have the right type.
- Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc);
- Value *GetVal(unsigned ID, Type *Ty, LocTy Loc);
+ Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc,
+ OperatorConstraint OC = OC_None);
+ Value *GetVal(unsigned ID, Type *Ty, LocTy Loc,
+ OperatorConstraint OC = OC_None);
/// SetInstName - After an instruction is parsed and inserted into its
/// basic block, this installs its name.
@@ -352,12 +362,15 @@ namespace llvm {
};
bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
- PerFunctionState *PFS);
+ PerFunctionState *PFS,
+ OperatorConstraint OC = OC_None);
bool parseConstantValue(Type *Ty, Constant *&C);
- bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS);
- bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) {
- return ParseValue(Ty, V, &PFS);
+ bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS,
+ OperatorConstraint OC = OC_None);
+ bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS,
+ OperatorConstraint OC = OC_None) {
+ return ParseValue(Ty, V, &PFS, OC);
}
bool ParseValue(Type *Ty, Value *&V, LocTy &Loc,
PerFunctionState &PFS) {
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index b379e59236d..7ede794bc76 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -41,6 +41,14 @@ enum {
SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
};
+/// Indicates which operator an operand allows (for the few operands that may
+/// only reference a certain operator).
+enum OperatorConstraint {
+ OC_None = 0, // No constraint
+ OC_CatchPad, // Must be CatchPadInst
+ OC_CleanupPad // Must be CleanupPadInst
+};
+
class BitcodeReaderValueList {
std::vector<WeakVH> ValuePtrs;
@@ -84,9 +92,10 @@ public:
}
Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
- Value *getValueFwdRef(unsigned Idx, Type *Ty);
+ Value *getValueFwdRef(unsigned Idx, Type *Ty,
+ OperatorConstraint OC = OC_None);
- void assignValue(Value *V, unsigned Idx);
+ bool assignValue(Value *V, unsigned Idx);
/// Once all constants are read, this method bulk resolves any forward
/// references.
@@ -262,10 +271,11 @@ private:
StructType *createIdentifiedStructType(LLVMContext &Context);
Type *getTypeByID(unsigned ID);
- Value *getFnValueByID(unsigned ID, Type *Ty) {
+ Value *getFnValueByID(unsigned ID, Type *Ty,
+ OperatorConstraint OC = OC_None) {
if (Ty && Ty->isMetadataTy())
return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
- return ValueList.getValueFwdRef(ID, Ty);
+ return ValueList.getValueFwdRef(ID, Ty, OC);
}
Metadata *getFnMetadataByID(unsigned ID) {
return MDValueList.getValueFwdRef(ID);
@@ -308,8 +318,9 @@ private:
/// past the number of slots used by the value in the record. Return true if
/// there is an error.
bool popValue(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Type *Ty, Value *&ResVal) {
- if (getValue(Record, Slot, InstNum, Ty, ResVal))
+ unsigned InstNum, Type *Ty, Value *&ResVal,
+ OperatorConstraint OC = OC_None) {
+ if (getValue(Record, Slot, InstNum, Ty, ResVal, OC))
return true;
// All values currently take a single record slot.
++Slot;
@@ -318,32 +329,34 @@ private:
/// Like popValue, but does not increment the Slot number.
bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty, Value *&ResVal) {
- ResVal = getValue(Record, Slot, InstNum, Ty);
+ unsigned InstNum, Type *Ty, Value *&ResVal,
+ OperatorConstraint OC = OC_None) {
+ ResVal = getValue(Record, Slot, InstNum, Ty, OC);
return ResVal == nullptr;
}
/// Version of getValue that returns ResVal directly, or 0 if there is an
/// error.
Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty) {
+ unsigned InstNum, Type *Ty, OperatorConstraint OC = OC_None) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)Record[Slot];
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty);
+ return getFnValueByID(ValNo, Ty, OC);
}
/// Like getValue, but decodes signed VBRs.
Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty) {
+ unsigned InstNum, Type *Ty,
+ OperatorConstraint OC = OC_None) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty);
+ return getFnValueByID(ValNo, Ty, OC);
}
/// Converts alignment exponent (i.e. power of two (or zero)) to the
@@ -753,10 +766,10 @@ struct OperandTraits<ConstantPlaceHolder> :
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
}
-void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
+bool BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
if (Idx == size()) {
push_back(V);
- return;
+ return false;
}
if (Idx >= size())
@@ -765,7 +778,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
WeakVH &OldV = ValuePtrs[Idx];
if (!OldV) {
OldV = V;
- return;
+ return false;
}
// Handle constants and non-constants (e.g. instrs) differently for
@@ -776,9 +789,26 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
} else {
// If there was a forward reference to this value, replace it.
Value *PrevVal = OldV;
+ // Check operator constraints. We only put cleanuppads or catchpads in
+ // the forward value map if the value is constrained to match.
+ if (CatchPadInst *CatchPad = dyn_cast<CatchPadInst>(PrevVal)) {
+ if (!isa<CatchPadInst>(V))
+ return true;
+ // Delete the dummy basic block that was created with the sentinel
+ // catchpad.
+ BasicBlock *DummyBlock = CatchPad->getUnwindDest();
+ assert(DummyBlock == CatchPad->getNormalDest());
+ CatchPad->dropAllReferences();
+ delete DummyBlock;
+ } else if (isa<CleanupPadInst>(PrevVal)) {
+ if (!isa<CleanupPadInst>(V))
+ return true;
+ }
OldV->replaceAllUsesWith(V);
delete PrevVal;
}
+
+ return false;
}
@@ -799,7 +829,8 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
return C;
}
-Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
+ OperatorConstraint OC) {
// Bail out for a clearly invalid value. This would make us call resize(0)
if (Idx == UINT_MAX)
return nullptr;
@@ -811,14 +842,39 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
// If the types don't match, it's invalid.
if (Ty && Ty != V->getType())
return nullptr;
- return V;
+ if (!OC)
+ return V;
+ // Use dyn_cast to enforce operator constraints
+ switch (OC) {
+ case OC_CatchPad:
+ return dyn_cast<CatchPadInst>(V);
+ case OC_CleanupPad:
+ return dyn_cast<CleanupPadInst>(V);
+ default:
+ llvm_unreachable("Unexpected operator constraint");
+ }
}
// No type specified, must be invalid reference.
if (!Ty) return nullptr;
// Create and return a placeholder, which will later be RAUW'd.
- Value *V = new Argument(Ty);
+ Value *V;
+ switch (OC) {
+ case OC_None:
+ V = new Argument(Ty);
+ break;
+ case OC_CatchPad: {
+ BasicBlock *BB = BasicBlock::Create(Context);
+ V = CatchPadInst::Create(BB, BB, {});
+ break;
+ }
+ default:
+ assert(OC == OC_CleanupPad && "unexpected operator constraint");
+ V = CleanupPadInst::Create(Context, {});
+ break;
+ }
+
ValuePtrs[Idx] = V;
return V;
}
@@ -2610,7 +2666,8 @@ std::error_code BitcodeReader::parseConstants() {
}
}
- ValueList.assignValue(V, NextCstNo);
+ if (ValueList.assignValue(V, NextCstNo))
+ return error("Invalid forward reference");
++NextCstNo;
}
}
@@ -3819,56 +3876,47 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
}
break;
}
- // CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#]
+ // CLEANUPRET: [val] or [val,bb#]
case bitc::FUNC_CODE_INST_CLEANUPRET: {
- if (Record.size() < 2)
+ if (Record.size() != 1 && Record.size() != 2)
return error("Invalid record");
unsigned Idx = 0;
- bool HasReturnValue = !!Record[Idx++];
- bool HasUnwindDest = !!Record[Idx++];
- Value *RetVal = nullptr;
- BasicBlock *UnwindDest = nullptr;
-
- if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal))
+ Value *CleanupPad = getValue(Record, Idx++, NextValueNo,
+ Type::getTokenTy(Context), OC_CleanupPad);
+ if (!CleanupPad)
return error("Invalid record");
- if (HasUnwindDest) {
- if (Idx == Record.size())
- return error("Invalid record");
+ BasicBlock *UnwindDest = nullptr;
+ if (Record.size() == 2) {
UnwindDest = getBasicBlock(Record[Idx++]);
if (!UnwindDest)
return error("Invalid record");
}
- if (Record.size() != Idx)
- return error("Invalid record");
-
- I = CleanupReturnInst::Create(Context, RetVal, UnwindDest);
+ I = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad),
+ UnwindDest);
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#]
- if (Record.size() != 1 && Record.size() != 3)
+ case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [val,bb#]
+ if (Record.size() != 2)
return error("Invalid record");
unsigned Idx = 0;
+ Value *CatchPad = getValue(Record, Idx++, NextValueNo,
+ Type::getTokenTy(Context), OC_CatchPad);
+ if (!CatchPad)
+ return error("Invalid record");
BasicBlock *BB = getBasicBlock(Record[Idx++]);
if (!BB)
return error("Invalid record");
- Value *RetVal = nullptr;
- if (Record.size() == 3 &&
- getValueTypePair(Record, Idx, NextValueNo, RetVal))
- return error("Invalid record");
- I = CatchReturnInst::Create(BB, RetVal);
+ I = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB);
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [ty,bb#,bb#,num,(ty,val)*]
- if (Record.size() < 4)
+ case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [bb#,bb#,num,(ty,val)*]
+ if (Record.size() < 3)
return error("Invalid record");
unsigned Idx = 0;
- Type *Ty = getTypeByID(Record[Idx++]);
- if (!Ty)
- return error("Invalid record");
BasicBlock *NormalBB = getBasicBlock(Record[Idx++]);
if (!NormalBB)
return error("Invalid record");
@@ -3886,7 +3934,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
if (Record.size() != Idx)
return error("Invalid record");
- I = CatchPadInst::Create(Ty, NormalBB, UnwindBB, Args);
+ I = CatchPadInst::Create(NormalBB, UnwindBB, Args);
InstructionList.push_back(I);
break;
}
@@ -3918,13 +3966,10 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [ty, num,(ty,val)*]
- if (Record.size() < 2)
+ case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [num,(ty,val)*]
+ if (Record.size() < 1)
return error("Invalid record");
unsigned Idx = 0;
- Type *Ty = getTypeByID(Record[Idx++]);
- if (!Ty)
- return error("Invalid record");
unsigned NumArgOperands = Record[Idx++];
SmallVector<Value *, 2> Args;
for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
@@ -3936,7 +3981,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
if (Record.size() != Idx)
return error("Invalid record");
- I = CleanupPadInst::Create(Ty, Args);
+ I = CleanupPadInst::Create(Context, Args);
InstructionList.push_back(I);
break;
}
@@ -4541,7 +4586,8 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
// Non-void values get registered in the value table for future use.
if (I && !I->getType()->isVoidTy())
- ValueList.assignValue(I, NextValueNo++);
+ if (ValueList.assignValue(I, NextValueNo++))
+ return error("Invalid forward reference");
}
OutOfRecordLoop:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 87b02e3dca4..c0eb5d497bc 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1855,10 +1855,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::CleanupRet: {
Code = bitc::FUNC_CODE_INST_CLEANUPRET;
const auto &CRI = cast<CleanupReturnInst>(I);
- Vals.push_back(CRI.hasReturnValue());
- Vals.push_back(CRI.hasUnwindDest());
- if (CRI.hasReturnValue())
- PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
+ pushValue(CRI.getCleanupPad(), InstID, Vals, VE);
if (CRI.hasUnwindDest())
Vals.push_back(VE.getValueID(CRI.getUnwindDest()));
break;
@@ -1866,15 +1863,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::CatchRet: {
Code = bitc::FUNC_CODE_INST_CATCHRET;
const auto &CRI = cast<CatchReturnInst>(I);
+ pushValue(CRI.getCatchPad(), InstID, Vals, VE);
Vals.push_back(VE.getValueID(CRI.getSuccessor()));
- if (CRI.hasReturnValue())
- PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
break;
}
case Instruction::CatchPad: {
Code = bitc::FUNC_CODE_INST_CATCHPAD;
const auto &CPI = cast<CatchPadInst>(I);
- Vals.push_back(VE.getTypeID(CPI.getType()));
Vals.push_back(VE.getValueID(CPI.getNormalDest()));
Vals.push_back(VE.getValueID(CPI.getUnwindDest()));
unsigned NumArgOperands = CPI.getNumArgOperands();
@@ -1898,7 +1893,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::CleanupPad: {
Code = bitc::FUNC_CODE_INST_CLEANUPPAD;
const auto &CPI = cast<CleanupPadInst>(I);
- Vals.push_back(VE.getTypeID(CPI.getType()));
unsigned NumOperands = CPI.getNumOperands();
Vals.push_back(NumOperands);
for (unsigned Op = 0; Op != NumOperands; ++Op)
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 68384f08b7c..3cc9c395c22 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -2956,8 +2956,7 @@ static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB) {
if (isa<CatchPadInst>(TI) || isa<CatchEndPadInst>(TI) ||
isa<TerminatePadInst>(TI))
return BB;
- return cast<CleanupPadInst>(cast<CleanupReturnInst>(TI)->getReturnValue())
- ->getParent();
+ return cast<CleanupReturnInst>(TI)->getCleanupPad()->getParent();
}
static void calculateExplicitStateNumbers(WinEHFuncInfo &FuncInfo,
@@ -3242,11 +3241,11 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) {
// The token consumed by a CatchReturnInst must match the funclet token.
bool IsUnreachableCatchret = false;
if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
- IsUnreachableCatchret = CRI->getReturnValue() != CatchPad;
+ IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
// The token consumed by a CleanupPadInst must match the funclet token.
bool IsUnreachableCleanupret = false;
if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
- IsUnreachableCleanupret = CRI->getReturnValue() != CleanupPad;
+ IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) {
new UnreachableInst(BB->getContext(), TI);
TI->eraseFromParent();
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 5ec111869f0..ae9ab8d6187 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2860,9 +2860,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(LPI->getClause(i), true);
}
} else if (const auto *CPI = dyn_cast<CatchPadInst>(&I)) {
- Out << ' ';
- TypePrinter.print(I.getType(), Out);
-
Out << " [";
for (unsigned Op = 0, NumOps = CPI->getNumArgOperands(); Op < NumOps;
++Op) {
@@ -2888,9 +2885,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
else
Out << "to caller";
} else if (const auto *CPI = dyn_cast<CleanupPadInst>(&I)) {
- Out << ' ';
- TypePrinter.print(I.getType(), Out);
-
Out << " [";
for (unsigned Op = 0, NumOps = CPI->getNumOperands(); Op < NumOps; ++Op) {
if (Op > 0)
@@ -2901,22 +2895,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
} else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
- if (CRI->hasReturnValue()) {
- Out << ' ';
- writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
- } else {
- Out << " void";
- }
+ Out << ' ';
+ writeOperand(CRI->getCatchPad(), /*PrintType=*/false);
Out << " to ";
writeOperand(CRI->getSuccessor(), /*PrintType=*/true);
} else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
- if (CRI->hasReturnValue()) {
- Out << ' ';
- writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
- } else {
- Out << " void";
- }
+ Out << ' ';
+ writeOperand(CRI->getCleanupPad(), /*PrintType=*/false);
Out << " unwind ";
if (CRI->hasUnwindDest())
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 85173d96562..0dc8633ac2a 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -261,7 +261,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case ExtractValue: return "extractvalue";
case InsertValue: return "insertvalue";
case LandingPad: return "landingpad";
- case CleanupPad: return "cleanuppad";
+ case CleanupPad: return "cleanuppad";
default: return "<Invalid operator> ";
}
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 46c799ece2c..e79fa415ffb 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -684,51 +684,39 @@ CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
CRI.getNumOperands()) {
SubclassOptionalData = CRI.SubclassOptionalData;
setInstructionSubclassData(CRI.getSubclassDataFromInstruction());
- if (Value *RetVal = CRI.getReturnValue())
- setReturnValue(RetVal);
- if (BasicBlock *UnwindDest = CRI.getUnwindDest())
- setUnwindDest(UnwindDest);
+ Op<-1>() = CRI.Op<-1>();
+ if (CRI.hasUnwindDest())
+ Op<-2>() = CRI.Op<-2>();
}
-void CleanupReturnInst::init(Value *RetVal, BasicBlock *UnwindBB) {
+void CleanupReturnInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) {
SubclassOptionalData = 0;
if (UnwindBB)
setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
- if (RetVal)
- setInstructionSubclassData(getSubclassDataFromInstruction() | 2);
+ Op<-1>() = CleanupPad;
if (UnwindBB)
- setUnwindDest(UnwindBB);
- if (RetVal)
- setReturnValue(RetVal);
+ Op<-2>() = UnwindBB;
}
-CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
+CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad,
BasicBlock *UnwindBB, unsigned Values,
Instruction *InsertBefore)
- : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
OperandTraits<CleanupReturnInst>::op_end(this) - Values,
Values, InsertBefore) {
- init(RetVal, UnwindBB);
+ init(CleanupPad, UnwindBB);
}
-CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
+CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad,
BasicBlock *UnwindBB, unsigned Values,
BasicBlock *InsertAtEnd)
- : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
OperandTraits<CleanupReturnInst>::op_end(this) - Values,
Values, InsertAtEnd) {
- init(RetVal, UnwindBB);
-}
-
-BasicBlock *CleanupReturnInst::getUnwindDest() const {
- if (hasUnwindDest())
- return cast<BasicBlock>(getOperand(getUnwindLabelOpIdx()));
- return nullptr;
-}
-void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
- assert(NewDest);
- setOperand(getUnwindLabelOpIdx(), NewDest);
+ init(CleanupPad, UnwindBB);
}
BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const {
@@ -797,38 +785,32 @@ void CatchEndPadInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
//===----------------------------------------------------------------------===//
// CatchReturnInst Implementation
//===----------------------------------------------------------------------===//
-void CatchReturnInst::init(BasicBlock *BB, Value *RetVal) {
- Op<-1>() = BB;
- if (RetVal)
- Op<-2>() = RetVal;
+void CatchReturnInst::init(CatchPadInst *CatchPad, BasicBlock *BB) {
+ Op<0>() = CatchPad;
+ Op<1>() = BB;
}
CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
: TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
- OperandTraits<CatchReturnInst>::op_end(this) -
- CRI.getNumOperands(),
- CRI.getNumOperands()) {
- Op<-1>() = CRI.Op<-1>();
- if (CRI.getNumOperands() != 1) {
- assert(CRI.getNumOperands() == 2);
- Op<-2>() = CRI.Op<-2>();
- }
+ OperandTraits<CatchReturnInst>::op_begin(this), 2) {
+ Op<0>() = CRI.Op<0>();
+ Op<1>() = CRI.Op<1>();
}
-CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
- OperandTraits<CatchReturnInst>::op_end(this) - Values,
- Values, InsertBefore) {
- init(BB, RetVal);
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertBefore) {
+ init(CatchPad, BB);
}
-CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
- OperandTraits<CatchReturnInst>::op_end(this) - Values,
- Values, InsertAtEnd) {
- init(BB, RetVal);
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertAtEnd) {
+ init(CatchPad, BB);
}
BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
@@ -863,21 +845,21 @@ CatchPadInst::CatchPadInst(const CatchPadInst &CPI)
std::copy(CPI.op_begin(), CPI.op_end(), op_begin());
}
-CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
- Instruction *InsertBefore)
- : TerminatorInst(RetTy, Instruction::CatchPad,
+CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore)
+ : TerminatorInst(Type::getTokenTy(IfNormal->getContext()),
+ Instruction::CatchPad,
OperandTraits<CatchPadInst>::op_end(this) - Values, Values,
InsertBefore) {
init(IfNormal, IfException, Args, NameStr);
}
-CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
- BasicBlock *InsertAtEnd)
- : TerminatorInst(RetTy, Instruction::CatchPad,
+CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::getTokenTy(IfNormal->getContext()),
+ Instruction::CatchPad,
OperandTraits<CatchPadInst>::op_end(this) - Values, Values,
InsertAtEnd) {
init(IfNormal, IfException, Args, NameStr);
@@ -962,17 +944,17 @@ CleanupPadInst::CleanupPadInst(const CleanupPadInst &CPI)
std::copy(CPI.op_begin(), CPI.op_end(), op_begin());
}
-CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args,
+CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore)
- : Instruction(RetTy, Instruction::CleanupPad,
+ : Instruction(Type::getTokenTy(C), Instruction::CleanupPad,
OperandTraits<CleanupPadInst>::op_end(this) - Args.size(),
Args.size(), InsertBefore) {
init(Args, NameStr);
}
-CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args,
+CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd)
- : Instruction(RetTy, Instruction::CleanupPad,
+ : Instruction(Type::getTokenTy(C), Instruction::CleanupPad,
OperandTraits<CleanupPadInst>::op_end(this) - Args.size(),
Args.size(), InsertAtEnd) {
init(Args, NameStr);
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 813d06cf643..7e10e4e1cee 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -184,12 +184,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// \brief Track unresolved string-based type references.
SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
- /// \brief The result type for a catchpad.
- Type *CatchPadResultTy;
-
- /// \brief The result type for a cleanuppad.
- Type *CleanupPadResultTy;
-
/// \brief The result type for a landingpad.
Type *LandingPadResultTy;
@@ -203,8 +197,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
public:
explicit Verifier(raw_ostream &OS)
- : VerifierSupport(OS), Context(nullptr), CatchPadResultTy(nullptr),
- CleanupPadResultTy(nullptr), LandingPadResultTy(nullptr),
+ : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr),
SawFrameEscape(false) {}
bool verify(const Function &F) {
@@ -239,8 +232,6 @@ public:
// FIXME: We strip const here because the inst visitor strips const.
visit(const_cast<Function &>(F));
InstsInThisBlock.clear();
- CatchPadResultTy = nullptr;
- CleanupPadResultTy = nullptr;
LandingPadResultTy = nullptr;
SawFrameEscape = false;
@@ -2877,14 +2868,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
visitEHPadPredecessors(CPI);
- if (!CatchPadResultTy)
- CatchPadResultTy = CPI.getType();
- else
- Assert(CatchPadResultTy == CPI.getType(),
- "The catchpad instruction should have a consistent result type "
- "inside a function.",
- &CPI);
-
BasicBlock *BB = CPI.getParent();
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
@@ -2896,6 +2879,14 @@ void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
"CatchPadInst not the first non-PHI instruction in the block.",
&CPI);
+ if (!BB->getSinglePredecessor())
+ for (BasicBlock *PredBB : predecessors(BB)) {
+ Assert(!isa<CatchPadInst>(PredBB->getTerminator()),
+ "CatchPadInst with CatchPadInst predecessor cannot have any other "
+ "predecessors.",
+ &CPI);
+ }
+
BasicBlock *UnwindDest = CPI.getUnwindDest();
Instruction *I = UnwindDest->getFirstNonPHI();
Assert(
@@ -2946,14 +2937,6 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
BasicBlock *BB = CPI.getParent();
- if (!CleanupPadResultTy)
- CleanupPadResultTy = CPI.getType();
- else
- Assert(CleanupPadResultTy == CPI.getType(),
- "The cleanuppad instruction should have a consistent result type "
- "inside a function.",
- &CPI);
-
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
"CleanupPadInst needs to be in a function with a personality.", &CPI);
@@ -2964,6 +2947,18 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
"CleanupPadInst not the first non-PHI instruction in the block.",
&CPI);
+ CleanupReturnInst *FirstCRI = nullptr;
+ for (User *U : CPI.users())
+ if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(U)) {
+ if (!FirstCRI)
+ FirstCRI = CRI;
+ else
+ Assert(CRI->getUnwindDest() == FirstCRI->getUnwindDest(),
+ "Cleanuprets from same cleanuppad have different exceptional "
+ "successors.",
+ FirstCRI, CRI);
+ }
+
visitInstruction(CPI);
}
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 46593ca7233..e36637a4fd8 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -2674,17 +2674,13 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
void visitCleanupPadInst(CleanupPadInst &I) {
- if (!I.getType()->isVoidTy()) {
- setShadow(&I, getCleanShadow(&I));
- setOrigin(&I, getCleanOrigin());
- }
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
}
void visitCatchPad(CatchPadInst &I) {
- if (!I.getType()->isVoidTy()) {
- setShadow(&I, getCleanShadow(&I));
- setOrigin(&I, getCleanOrigin());
- }
+ setShadow(&I, getCleanShadow(&I));
+ setOrigin(&I, getCleanOrigin());
}
void visitTerminatePad(TerminatePadInst &I) {
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 83dd1826c22..22d86c4fdc0 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -344,8 +344,7 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
if (auto *CRI = dyn_cast<CleanupReturnInst>(BB->getTerminator())) {
if (CRI->unwindsToCaller()) {
- CleanupReturnInst::Create(CRI->getContext(), CRI->getReturnValue(),
- UnwindDest, CRI);
+ CleanupReturnInst::Create(CRI->getCleanupPad(), UnwindDest, CRI);
CRI->eraseFromParent();
UpdatePHINodes(BB);
}
OpenPOWER on IntegriCloud