[cfe-commits] r91498 - in /cfe/trunk/lib/CodeGen: CGExpr.cpp CGExprScalar.cpp CodeGenFunction.h

Mike Stump mrs at apple.com
Tue Dec 15 18:57:01 PST 2009


Author: mrs
Date: Tue Dec 15 20:57:00 2009
New Revision: 91498

URL: http://llvm.org/viewvc/llvm-project?rev=91498&view=rev
Log:
Implement additional undefined checks for additional loads and stores.  WIP.

Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=91498&r1=91497&r2=91498&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Dec 15 20:57:00 2009
@@ -208,6 +208,34 @@
   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
@@ -245,6 +273,13 @@
                           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
 /// of the expression.
 ///
@@ -1071,8 +1106,9 @@
                             llvm::IntegerType::get(VMContext, LLVMPointerWidth),
                                 IdxSigned, "idxprom");
 
+  // FIXME: As llvm implements the object size checking, this can come out.
   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 (ICE->getCastKind() == CastExpr::CK_ArrayToPointerDecay) {
           if (const ConstantArrayType *CAT

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=91498&r1=91497&r2=91498&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Dec 15 20:57:00 2009
@@ -69,6 +69,7 @@
 
   const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
   LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
+  LValue EmitCheckedLValue(const Expr *E) { return CGF.EmitCheckedLValue(E); }
 
   Value *EmitLoadOfLValue(LValue LV, QualType T) {
     return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
@@ -78,7 +79,7 @@
   /// value l-value, this method emits the address of the l-value, then loads
   /// and returns the result.
   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
@@ -1217,7 +1218,7 @@
   OpInfo.Ty = E->getComputationResultType();
   OpInfo.E = E;
   // Load/convert the LHS.
-  LValue LHSLV = EmitLValue(E->getLHS());
+  LValue LHSLV = EmitCheckedLValue(E->getLHS());
   OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
   OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
                                     E->getComputationLHSType());
@@ -1654,7 +1655,7 @@
   // __block variables need to have the rhs evaluated first, plus this should
   // improve codegen just a little.
   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
   // because the result is altered by the store, i.e., [C99 6.5.16p1]

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=91498&r1=91497&r2=91498&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Dec 15 20:57:00 2009
@@ -807,6 +807,8 @@
   llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
   llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
 
+  void EmitCheck(llvm::Value *, unsigned Size);
+
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission
   //===--------------------------------------------------------------------===//
@@ -921,6 +923,12 @@
   ///
   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
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.





More information about the cfe-commits mailing list