|
@@ -486,6 +486,15 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
|
|
|
ReferenceTemporaryDtor,
|
|
|
ObjCARCReferenceLifetimeType,
|
|
|
InitializedDecl);
|
|
|
+ if (CatchUndefined && !E->getType()->isFunctionType()) {
|
|
|
+ // C++11 [dcl.ref]p5 (as amended by core issue 453):
|
|
|
+ // If a glvalue to which a reference is directly bound designates neither
|
|
|
+ // an existing object or function of an appropriate type nor a region of
|
|
|
+ // storage of suitable size and alignment to contain an object of the
|
|
|
+ // reference's type, the behavior is undefined.
|
|
|
+ QualType Ty = E->getType();
|
|
|
+ EmitCheck(CT_ReferenceBinding, Value, Ty);
|
|
|
+ }
|
|
|
if (!ReferenceTemporaryDtor && ObjCARCReferenceLifetimeType.isNull())
|
|
|
return RValue::get(Value);
|
|
|
|
|
@@ -549,22 +558,53 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
|
|
|
->getZExtValue();
|
|
|
}
|
|
|
|
|
|
-void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
|
|
|
+void CodeGenFunction::EmitCheck(CheckType CT, llvm::Value *Address, QualType Ty,
|
|
|
+ CharUnits Alignment) {
|
|
|
if (!CatchUndefined)
|
|
|
return;
|
|
|
|
|
|
- // This needs to be to the standard address space.
|
|
|
- Address = Builder.CreateBitCast(Address, Int8PtrTy);
|
|
|
-
|
|
|
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy);
|
|
|
-
|
|
|
- llvm::Value *Min = Builder.getFalse();
|
|
|
- llvm::Value *C = Builder.CreateCall2(F, Address, Min);
|
|
|
- llvm::BasicBlock *Cont = createBasicBlock();
|
|
|
- Builder.CreateCondBr(Builder.CreateICmpUGE(C,
|
|
|
- llvm::ConstantInt::get(IntPtrTy, Size)),
|
|
|
- Cont, getTrapBB());
|
|
|
- EmitBlock(Cont);
|
|
|
+ llvm::Value *Cond = 0;
|
|
|
+
|
|
|
+ if (CT != CT_Load && CT != CT_Store) {
|
|
|
+ // The glvalue must not be an empty glvalue. Don't bother checking this for
|
|
|
+ // loads and stores, because we will get a segfault anyway (if the operation
|
|
|
+ // isn't optimized out).
|
|
|
+ Cond = Builder.CreateICmpNE(
|
|
|
+ Address, llvm::Constant::getNullValue(Address->getType()));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!Ty->isIncompleteType()) {
|
|
|
+ uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
|
|
|
+ uint64_t AlignVal = Alignment.getQuantity();
|
|
|
+ if (!AlignVal)
|
|
|
+ AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity();
|
|
|
+
|
|
|
+ // This needs to be to the standard address space.
|
|
|
+ Address = Builder.CreateBitCast(Address, Int8PtrTy);
|
|
|
+
|
|
|
+ // The glvalue must refer to a large enough storage region.
|
|
|
+ // FIXME: If -faddress-sanitizer is enabled, insert dynamic instrumentation
|
|
|
+ // to check this.
|
|
|
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy);
|
|
|
+ llvm::Value *Min = Builder.getFalse();
|
|
|
+ llvm::Value *LargeEnough =
|
|
|
+ Builder.CreateICmpUGE(Builder.CreateCall2(F, Address, Min),
|
|
|
+ llvm::ConstantInt::get(IntPtrTy, Size));
|
|
|
+ Cond = Cond ? Builder.CreateAnd(Cond, LargeEnough) : LargeEnough;
|
|
|
+
|
|
|
+ // The glvalue must be suitably aligned.
|
|
|
+ llvm::Value *Align =
|
|
|
+ Builder.CreateAnd(Builder.CreatePtrToInt(Address, IntPtrTy),
|
|
|
+ llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
|
|
|
+ Cond = Builder.CreateAnd(Cond,
|
|
|
+ Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Cond) {
|
|
|
+ llvm::BasicBlock *Cont = createBasicBlock();
|
|
|
+ Builder.CreateCondBr(Cond, Cont, getTrapBB());
|
|
|
+ EmitBlock(Cont);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -641,11 +681,10 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
|
|
|
return MakeAddrLValue(llvm::UndefValue::get(Ty), E->getType());
|
|
|
}
|
|
|
|
|
|
-LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
|
|
|
+LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, CheckType CT) {
|
|
|
LValue LV = EmitLValue(E);
|
|
|
if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
|
|
|
- EmitCheck(LV.getAddress(),
|
|
|
- getContext().getTypeSizeInChars(E->getType()).getQuantity());
|
|
|
+ EmitCheck(CT, LV.getAddress(), E->getType(), LV.getAlignment());
|
|
|
return LV;
|
|
|
}
|
|
|
|
|
@@ -2114,11 +2153,13 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
|
|
|
|
|
|
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
|
|
|
LValue BaseLV;
|
|
|
- if (E->isArrow())
|
|
|
- BaseLV = MakeNaturalAlignAddrLValue(EmitScalarExpr(BaseExpr),
|
|
|
- BaseExpr->getType()->getPointeeType());
|
|
|
- else
|
|
|
- BaseLV = EmitLValue(BaseExpr);
|
|
|
+ if (E->isArrow()) {
|
|
|
+ llvm::Value *Ptr = EmitScalarExpr(BaseExpr);
|
|
|
+ QualType PtrTy = BaseExpr->getType()->getPointeeType();
|
|
|
+ EmitCheck(CT_MemberAccess, Ptr, PtrTy);
|
|
|
+ BaseLV = MakeNaturalAlignAddrLValue(Ptr, PtrTy);
|
|
|
+ } else
|
|
|
+ BaseLV = EmitCheckedLValue(BaseExpr, CT_MemberAccess);
|
|
|
|
|
|
NamedDecl *ND = E->getMemberDecl();
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
|