llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.77k stars 11.89k forks source link

[C++98]Should continue search after unexpected() throw a exception allowed by exception-spec #18619

Open llvmbot opened 10 years ago

llvmbot commented 10 years ago
Bugzilla Link 18245
Version trunk
OS Linux
Attachments test case for Sec 15.5.2
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; }

llvmbot commented 10 years ago

Any updates on this bug ?

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-frontend

| | | | --- | --- | | 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; }