Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions libcxx/include/__exception/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ class exception { // base of all library exceptions

virtual ~exception() _NOEXCEPT {}

virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
[[__nodiscard__]] virtual char const* what() const _NOEXCEPT {
return __data_._What ? __data_._What : "Unknown exception";
}

private:
__std_exception_data __data_;
Expand All @@ -76,7 +78,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception {
_LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;

virtual ~exception() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
[[__nodiscard__]] virtual const char* what() const _NOEXCEPT;
};

class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
Expand All @@ -85,7 +87,7 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
_LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
~bad_exception() _NOEXCEPT override;
const char* what() const _NOEXCEPT override;
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
};
#endif // !_LIBCPP_ABI_VCRUNTIME

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__exception/nested_exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class _LIBCPP_EXPORTED_FROM_ABI nested_exception {

// access functions
[[__noreturn__]] void rethrow_nested() const;
_LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
};

template <class _Tp>
Expand Down
10 changes: 5 additions & 5 deletions libcxx/include/__exception/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
defined(_LIBCPP_BUILDING_LIBRARY)
using unexpected_handler = void (*)();
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void unexpected();
#endif

using terminate_handler = void (*)();
_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT;

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
_LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 bool uncaught_exception() _NOEXCEPT;
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION)
_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT;

class _LIBCPP_EXPORTED_FROM_ABI exception_ptr;

_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
[[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD

Expand Down
14 changes: 7 additions & 7 deletions libcxx/include/__system_error/error_category.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class _LIBCPP_EXPORTED_FROM_ABI error_category {
error_category(const error_category&) = delete;
error_category& operator=(const error_category&) = delete;

virtual const char* name() const _NOEXCEPT = 0;
virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
virtual string message(int __ev) const = 0;
[[__nodiscard__]] virtual const char* name() const _NOEXCEPT = 0;
[[__nodiscard__]] virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
[[__nodiscard__]] virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
[[__nodiscard__]] virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
[[__nodiscard__]] virtual string message(int __ev) const = 0;

_LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; }

Expand All @@ -67,8 +67,8 @@ class _LIBCPP_HIDDEN __do_message : public error_category {
string message(int __ev) const override;
};

[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
[[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;
[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT;
[[__gnu__::__const__]] [[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT;

_LIBCPP_END_NAMESPACE_STD

Expand Down
10 changes: 5 additions & 5 deletions libcxx/include/__system_error/error_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,20 @@ class _LIBCPP_EXPORTED_FROM_ABI error_code {
__cat_ = &system_category();
}

_LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }

_LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }

_LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT {
return __cat_->default_error_condition(__val_);
}

string message() const;
[[__nodiscard__]] string message() const;

_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
};

inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT {
return error_code(static_cast<int>(__e), generic_category());
}

Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/__system_error/error_condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ class _LIBCPP_EXPORTED_FROM_ABI error_condition {
__cat_ = &generic_category();
}

_LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; }

_LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
string message() const;
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; }
[[__nodiscard__]] string message() const;

_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; }
};

inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT {
return error_condition(static_cast<int>(__e), generic_category());
}

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__system_error/system_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class _LIBCPP_EXPORTED_FROM_ABI system_error : public runtime_error {
_LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default;
~system_error() _NOEXCEPT override;

_LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; }
};

// __ev is expected to be an error in the generic_category domain (e.g. from
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/stdexcept
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public:

~logic_error() _NOEXCEPT override;

const char* what() const _NOEXCEPT override;
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
# else

public:
Expand All @@ -115,7 +115,7 @@ public:

~runtime_error() _NOEXCEPT override;

const char* what() const _NOEXCEPT override;
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
# else

public:
Expand Down
108 changes: 108 additions & 0 deletions libcxx/test/libcxx/diagnostics/syserr/nodiscard.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// Check that functions are marked [[nodiscard]]

#include <stdexcept>
#include <system_error>

void test() {
{ // <stdexcept>
std::logic_error le("logic error");
le.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::runtime_error re("runtime error");
re.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::domain_error de("domain error");
de.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::invalid_argument ia("invalid argument");
ia.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::length_error lerr("length error");
lerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::out_of_range oor("out of range");
oor.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::range_error rerr("range error");
rerr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::overflow_error oferr("overflow error");
oferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

std::underflow_error uferr("underflow error");
uferr.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{ // <system_error>
{
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::generic_category();

const std::error_category& ec = std::generic_category();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.name();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.default_error_condition(94);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.equivalent(94, ec.default_error_condition(82));
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.equivalent(std::error_code(49, ec), 94);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.message(82);
}
{
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::system_category();

const std::error_category& ec = std::system_category();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.name();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.default_error_condition(94);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.equivalent(94, ec.default_error_condition(82));
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.equivalent(std::error_code(49, ec), 94);
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.message(82);
}
{
std::error_code ec;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.value();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.category();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.default_error_condition();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.message();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_error_code(std::errc::invalid_argument);
}
{
std::error_condition ec;

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.value();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.category();
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
ec.message();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::make_error_condition(std::errc::invalid_argument);
}
}
}
41 changes: 40 additions & 1 deletion libcxx/test/libcxx/language.support/nodiscard.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03
// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION

// Check that functions are marked [[nodiscard]]

#include <compare>
#include <coroutine>
#include <exception>
#include <functional>
#include <initializer_list>

Expand Down Expand Up @@ -81,11 +84,47 @@ void test() {
}
#endif

{ // <exception>
{
std::bad_exception bex;

bex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{
std::exception ex;

ex.what(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
{
std::nested_exception nex;

nex.nested_ptr(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}

#if TEST_STD_VER <= 14
std::get_unexpected(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
#endif

std::get_terminate(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}

#if _LIBCPP_STD_VER <= 17
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::uncaught_exception();
#endif
// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::uncaught_exceptions();

// expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
std::current_exception();
}

#if TEST_STD_VER >= 11
{ // <initializer_list>
std::initializer_list<int> il{94, 82, 49};

il.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
il.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
il.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#endif
}
Loading