[llvm-branch-commits] [clang-tools-extra] [clang-tidy] support to detect conversion in `make_optional` for `bugprone-optional-value-conversion` (PR #130417)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Mar 8 05:54:38 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy

Author: Congcong Cai (HerrCai0907)

<details>
<summary>Changes</summary>

Fixes: #<!-- -->119554

---
Full diff: https://github.com/llvm/llvm-project/pull/130417.diff


3 Files Affected:

- (modified) clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp (+18) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4) 
- (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp (+13) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp
index 33e823ac07490..a3c6bebe3d17f 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;
@@ -27,10 +28,15 @@ AST_MATCHER_P(QualType, hasCleanType, Matcher<QualType>, InnerMatcher) {
       Finder, Builder);
 }
 
+AST_MATCHER_P(FunctionDecl, hasReturnType, Matcher<QualType>, InnerMatcher) {
+  return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
+}
+
 constexpr std::array<StringRef, 2> MakeSmartPtrList{
     "::std::make_unique",
     "::std::make_shared",
 };
+constexpr StringRef MakeOptional = "::std::make_optional";
 
 } // namespace
 
@@ -86,6 +92,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),
+                                       hasReturnType(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());
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/130417


More information about the llvm-branch-commits mailing list