diff --git a/clang/lib/Sema/BSC/SemaBSCTrait.cpp b/clang/lib/Sema/BSC/SemaBSCTrait.cpp index be4778e7f7d546168b5cbf1beb509da95af0d63d..32669d2e768b89c3722440ca03fb1a817dd12030 100644 --- a/clang/lib/Sema/BSC/SemaBSCTrait.cpp +++ b/clang/lib/Sema/BSC/SemaBSCTrait.cpp @@ -672,6 +672,15 @@ QualType Sema::DesugarTraitToStructTrait(TraitDecl *TD, QualType T, return RT; } +static int CountPointerLevels(QualType T) { + int PointerLevels = 0; + while (T->isPointerType()) { + T = T->getPointeeType(); + ++PointerLevels; + } + return PointerLevels; +} + // In this function, we aim to assign the Trait_xxx struct, // for example, we have desugared as follows: //`struct Trait_I { @@ -757,7 +766,7 @@ VarDecl *Sema::ActOnDesugarTraitInstance(Decl *D) { else if (VD->getType().isBorrowQualified()) TraitTy = QualType(TD->getBorrowTrait()->getTypeForDecl(), 0); else - TraitTy = QualType(TD->getTrait()->getTypeForDecl(), 0);; + TraitTy = QualType(TD->getTrait()->getTypeForDecl(), 0); if (dyn_cast(TraitTy)) { TraitTy = CompleteRecordType(TD->getTrait(), NewVD->getTypeSourceInfo()); } @@ -767,12 +776,22 @@ VarDecl *Sema::ActOnDesugarTraitInstance(Decl *D) { // trait I **c = (trait F **)a; // @endcode if (!TraitTy.isNull() && Context.hasSameType(InnerTy, TraitTy)) { + if (CountPointerLevels(Context.getPointerType(OriginQT)) != + CountPointerLevels(CompleteTraitType(T))) { + Diag(UO->getBeginLoc(), + diag::err_typecheck_convert_incompatible_pointer) + << Context.getPointerType(OriginQT) << CompleteTraitType(T) + << 4 // operation type: 4 = initializing + << 0; // hint type: 0 = no additional hint + return nullptr; + } AddInitializerToDecl(NewVD, UO, false); return NewVD; } const PointerType *PT = dyn_cast_or_null(T.getTypePtr()); if (!PT) { - Diag(UO->getBeginLoc(), diag::err_type_has_not_impl_trait) << OriginQT << T; + Diag(UO->getBeginLoc(), diag::err_type_has_not_impl_trait) + << OriginQT << CompleteTraitType(T); return nullptr; } diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_trait_decl/owned_trait_decl.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_trait_decl/owned_trait_decl.cbs index 93602cc25e6ad36f4bf73d6450df760e3927deff..e8c1fb30813c9161691ed30d5016366202522acc 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_trait_decl/owned_trait_decl.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_trait_decl/owned_trait_decl.cbs @@ -28,5 +28,5 @@ void test2(int x, float y, double d) { trait T* owned t2 = t1; trait U* owned u1 = (int* owned)&x; trait T* owned t3 = u1; // expected-error {{incompatible owned types, cannot cast 'struct __Trait_U_Owned' to 'trait T *owned'}} - // expected-error@-1 {{expected a pointer type which has implemented 'trait T', found 'struct __Trait_U_Owned'}} + // expected-error@-1 {{expected a pointer type which has implemented 'trait T', found 'trait U *'}} } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Trait/GenericTrait/multi_level_pointer_var/multi_level_pointer_var.cbs b/clang/test/BSC/Negative/Trait/GenericTrait/multi_level_pointer_var/multi_level_pointer_var.cbs index 9b04eb2c83d5a0be8242ccd76484087cfb19ce6b..413bbe8fe154331490f537ec2a7ac9ef6777d8da 100644 --- a/clang/test/BSC/Negative/Trait/GenericTrait/multi_level_pointer_var/multi_level_pointer_var.cbs +++ b/clang/test/BSC/Negative/Trait/GenericTrait/multi_level_pointer_var/multi_level_pointer_var.cbs @@ -21,6 +21,7 @@ int main() { struct S s; int num = 1; trait F *p = &s; + trait F **pp = p; // expected-error {{incompatible pointer types initializing 'trait F **' with an expression of type 'trait F *'}} trait F **q = &p; trait F **q1 = &p; diff --git a/clang/test/BSC/Negative/Trait/GenericTrait/trait_cast_trait/trait_cast_trait.cbs b/clang/test/BSC/Negative/Trait/GenericTrait/trait_cast_trait/trait_cast_trait.cbs index 2372520ed7d9016cd9269e5788922c78312a2130..e195b824ae629068326c9b06dea1380068b7ea4f 100644 --- a/clang/test/BSC/Negative/Trait/GenericTrait/trait_cast_trait/trait_cast_trait.cbs +++ b/clang/test/BSC/Negative/Trait/GenericTrait/trait_cast_trait/trait_cast_trait.cbs @@ -7,8 +7,8 @@ trait G {}; void test() { trait G *g; - trait F *q = g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'struct __Trait_G'}} - trait F *q1 = (trait F *)g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'struct __Trait_G'}} + trait F *q = g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'trait G *'}} + trait F *q1 = (trait F *)g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'trait G *'}} q = g; // expected-error {{assigning to 'struct __Trait_F' from incompatible type 'trait G *'}} q1 = (trait F *)g; // expected-error {{assigning to 'struct __Trait_F' from incompatible type 'trait G *'}} } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Trait/r3/trait_assignment/trait_assignment.cbs b/clang/test/BSC/Negative/Trait/r3/trait_assignment/trait_assignment.cbs index 9e7daaafa1479f2e7173f72b0f5f7dabb923edd1..52cf3014a9511b2af5edee062f8db0c092fc8a09 100644 --- a/clang/test/BSC/Negative/Trait/r3/trait_assignment/trait_assignment.cbs +++ b/clang/test/BSC/Negative/Trait/r3/trait_assignment/trait_assignment.cbs @@ -11,6 +11,6 @@ trait F* f() { int main() { int m = 0; - trait F* b = f(); // expected-error {{expected a pointer type which has implemented 'trait F', found 'struct __Trait_F'}} + trait F* b = f(); // expected-error {{expected a pointer type which has implemented 'trait F', found 'trait F *'}} return 0; } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Trait/r3/trait_cast_trait/trait_cast_trait.cbs b/clang/test/BSC/Negative/Trait/r3/trait_cast_trait/trait_cast_trait.cbs index 077cc6573fd31fdf71972f4eef78cda4e49e4316..1f4e27a9b908ab455dc7d8a2213ae5ee95df91e3 100644 --- a/clang/test/BSC/Negative/Trait/r3/trait_cast_trait/trait_cast_trait.cbs +++ b/clang/test/BSC/Negative/Trait/r3/trait_cast_trait/trait_cast_trait.cbs @@ -7,8 +7,8 @@ trait G {}; void test() { trait G *g; - trait F *q = g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'struct __Trait_G'}} - trait F *q1 = (trait F *)g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'struct __Trait_G'}} + trait F *q = g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'trait G *'}} + trait F *q1 = (trait F *)g; // expected-error {{expected a pointer type which has implemented 'trait F', found 'trait G *'}} q = g; // expected-error {{assigning to 'struct __Trait_F' from incompatible type 'trait G *'}} q1 = (trait F *)g; // expected-error {{assigning to 'struct __Trait_F' from incompatible type 'trait G *'}} } \ No newline at end of file