[clang-tidy] support to detect conversion in make_optional
for bugprone-optional-value-conversion
(#130417)
Add support for std::make_optional. Fixes #119554
This commit is contained in:
parent
4d6ca11622
commit
0e4ba47ca8
@ -12,6 +12,7 @@
|
||||
#include "../utils/OptionsUtils.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include <array>
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
@ -31,6 +32,7 @@ constexpr std::array<StringRef, 2> MakeSmartPtrList{
|
||||
"::std::make_unique",
|
||||
"::std::make_shared",
|
||||
};
|
||||
constexpr StringRef MakeOptional = "::std::make_optional";
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -83,9 +85,26 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// known template methods in std
|
||||
callExpr(
|
||||
argumentCountIs(1),
|
||||
callee(functionDecl(
|
||||
matchers::matchesAnyListedName(MakeSmartPtrList),
|
||||
hasTemplateArgument(0, refersToType(BindOptionalType)))),
|
||||
anyOf(
|
||||
// match std::make_unique std::make_shared
|
||||
callee(functionDecl(
|
||||
matchers::matchesAnyListedName(MakeSmartPtrList),
|
||||
hasTemplateArgument(
|
||||
0, refersToType(BindOptionalType)))),
|
||||
// match first std::make_optional by limit argument count
|
||||
// (1) and template count (1).
|
||||
// 1. template< class T > constexpr
|
||||
// std::optional<decay_t<T>> make_optional(T&& value);
|
||||
// 2. template< class T, class... Args > constexpr
|
||||
// std::optional<T> make_optional(Args&&... args);
|
||||
callee(functionDecl(templateArgumentCountIs(1),
|
||||
hasName(MakeOptional),
|
||||
returns(BindOptionalType)))),
|
||||
hasArgument(0, OptionalDerefMatcher)),
|
||||
callExpr(
|
||||
|
||||
argumentCountIs(1),
|
||||
|
||||
hasArgument(0, OptionalDerefMatcher))),
|
||||
unless(anyOf(hasAncestor(typeLoc()),
|
||||
hasAncestor(expr(matchers::hasUnevaluatedContext())))))
|
||||
|
@ -112,6 +112,10 @@ New check aliases
|
||||
Changes in existing checks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Improved :doc:`bugprone-optional-value-conversion
|
||||
<clang-tidy/checks/bugprone/optional-value-conversion>` check to detect
|
||||
conversion in argument of ``std::make_optional``.
|
||||
|
||||
- Improved :doc:`bugprone-string-constructor
|
||||
<clang-tidy/checks/bugprone/string-constructor>` check to find suspicious
|
||||
calls of ``std::string`` constructor with char pointer, start position and
|
||||
|
@ -27,9 +27,19 @@ class unique_ptr {};
|
||||
template <typename type>
|
||||
class shared_ptr {};
|
||||
|
||||
template <typename T>
|
||||
class initializer_list {};
|
||||
|
||||
template <class T, class... Args> unique_ptr<T> make_unique(Args &&...args);
|
||||
template <class T, class... Args> shared_ptr<T> make_shared(Args &&...args);
|
||||
|
||||
template <class T>
|
||||
constexpr std::optional<__decay(T)> make_optional(T &&value);
|
||||
template <class T, class... Args>
|
||||
constexpr std::optional<T> make_optional(Args &&...args);
|
||||
template <class T, class U, class... Args>
|
||||
constexpr std::optional<T> make_optional(std::initializer_list<U> il, Args &&...args);
|
||||
|
||||
} // namespace std
|
||||
|
||||
struct A {
|
||||
@ -45,9 +55,12 @@ void invalid() {
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional<int>' into 'int' and back into 'std::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||||
std::make_shared<std::optional<int>>(opt.value());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional<int>' into 'int' and back into 'std::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||||
std::make_optional(opt.value());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional<int>' into 'int' and back into 'std::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||||
}
|
||||
|
||||
void valid() {
|
||||
std::make_unique<A>(opt.value());
|
||||
std::make_shared<A>(opt.value());
|
||||
std::make_optional<int>(opt.value());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user