Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: tests/toolchain/eh_throw_tests.cc

Issue 105593002: Add tests for C++ exception types that use virtual base classes (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include <assert.h> 7 #include <assert.h>
8 #include <setjmp.h> 8 #include <setjmp.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 10
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 // where the return address has been overwritten with 321 // where the return address has been overwritten with
322 // longjmp()'s return address, so we return here. 322 // longjmp()'s return address, so we return here.
323 assert(false); 323 assert(false);
324 } 324 }
325 } catch (...) { 325 } catch (...) {
326 assert(false); 326 assert(false);
327 } 327 }
328 } 328 }
329 329
330 330
331 void allowed_exception_spec() throw(MyException) {
332 throw MyException(600);
333 }
334
335 // Test a case in which an exception propagates through an exception
336 // spec which allows the exception type.
337 void test_exception_spec_allowed() {
338 bool caught = false;
339 try {
340 allowed_exception_spec();
341 } catch (MyException &exc) {
342 assert(exc.value == 600);
343 caught = true;
344 }
345 assert(caught);
346 }
347
348
349 class VirtualBase {
350 public:
351 VirtualBase() : value(321) {}
352 int value;
353 };
354
355 class VirtualDerived : virtual public VirtualBase {};
356
357 void allowed_exception_spec_virtual_base() throw(VirtualBase) {
358 throw VirtualDerived();
359 }
360
361 // Test that exception types with virtual base classes work when the
362 // base class appears in an exception spec.
363 //
364 // In this case, the C++ runtime library must dereference the
365 // exception's vtable to find the offset of VirtualBase within
366 // VirtualDerived. That is not the case with non-virtual bases, for
367 // which the std::type_info data is enough to adjust the pointer to
368 // the exception without dereferencing it.
369 void test_exception_spec_allowed_with_virtual_base() {
370 bool caught = false;
371 try {
372 allowed_exception_spec_virtual_base();
373 } catch (VirtualBase &exc) {
374 assert(exc.value == 321);
375 caught = true;
376 }
377 assert(caught);
378 }
379
380
331 class RethrowExc {}; 381 class RethrowExc {};
332 382
333 bool g_dtor_called; 383 bool g_dtor_called;
334 384
335 void rethrow_unexpected_handler() { 385 void rethrow_unexpected_handler() {
336 // func_with_exception_spec()'s destructors should be run before the 386 // func_with_exception_spec()'s destructors should be run before the
337 // exception spec (a "filter" clause in LLVM) is checked and we are 387 // exception spec (a "filter" clause in LLVM) is checked and we are
338 // called. 388 // called.
339 // 389 //
340 // This means that the std::set_unexpected() handler should be 390 // This means that the std::set_unexpected() handler should be
(...skipping 11 matching lines...) Expand all
352 void func_with_exception_spec() throw(RethrowExc) { 402 void func_with_exception_spec() throw(RethrowExc) {
353 Dtor dtor(&g_dtor_called); 403 Dtor dtor(&g_dtor_called);
354 throw MyException(100); 404 throw MyException(100);
355 } 405 }
356 406
357 // Test that exception specs work. Test that if an exception doesn't 407 // Test that exception specs work. Test that if an exception doesn't
358 // match the exception spec of a function, the current 408 // match the exception spec of a function, the current
359 // std::set_unexpected() handler is called. The handler is allowed to 409 // std::set_unexpected() handler is called. The handler is allowed to
360 // throw a new exception that matches the exception spec -- we test 410 // throw a new exception that matches the exception spec -- we test
361 // this case to avoid aborting execution. 411 // this case to avoid aborting execution.
362 void test_exception_spec() { 412 void test_exception_spec_calls_handler() {
363 g_dtor_called = false; 413 g_dtor_called = false;
364 std::unexpected_handler old_unexpected_handler = 414 std::unexpected_handler old_unexpected_handler =
365 std::set_unexpected(rethrow_unexpected_handler); 415 std::set_unexpected(rethrow_unexpected_handler);
366 bool caught = false; 416 bool caught = false;
367 try { 417 try {
368 func_with_exception_spec(); 418 func_with_exception_spec();
369 } catch (RethrowExc &) { 419 } catch (RethrowExc &) {
370 caught = true; 420 caught = true;
371 } 421 }
372 assert(caught); 422 assert(caught);
373 // Clean up. 423 // Clean up.
374 std::set_unexpected(old_unexpected_handler); 424 std::set_unexpected(old_unexpected_handler);
375 } 425 }
376 426
377 427
428 void unexpected_handler_throwing_virtual_base() {
429 throw VirtualDerived();
430 }
431
432 void disallowed_exception_spec_virtual_base() throw(VirtualBase) {
433 throw MyException(0);
434 }
435
436 // Test that if a std::set_unexpected() handler throws an exception
437 // with a virtual base class, this new exception is checked against
438 // the original exception spec correctly.
439 void test_exception_spec_handler_throws_virtual_base() {
440 std::unexpected_handler old_unexpected_handler =
441 std::set_unexpected(unexpected_handler_throwing_virtual_base);
442 bool caught = false;
443 try {
444 disallowed_exception_spec_virtual_base();
445 } catch (VirtualBase &exc) {
446 assert(exc.value == 321);
447 caught = true;
448 }
449 assert(caught);
450 // Clean up.
451 std::set_unexpected(old_unexpected_handler);
452 }
453
454
378 void rethrowing_unexpected_handler() { 455 void rethrowing_unexpected_handler() {
379 try { 456 try {
380 throw; 457 throw;
381 } catch (MyException &exc) { 458 } catch (MyException &exc) {
382 assert(exc.value == 100); 459 assert(exc.value == 100);
383 } 460 }
384 throw RethrowExc(); 461 throw RethrowExc();
385 } 462 }
386 463
387 // Test that the "current exception" inside the std::set_unexpected() 464 // Test that the "current exception" inside the std::set_unexpected()
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 RUN_TEST(test_catch_all()); 646 RUN_TEST(test_catch_all());
570 RUN_TEST(test_nested_try_blocks()); 647 RUN_TEST(test_nested_try_blocks());
571 RUN_TEST(test_throw_in_catch_block()); 648 RUN_TEST(test_throw_in_catch_block());
572 RUN_TEST(test_dtor()); 649 RUN_TEST(test_dtor());
573 RUN_TEST(test_rethrow()); 650 RUN_TEST(test_rethrow());
574 RUN_TEST(test_stack_of_exceptions()); 651 RUN_TEST(test_stack_of_exceptions());
575 RUN_TEST(test_multiple_inheritance_exception()); 652 RUN_TEST(test_multiple_inheritance_exception());
576 RUN_TEST(test_multiple_inheritance_exception_ptr()); 653 RUN_TEST(test_multiple_inheritance_exception_ptr());
577 RUN_TEST(test_throw_catch_nested_in_dtor()); 654 RUN_TEST(test_throw_catch_nested_in_dtor());
578 RUN_TEST(test_setjmp_called_via_invoke()); 655 RUN_TEST(test_setjmp_called_via_invoke());
579 RUN_TEST(test_exception_spec()); 656 RUN_TEST(test_exception_spec_allowed());
657 RUN_TEST(test_exception_spec_allowed_with_virtual_base());
658 RUN_TEST(test_exception_spec_calls_handler());
659 RUN_TEST(test_exception_spec_handler_throws_virtual_base());
580 RUN_TEST(test_exception_spec_rethrow_inside_unexpected_handler()); 660 RUN_TEST(test_exception_spec_rethrow_inside_unexpected_handler());
581 RUN_TEST(test_exception_spec_convert_to_bad_exception()); 661 RUN_TEST(test_exception_spec_convert_to_bad_exception());
582 #if SUPPORTS_CXX11 662 #if SUPPORTS_CXX11
583 RUN_TEST(test_dependent_exception()); 663 RUN_TEST(test_dependent_exception());
584 RUN_TEST(test_dependent_exception_and_dtor()); 664 RUN_TEST(test_dependent_exception_and_dtor());
585 RUN_TEST(test_dependent_exception_and_exception_spec()); 665 RUN_TEST(test_dependent_exception_and_exception_spec());
586 #endif 666 #endif
587 // This leaves behind an active exception because of its use of 667 // This leaves behind an active exception because of its use of
588 // longjmp() to exit from a std::set_terminate() handler, so put it 668 // longjmp() to exit from a std::set_terminate() handler, so put it
589 // last, just in case that accidentally affects other tests. 669 // last, just in case that accidentally affects other tests.
590 RUN_TEST(test_exception_spec_bad_throw_from_unexpected_handler()); 670 RUN_TEST(test_exception_spec_bad_throw_from_unexpected_handler());
591 671
592 // Indicate success. 672 // Indicate success.
593 return 55; 673 return 55;
594 } 674 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698