Changes in / [99fea48:6f121b8]
- Files:
-
- 2 deleted
- 13 edited
-
libcfa/src/exception.c (modified) (7 diffs)
-
libcfa/src/exception.h (modified) (3 diffs)
-
libcfa/src/exception.hfa (modified) (1 diff)
-
src/ControlStruct/ExceptTranslate.cc (modified) (19 diffs)
-
src/ControlStruct/ExceptTranslate.h (modified) (2 diffs)
-
src/main.cc (modified) (3 diffs)
-
tests/errors/.expect/completeType.txt (modified) (1 diff)
-
tests/exceptions/.expect/defaults.txt (deleted)
-
tests/exceptions/conditional.cfa (modified) (2 diffs)
-
tests/exceptions/data-except.cfa (modified) (2 diffs)
-
tests/exceptions/defaults.cfa (deleted)
-
tests/exceptions/finally.cfa (modified) (2 diffs)
-
tests/exceptions/interact.cfa (modified) (10 diffs)
-
tests/exceptions/resume.cfa (modified) (8 diffs)
-
tests/exceptions/terminate.cfa (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
r99fea48 r6f121b8 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr May 21 12:18:00 202013 // Update Count : 2012 // Last Modified On : Tue Apr 14 12:01:00 2020 13 // Update Count : 18 14 14 // 15 15 … … 80 80 } 81 81 82 void __cfaehm_throw_resume(exception_t * except , void (*defaultHandler)(exception_t *)) {82 void __cfaehm_throw_resume(exception_t * except) { 83 83 struct exception_context_t * context = this_exception_context(); 84 84 … … 96 96 } 97 97 98 // No handler found, fall back to the default operation.99 98 __cfadbg_print_safe(exception, "Unhandled exception\n"); 100 defaultHandler(except); 99 100 // Fall back to termination: 101 __cfaehm_throw_terminate(except); 102 // TODO: Default handler for resumption. 101 103 } 102 104 … … 237 239 } 238 240 239 static void __cfaehm_cleanup_default( exception_t ** except ) {240 __cfaehm_delete_exception( *except );241 *except = NULL;242 }243 244 241 // The exception that is being thrown must already be stored. 245 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) { 246 struct exception_context_t * context = this_exception_context(); 247 struct _Unwind_Exception * storage = &this_exception_storage; 248 if ( NULL == context->current_exception ) { 242 static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) { 243 if ( ! this_exception_context()->current_exception ) { 249 244 printf("UNWIND ERROR missing exception in begin unwind\n"); 250 245 abort(); … … 252 247 253 248 // Call stdlibc to raise the exception 254 __cfadbg_print_safe(exception, "Begin unwinding (storage &p, context %p)\n", storage, context); 255 _Unwind_Reason_Code ret = _Unwind_RaiseException( storage ); 249 _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage ); 256 250 257 251 // If we reach here it means something happened. For resumption to work we need to find a way … … 262 256 // the whole stack. 263 257 258 // No handler found, go to the default operation. 259 // Currently this will always be a cancellation. 260 if ( ret == _URC_END_OF_STACK ) { 261 __cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage); 262 263 __cfaehm_cancel_stack(this_exception_context()->current_exception); 264 } 265 264 266 // We did not simply reach the end of the stack without finding a handler. This is an error. 265 if ( ret != _URC_END_OF_STACK ) { 266 printf("UNWIND ERROR %d after raise exception\n", ret); 267 abort(); 268 } 269 270 // No handler found, go to the default operation. 271 __cfadbg_print_safe(exception, "Uncaught exception %p\n", storage); 272 273 __attribute__((cleanup(__cfaehm_cleanup_default))) 274 exception_t * exception = context->current_exception; 275 defaultHandler( exception ); 276 } 277 278 void __cfaehm_throw_terminate( exception_t * val, void (*defaultHandler)(exception_t *) ) { 267 printf("UNWIND ERROR %d after raise exception\n", ret); 268 abort(); 269 } 270 271 void __cfaehm_throw_terminate( exception_t * val ) { 279 272 __cfadbg_print_safe(exception, "Throwing termination exception\n"); 280 273 281 274 __cfaehm_allocate_exception( val ); 282 __cfaehm_begin_unwind( defaultHandler ); 283 } 284 285 static __attribute__((noreturn)) void __cfaehm_rethrow_adapter( exception_t * except ) { 286 // TODO: Print some error message. 287 (void)except; 288 abort(); 275 __cfaehm_begin_unwind(); 289 276 } 290 277 … … 292 279 __cfadbg_print_safe(exception, "Rethrowing termination exception\n"); 293 280 294 __cfaehm_begin_unwind( __cfaehm_rethrow_adapter ); 295 abort(); 281 __cfaehm_begin_unwind(); 296 282 } 297 283 -
libcfa/src/exception.h
r99fea48 r6f121b8 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 19 14:17:00 202013 // Update Count : 1012 // Last Modified On : Fri Mar 27 10:16:00 2020 13 // Update Count : 9 14 14 // 15 15 … … 41 41 42 42 // Used in throw statement translation. 43 void __cfaehm_throw_terminate(exception_t * except , void (*)(exception_t *));43 void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn)); 44 44 void __cfaehm_rethrow_terminate() __attribute__((noreturn)); 45 void __cfaehm_throw_resume(exception_t * except , void (*)(exception_t *));45 void __cfaehm_throw_resume(exception_t * except); 46 46 47 47 // Function catches termination exceptions. … … 72 72 #ifdef __cforall 73 73 } 74 75 // Not all the built-ins can be expressed in C. These can't be76 // implemented in the .c file either so they all have to be inline.77 78 trait is_exception(dtype T) {79 /* The first field must be a pointer to a virtual table.80 * That virtual table must be a decendent of the base exception virtual tab$81 */82 void mark_exception(T *);83 // This is never used and should be a no-op.84 };85 86 trait is_termination_exception(dtype T | is_exception(T)) {87 void defaultTerminationHandler(T &);88 };89 90 trait is_resumption_exception(dtype T | is_exception(T)) {91 void defaultResumptionHandler(T &);92 };93 94 forall(dtype T | is_termination_exception(T))95 static inline void $throw(T & except) {96 __cfaehm_throw_terminate(97 (exception_t *)&except,98 (void(*)(exception_t *))defaultTerminationHandler99 );100 }101 102 forall(dtype T | is_resumption_exception(T))103 static inline void $throwResume(T & except) {104 __cfaehm_throw_resume(105 (exception_t *)&except,106 (void(*)(exception_t *))defaultResumptionHandler107 );108 }109 110 forall(dtype T | is_exception(T))111 static inline void cancel_stack(T & except) __attribute__((noreturn)) {112 __cfaehm_cancel_stack( (exception_t *)&except );113 }114 115 forall(dtype T | is_exception(T))116 static inline void defaultTerminationHandler(T & except) {117 return cancel_stack( except );118 }119 120 forall(dtype T | is_exception(T))121 static inline void defaultResumptionHandler(T & except) {122 throw except;123 }124 125 74 #endif -
libcfa/src/exception.hfa
r99fea48 r6f121b8 10 10 // Created On : Thu Apr 7 10:25:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 19 14:17:00 202013 // Update Count : 212 // Last Modified On : Wed Apr 13 15:42:00 2020 13 // Update Count : 1 14 14 // 15 16 trait is_exception(dtype T) { 17 // The trait system can't describe the actual constrants. 18 // Unused, should always be a no-op. 19 void mark_exception(T *); 20 }; 21 22 forall(dtype T | is_exception(T)) 23 inline void cancel_stack(T & except) __attribute__((noreturn)) { 24 __cfaehm_cancel_stack( (exception_t *)&except ); 25 } 15 26 16 27 // Everything below this line should be considered a patch while the exception -
src/ControlStruct/ExceptTranslate.cc
r99fea48 r6f121b8 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 21 13:18:00 202013 // Update Count : 1 512 // Last Modified On : Fri Mar 27 11:58:00 2020 13 // Update Count : 13 14 14 // 15 15 … … 64 64 } 65 65 66 class ThrowMutatorCore : public WithGuards { 67 ObjectDecl * terminate_handler_except; 68 enum Context { NoHandler, TerHandler, ResHandler } cur_context; 69 70 // The helper functions for code/syntree generation. 71 Statement * create_either_throw( 72 ThrowStmt * throwStmt, const char * throwFunc ); 73 Statement * create_terminate_rethrow( ThrowStmt * throwStmt ); 74 Statement * create_resume_rethrow( ThrowStmt * throwStmt ); 75 76 public: 77 ThrowMutatorCore() : 78 terminate_handler_except( nullptr ), 79 cur_context( NoHandler ) 80 {} 81 82 void premutate( CatchStmt *catchStmt ); 83 Statement * postmutate( ThrowStmt *throwStmt ); 84 }; 85 86 // ThrowStmt Mutation Helpers 87 88 Statement * ThrowMutatorCore::create_either_throw( 89 ThrowStmt * throwStmt, const char * throwFunc ) { 90 // `throwFunc`( `throwStmt->get_name()` ); 91 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 92 call->get_args().push_back( throwStmt->get_expr() ); 93 throwStmt->set_expr( nullptr ); 94 delete throwStmt; 95 return new ExprStmt( call ); 96 } 97 98 Statement * ThrowMutatorCore::create_terminate_rethrow( 99 ThrowStmt *throwStmt ) { 100 // { `terminate_handler_except` = 0p; __rethrow_terminate(); } 101 assert( nullptr == throwStmt->get_expr() ); 102 assert( terminate_handler_except ); 103 104 CompoundStmt * result = new CompoundStmt(); 105 result->labels = throwStmt->labels; 106 result->push_back( new ExprStmt( UntypedExpr::createAssign( 107 nameOf( terminate_handler_except ), 108 new ConstantExpr( Constant::null( 109 //new PointerType( 110 // noQualifiers, 111 terminate_handler_except->get_type()->clone() 112 // ) 113 ) ) 114 ) ) ); 115 result->push_back( new ExprStmt( 116 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) ) 117 ) ); 118 delete throwStmt; 119 return result; 120 } 121 122 Statement * ThrowMutatorCore::create_resume_rethrow( 123 ThrowStmt *throwStmt ) { 124 // return false; 125 Statement * result = new ReturnStmt( 126 new ConstantExpr( Constant::from_bool( false ) ) 127 ); 128 result->labels = throwStmt->labels; 129 delete throwStmt; 130 return result; 131 } 132 133 // Visiting/Mutating Functions 134 135 void ThrowMutatorCore::premutate( CatchStmt *catchStmt ) { 136 // Validate the statement's form. 137 ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 138 // Also checking the type would be nice. 139 if ( decl ) { 140 // Pass. 141 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 142 SemanticError(catchStmt->location, "catch must have exception type"); 143 } else { 144 SemanticError(catchStmt->location, "catchResume must have exception type"); 145 } 146 147 // Track the handler context. 148 GuardValue( cur_context ); 149 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 150 cur_context = TerHandler; 151 152 GuardValue( terminate_handler_except ); 153 terminate_handler_except = decl; 154 } else { 155 cur_context = ResHandler; 156 } 157 } 158 159 Statement * ThrowMutatorCore::postmutate( ThrowStmt *throwStmt ) { 160 // Ignoring throwStmt->get_target() for now. 161 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 162 if ( throwStmt->get_expr() ) { 163 return create_either_throw( throwStmt, "$throw" ); 164 } else if ( TerHandler == cur_context ) { 165 return create_terminate_rethrow( throwStmt ); 166 } else { 167 abort("Invalid throw in %s at %i\n", 168 throwStmt->location.filename.c_str(), 169 throwStmt->location.first_line); 170 } 171 } else { 172 if ( throwStmt->get_expr() ) { 173 return create_either_throw( throwStmt, "$throwResume" ); 174 } else if ( ResHandler == cur_context ) { 175 return create_resume_rethrow( throwStmt ); 176 } else { 177 abort("Invalid throwResume in %s at %i\n", 178 throwStmt->location.filename.c_str(), 179 throwStmt->location.first_line); 180 } 181 } 182 } 183 184 class TryMutatorCore { 66 class ExceptionMutatorCore : public WithGuards { 67 enum Context { NoHandler, TerHandler, ResHandler }; 68 69 // Also need to handle goto, break & continue. 70 // They need to be cut off in a ResHandler, until we enter another 71 // loop, switch or the goto stays within the function. 72 73 Context cur_context; 74 75 // The current (innermost) termination handler exception declaration. 76 ObjectDecl * handler_except_decl; 77 185 78 // The built in types used in translation. 186 79 StructDecl * except_decl; … … 189 82 190 83 // The many helper functions for code/syntree generation. 84 Statement * create_given_throw( 85 const char * throwFunc, ThrowStmt * throwStmt ); 86 Statement * create_terminate_throw( ThrowStmt * throwStmt ); 87 Statement * create_terminate_rethrow( ThrowStmt * throwStmt ); 88 Statement * create_resume_throw( ThrowStmt * throwStmt ); 89 Statement * create_resume_rethrow( ThrowStmt * throwStmt ); 191 90 CompoundStmt * take_try_block( TryStmt * tryStmt ); 192 91 FunctionDecl * create_try_wrapper( CompoundStmt * body ); … … 222 121 223 122 public: 224 TryMutatorCore() : 123 ExceptionMutatorCore() : 124 cur_context( NoHandler ), 125 handler_except_decl( nullptr ), 225 126 except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ), 226 127 try_func_t( noQualifiers, false ), … … 231 132 {} 232 133 134 void premutate( CatchStmt *catchStmt ); 233 135 void premutate( StructDecl *structDecl ); 234 136 Statement * postmutate( ThrowStmt *throwStmt ); … … 236 138 }; 237 139 238 void TryMutatorCore::init_func_types() {140 void ExceptionMutatorCore::init_func_types() { 239 141 assert( except_decl ); 240 142 … … 294 196 } 295 197 198 // ThrowStmt Mutation Helpers 199 200 Statement * ExceptionMutatorCore::create_given_throw( 201 const char * throwFunc, ThrowStmt * throwStmt ) { 202 // `throwFunc`( `throwStmt->get_name` ); 203 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 204 call->get_args().push_back( throwStmt->get_expr() ); 205 throwStmt->set_expr( nullptr ); 206 delete throwStmt; 207 return new ExprStmt( call ); 208 } 209 210 Statement * ExceptionMutatorCore::create_terminate_throw( 211 ThrowStmt *throwStmt ) { 212 // __throw_terminate( `throwStmt->get_name()` ); } 213 return create_given_throw( "__cfaehm_throw_terminate", throwStmt ); 214 } 215 216 Statement * ExceptionMutatorCore::create_terminate_rethrow( 217 ThrowStmt *throwStmt ) { 218 // { `handler_except_decl` = NULL; __rethrow_terminate(); } 219 assert( nullptr == throwStmt->get_expr() ); 220 assert( handler_except_decl ); 221 222 CompoundStmt * result = new CompoundStmt(); 223 result->labels = throwStmt->labels; 224 result->push_back( new ExprStmt( UntypedExpr::createAssign( 225 nameOf( handler_except_decl ), 226 new ConstantExpr( Constant::null( 227 new PointerType( 228 noQualifiers, 229 handler_except_decl->get_type()->clone() 230 ) 231 ) ) 232 ) ) ); 233 result->push_back( new ExprStmt( 234 new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) ) 235 ) ); 236 delete throwStmt; 237 return result; 238 } 239 240 Statement * ExceptionMutatorCore::create_resume_throw( 241 ThrowStmt *throwStmt ) { 242 // __throw_resume( `throwStmt->get_name` ); 243 return create_given_throw( "__cfaehm_throw_resume", throwStmt ); 244 } 245 246 Statement * ExceptionMutatorCore::create_resume_rethrow( 247 ThrowStmt *throwStmt ) { 248 // return false; 249 Statement * result = new ReturnStmt( 250 new ConstantExpr( Constant::from_bool( false ) ) 251 ); 252 result->labels = throwStmt->labels; 253 delete throwStmt; 254 return result; 255 } 256 296 257 // TryStmt Mutation Helpers 297 258 298 CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) {259 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) { 299 260 CompoundStmt * block = tryStmt->get_block(); 300 261 tryStmt->set_block( nullptr ); … … 302 263 } 303 264 304 FunctionDecl * TryMutatorCore::create_try_wrapper(265 FunctionDecl * ExceptionMutatorCore::create_try_wrapper( 305 266 CompoundStmt *body ) { 306 267 … … 309 270 } 310 271 311 FunctionDecl * TryMutatorCore::create_terminate_catch(272 FunctionDecl * ExceptionMutatorCore::create_terminate_catch( 312 273 CatchList &handlers ) { 313 274 std::list<CaseStmt *> handler_wrappers; … … 389 350 // Create a single check from a moddified handler. 390 351 // except_obj is referenced, modded_handler will be freed. 391 CompoundStmt * TryMutatorCore::create_single_matcher(352 CompoundStmt * ExceptionMutatorCore::create_single_matcher( 392 353 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 393 354 // { … … 427 388 } 428 389 429 FunctionDecl * TryMutatorCore::create_terminate_match(390 FunctionDecl * ExceptionMutatorCore::create_terminate_match( 430 391 CatchList &handlers ) { 431 392 // int match(exception * except) { … … 464 425 } 465 426 466 CompoundStmt * TryMutatorCore::create_terminate_caller(427 CompoundStmt * ExceptionMutatorCore::create_terminate_caller( 467 428 FunctionDecl * try_wrapper, 468 429 FunctionDecl * terminate_catch, … … 482 443 } 483 444 484 FunctionDecl * TryMutatorCore::create_resume_handler(445 FunctionDecl * ExceptionMutatorCore::create_resume_handler( 485 446 CatchList &handlers ) { 486 447 // bool handle(exception * except) { … … 519 480 } 520 481 521 CompoundStmt * TryMutatorCore::create_resume_wrapper(482 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper( 522 483 Statement * wraps, 523 484 FunctionDecl * resume_handler ) { … … 563 524 } 564 525 565 FunctionDecl * TryMutatorCore::create_finally_wrapper(526 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper( 566 527 TryStmt * tryStmt ) { 567 // void finally() { `finally->block`}528 // void finally() { <finally code> } 568 529 FinallyStmt * finally = tryStmt->get_finally(); 569 530 CompoundStmt * body = finally->get_block(); … … 576 537 } 577 538 578 ObjectDecl * TryMutatorCore::create_finally_hook(539 ObjectDecl * ExceptionMutatorCore::create_finally_hook( 579 540 FunctionDecl * finally_wrapper ) { 580 541 // struct __cfaehm_cleanup_hook __finally_hook 581 // __attribute__((cleanup( `finally_wrapper`)));542 // __attribute__((cleanup( finally_wrapper ))); 582 543 583 544 // Make Cleanup Attribute. … … 604 565 605 566 // Visiting/Mutating Functions 606 void TryMutatorCore::premutate( StructDecl *structDecl ) { 567 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 568 // Validate the Statement's form. 569 ObjectDecl * decl = 570 dynamic_cast<ObjectDecl *>( catchStmt->get_decl() ); 571 if ( decl && true /* check decl->get_type() */ ) { 572 // Pass. 573 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 574 SemanticError(catchStmt->location, "catch must have exception type"); 575 } else { 576 SemanticError(catchStmt->location, "catchResume must have exception type"); 577 } 578 579 // Track the handler context. 580 GuardValue( cur_context ); 581 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 582 cur_context = TerHandler; 583 584 GuardValue( handler_except_decl ); 585 handler_except_decl = decl; 586 } else { 587 cur_context = ResHandler; 588 } 589 } 590 591 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 607 592 if ( !structDecl->has_body() ) { 608 593 // Skip children? … … 619 604 hook_decl = structDecl; 620 605 } 621 } 622 623 Statement * TryMutatorCore::postmutate( ThrowStmt * ) { 624 // All throws should be removed by this point. 625 assert( false ); 626 } 627 628 Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) { 606 // Later we might get the exception type as well. 607 } 608 609 Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) { 610 assert( except_decl ); 611 612 // Ignoring throwStmt->get_target() for now. 613 if ( ThrowStmt::Terminate == throwStmt->get_kind() ) { 614 if ( throwStmt->get_expr() ) { 615 return create_terminate_throw( throwStmt ); 616 } else if ( TerHandler == cur_context ) { 617 return create_terminate_rethrow( throwStmt ); 618 } else { 619 abort("Invalid throw in %s at %i\n", 620 throwStmt->location.filename.c_str(), 621 throwStmt->location.first_line); 622 } 623 } else { 624 if ( throwStmt->get_expr() ) { 625 return create_resume_throw( throwStmt ); 626 } else if ( ResHandler == cur_context ) { 627 return create_resume_rethrow( throwStmt ); 628 } else { 629 abort("Invalid throwResume in %s at %i\n", 630 throwStmt->location.filename.c_str(), 631 throwStmt->location.first_line); 632 } 633 } 634 } 635 636 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 629 637 assert( except_decl ); 630 638 assert( node_decl ); … … 680 688 } 681 689 682 void translate Throws( std::list< Declaration *> & translationUnit ) {683 PassVisitor< ThrowMutatorCore> translator;690 void translateEHM( std::list< Declaration *> & translationUnit ) { 691 PassVisitor<ExceptionMutatorCore> translator; 684 692 mutateAll( translationUnit, translator ); 685 693 } 686 687 void translateTries( std::list< Declaration *> & translationUnit ) {688 PassVisitor<TryMutatorCore> translator;689 mutateAll( translationUnit, translator );690 }691 694 } -
src/ControlStruct/ExceptTranslate.h
r99fea48 r6f121b8 9 9 // Author : Andrew Beach 10 10 // Created On : Tus Jun 06 10:13:00 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tus May 19 11:47:00 202013 // Update Count : 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:19:23 2017 13 // Update Count : 4 14 14 // 15 15 … … 21 21 22 22 namespace ControlStruct { 23 void translateThrows( std::list< Declaration *> & translationUnit ); 24 /* Replaces all throw & throwResume statements with function calls. 25 * These still need to be resolved, so call this before the reslover. 26 */ 27 28 void translateTries( std::list< Declaration *> & translationUnit ); 29 /* Replaces all try blocks (and their many clauses) with function definitions and calls. 30 * This uses the exception built-ins to produce typed output and should take place after 31 * the resolver. 32 */ 23 void translateEHM( std::list< Declaration *> & translationUnit ); 24 // Converts exception handling structures into their underlying C code. Translation does use the exception 25 // handling header, make sure it is visible wherever translation occurs. 33 26 } 34 27 -
src/main.cc
r99fea48 r6f121b8 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue May 19 12:03:00 202013 // Update Count : 63 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 8 08:33:50 2020 13 // Update Count : 633 14 14 // 15 15 … … 312 312 } // if 313 313 314 PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) );315 314 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 316 315 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); … … 355 354 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 356 355 357 PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );356 PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) ); 358 357 359 358 PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) ); -
tests/errors/.expect/completeType.txt
r99fea48 r6f121b8 132 132 ?=?: pointer to function 133 133 ... with parameters 134 reference to instance of type _10 8_0_T (not function type)135 instance of type _10 8_0_T (not function type)134 reference to instance of type _104_0_T (not function type) 135 instance of type _104_0_T (not function type) 136 136 ... returning 137 _retval__operator_assign: instance of type _10 8_0_T (not function type)137 _retval__operator_assign: instance of type _104_0_T (not function type) 138 138 ... with attributes: 139 139 Attribute with name: unused -
tests/exceptions/conditional.cfa
r99fea48 r6f121b8 56 56 57 57 try { 58 throw exc;58 throw &exc; 59 59 } catch (num_error * error ; 3 == error->virtual_table->code( error )) { 60 60 caught_num_error(3, error); … … 64 64 65 65 try { 66 throwResume exc;66 throwResume &exc; 67 67 } catchResume (num_error * error ; 3 == error->virtual_table->code( error )) { 68 68 caught_num_error(3, error); -
tests/exceptions/data-except.cfa
r99fea48 r6f121b8 28 28 29 29 try { 30 throw except;30 throw &except; 31 31 } catch (paired * exc) { 32 32 printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second); … … 37 37 38 38 try { 39 throwResume except;39 throwResume &except; 40 40 } catchResume (paired * exc) { 41 41 printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second); -
tests/exceptions/finally.cfa
r99fea48 r6f121b8 12 12 try { 13 13 printf("termination throw\n"); 14 throw exc;14 throw &exc; 15 15 } finally { 16 16 loud_exit a = "termination inner finally"; … … 28 28 try { 29 29 printf("resumption throw\n"); 30 throwResume exc;30 throwResume &exc; 31 31 } finally { 32 32 loud_exit a = "resumption inner finally"; -
tests/exceptions/interact.cfa
r99fea48 r6f121b8 10 10 // Resume falls back to terminate. 11 11 try { 12 throwResume (star){};12 throwResume &(star){}; 13 13 } catch (star *) { 14 14 printf("caught as termination\n"); … … 17 17 try { 18 18 loud_region a = "try block with resume throw"; 19 throwResume (star){};19 throwResume &(star){}; 20 20 } catch (star *) { 21 21 printf("caught as termination\n"); … … 29 29 try { 30 30 try { 31 throw (star){};31 throw &(star){}; 32 32 } catchResume (star *) { 33 33 printf("resume catch on terminate\n"); … … 43 43 try { 44 44 try { 45 throwResume (star){};45 throwResume &(star){}; 46 46 } catch (star *) { 47 47 printf("terminate catch on resume\n"); … … 58 58 try { 59 59 try { 60 throw (star){};60 throw &(star){}; 61 61 } catchResume (star *) { 62 62 printf("inner resume catch (error)\n"); … … 64 64 } catch (star * error) { 65 65 printf("termination catch, will resume\n"); 66 throwResume *error;66 throwResume error; 67 67 } 68 68 } catchResume (star *) { … … 75 75 try { 76 76 try { 77 throwResume (star){};77 throwResume &(star){}; 78 78 } catch (star *) { 79 79 printf("inner termination catch\n"); … … 81 81 } catchResume (star * error) { 82 82 printf("resumption catch, will terminate\n"); 83 throw *error;83 throw error; 84 84 } 85 85 } catch (star *) { … … 94 94 try { 95 95 printf("throwing resume moon\n"); 96 throwResume (moon){};96 throwResume &(moon){}; 97 97 } catch (star *) { 98 98 printf("termination catch\n"); 99 99 } 100 100 printf("throwing resume star\n"); 101 throwResume (star){};101 throwResume &(star){}; 102 102 } catchResume (star *) { 103 103 printf("resumption star catch\n"); … … 105 105 } catchResume (moon *) { 106 106 printf("resumption moon catch, will terminate\n"); 107 throw (star){};107 throw &(star){}; 108 108 } 109 109 } catchResume (star *) { -
tests/exceptions/resume.cfa
r99fea48 r6f121b8 14 14 loud_exit a = "simple try clause"; 15 15 printf("simple throw\n"); 16 throwResume (zen){};16 throwResume &(zen){}; 17 17 printf("end of try clause\n"); 18 18 } catchResume (zen * error) { … … 24 24 // Throw catch-all test. 25 25 try { 26 throwResume (zen){};26 throwResume &(zen){}; 27 27 } catchResume (exception_t * error) { 28 28 printf("catch-all\n"); … … 33 33 try { 34 34 printf("throwing child exception\n"); 35 throwResume (moment_of){};35 throwResume &(moment_of){}; 36 36 } catchResume (zen *) { 37 37 printf("inner parent match\n"); … … 44 44 try { 45 45 try { 46 throwResume (yin){};46 throwResume &(yin){}; 47 47 } catchResume (zen *) { 48 48 printf("caught yin as zen\n"); … … 60 60 loud_exit a = "rethrow inner try"; 61 61 printf("rethrow inner try\n"); 62 throwResume (zen){};62 throwResume &(zen){}; 63 63 } catchResume (zen *) { 64 64 loud_exit a = "rethrowing catch clause"; … … 75 75 try { 76 76 try { 77 throwResume (yin){};77 throwResume &(yin){}; 78 78 } catchResume (yin *) { 79 79 printf("caught yin, will throw yang\n"); 80 throwResume (yang){};80 throwResume &(yang){}; 81 81 } catchResume (yang *) { 82 82 printf("caught exception from same try\n"); … … 91 91 try { 92 92 printf("throwing first exception\n"); 93 throwResume (yin){};93 throwResume &(yin){}; 94 94 } catchResume (yin *) { 95 95 printf("caught first exception\n"); 96 96 try { 97 97 printf("throwing second exception\n"); 98 throwResume (yang){};98 throwResume &(yang){}; 99 99 } catchResume (yang *) { 100 100 printf("caught second exception\n"); … … 112 112 try { 113 113 try { 114 throwResume (zen){};115 throwResume (zen){};114 throwResume &(zen){}; 115 throwResume &(zen){}; 116 116 } catchResume (zen *) { 117 117 printf("inner catch\n"); 118 118 } 119 throwResume (zen){};119 throwResume &(zen){}; 120 120 } catchResume (zen *) { 121 121 printf("outer catch\n"); -
tests/exceptions/terminate.cfa
r99fea48 r6f121b8 14 14 loud_exit a = "simple try clause"; 15 15 printf("simple throw\n"); 16 throw (zen){};16 throw &(zen){}; 17 17 printf("end of try clause\n"); 18 18 } catch (zen * error) { … … 24 24 // Throw catch-all test. 25 25 try { 26 throw (zen){};26 throw &(zen){}; 27 27 } catch (exception_t * error) { 28 28 printf("catch-all\n"); … … 33 33 try { 34 34 printf("throwing child exception\n"); 35 throw (moment_of){};35 throw &(moment_of){}; 36 36 } catch (zen *) { 37 37 printf("inner parent match\n"); … … 44 44 try { 45 45 try { 46 throw (yin){};46 throw &(yin){}; 47 47 } catch (zen *) { 48 48 printf("caught yin as zen\n"); … … 60 60 loud_exit a = "rethrow inner try"; 61 61 printf("rethrow inner try\n"); 62 throw (zen){};62 throw &(zen){}; 63 63 } catch (zen *) { 64 64 loud_exit a = "rethrowing catch clause"; … … 75 75 try { 76 76 try { 77 throw (yin){};77 throw &(yin){}; 78 78 } catch (yin *) { 79 79 printf("caught yin, will throw yang\n"); 80 throw (yang){};80 throw &(yang){}; 81 81 } catch (yang *) { 82 82 printf("caught exception from same try\n"); … … 91 91 try { 92 92 printf("throwing first exception\n"); 93 throw (yin){};93 throw &(yin){}; 94 94 } catch (yin *) { 95 95 printf("caught first exception\n"); 96 96 try { 97 97 printf("throwing second exception\n"); 98 throw (yang){};98 throw &(yang){}; 99 99 } catch (yang *) { 100 100 printf("caught second exception\n"); … … 112 112 try { 113 113 try { 114 throw (zen){};115 throw (zen){};114 throw &(zen){}; 115 throw &(zen){}; 116 116 } catch (zen *) { 117 117 printf("inner catch\n"); 118 118 } 119 throw (zen){};119 throw &(zen){}; 120 120 } catch (zen *) { 121 121 printf("outer catch\n");
Note:
See TracChangeset
for help on using the changeset viewer.