1 // RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-optional-value-conversion %t
2 
3 namespace std {
4 template <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 
20 template <class T> T &&move(T &x) { return static_cast<T &&>(x); }
21 
22 template <typename T> class default_delete {};
23 
24 template <typename type, typename Deleter = std::default_delete<type>>
25 class unique_ptr {};
26 
27 template <typename type>
28 class shared_ptr {};
29 
30 template <class T, class... Args> unique_ptr<T> make_unique(Args &&...args);
31 template <class T, class... Args> shared_ptr<T> make_shared(Args &&...args);
32 
33 } // namespace std
34 
35 struct A {
36     explicit A (int);
37 };
38 std::optional<int> opt;
39 
40 void invalid() {
41   std::make_unique<std::optional<int>>(opt.value());
42   // 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]
43   using A = std::optional<int>;
44   std::make_unique<A>(opt.value());
45   // 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]
46   std::make_shared<std::optional<int>>(opt.value());
47   // 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]
48 }
49 
50 void valid() {
51   std::make_unique<A>(opt.value());
52   std::make_shared<A>(opt.value());
53 }
54