19 SourceType = SourceType.getNonReferenceType();
20 DestType = DestType.getNonReferenceType();
21 while (SourceType->isPointerType() && DestType->isPointerType()) {
22 SourceType = SourceType->getPointeeType();
23 DestType = DestType->getPointeeType();
24 if (SourceType.isConstQualified() && !DestType.isConstQualified())
36 const auto *MatchedCast = Result.Nodes.getNodeAs<CStyleCastExpr>(
"cast");
38 if (MatchedCast->getCastKind() == CK_BitCast ||
39 MatchedCast->getCastKind() == CK_LValueBitCast ||
40 MatchedCast->getCastKind() == CK_IntegralToPointer ||
41 MatchedCast->getCastKind() == CK_PointerToIntegral ||
42 MatchedCast->getCastKind() == CK_ReinterpretMemberPointer) {
43 diag(MatchedCast->getBeginLoc(),
44 "do not use C-style cast to convert between unrelated types");
48 QualType SourceType = MatchedCast->getSubExpr()->getType();
50 if (MatchedCast->getCastKind() == CK_BaseToDerived) {
51 const auto *SourceDecl = SourceType->getPointeeCXXRecordDecl();
53 SourceDecl = SourceType->getAsCXXRecordDecl();
57 if (SourceDecl->isPolymorphic()) {
61 StringRef DestTypeString = Lexer::getSourceText(
62 CharSourceRange::getTokenRange(
63 MatchedCast->getLParenLoc().getLocWithOffset(1),
64 MatchedCast->getRParenLoc().getLocWithOffset(-1)),
65 *Result.SourceManager, getLangOpts());
67 auto DiagBuilder = diag(
68 MatchedCast->getBeginLoc(),
69 "do not use C-style cast to downcast from a base to a derived class; "
70 "use dynamic_cast instead");
73 MatchedCast->getSubExprAsWritten()->IgnoreImpCasts();
74 std::string CastText = (
"dynamic_cast<" + DestTypeString +
">").str();
75 if (!isa<ParenExpr>(SubExpr)) {
76 CastText.push_back(
'(');
77 DiagBuilder << FixItHint::CreateInsertion(
78 Lexer::getLocForEndOfToken(SubExpr->getEndLoc(), 0,
79 *Result.SourceManager, getLangOpts()),
82 auto ParenRange = CharSourceRange::getTokenRange(
83 MatchedCast->getLParenLoc(), MatchedCast->getRParenLoc());
84 DiagBuilder << FixItHint::CreateReplacement(ParenRange, CastText);
87 MatchedCast->getBeginLoc(),
88 "do not use C-style cast to downcast from a base to a derived class");
93 if (MatchedCast->getCastKind() == CK_NoOp &&
95 diag(MatchedCast->getBeginLoc(),
96 "do not use C-style cast to cast away constness");