214 lines
13 KiB
C++
214 lines
13 KiB
C++
|
// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-optional-value-conversion %t -- --fix-notes
|
||
|
// RUN: %check_clang_tidy -check-suffix=CUSTOM -std=c++17-or-later %s bugprone-optional-value-conversion %t -- \
|
||
|
// RUN: -config="{CheckOptions: {bugprone-optional-value-conversion.OptionalTypes: 'CustomOptional', \
|
||
|
// RUN: bugprone-optional-value-conversion.ValueMethods: '::Read$;::Ooo$'}}" --fix-notes
|
||
|
|
||
|
namespace std {
|
||
|
template<typename T>
|
||
|
struct optional
|
||
|
{
|
||
|
constexpr optional() noexcept;
|
||
|
constexpr optional(T&&) noexcept;
|
||
|
constexpr optional(const T&) noexcept;
|
||
|
template<typename U>
|
||
|
constexpr optional(U&&) noexcept;
|
||
|
const T& operator*() const;
|
||
|
T* operator->();
|
||
|
const T* operator->() const;
|
||
|
T& operator*();
|
||
|
const T& value() const;
|
||
|
T& value();
|
||
|
const T& get() const;
|
||
|
T& get();
|
||
|
T value_or(T) const;
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
T&& move(T &x) {
|
||
|
return static_cast<T&&>(x);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace boost {
|
||
|
template<typename T>
|
||
|
struct optional {
|
||
|
constexpr optional() noexcept;
|
||
|
constexpr optional(const T&) noexcept;
|
||
|
const T& operator*() const;
|
||
|
const T& get() const;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace absl {
|
||
|
template<typename T>
|
||
|
struct optional {
|
||
|
constexpr optional() noexcept;
|
||
|
constexpr optional(const T&) noexcept;
|
||
|
const T& operator*() const;
|
||
|
const T& value() const;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
struct CustomOptional {
|
||
|
CustomOptional();
|
||
|
CustomOptional(const T&);
|
||
|
const T& Read() const;
|
||
|
T& operator*();
|
||
|
T& Ooo();
|
||
|
};
|
||
|
|
||
|
void takeOptionalValue(std::optional<int>);
|
||
|
void takeOptionalRef(const std::optional<int>&);
|
||
|
void takeOptionalRRef(std::optional<int>&&);
|
||
|
void takeOtherOptional(std::optional<long>);
|
||
|
void takeBOptionalValue(boost::optional<int>);
|
||
|
void takeAOptionalValue(absl::optional<int>);
|
||
|
|
||
|
void incorrect(std::optional<int> param)
|
||
|
{
|
||
|
std::optional<int>* ptr = ¶m;
|
||
|
takeOptionalValue(**ptr);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(*ptr);
|
||
|
takeOptionalValue(*param);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(param);
|
||
|
takeOptionalValue(param.value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(param);
|
||
|
takeOptionalValue(ptr->value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(*ptr);
|
||
|
takeOptionalValue(param.operator*());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(param);
|
||
|
takeOptionalValue(ptr->operator*());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(*ptr);
|
||
|
takeOptionalRef(*param);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(param);
|
||
|
takeOptionalRef(param.value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(param);
|
||
|
takeOptionalRef(ptr->value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(*ptr);
|
||
|
takeOptionalRef(param.operator*());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(param);
|
||
|
takeOptionalRef(ptr->operator*());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(*ptr);
|
||
|
std::optional<int> p = *param;
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:26: 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-FIXES: std::optional<int> p = param;
|
||
|
|
||
|
takeOptionalValue(std::move(**ptr));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(std::move(*ptr));
|
||
|
takeOptionalValue(std::move(*param));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(std::move(param));
|
||
|
takeOptionalValue(std::move(param.value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(std::move(param));
|
||
|
takeOptionalValue(std::move(ptr->value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(std::move(*ptr));
|
||
|
takeOptionalValue(std::move(param.operator*()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(std::move(param));
|
||
|
takeOptionalRef(std::move(*param));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(std::move(param));
|
||
|
takeOptionalRef(std::move(param.value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(std::move(param));
|
||
|
takeOptionalRef(std::move(ptr->value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(std::move(*ptr));
|
||
|
takeOptionalRef(std::move(param.operator*()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:19: 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-FIXES: takeOptionalRef(std::move(param));
|
||
|
takeOptionalRRef(std::move(*param));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: 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-FIXES: takeOptionalRRef(std::move(param));
|
||
|
takeOptionalRRef(std::move(param.value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: 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-FIXES: takeOptionalRRef(std::move(param));
|
||
|
takeOptionalRRef(std::move(ptr->value()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: 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-FIXES: takeOptionalRRef(std::move(*ptr));
|
||
|
takeOptionalRRef(std::move(param.operator*()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: 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-FIXES: takeOptionalRRef(std::move(param));
|
||
|
takeOptionalRRef(std::move(ptr->operator*()));
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:20: 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-FIXES: takeOptionalRRef(std::move(*ptr));
|
||
|
std::optional<int> p2 = std::move(*param);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:27: 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-FIXES: std::optional<int> p2 = std::move(param);
|
||
|
|
||
|
std::optional<std::optional<int>> opt;
|
||
|
takeOptionalValue(opt->value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(*opt);
|
||
|
takeOptionalValue(opt->operator*());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:21: 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-FIXES: takeOptionalValue(*opt);
|
||
|
|
||
|
boost::optional<int> bopt;
|
||
|
takeBOptionalValue(*bopt);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: conversion from 'boost::optional<int>' into 'int' and back into 'boost::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES: takeBOptionalValue(bopt);
|
||
|
takeBOptionalValue(bopt.get());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: conversion from 'boost::optional<int>' into 'int' and back into 'boost::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES: takeBOptionalValue(bopt);
|
||
|
|
||
|
absl::optional<int> aopt;
|
||
|
takeAOptionalValue(*aopt);
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: conversion from 'absl::optional<int>' into 'int' and back into 'absl::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES: takeAOptionalValue(aopt);
|
||
|
takeAOptionalValue(aopt.value());
|
||
|
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: conversion from 'absl::optional<int>' into 'int' and back into 'absl::optional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES: takeAOptionalValue(aopt);
|
||
|
}
|
||
|
|
||
|
void takeCustom(const CustomOptional<int>&);
|
||
|
|
||
|
void testCustom(CustomOptional<int> param) {
|
||
|
takeCustom(*param);
|
||
|
// CHECK-MESSAGES-CUSTOM: :[[@LINE-1]]:14: warning: conversion from 'CustomOptional<int>' into 'int' and back into 'CustomOptional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES-CUSTOM: takeCustom(param);
|
||
|
takeCustom(param.Read());
|
||
|
// CHECK-MESSAGES-CUSTOM: :[[@LINE-1]]:14: warning: conversion from 'CustomOptional<int>' into 'int' and back into 'CustomOptional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES-CUSTOM: takeCustom(param);
|
||
|
takeCustom(param.Ooo());
|
||
|
// CHECK-MESSAGES-CUSTOM: :[[@LINE-1]]:14: warning: conversion from 'CustomOptional<int>' into 'int' and back into 'CustomOptional<int>', remove potentially error-prone optional dereference [bugprone-optional-value-conversion]
|
||
|
// CHECK-FIXES-CUSTOM: takeCustom(param);
|
||
|
}
|
||
|
|
||
|
void correct(std::optional<int> param)
|
||
|
{
|
||
|
takeOtherOptional(*param);
|
||
|
takeOtherOptional(param.value());
|
||
|
takeOtherOptional(param.value_or(5U));
|
||
|
takeOtherOptional(param.operator*());
|
||
|
|
||
|
std::optional<long> p = *param;
|
||
|
takeOptionalValue(param.value_or(5U));
|
||
|
takeOptionalRef(param.value_or(5U));
|
||
|
|
||
|
std::optional<int>* ptr = ¶m;
|
||
|
takeOtherOptional(**ptr);
|
||
|
takeOtherOptional(ptr->value());
|
||
|
takeOtherOptional(ptr->value_or(5U));
|
||
|
takeOtherOptional(ptr->operator*());
|
||
|
|
||
|
std::optional<long>* p2 = &p;
|
||
|
takeOptionalValue(p2->value_or(5U));
|
||
|
takeOptionalRef(p2->value_or(5U));
|
||
|
}
|