https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/130417
>From 1747df81cf0bf83838777a71ec577b083a66d85d Mon Sep 17 00:00:00 2001 From: Congcong Cai <congcongcai0...@163.com> Date: Sat, 8 Mar 2025 21:50:19 +0800 Subject: [PATCH] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` Fixes: #119554 --- .../bugprone/OptionalValueConversionCheck.cpp | 14 ++++++++++++++ clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++ ...ptional-value-conversion-construct-from-std.cpp | 13 +++++++++++++ 3 files changed, 31 insertions(+) diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 33e823ac07490..cb5a1c7bea801 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -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 @@ -86,6 +88,18 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { callee(functionDecl( matchers::matchesAnyListedName(MakeSmartPtrList), hasTemplateArgument(0, refersToType(BindOptionalType)))), + hasArgument(0, OptionalDerefMatcher)), + callExpr( + // 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); + argumentCountIs(1), + callee(functionDecl(templateArgumentCountIs(1), + hasName(MakeOptional), + returns(BindOptionalType))), hasArgument(0, OptionalDerefMatcher))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(matchers::hasUnevaluatedContext()))))) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ce1418a2a7d58..a726015a708f7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -115,6 +115,10 @@ Changes in existing checks no longer be needed and will be removed. Also fixing false positive from const reference accessors to objects containing optional member. +- 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-unsafe-functions <clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying additional C++ member functions to match. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp index 768ab1ce014ce..305fd6890710d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp @@ -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()); } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits