1// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-optional-value-conversion %t
2
3namespace std {
4template <typename T> struct optional {
5 constexpr optional() noexcept;
6 constexpr optional(T &&) noexcept;
7 constexpr optional(const T &) noexcept;
8 template <typename U> constexpr optional(U &&) noexcept;
9 const T &operator*() const;
10 T *operator->();
11 const T *operator->() const;
12 T &operator*();
13 const T &value() const;
14 T &value();
15 const T &get() const;
16 T &get();
17 T value_or(T) const;
18};
19
20template <class T> T &&move(T &x) { return static_cast<T &&>(x); }
21
22template <typename T> class default_delete {};
23
24template <typename type, typename Deleter = std::default_delete<type>>
25class unique_ptr {};
26
27template <typename type>
28class shared_ptr {};
29
30template <typename T>
31class initializer_list {};
32
33template <class T, class... Args> unique_ptr<T> make_unique(Args &&...args);
34template <class T, class... Args> shared_ptr<T> make_shared(Args &&...args);
35
36template <class T>
37constexpr std::optional<__decay(T)> make_optional(T &&value);
38template <class T, class... Args>
39constexpr std::optional<T> make_optional(Args &&...args);
40template <class T, class U, class... Args>
41constexpr std::optional<T> make_optional(std::initializer_list<U> il, Args &&...args);
42
43} // namespace std
44
45struct A {
46 explicit A (int);
47};
48std::optional<int> opt;
49
50void invalid() {
51 std::make_unique<std::optional<int>>(args&: opt.value());
52 // 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]
53 using A = std::optional<int>;
54 std::make_unique<A>(args&: opt.value());
55 // 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]
56 std::make_shared<std::optional<int>>(args&: opt.value());
57 // 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]
58 std::make_optional(value&: opt.value());
59 // 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]
60}
61
62void valid() {
63 std::make_unique<A>(args&: opt.value());
64 std::make_shared<A>(args&: opt.value());
65 std::make_optional<int>(args&: opt.value());
66}
67

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp