The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated.
$ qemu-arm -cpu cortex-a15 ./15.5.2.unexpected.comm.exe
terminate called after throwing an instance of 'B'
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted
$ cat 15.5.2.unexpected.cpp
include
include
include
class B {
public:
const char s;
B(const char p) : s(p) {}
B() : s("NULL") {}
};
class D : public B {
public:
const char t;
D(const char p) : B(p), t(p) {}
D() : B(), t("NULL") {}
};
static void goo() {
try {
foo();
} catch (const B &b) {
boo(); // should not reach here, given above expection-spec unexpected is called
} catch (const char *s) {
exit(3);
}
boo(); // should not reach here
}
/
Sec 15.5.2
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a
new exception which is allowed by the exception specification which previously was violated, then the
search for another handler will continue at the call of the function whose exception specification was vio-
lated.
/
void shutdown() {
static const char *s = "shutdown";
throw s;
}
typedef void(PFV)();
int main (int argc, char argv[]) {
PFV prev_fn = std::set_unexpected(&shutdown);
goo();
boo(); // should not reach here
return 0;
}
| | |
| --- | --- |
| Bugzilla Link | [18245](https://llvm.org/bz18245) |
| Version | trunk |
| OS | Linux |
| Attachments | [test case for Sec 15.5.2](https://user-images.githubusercontent.com/60944935/143748659-141b1b14-e665-4573-aa13-a192673f738d.gz) |
| Reporter | LLVM Bugzilla Contributor |
| CC | @DougGregor,@zygoloid |
## Extended Description
From C++98 standard, Sec 15.5.2
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated.
$ clang++ -target arm-none-linux-gnueabi -mfloat-abi=softfp -mfpu=neon --sysroot=/prj/llvm-arm/home/common/build_tools/gcc-4.6.1-cs/arm-2011.09 -marm -march=armv7-a 15.5.2.unexpected.cpp -o 15.5.2.unexpected.comm.exe -static
$ qemu-arm -cpu cortex-a15 ./15.5.2.unexpected.comm.exe
terminate called after throwing an instance of 'B'
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted
$ cat 15.5.2.unexpected.cpp
#include
#include
#include
class B {
public:
const char *s;
B(const char *p) : s(p) {}
B() : s("NULL") {}
};
class D : public B {
public:
const char *t;
D(const char *p) : B(p), t(p) {}
D() : B(), t("NULL") {}
};
static void boo() {
printf("UNREACHABLE!\n");
}
static void foo() throw (D, const char*) {
throw B("x"); // violates exception-specification
}
static void goo() {
try {
foo();
} catch (const B &b) {
boo(); // should not reach here, given above expection-spec unexpected is called
} catch (const char *s) {
exit(3);
}
boo(); // should not reach here
}
/*
Sec 15.5.2
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a
new exception which is allowed by the exception specification which previously was violated, then the
search for another handler will continue at the call of the function whose exception specification was vio-
lated.
*/
void shutdown() {
static const char *s = "shutdown";
throw s;
}
typedef void(*PFV)();
int main (int argc, char *argv[]) {
PFV prev_fn = std::set_unexpected(&shutdown);
goo();
boo(); // should not reach here
return 0;
}
Extended Description
From C++98 standard, Sec 15.5.2
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated.
$ clang++ -target arm-none-linux-gnueabi -mfloat-abi=softfp -mfpu=neon --sysroot=/prj/llvm-arm/home/common/build_tools/gcc-4.6.1-cs/arm-2011.09 -marm -march=armv7-a 15.5.2.unexpected.cpp -o 15.5.2.unexpected.comm.exe -static
$ qemu-arm -cpu cortex-a15 ./15.5.2.unexpected.comm.exe
terminate called after throwing an instance of 'B' qemu: uncaught target signal 6 (Aborted) - core dumped Aborted
$ cat 15.5.2.unexpected.cpp
include
include
include
class B { public: const char s; B(const char p) : s(p) {} B() : s("NULL") {} };
class D : public B { public: const char t; D(const char p) : B(p), t(p) {} D() : B(), t("NULL") {} };
static void boo() { printf("UNREACHABLE!\n"); }
static void foo() throw (D, const char*) { throw B("x"); // violates exception-specification }
static void goo() { try { foo(); } catch (const B &b) { boo(); // should not reach here, given above expection-spec unexpected is called } catch (const char *s) { exit(3); } boo(); // should not reach here }
/ Sec 15.5.2 The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was vio- lated. / void shutdown() { static const char *s = "shutdown"; throw s; }
typedef void(PFV)(); int main (int argc, char argv[]) { PFV prev_fn = std::set_unexpected(&shutdown); goo(); boo(); // should not reach here return 0; }