Skip to content

Commit e71d9b9

Browse files
committed
Abuse assignment operator
1 parent 98aff18 commit e71d9b9

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

include/pybind11/pytypes.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "buffer_info.h"
1414

1515
#include <exception>
16+
#include <stdexcept>
1617
#include <string>
1718
#include <type_traits>
1819
#include <utility>
@@ -387,13 +388,16 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
387388
}
388389
}
389390

390-
error_already_set(const error_already_set &) = default;
391-
error_already_set(error_already_set &&) = default;
391+
error_already_set(const error_already_set &) noexcept = default;
392+
error_already_set(error_already_set &&) noexcept = default;
392393

393394
inline ~error_already_set() override;
394395

395396
const char *what() const noexcept override {
396-
if (m_lazy_what.empty()) {
397+
auto *sup_what = std::runtime_error::what();
398+
if (sup_what[0] != '\0') {
399+
return sup_what;
400+
} else if (m_lazy_what.empty()) {
397401
try {
398402
m_lazy_what = detail::error_string(m_type.ptr(), m_value.ptr(), m_trace.ptr());
399403
} catch (const std::exception &e) {
@@ -407,6 +411,7 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
407411
return m_lazy_what.c_str();
408412
}
409413
}
414+
410415
assert(!m_lazy_what.empty());
411416
return m_lazy_what.c_str();
412417
}
@@ -415,7 +420,8 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
415420
/// already set it is cleared first. After this call, the current object no longer stores the
416421
/// error variables (but the `.what()` string is still available).
417422
void restore() {
418-
what(); // Force-build `.what()`.
423+
// Abuse assignment operator to cache what()
424+
std::runtime_error::operator=(std::runtime_error(what())); // Force-build `.what()`.
419425
if (m_lazy_what.empty()) {
420426
pybind11_fail("Critical error building lazy error_string().");
421427
}

0 commit comments

Comments
 (0)