Index: clang-tidy/modernize/MakeSmartPtrCheck.cpp =================================================================== --- clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -25,8 +25,7 @@ constexpr char ResetCall[] = "resetCall"; constexpr char NewExpression[] = "newExpression"; -std::string GetNewExprName(const CXXNewExpr *NewExpr, - const SourceManager &SM, +std::string GetNewExprName(const CXXNewExpr *NewExpr, const SourceManager &SM, const LangOptions &Lang) { StringRef WrittenName = Lexer::getSourceText( CharSourceRange::getTokenRange( @@ -42,8 +41,7 @@ const char MakeSmartPtrCheck::PointerType[] = "pointerType"; -MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, - ClangTidyContext* Context, +MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, StringRef MakeSmartPtrFunctionName) : ClangTidyCheck(Name, Context), IncludeStyle(utils::IncludeSorter::parseIncludeStyle( @@ -77,7 +75,6 @@ void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { if (!isLanguageVersionSupported(getLangOpts())) return; - // Calling make_smart_ptr from within a member function of a type with a // private or protected constructor would be ill-formed. auto CanCallCtor = unless(has(ignoringImpCasts( @@ -87,11 +84,14 @@ cxxBindTemporaryExpr(has(ignoringParenImpCasts( cxxConstructExpr( hasType(getSmartPointerTypeMatcher()), argumentCountIs(1), - hasArgument(0, - cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( - equalsBoundNode(PointerType))))), - CanCallCtor) - .bind(NewExpression)), + hasArgument( + 0, + cxxNewExpr(anyOf(hasType(pointsTo(qualType(hasCanonicalType( + equalsBoundNode(PointerType))))), + hasType(pointsTo(cxxRecordDecl(anyOf( + isClass(), isStruct()))))), + CanCallCtor) + .bind(NewExpression)), unless(isInTemplateInstantiation())) .bind(ConstructorCall)))), this); @@ -110,7 +110,6 @@ // 'smart_ptr' refers to 'std::shared_ptr' or 'std::unique_ptr' or other // pointer, 'make_smart_ptr' refers to 'std::make_shared' or // 'std::make_unique' or other function that creates smart_ptr. - SourceManager &SM = *Result.SourceManager; const auto *Construct = Result.Nodes.getNodeAs(ConstructorCall); @@ -124,6 +123,13 @@ if (New->getType()->getPointeeType()->getContainedAutoType()) return; + // Skip classes from different hierarchies + const auto *NewAllocatedRecord = + New->getAllocatedType().getTypePtr()->getAsCXXRecordDecl(); + const auto *OriginalPointerRecord = Type->getTypePtr()->getAsCXXRecordDecl(); + if (NewAllocatedRecord != nullptr && OriginalPointerRecord != nullptr && + !NewAllocatedRecord->isDerivedFrom(OriginalPointerRecord)) + return; // Be conservative for cases where we construct an array without any // initalization. // For example, @@ -145,7 +151,6 @@ const CXXNewExpr *New) { SourceLocation ConstructCallStart = Construct->getExprLoc(); bool InMacro = ConstructCallStart.isMacroID(); - if (InMacro && IgnoreMacros) { return; } @@ -178,8 +183,7 @@ // we have to add it back. ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size()); Diag << FixItHint::CreateInsertion( - ConstructCallEnd, - "<" + GetNewExprName(New, SM, getLangOpts()) + ">"); + ConstructCallEnd, "<" + GetNewExprName(New, SM, getLangOpts()) + ">"); } else { ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle); } @@ -277,7 +281,7 @@ return false; std::string ArraySizeExpr; - if (const auto* ArraySize = New->getArraySize()) { + if (const auto *ArraySize = New->getArraySize()) { ArraySizeExpr = Lexer::getSourceText(CharSourceRange::getTokenRange( ArraySize->getSourceRange()), SM, getLangOpts()) @@ -343,8 +347,7 @@ Diag << FixItHint::CreateRemoval( SourceRange(NewStart, InitRange.getBegin())); Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd)); - } - else { + } else { // New array expression with default/value initialization: // smart_ptr(new int[5]()); // smart_ptr(new Foo[5]());