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
12 changes: 8 additions & 4 deletions sycl/include/sycl/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ class __SYCL_EXPORT exception : public std::exception {
cl_int get_cl_code() const;

private:
std::string MMsg;
// Exceptions must be noexcept copy constructible, so cannot use std::string
// directly.
std::shared_ptr<std::string> MMsg;
pi_int32 MPIErr;
std::shared_ptr<context> MContext;

Expand All @@ -108,8 +110,9 @@ class __SYCL_EXPORT exception : public std::exception {
: exception(std::string(Msg), PIErr, Context) {}
exception(const std::string &Msg, const pi_int32 PIErr,
std::shared_ptr<context> Context = nullptr)
: MMsg(Msg + " " + detail::codeToString(PIErr)), MPIErr(PIErr),
MContext(Context) {}
: MMsg(std::make_shared<std::string>(Msg + " " +
detail::codeToString(PIErr))),
MPIErr(PIErr), MContext(Context) {}

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

exception(const std::string &Msg) : MMsg(Msg), MContext(nullptr) {}
exception(const std::string &Msg)
: MMsg(std::make_shared<std::string>(Msg)), MContext(nullptr) {}

// base constructor for all SYCL 2020 constructors
// exception(context *ctxPtr, std::error_code ec, const std::string
Expand Down
14 changes: 7 additions & 7 deletions sycl/source/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ exception::exception(context Ctx, int EV, const std::error_category &ECat)
// protected base constructor for all SYCL 2020 constructors
exception::exception(std::error_code EC, std::shared_ptr<context> SharedPtrCtx,
const std::string &WhatArg)
: MMsg(WhatArg + ReservedForErrorcode), MPIErr(PI_ERROR_INVALID_VALUE),
MContext(SharedPtrCtx) {
: MMsg(std::make_shared<std::string>(WhatArg + ReservedForErrorcode)),
MPIErr(PI_ERROR_INVALID_VALUE), MContext(SharedPtrCtx) {
// For compatibility with previous implementation, we are "hiding" the
// std::error_code in the MMsg string, behind the null string terminator
const int StringTermPoint = MMsg.length() - strlen(ReservedForErrorcode);
char *ReservedPtr = &MMsg[StringTermPoint];
const int StringTermPoint = MMsg->length() - strlen(ReservedForErrorcode);
char *ReservedPtr = &(*MMsg)[StringTermPoint];
ReservedPtr[0] = '\0';
ReservedPtr++;
// insert error code
Expand All @@ -79,9 +79,9 @@ exception::exception(std::error_code EC, std::shared_ptr<context> SharedPtrCtx,
}

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

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

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

Expand Down
11 changes: 11 additions & 0 deletions sycl/test/regression/exception_nothrow_copy_constructible.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify %s
// expected-no-diagnostics

#include <sycl/sycl.hpp>
#include <type_traits>

int main() {
static_assert(std::is_nothrow_copy_constructible_v<sycl::exception>,
"sycl::exception is not nothrow copy constructible.");
return 0;
}