Skip to content

Commit 289e33d

Browse files
[SYCL] Make sycl::exception nothrow copy constructible (#6571)
Due to std::string not being nothrow copy constructible, neither is sycl::exception. As a throw in the copy constructor when throwing an exception will cause a termination of the program, sycl::exception should never be able to throw. These changes make sycl::exception nothrow copy constructible by making its std::string member a shared pointer. Signed-off-by: Larsen, Steffen <[email protected]> Co-authored-by: aelovikov-intel <[email protected]>
1 parent 417b5a2 commit 289e33d

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

sycl/include/sycl/exception.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ class __SYCL_EXPORT exception : public std::exception {
9797
cl_int get_cl_code() const;
9898

9999
private:
100-
std::string MMsg;
100+
// Exceptions must be noexcept copy constructible, so cannot use std::string
101+
// directly.
102+
std::shared_ptr<std::string> MMsg;
101103
pi_int32 MPIErr;
102104
std::shared_ptr<context> MContext;
103105

@@ -108,8 +110,9 @@ class __SYCL_EXPORT exception : public std::exception {
108110
: exception(std::string(Msg), PIErr, Context) {}
109111
exception(const std::string &Msg, const pi_int32 PIErr,
110112
std::shared_ptr<context> Context = nullptr)
111-
: MMsg(Msg + " " + detail::codeToString(PIErr)), MPIErr(PIErr),
112-
MContext(Context) {}
113+
: MMsg(std::make_shared<std::string>(Msg + " " +
114+
detail::codeToString(PIErr))),
115+
MPIErr(PIErr), MContext(Context) {}
113116

114117
// base constructors used by SYCL 1.2.1 exception subclasses
115118
exception(std::error_code ec, const char *Msg, const pi_int32 PIErr,
@@ -122,7 +125,8 @@ class __SYCL_EXPORT exception : public std::exception {
122125
MPIErr = PIErr;
123126
}
124127

125-
exception(const std::string &Msg) : MMsg(Msg), MContext(nullptr) {}
128+
exception(const std::string &Msg)
129+
: MMsg(std::make_shared<std::string>(Msg)), MContext(nullptr) {}
126130

127131
// base constructor for all SYCL 2020 constructors
128132
// exception(context *ctxPtr, std::error_code ec, const std::string

sycl/source/exception.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,12 @@ exception::exception(context Ctx, int EV, const std::error_category &ECat)
6565
// protected base constructor for all SYCL 2020 constructors
6666
exception::exception(std::error_code EC, std::shared_ptr<context> SharedPtrCtx,
6767
const std::string &WhatArg)
68-
: MMsg(WhatArg + ReservedForErrorcode), MPIErr(PI_ERROR_INVALID_VALUE),
69-
MContext(SharedPtrCtx) {
68+
: MMsg(std::make_shared<std::string>(WhatArg + ReservedForErrorcode)),
69+
MPIErr(PI_ERROR_INVALID_VALUE), MContext(SharedPtrCtx) {
7070
// For compatibility with previous implementation, we are "hiding" the
7171
// std::error_code in the MMsg string, behind the null string terminator
72-
const int StringTermPoint = MMsg.length() - strlen(ReservedForErrorcode);
73-
char *ReservedPtr = &MMsg[StringTermPoint];
72+
const int StringTermPoint = MMsg->length() - strlen(ReservedForErrorcode);
73+
char *ReservedPtr = &(*MMsg)[StringTermPoint];
7474
ReservedPtr[0] = '\0';
7575
ReservedPtr++;
7676
// insert error code
@@ -79,9 +79,9 @@ exception::exception(std::error_code EC, std::shared_ptr<context> SharedPtrCtx,
7979
}
8080

8181
const std::error_code &exception::code() const noexcept {
82-
const char *WhatStr = MMsg.c_str();
82+
const char *WhatStr = MMsg->c_str();
8383
// advance to inner string-terminator
84-
int StringTermPoint = MMsg.length() - strlen(ReservedForErrorcode);
84+
int StringTermPoint = MMsg->length() - strlen(ReservedForErrorcode);
8585
if (StringTermPoint >= 0) {
8686
const char *ReservedPtr = &WhatStr[StringTermPoint];
8787
// check for string terminator, which denotes a SYCL 2020 exception
@@ -100,7 +100,7 @@ const std::error_category &exception::category() const noexcept {
100100
return code().category();
101101
}
102102

103-
const char *exception::what() const noexcept { return MMsg.c_str(); }
103+
const char *exception::what() const noexcept { return MMsg->c_str(); }
104104

105105
bool exception::has_context() const { return (MContext != nullptr); }
106106

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify %s
2+
// expected-no-diagnostics
3+
4+
#include <sycl/sycl.hpp>
5+
#include <type_traits>
6+
7+
int main() {
8+
static_assert(std::is_nothrow_copy_constructible_v<sycl::exception>,
9+
"sycl::exception is not nothrow copy constructible.");
10+
return 0;
11+
}

0 commit comments

Comments
 (0)