[PATCH 2/3] Implicit address space conversion on POD assign
Richard Smith
richard at metafoo.co.uk
Sun May 18 20:00:09 PDT 2014
On Sun, May 18, 2014 at 5:19 PM, Alp Toker <alp at nuanti.com> wrote:
>
> On 19/05/2014 02:29, Adam Strzelecki wrote:
>
>> When assigning to POD without user defined copy constructor implicit
>> address
>> space conversion will be done if assigned value has same type but
>> different
>> address space and no matching constructor was found.
>>
>> This allows OpenCL address space conversion in C++ mode for POD types.
>> ---
>> lib/Sema/SemaInit.cpp | 22 +++++++++++++++++++++-
>> test/SemaCXX/address-space-initialize.cpp | 28
>> ++++++++++++++++++++++++++++
>> 2 files changed, 49 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
>> index fe1f7c8..63ddd72 100644
>> --- a/lib/Sema/SemaInit.cpp
>> +++ b/lib/Sema/SemaInit.cpp
>> @@ -4606,9 +4606,28 @@ void InitializationSequence::InitializeFrom(Sema
>> &S,
>> if (Kind.getKind() == InitializationKind::IK_Direct ||
>> (Kind.getKind() == InitializationKind::IK_Copy &&
>> (Context.hasSameUnqualifiedType(SourceType, DestType) ||
>> - S.IsDerivedFrom(SourceType, DestType))))
>> + S.IsDerivedFrom(SourceType, DestType)))) {
>> +
>> TryConstructorInitialization(S, Entity, Kind, Args,
>> Entity.getType(), *this);
>> +
>> + // Relax rules and do implicit conversion if copy constructor
>> + // initialization fails due address space mismatch and destination
>> class
>> + // is POD without user defined copy constructor
>> + if (Failed() && Failure == FK_ConstructorOverloadFailed &&
>> + Kind.getKind() == InitializationKind::IK_Copy &&
>> + SourceType.getAddressSpace() != DestType.getAddressSpace()) {
>> + const RecordType *DestRecordType = DestType->getAs<RecordType>();
>> + CXXRecordDecl *DestRecordDecl
>> + = cast<CXXRecordDecl>(DestRecordType->getDecl());
>> + if (DestRecordDecl->isPOD() &&
>> + !DestRecordDecl->hasUserDeclaredCopyConstructor() &&
>> + DestRecordDecl->hasCopyConstructorWithConstParam()) {
>> + setSequenceKind(SequenceKind::NormalSequence);
>> + goto ImplicitConversion;
>> + }
>> + }
>> + }
>>
>
> Would your use case be satisfied with isCXX11PODType(), essentially
> RD->isTrivial() && RD->isStandardLayout()?
>
> If so (and if there's interest in going with this) it'd be preferable to
> define the language extension in those existing terms.
>
I think you're right that using POD here is a mistake, but I don't really
think that trivial and standard layout are the right things to check.
Instead, I think the rule should be something like: if you cannot
initialize an X from a Y, and dropping the address space from Y allows the
initialization to succeed in such a way that it only invokes trivial
copy/move constructors, then the initialization is permitted, and is
performed by first copying Y into X's address space, then calling the
trivial constructor (the latter copy should always be elided in practice).
Do we want an extension diagnostic here? As David Chisnall pointed out
> there are other possible interpretations even if this happens to be the one
> we already use in C mode.
>
Do we have some underlying standard of which this is an extension?
> Alp.
>
>
>
> // - Otherwise (i.e., for the remaining copy-initialization
>> cases),
>> // user-defined conversion sequences that can convert from
>> the source
>> // type to the destination type or (when a conversion
>> function is
>> @@ -4636,6 +4655,7 @@ void InitializationSequence::InitializeFrom(Sema
>> &S,
>> return;
>> }
>> +ImplicitConversion:
>> // - Otherwise, the initial value of the object being initialized
>> is the
>> // (possibly converted) value of the initializer expression.
>> Standard
>> // conversions (Clause 4) will be used, if necessary, to convert
>> the
>> diff --git a/test/SemaCXX/address-space-initialize.cpp
>> b/test/SemaCXX/address-space-initialize.cpp
>> index 5091338..293a9cf 100644
>> --- a/test/SemaCXX/address-space-initialize.cpp
>> +++ b/test/SemaCXX/address-space-initialize.cpp
>> @@ -23,3 +23,31 @@ int* as_ptr = nocv_iarray; // expected-error{{cannot
>> initialize a variable of ty
>> __attribute__((address_space(42))) int* __attribute__((address_space(42)))
>> ptr_in_same_addr_space = nocv_iarray;
>> __attribute__((address_space(42))) int* __attribute__((address_space(999)))
>> ptr_in_different_addr_space = nocv_iarray;
>> +
>> +struct A { virtual ~A() {} }; // \
>> + expected-note 1 {{candidate constructor (the implicit copy
>> constructor)}} \
>> + expected-note 1 {{candidate constructor (the implicit default
>> constructor)}}
>> +struct C { float x, y; };
>> +struct D : C { D(const D &i) {} }; // \
>> + expected-note 1 {{candidate constructor not viable}}
>> +
>> +typedef A *A_ptr;
>> +typedef A __attribute__((address_space(1))) *A_ptr_1;
>> +typedef C *C_ptr;
>> +typedef C __attribute__((address_space(1))) *C_ptr_1;
>> +typedef D *D_ptr;
>> +typedef D __attribute__((address_space(1))) *D_ptr_1;
>> +
>> +void test_assignment(A_ptr ap, A_ptr_1 ap1,
>> + C_ptr cp, C_ptr_1 cp1,
>> + D_ptr dp, D_ptr_1 dp1) {
>> + // No address space conversions
>> + A a1 = ap[0];
>> + C c1 = cp[0];
>> + D d1 = dp[0];
>> +
>> + // Implicit address space conversion allowed only for POD without user
>> defined copy constructor (C)
>> + A a2 = ap1[0]; // expected-error{{no matching constructor for
>> initialization}}
>> + C c2 = cp1[0];
>> + D d2 = dp1[0]; // expected-error{{no matching constructor for
>> initialization}}
>> +}
>>
>
> --
> http://www.nuanti.com
> the browser experts
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140518/25dfd623/attachment.html>
More information about the cfe-commits
mailing list