From fbce89e4c17fe4486beba5fad91822cfd551e8e9 Mon Sep 17 00:00:00 2001 From: Javier Alvarez Garcia Date: Tue, 2 Aug 2022 09:12:32 +0200 Subject: [PATCH] Fixes for type-conversions --- .../daedalean/TypeConversionsCheck.cpp | 18 ++++++++++++++++-- .../checkers/daedalean-type-conversions.cpp | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/daedalean/TypeConversionsCheck.cpp b/clang-tools-extra/clang-tidy/daedalean/TypeConversionsCheck.cpp index 6e531f8c6a0674..6206e15536e90b 100644 --- a/clang-tools-extra/clang-tidy/daedalean/TypeConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/daedalean/TypeConversionsCheck.cpp @@ -27,6 +27,7 @@ QualType getPointee(QualType type) { return llvm::cast(type)->getPointeeType(); } assert(false && "Not a valid pointer type!"); + return type; } bool hasPointerRepresentation(QualType type) { @@ -216,7 +217,8 @@ void TypeConversionsCheck::handleImplicitCast(clang::ASTContext *context, return; } - if (sourceType->isNullPtrType() && destType->isPointerType()) { + if (sourceType->isNullPtrType() && + (destType->isPointerType() || destType->isMemberPointerType())) { // Casting from nullptr to a pointer type is always allowed return; } @@ -226,7 +228,7 @@ void TypeConversionsCheck::handleImplicitCast(clang::ASTContext *context, return; } - if (sourceType->isBuiltinType()) { + if (llvm::isa(sourceType)) { const BuiltinType *Builtin = llvm::dyn_cast(sourceType); if ((Builtin->getKind() == BuiltinType::Kind::BuiltinFn) && destType->isFunctionPointerType()) { @@ -265,6 +267,18 @@ void TypeConversionsCheck::handleImplicitCast(clang::ASTContext *context, return; } + if (hasPointerRepresentation(sourceType) && + hasPointerRepresentation(destType)) { + const CXXRecordDecl *sourceRecord = + getPointee(sourceType)->getAsCXXRecordDecl(); + const CXXRecordDecl *destRecord = + getPointee(destType)->getAsCXXRecordDecl(); + if (sourceRecord && destRecord && sourceRecord->isDerivedFrom(destRecord)) { + // Cast pointer or reference from child to base MAY be implicit. + return; + } + } + diag(location, "Type conversions MUST be explicit"); diag(location, "Implicit conversion from %1 to %0", DiagnosticIDs::Note) << destType << sourceType; diff --git a/clang-tools-extra/test/clang-tidy/checkers/daedalean-type-conversions.cpp b/clang-tools-extra/test/clang-tidy/checkers/daedalean-type-conversions.cpp index 36e5e9ff00bcda..85f2a899dc9e5f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/daedalean-type-conversions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/daedalean-type-conversions.cpp @@ -73,7 +73,9 @@ void testImplicitCastFromDerivedPtrToBase() { // Implicit B to A is fine A &NonConstA{Obj}; + A *NonConstAPtr{&Obj}; static_cast(NonConstA); + static_cast(NonConstAPtr); } void testImplicitCastAddingQualifiers() {