diff --git a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td index 6bbd8d5813c625adadafbe04ccb81e81cea00de2..06596c8367305565921260c8a4921d3f3a603e75 100644 --- a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td +++ b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td @@ -82,6 +82,8 @@ def warn_type_has_not_impl_trait : Warning< "expected a pointer type which has implemented %0, found %1">, InGroup; def err_trait_is_undefined : Error<"%0 must be defined before it can be used">; +def err_impl_trait_for_instantiated_type : Error< + "cannot impl trait for an instantiated type">; // BSC generic warnings and errors. def err_invalid_struct_definition : Error < diff --git a/clang/lib/Sema/BSC/SemaBSCTrait.cpp b/clang/lib/Sema/BSC/SemaBSCTrait.cpp index 64f3b4604086747446ba1f09fca6ca73624a131c..eb89af0024fb37123dbffd6299c4fa276e3aee9d 100644 --- a/clang/lib/Sema/BSC/SemaBSCTrait.cpp +++ b/clang/lib/Sema/BSC/SemaBSCTrait.cpp @@ -337,11 +337,22 @@ static bool IsImplTraitDeclIllegal(Sema &S, QualType TraitQT, QualType &ImplQT, QualType OriginTraitTy) { CXXScopeSpec SS; NamedDecl *Def = nullptr; - Sema::BoundTypeDiagnoser<> Diagnoser( - diag::err_typecheck_decl_incomplete_type); - if (ImplQT->isIncompleteType(&Def)) + if (ImplQT.getCanonicalType()->isRecordType()) { + const RecordDecl *RD = + ImplQT.getCanonicalType()->castAs()->getDecl(); + if (isa(RD)) { + S.Diag(TypeLoc, diag::err_impl_trait_for_instantiated_type); + return true; + } + } + + if (ImplQT->isIncompleteType(&Def)) { + Sema::BoundTypeDiagnoser<> Diagnoser( + diag::err_typecheck_decl_incomplete_type); Diagnoser.diagnose(S, TypeLoc, ImplQT); + return true; + } IdentifierInfo *FunctionID = nullptr; RecordDecl *VT = TD->getVtable(); diff --git a/clang/test/BSC/Negative/Generic/StructAndFunction/generic_type_without_tag/generic_type_without_tag.cbs b/clang/test/BSC/Negative/Generic/StructAndFunction/generic_type_without_tag/generic_type_without_tag.cbs index 2ef48bdc28718882c4c6582982a84ef78071ae3d..5f13faf9e4861f7bcd419e5c4c4443fd17d3465b 100644 --- a/clang/test/BSC/Negative/Generic/StructAndFunction/generic_type_without_tag/generic_type_without_tag.cbs +++ b/clang/test/BSC/Negative/Generic/StructAndFunction/generic_type_without_tag/generic_type_without_tag.cbs @@ -5,7 +5,7 @@ void S::foo(This* this) {} // expected-error {{extended type of a BSC memb trait F {}; impl trait F for S; // expected-error {{use of undeclared identifier 'T'}} -impl trait F for S; // expected-error {{variable has incomplete type 'struct S'}} +impl trait F for S; // expected-error {{cannot impl trait for an instantiated type}} void struct S::foo1(This* this) {} // expected-note {{previous definition is here}} diff --git a/clang/test/BSC/Negative/Trait/r3/impl_trait_for_generic_type/impl_trait_for_generic_type.cbs b/clang/test/BSC/Negative/Trait/r3/impl_trait_for_generic_type/impl_trait_for_generic_type.cbs new file mode 100644 index 0000000000000000000000000000000000000000..a5c2022fde4f0fb656c28696be4f5c74d68655c8 --- /dev/null +++ b/clang/test/BSC/Negative/Trait/r3/impl_trait_for_generic_type/impl_trait_for_generic_type.cbs @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +trait F{}; + +struct S {}; +union U {}; +impl trait F for S; // expected-error {{use of undeclared identifier 'T'}} +impl trait F for struct S; // expected-error {{use of undeclared identifier 'T'}} +impl trait F for S; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for struct S; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for U; // expected-error {{use of undeclared identifier 'T'}} +impl trait F for union U; // expected-error {{use of undeclared identifier 'T'}} +impl trait F for U; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for union U; // expected-error {{cannot impl trait for an instantiated type}} + +owned struct K {}; +impl trait F for K; // expected-error {{use of undeclared identifier 'T'}} +impl trait F for K; // expected-error {{cannot impl trait for an instantiated type}} + +struct M { + U u; + S s; + K k; +}; +impl trait F for U; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for union U; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for S; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for struct S; // expected-error {{cannot impl trait for an instantiated type}} +impl trait F for K; // expected-error {{cannot impl trait for an instantiated type}} \ No newline at end of file