[PATCH 2/3] Implicit address space conversion on POD assign

Alp Toker alp at nuanti.com
Sun May 18 17:19:55 PDT 2014


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.

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.

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




More information about the cfe-commits mailing list