[PATCH] D50852: [clang-tidy] abseil-auto-make-unique

Jonas Toth via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 16 13:52:21 PDT 2018


JonasToth added inline comments.


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:21
+void AutoMakeUniqueCheck::registerMatchers(MatchFinder* finder) {
+  if (!getLangOpts().CPlusPlus) return;
+
----------------
Please clang-format, `return` on next line.


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:23
+
+  using clang::ast_matchers::isTemplateInstantiation;
+  auto is_instantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
----------------
`clang::ast_matchers` is used already at line 14. No need to add this line.


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:27
+                                     functionDecl(isTemplateInstantiation())));
+  // There should be no additional expressions inbetween.
+  // E.g. this statement contains implicitCastExpr which makes it not eligible:
----------------
This sentence misses something. inbetween what?


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:34
+                      has(ignoringParenImpCasts(callExpr(callee(functionDecl(
+                          hasAnyName("absl::MakeUnique", "absl::make_unique",
+                                     "gtl::MakeUnique", "std::make_unique"),
----------------
The same rules apply for `make_shared`.

`make_pair` would be interesting as well, are there are standard `make_` templates?


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:51
+      var->getType()->getAsCXXRecordDecl());
+  if (!unique) return nullptr;
+  QualType type = unique->getTemplateArgs().get(0).getAsType();
----------------
Formatting and Naming conventions.

I think the following is more readable:

```
if (const auto* Unique = dyn_cast<ClassTemplateSpecializationDecl>(var...)) {
  // stuff with var
}

return nullptr;
```


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:57
+const Type* GetMakeUniqueType(const FunctionDecl* make_unique_decl) {
+  const auto& template_arg =
+      make_unique_decl->getTemplateSpecializationInfo()->TemplateArguments->get(
----------------
Naming conventions.


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:64
+void AutoMakeUniqueCheck::check(
+    const ast_matchers::MatchFinder::MatchResult& result) {
+  const auto* var_decl = result.Nodes.getNodeAs<VarDecl>("var_decl");
----------------
You don't need the `ast_matchers` namespace here.

Please follow the naming convention inside the function.


================
Comment at: clang-tidy/abseil/AutoMakeUniqueCheck.cpp:69
+  if (var_decl->isOutOfLine()) {
+    // "auto Struct::field = make_unique<...>();" doesn't work in GCC.
+    return;
----------------
What exactly is the issue here in GCC? Please make this comment more explanatory and maybe add a `FIXME` to work around the issue (depending on the nature of the issue)


================
Comment at: docs/ReleaseNotes.rst:63
+
+  FIXME: add release notes.
+
----------------
Please add release notes.


================
Comment at: docs/clang-tidy/checks/abseil-auto-make-unique.rst:11
+  std::unique_ptr<Foo> x = MakeUnique<Foo>(...);
+
+with
----------------
Please add documentation that the 'Abstract Factory' use case is resolved correctly.


================
Comment at: test/clang-tidy/abseil-auto-make-unique.cpp:34
+void Primitive() {
+  std::unique_ptr<int> x = absl::make_unique<int>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'auto' to avoid repeating the type name
----------------
How does the code look with multiple variable declarations?

Please add a test for
```
std::unique_ptr<int> x = absl::make_unique<int>(), y = absl::make_unique<int>(), z;
```


================
Comment at: test/clang-tidy/abseil-auto-make-unique.cpp:73
+  // Different type. No change.
+  std::unique_ptr<Base> z = make_unique<Derived>();
+  std::unique_ptr<Base> z2(make_unique<Derived>());
----------------
lets consider a 3 level class hierarchy.

```
struct A { virtual void Something(); };
struct B : A { void Something() override; };
struct C : B { void Something() override; };

std::unique_ptr<B> b_ptr = make_unique<B>(), c_ptr = make_unique<C>();
std::unique_ptr<B> c_ptr2 = make_unique<C>(), b_ptr2 = make_unique<B>();
```

What is the behaviour? I expect that these places break when transformed. To avoid you can check the `VarDecl` `isSingleDecl()` (or similar, i forgot the exact name) and only emit a fixit if it is.
Doing type transformations for the multi-definitions is tricky.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50852





More information about the cfe-commits mailing list