Author: stulova Date: Thu Apr 4 03:48:36 2019 New Revision: 357682 URL: http://llvm.org/viewvc/llvm-project?rev=357682&view=rev Log: [PR41276] Fixed incorrect generation of addr space cast for 'this' in C++. Improved classification of address space cast when qualification conversion is performed - prevent adding addr space cast for non-pointer and non-reference types. Take address space correctly from the pointee.
Also pass correct address space from 'this' object using AggValueSlot when generating addrspacecast in the constructor call. Differential Revision: https://reviews.llvm.org/D59988 Added: cfe/trunk/test/CodeGenCXX/address-space-of-this.cpp Modified: cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/CodeGen/CGExprAgg.cpp cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/Sema/SemaInit.cpp Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Thu Apr 4 03:48:36 2019 @@ -1678,7 +1678,7 @@ bool CastExpr::CastConsistency() const { auto Ty = getType(); auto SETy = getSubExpr()->getType(); assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy)); - if (isRValue()) { + if (/*isRValue()*/ !Ty->getPointeeType().isNull()) { Ty = Ty->getPointeeType(); SETy = SETy->getPointeeType(); } Modified: cfe/trunk/lib/CodeGen/CGClass.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Apr 4 03:48:36 2019 @@ -1978,10 +1978,14 @@ void CodeGenFunction::EmitCXXAggrConstru pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment, *destroyer); } - + auto currAVS = AggValueSlot::forAddr( + curAddr, type.getQualifiers(), AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, + AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed, + NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked + : AggValueSlot::IsNotSanitizerChecked); EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false, - /*Delegating=*/false, curAddr, E, - AggValueSlot::DoesNotOverlap, NewPointerIsChecked); + /*Delegating=*/false, currAVS, E); } // Go to the next element. @@ -2015,16 +2019,16 @@ void CodeGenFunction::destroyCXXObject(C void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, - bool Delegating, Address This, - const CXXConstructExpr *E, - AggValueSlot::Overlap_t Overlap, - bool NewPointerIsChecked) { + bool Delegating, + AggValueSlot ThisAVS, + const CXXConstructExpr *E) { CallArgList Args; - - LangAS SlotAS = E->getType().getAddressSpace(); + Address This = ThisAVS.getAddress(); + LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); QualType ThisType = D->getThisType(); LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace(); llvm::Value *ThisPtr = This.getPointer(); + if (SlotAS != ThisAS) { unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); llvm::Type *NewType = @@ -2032,6 +2036,7 @@ void CodeGenFunction::EmitCXXConstructor ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), ThisAS, SlotAS, NewType); } + // Push the this ptr. Args.add(RValue::get(ThisPtr), D->getThisType()); @@ -2045,7 +2050,7 @@ void CodeGenFunction::EmitCXXConstructor LValue Src = EmitLValue(Arg); QualType DestTy = getContext().getTypeDeclType(D->getParent()); LValue Dest = MakeAddrLValue(This, DestTy); - EmitAggregateCopyCtor(Dest, Src, Overlap); + EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap()); return; } @@ -2058,7 +2063,8 @@ void CodeGenFunction::EmitCXXConstructor /*ParamsToSkip*/ 0, Order); EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args, - Overlap, E->getExprLoc(), NewPointerIsChecked); + ThisAVS.mayOverlap(), E->getExprLoc(), + ThisAVS.isSanitizerChecked()); } static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Apr 4 03:48:36 2019 @@ -783,6 +783,8 @@ void AggExprEmitter::VisitCastExpr(CastE RValue rvalue = RValue::getAggregate(valueAddr, atomicSlot.isVolatile()); return EmitFinalDestCopy(valueType, rvalue); } + case CK_AddressSpaceConversion: + return Visit(E->getSubExpr()); case CK_LValueToRValue: // If we're loading from a volatile type, force the destination @@ -794,6 +796,7 @@ void AggExprEmitter::VisitCastExpr(CastE LLVM_FALLTHROUGH; + case CK_NoOp: case CK_UserDefinedConversion: case CK_ConstructorConversion: @@ -849,7 +852,7 @@ void AggExprEmitter::VisitCastExpr(CastE case CK_CopyAndAutoreleaseBlockObject: case CK_BuiltinFnToFnPtr: case CK_ZeroToOCLOpaqueType: - case CK_AddressSpaceConversion: + case CK_IntToOCLSampler: case CK_FixedPointCast: case CK_FixedPointToBoolean: Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Apr 4 03:48:36 2019 @@ -614,12 +614,10 @@ CodeGenFunction::EmitCXXConstructExpr(co case CXXConstructExpr::CK_NonVirtualBase: Type = Ctor_Base; - } + } - // Call the constructor. - EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, - Dest.getAddress(), E, Dest.mayOverlap(), - Dest.isSanitizerChecked()); + // Call the constructor. + EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, Dest, E); } } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Apr 4 03:48:36 2019 @@ -2503,16 +2503,13 @@ public: void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, - Address This, const CXXConstructExpr *E, - AggValueSlot::Overlap_t Overlap, - bool NewPointerIsChecked); + AggValueSlot ThisAVS, const CXXConstructExpr *E); void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, CallArgList &Args, AggValueSlot::Overlap_t Overlap, - SourceLocation Loc, - bool NewPointerIsChecked); + SourceLocation Loc, bool NewPointerIsChecked); /// Emit assumption load for all bases. Requires to be be called only on /// most-derived class and not under construction of the object. Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=357682&r1=357681&r2=357682&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Apr 4 03:48:36 2019 @@ -7321,9 +7321,19 @@ ExprResult Sema::TemporaryMaterializatio ExprResult Sema::PerformQualificationConversion(Expr *E, QualType Ty, ExprValueKind VK, CheckedConversionKind CCK) { - CastKind CK = (Ty.getAddressSpace() != E->getType().getAddressSpace()) - ? CK_AddressSpaceConversion - : CK_NoOp; + + CastKind CK = CK_NoOp; + + if (VK == VK_RValue) { + auto PointeeTy = Ty->getPointeeType(); + auto ExprPointeeTy = E->getType()->getPointeeType(); + if (!PointeeTy.isNull() && + PointeeTy.getAddressSpace() != ExprPointeeTy.getAddressSpace()) + CK = CK_AddressSpaceConversion; + } else if (Ty.getAddressSpace() != E->getType().getAddressSpace()) { + CK = CK_AddressSpaceConversion; + } + return ImpCastExprToType(E, Ty, CK, VK, /*BasePath=*/nullptr, CCK); } Added: cfe/trunk/test/CodeGenCXX/address-space-of-this.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/address-space-of-this.cpp?rev=357682&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/address-space-of-this.cpp (added) +++ cfe/trunk/test/CodeGenCXX/address-space-of-this.cpp Thu Apr 4 03:48:36 2019 @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -std=c++14 -triple=spir -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -std=c++17 -triple=spir -emit-llvm -o - | FileCheck %s + +struct MyType { + MyType(int i) : i(i) {} + int i; +}; +//CHECK: call void @_ZN6MyTypeC1Ei(%struct.MyType* addrspacecast (%struct.MyType addrspace(10)* @m to %struct.MyType*), i32 123) +MyType __attribute__((address_space(10))) m = 123; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits