diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:31:20 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:31:20 +0000 | 
| commit | 20e90f04ad65d84361f769ef539883f75e3ef80d (patch) | |
| tree | 6f84b34d122575877ff298feeb61ee7bd0b66f78 /contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp | |
| parent | 7a7e6055035bfd93ab507051819373a6f171258b (diff) | |
| parent | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp | 66 | 
1 files changed, 47 insertions, 19 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp index 05d056739524..7ba03a0d42dd 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp @@ -309,8 +309,10 @@ Address CodeGenFunction::GetAddressOfBaseClass(    // just do a bitcast; null checks are unnecessary.    if (NonVirtualOffset.isZero() && !VBase) {      if (sanitizePerformTypeCheck()) { +      SanitizerSet SkippedChecks; +      SkippedChecks.set(SanitizerKind::Null, !NullCheckValue);        EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), -                    DerivedTy, DerivedAlign, !NullCheckValue); +                    DerivedTy, DerivedAlign, SkippedChecks);      }      return Builder.CreateBitCast(Value, BasePtrTy);    } @@ -331,8 +333,10 @@ Address CodeGenFunction::GetAddressOfBaseClass(    }    if (sanitizePerformTypeCheck()) { +    SanitizerSet SkippedChecks; +    SkippedChecks.set(SanitizerKind::Null, true);      EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc, -                  Value.getPointer(), DerivedTy, DerivedAlign, true); +                  Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks);    }    // Compute the virtual offset. @@ -685,7 +689,8 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,  /// complete-to-base constructor delegation optimization, i.e.  /// emitting the complete constructor as a simple call to the base  /// constructor. -static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) { +bool CodeGenFunction::IsConstructorDelegationValid( +    const CXXConstructorDecl *Ctor) {    // Currently we disable the optimization for classes with virtual    // bases because (1) the addresses of parameter variables need to be @@ -1131,10 +1136,11 @@ namespace {            RHS = EC->getSubExpr();          if (!RHS)            return nullptr; -        MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS); -        if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field) -          return nullptr; -        return Field; +        if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) { +          if (ME2->getMemberDecl() == Field) +            return Field; +        } +        return nullptr;        } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {          CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());          if (!(MD && isMemcpyEquivalentSpecialMember(MD))) @@ -1384,6 +1390,20 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {    const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());    CXXDtorType DtorType = CurGD.getDtorType(); +  // For an abstract class, non-base destructors are never used (and can't +  // be emitted in general, because vbase dtors may not have been validated +  // by Sema), but the Itanium ABI doesn't make them optional and Clang may +  // in fact emit references to them from other compilations, so emit them +  // as functions containing a trap instruction. +  if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) { +    llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); +    TrapCall->setDoesNotReturn(); +    TrapCall->setDoesNotThrow(); +    Builder.CreateUnreachable(); +    Builder.ClearInsertionPoint(); +    return; +  } +    Stmt *Body = Dtor->getBody();    if (Body)      incrementProfileCounter(Body); @@ -1416,9 +1436,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {    // we'd introduce *two* handler blocks.  In the Microsoft ABI, we    // always delegate because we might not have a definition in this TU.    switch (DtorType) { -  case Dtor_Comdat: -    llvm_unreachable("not expecting a COMDAT"); - +  case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");    case Dtor_Deleting: llvm_unreachable("already handled deleting case");    case Dtor_Complete: @@ -1433,7 +1451,9 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {                              /*Delegating=*/false, LoadCXXThisAddress());        break;      } +      // Fallthrough: act like we're in the base variant. +    LLVM_FALLTHROUGH;    case Dtor_Base:      assert(Body); @@ -1950,7 +1970,11 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,    // Add the rest of the user-supplied arguments.    const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); -  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor()); +  EvaluationOrder Order = E->isListInitialization() +                              ? EvaluationOrder::ForceLeftToRight +                              : EvaluationOrder::Default; +  EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(), +               /*ParamsToSkip*/ 0, Order);    EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args);  } @@ -1970,7 +1994,7 @@ static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,      // Likewise if they're inalloca.      const CGFunctionInfo &Info = -        CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0); +        CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);      if (Info.usesInAlloca())        return false;    } @@ -2012,10 +2036,11 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,      return;    } +  bool PassPrototypeArgs = true;    // Check whether we can actually emit the constructor before trying to do so.    if (auto Inherited = D->getInheritedConstructor()) { -    if (getTypes().inheritingCtorHasParams(Inherited, Type) && -        !canEmitDelegateCallArgs(*this, D, Type, Args)) { +    PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type); +    if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) {        EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,                                                Delegating, Args);        return; @@ -2023,14 +2048,15 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,    }    // Insert any ABI-specific implicit constructor arguments. -  unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs( -      *this, D, Type, ForVirtualBase, Delegating, Args); +  CGCXXABI::AddedStructorArgs ExtraArgs = +      CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase, +                                                 Delegating, Args);    // Emit the call.    llvm::Constant *CalleePtr =      CGM.getAddrOfCXXStructor(D, getFromCtorType(Type)); -  const CGFunctionInfo &Info = -    CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs); +  const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( +      Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);    CGCallee Callee = CGCallee::forDirect(CalleePtr, D);    EmitCall(Info, Callee, ReturnValueSlot(), Args); @@ -2102,7 +2128,9 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall(  void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(      const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,      bool Delegating, CallArgList &Args) { -  InlinedInheritingConstructorScope Scope(*this, GlobalDecl(Ctor, CtorType)); +  GlobalDecl GD(Ctor, CtorType); +  InlinedInheritingConstructorScope Scope(*this, GD); +  ApplyInlineDebugLocation DebugScope(*this, GD);    // Save the arguments to be passed to the inherited constructor.    CXXInheritedCtorInitExprArgs = Args;  | 
