diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -8914,12 +8914,16 @@ S.EmitRelatedResultTypeNoteForReturn(destType); } QualType fromType = op->getType(); - auto *fromDecl = fromType.getTypePtr()->getPointeeCXXRecordDecl(); - auto *destDecl = destType.getTypePtr()->getPointeeCXXRecordDecl(); + QualType fromPointeeType = fromType.getCanonicalType()->getPointeeType(); + QualType destPointeeType = destType.getCanonicalType()->getPointeeType(); + auto *fromDecl = fromType->getPointeeCXXRecordDecl(); + auto *destDecl = destType->getPointeeCXXRecordDecl(); if (fromDecl && destDecl && fromDecl->getDeclKind() == Decl::CXXRecord && destDecl->getDeclKind() == Decl::CXXRecord && !fromDecl->isInvalidDecl() && !destDecl->isInvalidDecl() && - !fromDecl->hasDefinition()) + !fromDecl->hasDefinition() && + destPointeeType.getQualifiers().compatiblyIncludes( + fromPointeeType.getQualifiers())) S.Diag(fromDecl->getLocation(), diag::note_forward_class_conversion) << S.getASTContext().getTagDeclType(fromDecl) << S.getASTContext().getTagDeclType(destDecl); diff --git a/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp b/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp --- a/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp +++ b/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp @@ -9,3 +9,9 @@ template class B2; B2 *b2; A2 *a2 = b2; // expected-error{{cannot initialize a variable of type 'A2 *' with an lvalue of type 'B2 *'}} + +typedef struct S s; +const s *f(); +s *g1() { return f(); } // expected-error{{cannot initialize return object of type 's *' (aka 'S *') with an rvalue of type 'const s *' (aka 'const S *')}} + +B1 *g2() { return f(); } // expected-error{{cannot initialize return object of type 'B1 *' with an rvalue of type 'const s *' (aka 'const S *')}} \ No newline at end of file