diff options
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 568 | 
1 files changed, 380 insertions, 188 deletions
| diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 1fe4c18badc6..63cc5b515da8 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -26,7 +26,8 @@  #include "llvm/Intrinsics.h"  #include "llvm/LLVMContext.h"  #include "llvm/MDBuilder.h" -#include "llvm/Target/TargetData.h" +#include "llvm/DataLayout.h" +#include "llvm/ADT/Hashing.h"  using namespace clang;  using namespace CodeGen; @@ -156,50 +157,6 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,    }  } -namespace { -/// \brief An adjustment to be made to the temporary created when emitting a -/// reference binding, which accesses a particular subobject of that temporary. -  struct SubobjectAdjustment { -    enum { -      DerivedToBaseAdjustment, -      FieldAdjustment, -      MemberPointerAdjustment -    } Kind; - -    union { -      struct { -        const CastExpr *BasePath; -        const CXXRecordDecl *DerivedClass; -      } DerivedToBase; - -      FieldDecl *Field; - -      struct { -        const MemberPointerType *MPT; -        llvm::Value *Ptr; -      } Ptr; -    }; - -    SubobjectAdjustment(const CastExpr *BasePath, -                        const CXXRecordDecl *DerivedClass) -      : Kind(DerivedToBaseAdjustment) { -      DerivedToBase.BasePath = BasePath; -      DerivedToBase.DerivedClass = DerivedClass; -    } - -    SubobjectAdjustment(FieldDecl *Field) -      : Kind(FieldAdjustment) { -      this->Field = Field; -    } - -    SubobjectAdjustment(const MemberPointerType *MPT, llvm::Value *Ptr) -      : Kind(MemberPointerAdjustment) { -      this->Ptr.MPT = MPT; -      this->Ptr.Ptr = Ptr; -    } -  }; -} -  static llvm::Value *  CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type,                           const NamedDecl *InitializedDecl) { @@ -232,32 +189,18 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,                              const CXXDestructorDecl *&ReferenceTemporaryDtor,                              QualType &ObjCARCReferenceLifetimeType,                              const NamedDecl *InitializedDecl) { -  // Look through single-element init lists that claim to be lvalues. They're -  // just syntactic wrappers in this case. -  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) { -    if (ILE->getNumInits() == 1 && ILE->isGLValue()) -      E = ILE->getInit(0); -  } - -  // Look through expressions for materialized temporaries (for now). -  if (const MaterializeTemporaryExpr *M  -                                      = dyn_cast<MaterializeTemporaryExpr>(E)) { -    // Objective-C++ ARC: -    //   If we are binding a reference to a temporary that has ownership, we  -    //   need to perform retain/release operations on the temporary. -    if (CGF.getContext().getLangOpts().ObjCAutoRefCount &&         -        E->getType()->isObjCLifetimeType() && -        (E->getType().getObjCLifetime() == Qualifiers::OCL_Strong || -         E->getType().getObjCLifetime() == Qualifiers::OCL_Weak || -         E->getType().getObjCLifetime() == Qualifiers::OCL_Autoreleasing)) -      ObjCARCReferenceLifetimeType = E->getType(); -     -    E = M->GetTemporaryExpr(); -  } +  const MaterializeTemporaryExpr *M = NULL; +  E = E->findMaterializedTemporary(M); +  // Objective-C++ ARC: +  //   If we are binding a reference to a temporary that has ownership, we +  //   need to perform retain/release operations on the temporary. +  if (M && CGF.getLangOpts().ObjCAutoRefCount && +      M->getType()->isObjCLifetimeType() && +      (M->getType().getObjCLifetime() == Qualifiers::OCL_Strong || +       M->getType().getObjCLifetime() == Qualifiers::OCL_Weak || +       M->getType().getObjCLifetime() == Qualifiers::OCL_Autoreleasing)) +    ObjCARCReferenceLifetimeType = M->getType(); -  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E)) -    E = DAE->getExpr(); -      if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E)) {      CGF.enterFullExpression(EWC);      CodeGenFunction::RunCleanupsScope Scope(CGF); @@ -335,54 +278,13 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,        return ReferenceTemporary;      } -     -    SmallVector<SubobjectAdjustment, 2> Adjustments; -    while (true) { -      E = E->IgnoreParens(); - -      if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { -        if ((CE->getCastKind() == CK_DerivedToBase || -             CE->getCastKind() == CK_UncheckedDerivedToBase) && -            E->getType()->isRecordType()) { -          E = CE->getSubExpr(); -          CXXRecordDecl *Derived  -            = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); -          Adjustments.push_back(SubobjectAdjustment(CE, Derived)); -          continue; -        } - -        if (CE->getCastKind() == CK_NoOp) { -          E = CE->getSubExpr(); -          continue; -        } -      } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) { -        if (!ME->isArrow() && ME->getBase()->isRValue()) { -          assert(ME->getBase()->getType()->isRecordType()); -          if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) { -            E = ME->getBase(); -            Adjustments.push_back(SubobjectAdjustment(Field)); -            continue; -          } -        } -      } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { -        if (BO->isPtrMemOp()) { -          assert(BO->getLHS()->isRValue()); -          E = BO->getLHS(); -          const MemberPointerType *MPT = -              BO->getRHS()->getType()->getAs<MemberPointerType>(); -          llvm::Value *Ptr = CGF.EmitScalarExpr(BO->getRHS()); -          Adjustments.push_back(SubobjectAdjustment(MPT, Ptr)); -        } -      } -      if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) -        if (opaque->getType()->isRecordType()) -          return CGF.EmitOpaqueValueLValue(opaque).getAddress(); +    SmallVector<SubobjectAdjustment, 2> Adjustments; +    E = E->skipRValueSubobjectAdjustments(Adjustments); +    if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) +      if (opaque->getType()->isRecordType()) +        return CGF.EmitOpaqueValueLValue(opaque).getAddress(); -      // Nothing changed. -      break; -    } -          // Create a reference temporary if necessary.      AggValueSlot AggSlot = AggValueSlot::ignored();      if (CGF.hasAggregateLLVMType(E->getType()) && @@ -446,8 +348,9 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,          }          case SubobjectAdjustment::MemberPointerAdjustment: { +          llvm::Value *Ptr = CGF.EmitScalarExpr(Adjustment.Ptr.RHS);            Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress( -                        CGF, Object, Adjustment.Ptr.Ptr, Adjustment.Ptr.MPT); +                        CGF, Object, Ptr, Adjustment.Ptr.MPT);            break;          }          } @@ -486,6 +389,15 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,                                                     ReferenceTemporaryDtor,                                                     ObjCARCReferenceLifetimeType,                                                     InitializedDecl); +  if (SanitizePerformTypeCheck && !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(); +    EmitTypeCheck(TCK_ReferenceBinding, E->getExprLoc(), Value, Ty); +  }    if (!ReferenceTemporaryDtor && ObjCARCReferenceLifetimeType.isNull())      return RValue::get(Value); @@ -549,22 +461,133 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,        ->getZExtValue();  } -void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) { -  if (!CatchUndefined) +/// Emit the hash_16_bytes function from include/llvm/ADT/Hashing.h. +static llvm::Value *emitHash16Bytes(CGBuilderTy &Builder, llvm::Value *Low, +                                    llvm::Value *High) { +  llvm::Value *KMul = Builder.getInt64(0x9ddfea08eb382d69ULL); +  llvm::Value *K47 = Builder.getInt64(47); +  llvm::Value *A0 = Builder.CreateMul(Builder.CreateXor(Low, High), KMul); +  llvm::Value *A1 = Builder.CreateXor(Builder.CreateLShr(A0, K47), A0); +  llvm::Value *B0 = Builder.CreateMul(Builder.CreateXor(High, A1), KMul); +  llvm::Value *B1 = Builder.CreateXor(Builder.CreateLShr(B0, K47), B0); +  return Builder.CreateMul(B1, KMul); +} + +void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, +                                    llvm::Value *Address, +                                    QualType Ty, CharUnits Alignment) { +  if (!SanitizePerformTypeCheck)      return; -  // This needs to be to the standard address space. -  Address = Builder.CreateBitCast(Address, Int8PtrTy); +  // Don't check pointers outside the default address space. The null check +  // isn't correct, the object-size check isn't supported by LLVM, and we can't +  // communicate the addresses to the runtime handler for the vptr check. +  if (Address->getType()->getPointerAddressSpace()) +    return; -  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy); +  llvm::Value *Cond = 0; -  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); +  if (getLangOpts().SanitizeNull) { +    // The glvalue must not be an empty glvalue. +    Cond = Builder.CreateICmpNE( +        Address, llvm::Constant::getNullValue(Address->getType())); +  } + +  if (getLangOpts().SanitizeObjectSize && !Ty->isIncompleteType()) { +    uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity(); + +    // The glvalue must refer to a large enough storage region. +    // FIXME: If Address 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 *CastAddr = Builder.CreateBitCast(Address, Int8PtrTy); +    llvm::Value *LargeEnough = +        Builder.CreateICmpUGE(Builder.CreateCall2(F, CastAddr, Min), +                              llvm::ConstantInt::get(IntPtrTy, Size)); +    Cond = Cond ? Builder.CreateAnd(Cond, LargeEnough) : LargeEnough; +  } + +  uint64_t AlignVal = 0; + +  if (getLangOpts().SanitizeAlignment) { +    AlignVal = Alignment.getQuantity(); +    if (!Ty->isIncompleteType() && !AlignVal) +      AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); + +    // The glvalue must be suitably aligned. +    if (AlignVal) { +      llvm::Value *Align = +          Builder.CreateAnd(Builder.CreatePtrToInt(Address, IntPtrTy), +                            llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); +      llvm::Value *Aligned = +        Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); +      Cond = Cond ? Builder.CreateAnd(Cond, Aligned) : Aligned; +    } +  } + +  if (Cond) { +    llvm::Constant *StaticData[] = { +      EmitCheckSourceLocation(Loc), +      EmitCheckTypeDescriptor(Ty), +      llvm::ConstantInt::get(SizeTy, AlignVal), +      llvm::ConstantInt::get(Int8Ty, TCK) +    }; +    EmitCheck(Cond, "type_mismatch", StaticData, Address); +  } + +  // If possible, check that the vptr indicates that there is a subobject of +  // type Ty at offset zero within this object. +  CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); +  if (getLangOpts().SanitizeVptr && TCK != TCK_ConstructorCall && +      RD && RD->hasDefinition() && RD->isDynamicClass()) { +    // Compute a hash of the mangled name of the type. +    // +    // FIXME: This is not guaranteed to be deterministic! Move to a +    //        fingerprinting mechanism once LLVM provides one. For the time +    //        being the implementation happens to be deterministic. +    llvm::SmallString<64> MangledName; +    llvm::raw_svector_ostream Out(MangledName); +    CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(), +                                                     Out); +    llvm::hash_code TypeHash = hash_value(Out.str()); + +    // Load the vptr, and compute hash_16_bytes(TypeHash, vptr). +    llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash); +    llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0); +    llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy); +    llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr); +    llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty); + +    llvm::Value *Hash = emitHash16Bytes(Builder, Low, High); +    Hash = Builder.CreateTrunc(Hash, IntPtrTy); + +    // Look the hash up in our cache. +    const int CacheSize = 128; +    llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize); +    llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable, +                                                   "__ubsan_vptr_type_cache"); +    llvm::Value *Slot = Builder.CreateAnd(Hash, +                                          llvm::ConstantInt::get(IntPtrTy, +                                                                 CacheSize-1)); +    llvm::Value *Indices[] = { Builder.getInt32(0), Slot }; +    llvm::Value *CacheVal = +      Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices)); + +    // If the hash isn't in the cache, call a runtime handler to perform the +    // hard work of checking whether the vptr is for an object of the right +    // type. This will either fill in the cache and return, or produce a +    // diagnostic. +    llvm::Constant *StaticData[] = { +      EmitCheckSourceLocation(Loc), +      EmitCheckTypeDescriptor(Ty), +      CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()), +      llvm::ConstantInt::get(Int8Ty, TCK) +    }; +    llvm::Value *DynamicData[] = { Address, Hash }; +    EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash), +              "dynamic_type_cache_miss", StaticData, DynamicData, true); +  }  } @@ -641,11 +664,11 @@ 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, TypeCheckKind TCK) {    LValue LV = EmitLValue(E);    if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) -    EmitCheck(LV.getAddress(),  -              getContext().getTypeSizeInChars(E->getType()).getQuantity()); +    EmitTypeCheck(TCK, E->getExprLoc(), LV.getAddress(), +                  E->getType(), LV.getAlignment());    return LV;  } @@ -672,7 +695,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {      llvm_unreachable("cannot emit a property reference directly");    case Expr::ObjCSelectorExprClass: -  return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E)); +    return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));    case Expr::ObjCIsaExprClass:      return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));    case Expr::BinaryOperatorClass: @@ -709,6 +732,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {      return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));    case Expr::CXXBindTemporaryExprClass:      return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E)); +  case Expr::CXXUuidofExprClass: +    return EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E));    case Expr::LambdaExprClass:      return EmitLambdaLValue(cast<LambdaExpr>(E)); @@ -1124,7 +1149,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {    // Get the output type.    llvm::Type *ResLTy = ConvertType(LV.getType()); -  unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy); +  unsigned ResSizeInBits = CGM.getDataLayout().getTypeSizeInBits(ResLTy);    // Compute the result as an OR of all of the individual component accesses.    llvm::Value *Res = 0; @@ -1322,7 +1347,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,    // Get the output type.    llvm::Type *ResLTy = ConvertTypeForMem(Dst.getType()); -  unsigned ResSizeInBits = CGM.getTargetData().getTypeSizeInBits(ResLTy); +  unsigned ResSizeInBits = CGM.getDataLayout().getTypeSizeInBits(ResLTy);    // Get the source value, truncated to the width of the bit-field.    llvm::Value *SrcVal = Src.getScalarVal(); @@ -1645,6 +1670,21 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {    CharUnits Alignment = getContext().getDeclAlign(ND);    QualType T = E->getType(); +  // A DeclRefExpr for a reference initialized by a constant expression can +  // appear without being odr-used. Directly emit the constant initializer. +  if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { +    const Expr *Init = VD->getAnyInitializer(VD); +    if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() && +        VD->isUsableInConstantExpressions(getContext()) && +        VD->checkInitIsICE()) { +      llvm::Constant *Val = +        CGM.EmitConstantValue(*VD->evaluateValue(), VD->getType(), this); +      assert(Val && "failed to emit reference constant expression"); +      // FIXME: Eventually we will want to emit vector element references. +      return MakeAddrLValue(Val, T, Alignment); +    } +  } +    // FIXME: We should be able to assert this for FunctionDecls as well!    // FIXME: We should be able to assert this for all DeclRefExprs, not just    // those with a valid source location. @@ -1655,7 +1695,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {    if (ND->hasAttr<WeakRefAttr>()) {      const ValueDecl *VD = cast<ValueDecl>(ND);      llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD); -    return MakeAddrLValue(Aliasee, E->getType(), Alignment); +    return MakeAddrLValue(Aliasee, T, Alignment);    }    if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { @@ -1683,9 +1723,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {        }        assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal()); -      CharUnits alignment = getContext().getDeclAlign(VD);        return MakeAddrLValue(GetAddrOfBlockDecl(VD, isBlockVariable), -                            E->getType(), alignment); +                            T, Alignment);      }      assert(V && "DeclRefExpr not entered in LocalDeclMap?"); @@ -1736,8 +1775,8 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {      // of a pointer to object; as in void foo (__weak id *param); *param = 0;      // But, we continue to generate __strong write barrier on indirect write      // into a pointer to object. -    if (getContext().getLangOpts().ObjC1 && -        getContext().getLangOpts().getGC() != LangOptions::NonGC && +    if (getLangOpts().ObjC1 && +        getLangOpts().getGC() != LangOptions::NonGC &&          LV.isObjCWeak())        LV.setNonGC(!E->isOBJCGCCandidate(getContext()));      return LV; @@ -1815,8 +1854,9 @@ GetAddrOfConstantWideString(StringRef Str,  static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,                                      SmallString<32>& Target) {    Target.resize(CharByteWidth * (Source.size() + 1)); -  char* ResultPtr = &Target[0]; -  bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr); +  char *ResultPtr = &Target[0]; +  const UTF8 *ErrorPtr; +  bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr, ErrorPtr);    (void)success;    assert(success);    Target.resize(ResultPtr - &Target[0]); @@ -1888,33 +1928,167 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {    }  } -llvm::BasicBlock *CodeGenFunction::getTrapBB() { -  const CodeGenOptions &GCO = CGM.getCodeGenOpts(); +/// Emit a type description suitable for use by a runtime sanitizer library. The +/// format of a type descriptor is +/// +/// \code +///   { i16 TypeKind, i16 TypeInfo } +/// \endcode +/// +/// followed by an array of i8 containing the type name. TypeKind is 0 for an +/// integer, 1 for a floating point value, and -1 for anything else. +llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { +  // FIXME: Only emit each type's descriptor once. +  uint16_t TypeKind = -1; +  uint16_t TypeInfo = 0; + +  if (T->isIntegerType()) { +    TypeKind = 0; +    TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) | +               T->isSignedIntegerType(); +  } else if (T->isFloatingType()) { +    TypeKind = 1; +    TypeInfo = getContext().getTypeSize(T); +  } + +  // Format the type name as if for a diagnostic, including quotes and +  // optionally an 'aka'. +  llvm::SmallString<32> Buffer; +  CGM.getDiags().ConvertArgToString(DiagnosticsEngine::ak_qualtype, +                                    (intptr_t)T.getAsOpaquePtr(), +                                    0, 0, 0, 0, 0, 0, Buffer, +                                    ArrayRef<intptr_t>()); + +  llvm::Constant *Components[] = { +    Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo), +    llvm::ConstantDataArray::getString(getLLVMContext(), Buffer) +  }; +  llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components); + +  llvm::GlobalVariable *GV = +    new llvm::GlobalVariable(CGM.getModule(), Descriptor->getType(), +                             /*isConstant=*/true, +                             llvm::GlobalVariable::PrivateLinkage, +                             Descriptor); +  GV->setUnnamedAddr(true); +  return GV; +} -  // If we are not optimzing, don't collapse all calls to trap in the function -  // to the same call, that way, in the debugger they can see which operation -  // did in fact fail.  If we are optimizing, we collapse all calls to trap down -  // to just one per function to save on codesize. -  if (GCO.OptimizationLevel && TrapBB) -    return TrapBB; +llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { +  llvm::Type *TargetTy = IntPtrTy; + +  // Integers which fit in intptr_t are zero-extended and passed directly. +  if (V->getType()->isIntegerTy() && +      V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth()) +    return Builder.CreateZExt(V, TargetTy); + +  // Pointers are passed directly, everything else is passed by address. +  if (!V->getType()->isPointerTy()) { +    llvm::Value *Ptr = Builder.CreateAlloca(V->getType()); +    Builder.CreateStore(V, Ptr); +    V = Ptr; +  } +  return Builder.CreatePtrToInt(V, TargetTy); +} + +/// \brief Emit a representation of a SourceLocation for passing to a handler +/// in a sanitizer runtime library. The format for this data is: +/// \code +///   struct SourceLocation { +///     const char *Filename; +///     int32_t Line, Column; +///   }; +/// \endcode +/// For an invalid SourceLocation, the Filename pointer is null. +llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) { +  PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc); + +  llvm::Constant *Data[] = { +    // FIXME: Only emit each file name once. +    PLoc.isValid() ? cast<llvm::Constant>( +                       Builder.CreateGlobalStringPtr(PLoc.getFilename())) +                   : llvm::Constant::getNullValue(Int8PtrTy), +    Builder.getInt32(PLoc.getLine()), +    Builder.getInt32(PLoc.getColumn()) +  }; -  llvm::BasicBlock *Cont = 0; -  if (HaveInsertPoint()) { -    Cont = createBasicBlock("cont"); -    EmitBranch(Cont); +  return llvm::ConstantStruct::getAnon(Data); +} + +void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, +                                llvm::ArrayRef<llvm::Constant *> StaticArgs, +                                llvm::ArrayRef<llvm::Value *> DynamicArgs, +                                bool Recoverable) { +  llvm::BasicBlock *Cont = createBasicBlock("cont"); + +  llvm::BasicBlock *Handler = createBasicBlock("handler." + CheckName); +  Builder.CreateCondBr(Checked, Cont, Handler); +  EmitBlock(Handler); + +  llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs); +  llvm::GlobalValue *InfoPtr = +      new llvm::GlobalVariable(CGM.getModule(), Info->getType(), true, +                               llvm::GlobalVariable::PrivateLinkage, Info); +  InfoPtr->setUnnamedAddr(true); + +  llvm::SmallVector<llvm::Value *, 4> Args; +  llvm::SmallVector<llvm::Type *, 4> ArgTypes; +  Args.reserve(DynamicArgs.size() + 1); +  ArgTypes.reserve(DynamicArgs.size() + 1); + +  // Handler functions take an i8* pointing to the (handler-specific) static +  // information block, followed by a sequence of intptr_t arguments +  // representing operand values. +  Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy)); +  ArgTypes.push_back(Int8PtrTy); +  for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) { +    Args.push_back(EmitCheckValue(DynamicArgs[i])); +    ArgTypes.push_back(IntPtrTy); +  } + +  llvm::FunctionType *FnType = +    llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false); +  llvm::AttrBuilder B; +  if (!Recoverable) { +    B.addAttribute(llvm::Attributes::NoReturn) +     .addAttribute(llvm::Attributes::NoUnwind); +  } +  B.addAttribute(llvm::Attributes::UWTable); +  llvm::Value *Fn = CGM.CreateRuntimeFunction(FnType, +                                          ("__ubsan_handle_" + CheckName).str(), +                                         llvm::Attributes::get(getLLVMContext(), +                                                               B)); +  llvm::CallInst *HandlerCall = Builder.CreateCall(Fn, Args); +  if (Recoverable) { +    Builder.CreateBr(Cont); +  } else { +    HandlerCall->setDoesNotReturn(); +    HandlerCall->setDoesNotThrow(); +    Builder.CreateUnreachable();    } -  TrapBB = createBasicBlock("trap"); -  EmitBlock(TrapBB); -  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap); -  llvm::CallInst *TrapCall = Builder.CreateCall(F); -  TrapCall->setDoesNotReturn(); -  TrapCall->setDoesNotThrow(); -  Builder.CreateUnreachable(); +  EmitBlock(Cont); +} -  if (Cont) -    EmitBlock(Cont); -  return TrapBB; +void CodeGenFunction::EmitTrapvCheck(llvm::Value *Checked) { +  llvm::BasicBlock *Cont = createBasicBlock("cont"); + +  // If we're optimizing, collapse all calls to trap down to just one per +  // function to save on code size. +  if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) { +    TrapBB = createBasicBlock("trap"); +    Builder.CreateCondBr(Checked, Cont, TrapBB); +    EmitBlock(TrapBB); +    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap); +    llvm::CallInst *TrapCall = Builder.CreateCall(F); +    TrapCall->setDoesNotReturn(); +    TrapCall->setDoesNotThrow(); +    Builder.CreateUnreachable(); +  } else { +    Builder.CreateCondBr(Checked, Cont, TrapBB); +  } + +  EmitBlock(Cont);  }  /// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an @@ -2007,14 +2181,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {      // Propagate the alignment from the array itself to the result.      ArrayAlignment = ArrayLV.getAlignment(); -    if (getContext().getLangOpts().isSignedOverflowDefined()) +    if (getLangOpts().isSignedOverflowDefined())        Address = Builder.CreateGEP(ArrayPtr, Args, "arrayidx");      else        Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, "arrayidx");    } else {      // The base must be a pointer, which is not an aggregate.  Emit it.      llvm::Value *Base = EmitScalarExpr(E->getBase()); -    if (getContext().getLangOpts().isSignedOverflowDefined()) +    if (getLangOpts().isSignedOverflowDefined())        Address = Builder.CreateGEP(Base, Idx, "arrayidx");      else        Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx"); @@ -2037,8 +2211,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {    LV.getQuals().setAddressSpace(E->getBase()->getType().getAddressSpace()); -  if (getContext().getLangOpts().ObjC1 && -      getContext().getLangOpts().getGC() != LangOptions::NonGC) { +  if (getLangOpts().ObjC1 && +      getLangOpts().getGC() != LangOptions::NonGC) {      LV.setNonGC(!E->isOBJCGCCandidate(getContext()));      setObjCGCLValueClass(getContext(), E, LV);    } @@ -2114,11 +2288,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(); +    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Ptr, PtrTy); +    BaseLV = MakeNaturalAlignAddrLValue(Ptr, PtrTy); +  } else +    BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);    NamedDecl *ND = E->getMemberDecl();    if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) { @@ -2355,7 +2531,10 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    case CK_Dependent:      llvm_unreachable("dependent cast kind in IR gen!"); -  + +  case CK_BuiltinFnToFnPtr: +    llvm_unreachable("builtin functions are handled elsewhere"); +    // These two casts are currently treated as no-ops, although they could    // potentially be real operations depending on the target's ABI.    case CK_NonAtomicToAtomic: @@ -2546,7 +2725,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,    if (const CXXPseudoDestructorExpr *PseudoDtor             = dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {      QualType DestroyedType = PseudoDtor->getDestroyedType(); -    if (getContext().getLangOpts().ObjCAutoRefCount && +    if (getLangOpts().ObjCAutoRefCount &&          DestroyedType->isObjCLifetimeType() &&          (DestroyedType.getObjCLifetime() == Qualifiers::OCL_Strong ||           DestroyedType.getObjCLifetime() == Qualifiers::OCL_Weak)) { @@ -2635,7 +2814,7 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {      }      RValue RV = EmitAnyExpr(E->getRHS()); -    LValue LV = EmitLValue(E->getLHS()); +    LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);      EmitStoreThroughLValue(RV, LV);      return LV;    } @@ -2677,6 +2856,14 @@ CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {    return MakeAddrLValue(EmitCXXTypeidExpr(E), E->getType());  } +llvm::Value *CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) { +  return CGM.GetAddrOfUuidDescriptor(E); +} + +LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) { +  return MakeAddrLValue(EmitCXXUuidofExpr(E), E->getType()); +} +  LValue  CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {    AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue"); @@ -2977,11 +3164,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {    uint64_t Size = sizeChars.getQuantity();    CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy);    unsigned Align = alignChars.getQuantity(); -  unsigned MaxInlineWidth = -      getContext().getTargetInfo().getMaxAtomicInlineWidth(); -  bool UseLibcall = (Size != Align || Size > MaxInlineWidth); - - +  unsigned MaxInlineWidthInBits = +    getContext().getTargetInfo().getMaxAtomicInlineWidth(); +  bool UseLibcall = (Size != Align || +                     getContext().toBits(sizeChars) > MaxInlineWidthInBits);    llvm::Value *Ptr, *Order, *OrderFail = 0, *Val1 = 0, *Val2 = 0;    Ptr = EmitScalarExpr(E->getPtr()); @@ -3177,6 +3363,13 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {      return ConvertTempToRValue(*this, E->getType(), Dest);    } +  bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || +                 E->getOp() == AtomicExpr::AO__atomic_store || +                 E->getOp() == AtomicExpr::AO__atomic_store_n; +  bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || +                E->getOp() == AtomicExpr::AO__atomic_load || +                E->getOp() == AtomicExpr::AO__atomic_load_n; +    llvm::Type *IPtrTy =        llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();    llvm::Value *OrigDest = Dest; @@ -3194,14 +3387,20 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {        break;      case 1:  // memory_order_consume      case 2:  // memory_order_acquire +      if (IsStore) +        break; // Avoid crashing on code with undefined behavior        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,                     llvm::Acquire);        break;      case 3:  // memory_order_release +      if (IsLoad) +        break; // Avoid crashing on code with undefined behavior        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,                     llvm::Release);        break;      case 4:  // memory_order_acq_rel +      if (IsLoad || IsStore) +        break; // Avoid crashing on code with undefined behavior        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,                     llvm::AcquireRelease);        break; @@ -3221,13 +3420,6 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {    // Long case, when Order isn't obviously constant. -  bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || -                 E->getOp() == AtomicExpr::AO__atomic_store || -                 E->getOp() == AtomicExpr::AO__atomic_store_n; -  bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || -                E->getOp() == AtomicExpr::AO__atomic_load || -                E->getOp() == AtomicExpr::AO__atomic_load_n; -    // Create all the relevant BB's    llvm::BasicBlock *MonotonicBB = 0, *AcquireBB = 0, *ReleaseBB = 0,                     *AcqRelBB = 0, *SeqCstBB = 0; | 
