forked from OSchip/llvm-project
Implement additional undefined checks for additional loads and stores. WIP.
llvm-svn: 91498
This commit is contained in:
parent
dd7418ae3f
commit
3f6f9febad
|
@ -208,6 +208,34 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
|
||||||
return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
|
return cast<llvm::ConstantInt>(Elts->getOperand(Idx))->getZExtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
|
||||||
|
if (!CatchUndefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const llvm::IntegerType *Size_tTy
|
||||||
|
= llvm::IntegerType::get(VMContext, LLVMPointerWidth);
|
||||||
|
Address = Builder.CreateBitCast(Address, PtrToInt8Ty);
|
||||||
|
|
||||||
|
const llvm::Type *ResType[] = {
|
||||||
|
Size_tTy
|
||||||
|
};
|
||||||
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, ResType, 1);
|
||||||
|
const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
|
||||||
|
CGM.getTypes().ConvertType(CGM.getContext().IntTy));
|
||||||
|
// In time, people may want to control this and use a 1 here.
|
||||||
|
llvm::Value *Arg = llvm::ConstantInt::get(IntTy, 0);
|
||||||
|
llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
|
||||||
|
llvm::BasicBlock *Cont = createBasicBlock();
|
||||||
|
llvm::BasicBlock *Check = createBasicBlock();
|
||||||
|
llvm::Value *NegativeOne = llvm::ConstantInt::get(Size_tTy, -1ULL);
|
||||||
|
Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check);
|
||||||
|
|
||||||
|
EmitBlock(Check);
|
||||||
|
Builder.CreateCondBr(Builder.CreateICmpUGE(C,
|
||||||
|
llvm::ConstantInt::get(Size_tTy, Size)),
|
||||||
|
Cont, getTrapBB());
|
||||||
|
EmitBlock(Cont);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// LValue Expression Emission
|
// LValue Expression Emission
|
||||||
|
@ -245,6 +273,13 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
|
||||||
MakeQualifiers(E->getType()));
|
MakeQualifiers(E->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
|
||||||
|
LValue LV = EmitLValue(E);
|
||||||
|
if (!isa<DeclRefExpr>(E) && !LV.isBitfield() && LV.isSimple())
|
||||||
|
EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);
|
||||||
|
return LV;
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitLValue - Emit code to compute a designator that specifies the location
|
/// EmitLValue - Emit code to compute a designator that specifies the location
|
||||||
/// of the expression.
|
/// of the expression.
|
||||||
///
|
///
|
||||||
|
@ -1071,6 +1106,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
|
||||||
llvm::IntegerType::get(VMContext, LLVMPointerWidth),
|
llvm::IntegerType::get(VMContext, LLVMPointerWidth),
|
||||||
IdxSigned, "idxprom");
|
IdxSigned, "idxprom");
|
||||||
|
|
||||||
|
// FIXME: As llvm implements the object size checking, this can come out.
|
||||||
if (CatchUndefined) {
|
if (CatchUndefined) {
|
||||||
if (const ImplicitCastExpr *ICE=dyn_cast<ImplicitCastExpr>(E->getBase())) {
|
if (const ImplicitCastExpr *ICE=dyn_cast<ImplicitCastExpr>(E->getBase())) {
|
||||||
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
|
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
|
|
||||||
const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
|
const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
|
||||||
LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
|
LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
|
||||||
|
LValue EmitCheckedLValue(const Expr *E) { return CGF.EmitCheckedLValue(E); }
|
||||||
|
|
||||||
Value *EmitLoadOfLValue(LValue LV, QualType T) {
|
Value *EmitLoadOfLValue(LValue LV, QualType T) {
|
||||||
return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
|
return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
|
||||||
|
@ -78,7 +79,7 @@ public:
|
||||||
/// value l-value, this method emits the address of the l-value, then loads
|
/// value l-value, this method emits the address of the l-value, then loads
|
||||||
/// and returns the result.
|
/// and returns the result.
|
||||||
Value *EmitLoadOfLValue(const Expr *E) {
|
Value *EmitLoadOfLValue(const Expr *E) {
|
||||||
return EmitLoadOfLValue(EmitLValue(E), E->getType());
|
return EmitLoadOfLValue(EmitCheckedLValue(E), E->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitConversionToBool - Convert the specified expression value to a
|
/// EmitConversionToBool - Convert the specified expression value to a
|
||||||
|
@ -1217,7 +1218,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
|
||||||
OpInfo.Ty = E->getComputationResultType();
|
OpInfo.Ty = E->getComputationResultType();
|
||||||
OpInfo.E = E;
|
OpInfo.E = E;
|
||||||
// Load/convert the LHS.
|
// Load/convert the LHS.
|
||||||
LValue LHSLV = EmitLValue(E->getLHS());
|
LValue LHSLV = EmitCheckedLValue(E->getLHS());
|
||||||
OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
|
OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
|
||||||
OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
|
OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
|
||||||
E->getComputationLHSType());
|
E->getComputationLHSType());
|
||||||
|
@ -1654,7 +1655,7 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
||||||
// __block variables need to have the rhs evaluated first, plus this should
|
// __block variables need to have the rhs evaluated first, plus this should
|
||||||
// improve codegen just a little.
|
// improve codegen just a little.
|
||||||
Value *RHS = Visit(E->getRHS());
|
Value *RHS = Visit(E->getRHS());
|
||||||
LValue LHS = EmitLValue(E->getLHS());
|
LValue LHS = EmitCheckedLValue(E->getLHS());
|
||||||
|
|
||||||
// Store the value into the LHS. Bit-fields are handled specially
|
// Store the value into the LHS. Bit-fields are handled specially
|
||||||
// because the result is altered by the store, i.e., [C99 6.5.16p1]
|
// because the result is altered by the store, i.e., [C99 6.5.16p1]
|
||||||
|
|
|
@ -807,6 +807,8 @@ public:
|
||||||
llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
|
llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
|
||||||
llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
|
llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
|
||||||
|
|
||||||
|
void EmitCheck(llvm::Value *, unsigned Size);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Declaration Emission
|
// Declaration Emission
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
@ -921,6 +923,12 @@ public:
|
||||||
///
|
///
|
||||||
LValue EmitLValue(const Expr *E);
|
LValue EmitLValue(const Expr *E);
|
||||||
|
|
||||||
|
/// EmitCheckedLValue - Same as EmitLValue but additionally we generate
|
||||||
|
/// checking code to guard against undefined behavior. This is only
|
||||||
|
/// suitable when we know that the address will be used to access the
|
||||||
|
/// object.
|
||||||
|
LValue EmitCheckedLValue(const Expr *E);
|
||||||
|
|
||||||
/// EmitLoadOfScalar - Load a scalar value from an address, taking
|
/// EmitLoadOfScalar - Load a scalar value from an address, taking
|
||||||
/// care to appropriately convert from the memory representation to
|
/// care to appropriately convert from the memory representation to
|
||||||
/// the LLVM value representation.
|
/// the LLVM value representation.
|
||||||
|
|
Loading…
Reference in New Issue