Changes in / [6988dc6:fca3bf8]
- Files:
-
- 4 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
r6988dc6 rfca3bf8 248 248 } 249 249 250 #if defined(PIC) 251 #warning Exceptions not yet supported when using Position-Independent Code 252 __attribute__((noinline)) 253 void __cfaabi_ehm__try_terminate(void (*try_block)(), 254 void (*catch_block)(int index, exception_t * except), 255 __attribute__((unused)) int (*match_block)(exception_t * except)) { 256 abort(); 257 } 258 #else // PIC 250 #pragma GCC push_options 251 #pragma GCC optimize("O0") 252 259 253 // This is our personality routine. For every stack frame annotated with 260 254 // ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding. … … 431 425 432 426 // Setup the personality routine and exception table. 427 #ifdef __PIC__ 428 asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0"); 429 asm volatile (".cfi_lsda 0x1b, .LLSDACFA2"); 430 #else 433 431 asm volatile (".cfi_personality 0x3,__gcfa_personality_v0"); 434 432 asm volatile (".cfi_lsda 0x3, .LLSDACFA2"); 433 #endif 435 434 436 435 // Label which defines the start of the area for which the handler is setup. … … 464 463 // have a single call to the try routine. 465 464 465 #ifdef __PIC__ 466 #if defined( __i386 ) || defined( __x86_64 ) 467 asm ( 468 // HEADER 469 ".LFECFA1:\n" 470 " .globl __gcfa_personality_v0\n" 471 " .section .gcc_except_table,\"a\",@progbits\n" 472 // TABLE HEADER (important field is the BODY length at the end) 473 ".LLSDACFA2:\n" 474 " .byte 0xff\n" 475 " .byte 0xff\n" 476 " .byte 0x1\n" 477 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" 478 // BODY (language specific data) 479 // This uses language specific data and can be modified arbitrarily 480 // We use handled area offset, handled area length, 481 // handler landing pad offset and 1 (action code, gcc seems to use 0). 482 ".LLSDACSBCFA2:\n" 483 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" 484 " .uleb128 .TRYEND-.TRYSTART\n" 485 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" 486 " .uleb128 1\n" 487 ".LLSDACSECFA2:\n" 488 // TABLE FOOTER 489 " .text\n" 490 " .size __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n" 491 ); 492 493 // Somehow this piece of helps with the resolution of debug symbols. 494 __attribute__((unused)) static const int dummy = 0; 495 496 asm ( 497 // Add a hidden symbol which points at the function. 498 " .hidden CFA.ref.__gcfa_personality_v0\n" 499 " .weak CFA.ref.__gcfa_personality_v0\n" 500 // No clue what this does specifically 501 " .section .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n" 502 " .align 8\n" 503 " .type CFA.ref.__gcfa_personality_v0, @object\n" 504 " .size CFA.ref.__gcfa_personality_v0, 8\n" 505 "CFA.ref.__gcfa_personality_v0:\n" 506 #if defined( __x86_64 ) 507 " .quad __gcfa_personality_v0\n" 508 #else // then __i386 509 " .long __gcfa_personality_v0\n" 510 #endif 511 ); 512 #else 513 #error Exception Handling: unknown architecture for position independent code. 514 #endif // __i386 || __x86_64 515 #else // __PIC__ 466 516 #if defined( __i386 ) || defined( __x86_64 ) 467 517 asm ( … … 491 541 " .size __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n" 492 542 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n" 493 //" .section .note.GNU-stack,\"x\",@progbits\n"543 " .section .note.GNU-stack,\"x\",@progbits\n" 494 544 ); 545 #else 546 #error Exception Handling: unknown architecture for position dependent code. 495 547 #endif // __i386 || __x86_64 496 #endif // PIC 548 #endif // __PIC__ 549 550 #pragma GCC pop_options -
src/ResolvExpr/Resolver.cc
r6988dc6 rfca3bf8 84 84 void previsit( ThrowStmt * throwStmt ); 85 85 void previsit( CatchStmt * catchStmt ); 86 void postvisit( CatchStmt * catchStmt ); 86 87 void previsit( WaitForStmt * stmt ); 87 88 … … 567 568 568 569 void Resolver_old::previsit( CatchStmt * catchStmt ) { 570 // Until we are very sure this invarent (ifs that move between passes have thenPart) 571 // holds, check it. This allows a check for when to decode the mangling. 572 if ( IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ) ) { 573 assert( ifStmt->thenPart ); 574 } 575 // Encode the catchStmt so the condition can see the declaration. 569 576 if ( catchStmt->cond ) { 570 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); 577 IfStmt * ifStmt = new IfStmt( catchStmt->cond, nullptr, catchStmt->body ); 578 catchStmt->cond = nullptr; 579 catchStmt->body = ifStmt; 580 } 581 } 582 583 void Resolver_old::postvisit( CatchStmt * catchStmt ) { 584 // Decode the catchStmt so everything is stored properly. 585 IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ); 586 if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) { 587 assert( ifStmt->condition ); 588 assert( ifStmt->elsePart ); 589 catchStmt->cond = ifStmt->condition; 590 catchStmt->body = ifStmt->elsePart; 591 ifStmt->condition = nullptr; 592 ifStmt->elsePart = nullptr; 593 delete ifStmt; 571 594 } 572 595 } … … 1466 1489 1467 1490 const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 1491 // TODO: This will need a fix for the decl/cond scoping problem. 1468 1492 if ( catchStmt->cond ) { 1469 1493 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; -
tests/exceptions/except-0.cfa
r6988dc6 rfca3bf8 19 19 }; 20 20 21 void ?{}(signal_exit *this, const char * area) {22 this ->area = area;23 } 24 25 void ^?{}(signal_exit *this) {26 printf("Exiting: %s\n", this ->area);21 void ?{}(signal_exit & this, const char * area) { 22 this.area = area; 23 } 24 25 void ^?{}(signal_exit & this) { 26 printf("Exiting: %s\n", this.area); 27 27 // sout | "Exiting:" | this->area; 28 28 } … … 242 242 243 243 // Uncaught termination test. 244 /* Removed due to non-deterministic output. 244 245 printf("Throw uncaught.\n"); 245 246 yang z; 246 247 terminate(&z); 247 } 248 */ 249 } -
tests/exceptions/except-2.cfa
r6988dc6 rfca3bf8 12 12 struct TABLE(BASE_EXCEPT) const * parent; 13 13 size_t size; 14 void (*copy)(num_error *this, num_error *other);15 void (*free)(num_error *this);14 void (*copy)(num_error &this, num_error & other); 15 void (*free)(num_error &this); 16 16 const char * (*msg)(num_error *this); 17 17 int (*code)(num_error *this); … … 28 28 if ( ! this->msg ) { 29 29 static const char * base = "Num Error with code: X"; 30 this->msg = malloc(22);30 this->msg = (char *)malloc(22); 31 31 for (int i = 0 ; (this->msg[i] = base[i]) ; ++i); 32 32 } … … 34 34 return this->msg; 35 35 } 36 void ?{}(num_error *this, int num) {37 this ->virtual_table = &INSTANCE(num_error);38 this ->msg = 0;39 this ->num = num;36 void ?{}(num_error & this, int num) { 37 this.virtual_table = &INSTANCE(num_error); 38 this.msg = 0; 39 this.num = num; 40 40 } 41 void ?{}(num_error * this, num_error *other) {42 this ->virtual_table = other->virtual_table;43 this ->msg = 0;44 this ->num = other->num;41 void ?{}(num_error & this, num_error & other) { 42 this.virtual_table = other.virtual_table; 43 this.msg = 0; 44 this.num = other.num; 45 45 } 46 void ^?{}(num_error *this) {47 if( this ->msg ) free( this->msg );46 void ^?{}(num_error & this) { 47 if( this.msg ) free( this.msg ); 48 48 } 49 49 int num_error_code( num_error * this ) {
Note: See TracChangeset
for help on using the changeset viewer.