[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
llvm-svn: 357682
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index d4df310..d16cae6 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1978,10 +1978,14 @@
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::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 @@
ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(),
ThisAS, SlotAS, NewType);
}
+
// Push the this ptr.
Args.add(RValue::get(ThisPtr), D->getThisType());
@@ -2045,7 +2050,7 @@
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 @@
/*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,
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 161d6ed..cd49be4 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -783,6 +783,8 @@
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 @@
LLVM_FALLTHROUGH;
+
case CK_NoOp:
case CK_UserDefinedConversion:
case CK_ConstructorConversion:
@@ -849,7 +852,7 @@
case CK_CopyAndAutoreleaseBlockObject:
case CK_BuiltinFnToFnPtr:
case CK_ZeroToOCLOpaqueType:
- case CK_AddressSpaceConversion:
+
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 10ee829..b0078c2 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -614,12 +614,10 @@
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);
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index c24fc77..fddbe14 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2503,16 +2503,13 @@
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.