This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Add new check 'shared-ptr-array-mismatch'.
ClosedPublic

Authored by balazske on Jan 14 2022, 6:42 AM.

Diff Detail

Event Timeline

balazske created this revision.Jan 14 2022, 6:42 AM
balazske requested review of this revision.Jan 14 2022, 6:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 14 2022, 6:42 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

I think this check belongs to bugprone module. How about std::unique_ptr?

clang-tools-extra/clang-tidy/misc/SharedPtrArrayMismatchCheck.cpp
1 ↗(On Diff #399970)

Please make it same length and single line as closing comment.

clang-tools-extra/docs/clang-tidy/checks/misc-shared-ptr-array-mismatch.rst
6 ↗(On Diff #399970)

Please make first statement same as in Release Notes.

How does this check play with the modernize-make-shared check?

clang-tools-extra/clang-tidy/misc/SharedPtrArrayMismatchCheck.cpp
21–26 ↗(On Diff #399970)

If you're not doing anything different in the c'tor I think you can
eliminate this definition and just lift the visibility of the base class
c'tor in the class declaration:

using ClangTidyCheck::ClangTidyCheck;
39 ↗(On Diff #399970)

What about the other constructor overloads?
Creating a shared_ptr with a deleter is quite common.

104 ↗(On Diff #399970)

I'm not sure what this is doing?

106 ↗(On Diff #399970)

Is this to guard against multiple variables being declared at once?

How does this check play with the modernize-make-shared check?

Wouldn't it be orthogonal?

This check looks for existing make_shared usages, whereas
modernize-make-shared adds new make_shared usages from
new shared_ptr usages. I wouldn't expect modernize-make-shared
to generate mismatched scalar/array shared_ptr instances.

I am not sure if it is correct to have replacement (fixit) for a part of the cases only. It is not possible to make a fixit for every use. In a case like shared_ptr<int> p1{new int}, p2{new int[10]}; the type can not be changed without other changes. For this reason the replacement is offered only for single-variable declarations.

Is there a fast way to find single-variable field declaration?

class A {
  shared_ptr<int> F1{new int}, F2{new int[10]};
};

The FieldDecl does not contain information like DeclStmt::isSingleDecl. The only way looks like to check the source locations.

How does this check play with the modernize-make-shared check?

Wouldn't it be orthogonal?

This check looks for existing make_shared usages, whereas
modernize-make-shared adds new make_shared usages from
new shared_ptr usages. I wouldn't expect modernize-make-shared
to generate mismatched scalar/array shared_ptr instances.

This check looks for constructions of shared_ptr types from an array new expression. modernize-make-shared looks for constructions of shared_ptr types using the new expression, However I'm not sure how it handles the array version.

balazske marked 2 inline comments as done.Jan 17 2022, 4:04 AM

How does this check play with the modernize-make-shared check?

Wouldn't it be orthogonal?

This check looks for existing make_shared usages, whereas
modernize-make-shared adds new make_shared usages from
new shared_ptr usages. I wouldn't expect modernize-make-shared
to generate mismatched scalar/array shared_ptr instances.

This check looks for constructions of shared_ptr types from an array new expression. modernize-make-shared looks for constructions of shared_ptr types using the new expression, However I'm not sure how it handles the array version.

I found out that make_shared can not handle array at all (until C++20, but I do not plan to handle such new features). modernize-make-shared should not transform into make_shared if an array is created (if it works correct) but I do not see test cases for this.

clang-tools-extra/clang-tidy/misc/SharedPtrArrayMismatchCheck.cpp
39 ↗(On Diff #399970)

The intent is to find cases where no deleter is specified. If a deleter is used we can not tell in reliable way if it is correct for an array. The check assumes that a deleter is correct and needs no check.

104 ↗(On Diff #399970)

I think that this adds the additional range to the bug report. It is shown in the output (but I did not find a way how to check it in the test).

106 ↗(On Diff #399970)

Yes, this is to check for "single variable declaration". But works only for variables (not fields).

LGTM, but there are still some outstanding review comments.

balazske updated this revision to Diff 400791.Jan 18 2022, 3:18 AM
  • Moved to bugprone module.
  • Introduced a common base class, it is possible to add similar check for unique_ptr.
  • Documentation changes.

Possible improvement: Add the check for reset too.

clang-tools-extra/test/clang-tidy/checkers/modernize-make-shared.cpp
48 ↗(On Diff #400791)

This change was not intentional (should be removed).

steakhal added inline comments.Jan 19 2022, 2:56 AM
clang-tools-extra/docs/clang-tidy/checks/bugprone-shared-ptr-array-mismatch.rst
23

typo

balazske updated this revision to Diff 402439.Jan 24 2022, 2:16 AM

Fixed small issues.

clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.h
41

There's only one implementation of this abstract method declared here.

Why the extra level in the class hierarchy if there's only one implementation?

njames93 added inline comments.Feb 3 2022, 5:05 AM
clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp
42–48
clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.h
41

The idea I think is so that this can be used to make a similar check for unique_ptr. However I almost don't see the need for this, and I'd argue that they should both be implemented in one check. So this will detect

std::shared_ptr<int> X = new int[5];
std::unique_ptr<int> Y = new int[5];
balazske marked an inline comment as done.Feb 4 2022, 7:40 AM
balazske added inline comments.
clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.h
41

If I remember correctly the idea was to make the possible check for unique_ptr. Putting it into a separate check allows to independently turn the checks for shared or unique pointer on or off (like MakeSmartPtrCheck).

balazske updated this revision to Diff 405971.Feb 4 2022, 7:48 AM

Code simplification.

balazske marked an inline comment as done.Feb 4 2022, 7:49 AM
This revision is now accepted and ready to land.Feb 4 2022, 9:17 AM
This revision was landed with ongoing or failed builds.Feb 7 2022, 3:59 AM
This revision was automatically updated to reflect the committed changes.