[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 "../utils/OptionsUtils.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||||
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
using namespace clang::ast_matchers;
|
using namespace clang::ast_matchers;
|
||||||
@ -31,6 +32,7 @@ constexpr std::array<StringRef, 2> MakeSmartPtrList{
|
|||||||
"::std::make_unique",
|
"::std::make_unique",
|
||||||
"::std::make_shared",
|
"::std::make_shared",
|
||||||
};
|
};
|
||||||
|
constexpr StringRef MakeOptional = "::std::make_optional";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -83,9 +85,26 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) {
|
|||||||
// known template methods in std
|
// known template methods in std
|
||||||
callExpr(
|
callExpr(
|
||||||
argumentCountIs(1),
|
argumentCountIs(1),
|
||||||
|
anyOf(
|
||||||
|
// match std::make_unique std::make_shared
|
||||||
callee(functionDecl(
|
callee(functionDecl(
|
||||||
matchers::matchesAnyListedName(MakeSmartPtrList),
|
matchers::matchesAnyListedName(MakeSmartPtrList),
|
||||||
hasTemplateArgument(0, refersToType(BindOptionalType)))),
|
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))),
|
hasArgument(0, OptionalDerefMatcher))),
|
||||||
unless(anyOf(hasAncestor(typeLoc()),
|
unless(anyOf(hasAncestor(typeLoc()),
|
||||||
hasAncestor(expr(matchers::hasUnevaluatedContext())))))
|
hasAncestor(expr(matchers::hasUnevaluatedContext())))))
|
||||||
|
@ -112,6 +112,10 @@ New check aliases
|
|||||||
Changes in existing checks
|
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
|
- Improved :doc:`bugprone-string-constructor
|
||||||
<clang-tidy/checks/bugprone/string-constructor>` check to find suspicious
|
<clang-tidy/checks/bugprone/string-constructor>` check to find suspicious
|
||||||
calls of ``std::string`` constructor with char pointer, start position and
|
calls of ``std::string`` constructor with char pointer, start position and
|
||||||
|
@ -27,9 +27,19 @@ class unique_ptr {};
|
|||||||
template <typename type>
|
template <typename type>
|
||||||
class shared_ptr {};
|
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> unique_ptr<T> make_unique(Args &&...args);
|
||||||
template <class T, class... Args> shared_ptr<T> make_shared(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
|
} // namespace std
|
||||||
|
|
||||||
struct A {
|
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]
|
// 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());
|
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]
|
// 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() {
|
void valid() {
|
||||||
std::make_unique<A>(opt.value());
|
std::make_unique<A>(opt.value());
|
||||||
std::make_shared<A>(opt.value());
|
std::make_shared<A>(opt.value());
|
||||||
|
std::make_optional<int>(opt.value());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user