Ignore:
Timestamp:
Jun 14, 2017, 3:16:46 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
f146716
Parents:
bf70aa9 (diff), 6a48cc9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/working/exception/impl/test-main.c

    rbf70aa9 r838ef08  
    11#include "exception.h"
    22
     3// Use: gcc -fexceptions -Wall -Werror -g exception.c test-main.c
     4
    35#include <stdio.h>
     6#include <stdbool.h>
    47
    58// Translation Helpers:
     
    710        struct __cleanup_hook __hidden_hook __attribute__((cleanup(function)))
    811
     12#define SET_UP_RESUME_NODE(handler_function) \
     13        struct __try_resume_node node \
     14                __attribute__((cleanup(__try_resume_node_delete))); \
     15        __try_resume_node_new(&node, handler_function)
     16
     17void __try_resume_node_new(struct __try_resume_node * node,
     18        _Bool (*handler)(exception except)) {
     19    node->next = shared_stack.top_resume;
     20    shared_stack.top_resume = node;
     21    node->try_to_handle = handler;
     22}
     23
     24void __try_resume_node_delete(struct __try_resume_node * node) {
     25    shared_stack.top_resume = node->next;
     26}
    927
    1028// Local Print On Exit:
     
    1937#define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type
    2038
     39// ===========================================================================
    2140// Runtime code (post-translation).
    2241void terminate(int except_value) {
     
    3453// Termination Test: Two handlers: no catch, catch
    3554void bar() {
    36         void bar_try1() {
    37                 terminate(4);
    38         }
    39         void bar_catch1(int index, exception except) {
    40                 switch(except) {
    41                 case 1:
    42                         printf("bar caught exception.\n");
    43                         break;
    44                 default:
    45                         printf("INVALID INDEX in bar: %d\n", except);
    46                 }
    47         }
    48         int bar_match1(exception except) {
    49                 if (3 == except) {
    50                         return 1;
    51                 } else {
    52                         return 0;
    53                 }
    54         }
    55         __try_terminate(bar_try1, bar_catch1, bar_match1);
     55        raii_t a = {"bar function"};
     56        {
     57                void bar_try1() {
     58                        terminate(4);
     59                }
     60                void bar_catch1(int index, exception except) {
     61                        switch(except) {
     62                        case 1:
     63                                printf("bar caught exception 3.\n");
     64                                break;
     65                        default:
     66                                printf("INVALID INDEX in bar: %d (%d)\n", index, except);
     67                        }
     68                }
     69                int bar_match1(exception except) {
     70                        if (3 == except) {
     71                                return 1;
     72                        } else {
     73                                return 0;
     74                        }
     75                }
     76                __try_terminate(bar_try1, bar_catch1, bar_match1);
     77        }
    5678}
    5779
    5880void foo() {
    59         void foo_try1() {
    60                 bar();
    61         }
    62         void foo_catch1(int index, exception except) {
    63                 switch(except) {
    64                 case 1:
    65                         printf("foo caught exception 4.\n");
    66                         break;
    67                 case 2:
    68                         printf("foo caught exception 2.\n");
    69                         break;
    70                 default:
    71                         printf("INVALID INDEX in foo: %d\n", except);
    72                 }
    73         }
    74         int foo_match1(exception except) {
    75                 if (4 == except) {
    76                         return 1;
    77                 } else if (2 == except) {
    78                         return 2;
    79                 } else {
    80                         return 0;
    81                 }
    82         }
    83         __try_terminate(foo_try1, foo_catch1, foo_match1);
    84 }
    85 
     81        raii_t a = {"foo function"};
     82        {
     83                void foo_try1() {
     84                        bar();
     85                }
     86                void foo_catch1(int index, exception except) {
     87                        switch(index) {
     88                        case 1:
     89                                printf("foo caught exception 4.\n");
     90                                break;
     91                        case 2:
     92                                printf("foo caught exception 2.\n");
     93                                break;
     94                        default:
     95                                printf("INVALID INDEX in foo: %d (%d)\n", index, except);
     96                        }
     97                }
     98                int foo_match1(exception except) {
     99                        if (4 == except) {
     100                                return 1;
     101                        } else if (2 == except) {
     102                                return 2;
     103                        } else {
     104                                return 0;
     105                        }
     106                }
     107                __try_terminate(foo_try1, foo_catch1, foo_match1);
     108        }
     109}
     110
     111// Resumption Two Handler Test: no catch, catch.
     112void beta() {
     113        raii_t a = {"beta function"};
     114        {
     115                bool beta_handle1(exception except) {
     116                        if (3 == except) {
     117                                printf("beta caught exception 3\n");
     118                                return true;
     119                        } else {
     120                                return false;
     121                        }
     122                }
     123                struct __try_resume_node node
     124                        __attribute__((cleanup(__try_resume_node_delete)));
     125                __try_resume_node_new(&node, beta_handle1);
     126                {
     127                        resume(4);
     128                }
     129        }
     130}
     131void alpha() {
     132        raii_t a = {"alpha function"};
     133        {
     134                bool alpha_handle1(exception except) {
     135                        if (2 == except) {
     136                                printf("alpha caught exception 2\n");
     137                                return true;
     138                        } else if (4 == except) {
     139                                printf("alpha caught exception 4\n");
     140                                return true;
     141                        } else {
     142                                return false;
     143                        }
     144                }
     145                struct __try_resume_node node
     146                        __attribute__((cleanup(__try_resume_node_delete)));
     147                __try_resume_node_new(&node, alpha_handle1);
     148                {
     149                        beta();
     150                }
     151        }
     152}
     153
     154// Finally Test:
     155void farewell() {
     156        {
     157                void farewell_finally1() {
     158                        printf("See you next time\n");
     159                }
     160                struct __cleanup_hook __hidden_hook
     161                        __attribute__((cleanup(farewell_finally1)));
     162                {
     163                        printf("walk out of farewell\n");
     164                }
     165        }
     166}
     167
     168// Resume-to-Terminate Test:
     169void fallback() {
     170        {
     171                void fallback_try1() {
     172                        resume(1);
     173                }
     174                void fallback_catch1(int index, exception except) {
     175                        switch (index) {
     176                        case 1:
     177                                printf("fallback caught termination 1\n");
     178                                break;
     179                        default:
     180                                printf("INVALID INDEX in fallback: %d (%d)\n", index, except);
     181                        }
     182                }
     183                int fallback_match1(exception except) {
     184                        if (1 == except) {
     185                                return 1;
     186                        } else {
     187                                return 0;
     188                        }
     189                }
     190                __try_terminate(fallback_try1, fallback_catch1, fallback_match1);
     191        }
     192}
     193
     194// Terminate Throw New Exception:
     195void terminate_swap() {
     196        raii_t a = {"terminate_swap"};
     197        {
     198                void fn_try1() {
     199                        terminate(2);
     200                }
     201                void fn_catch1(int index, exception except) {
     202                        switch (index) {
     203                        case 1:
     204                                terminate(1);
     205                                break;
     206                        default:
     207                                printf("INVALID INDEX in terminate_swap: %d (%d)\n",
     208                                        index, except);
     209                        }
     210                }
     211                int fn_match1(exception except) {
     212                        if (2 == except) {
     213                                return 1;
     214                        } else {
     215                                return 0;
     216                        }
     217                }
     218                __try_terminate(fn_try1, fn_catch1, fn_match1);
     219        }
     220}
     221
     222void terminate_swapped() {
     223        raii_t a = {"terminate_swapped"};
     224        {
     225                void fn_try1() {
     226                        terminate_swap();
     227                }
     228                void fn_catch1(int index, exception except) {
     229                        switch (index) {
     230                        case 1:
     231                                printf("terminate_swapped caught exception 1\n");
     232                                break;
     233                        default:
     234                                printf("INVALID INDEX in terminate_swapped: %d (%d)\n",
     235                                        index, except);
     236                        }
     237                }
     238                int fn_match1(exception except) {
     239                        if (1 == except) {
     240                                return 1;
     241                        } else {
     242                                return 0;
     243                        }
     244                }
     245                __try_terminate(fn_try1, fn_catch1, fn_match1);
     246        }
     247}
     248
     249// Resume Throw New Exception:
     250void resume_swap() {
     251        raii_t a = {"terminate_swap"};
     252        {
     253                bool fn_handle1(exception except) {
     254                        if (2 == except) {
     255                                resume(1);
     256                                return true;
     257                        } else {
     258                                return false;
     259                        }
     260                }
     261                struct __try_resume_node node
     262                        __attribute__((cleanup(__try_resume_node_delete)));
     263                __try_resume_node_new(&node, fn_handle1);
     264                {
     265                        resume(2);
     266                }
     267        }
     268}
     269
     270void resume_swapped() {
     271        {
     272                bool fn_handle1(exception except) {
     273                        if (1 == except) {
     274                                printf("resume_swapped caught exception 1\n");
     275                                return true;
     276                        } else {
     277                                return false;
     278                        }
     279                }
     280                struct __try_resume_node node
     281                        __attribute__((cleanup(__try_resume_node_delete)));
     282                __try_resume_node_new(&node, fn_handle1);
     283                {
     284                        resume_swap();
     285                }
     286        }
     287}
     288
     289// Terminate Rethrow:
     290// I don't have an implementation for this.
     291
     292// Resume Rethrow:
     293void reresume() {
     294        {
     295                bool reresume_handle1(exception except) {
     296                        if (1 == except) {
     297                                printf("reresume 1 caught exception 1\n");
     298                                return true;
     299                        } else {
     300                                return false;
     301                        }
     302                }
     303                struct __try_resume_node node
     304                        __attribute__((cleanup(__try_resume_node_delete)));
     305                __try_resume_node_new(&node, reresume_handle1);
     306                {
     307                        bool reresume_handle2(exception except) {
     308                                if (1 == except) {
     309                                        printf("reresume 2 caught and rethrows exception 1\n");
     310                                        return false;
     311                                } else {
     312                                        return false;
     313                                }
     314                        }
     315                        struct __try_resume_node node
     316                                __attribute__((cleanup(__try_resume_node_delete)));
     317                        __try_resume_node_new(&node, reresume_handle2);
     318                        {
     319                                resume(1);
     320                        }
     321                }
     322        }
     323}
     324
     325// Terminate-Resume interaction:
     326void fum() {
     327        // terminate block, call resume
     328        {
     329                void fum_try1() {
     330                        resume(3);
     331                }
     332                void fum_catch1(int index, exception except) {
     333                        switch (index) {
     334                        case 1:
     335                                printf("fum caught exception 3\n");
     336                                break;
     337                        default:
     338                                printf("INVALID INDEX in fum: %d (%d)\n", index, except);
     339                        }
     340                }
     341                int fum_match1(exception except) {
     342                        if (3 == except) {
     343                                return 1;
     344                        } else {
     345                                return 0;
     346                        }
     347                }
     348                __try_terminate(fum_try1, fum_catch1, fum_match1);
     349        }
     350}
     351
     352void foe() {
     353        // resume block, call terminate
     354        {
     355                bool foe_handle1(exception except) {
     356                        if (3 == except) {
     357                                printf("foe caught exception 3\n");
     358                                return true;
     359                        } else {
     360                                return false;
     361                        }
     362                }
     363                struct __try_resume_node node
     364                        __attribute__((cleanup(__try_resume_node_delete)));
     365                __try_resume_node_new(&node, foe_handle1);
     366                {
     367                        terminate(3);
     368                }
     369        }
     370}
     371
     372void fy() {
     373        // terminate block calls fum, call foe
     374        {
     375                void fy_try1() {
     376                        foe();
     377                }
     378                void fy_catch1(int index, exception except) {
     379                        switch (index) {
     380                        case 1:
     381                                printf("fy caught exception 3\n");
     382                                fum();
     383                                break;
     384                        default:
     385                                printf("INVALID INDEX in fy: %d (%d)\n", index, except);
     386                        }
     387                }
     388                int fy_match1(exception except) {
     389                        if (3 == except) {
     390                                return 1;
     391                        } else {
     392                                return 0;
     393                        }
     394                }
     395                __try_terminate(fy_try1, fy_catch1, fy_match1);
     396        }
     397}
     398
     399void fee() {
     400        // resume block, call fy
     401        {
     402                bool fee_handle1(exception except) {
     403                        if (3 == except) {
     404                                printf("fee caught exception 3\n");
     405                                return true;
     406                        } else {
     407                                return false;
     408                        }
     409                }
     410                struct __try_resume_node node
     411                        __attribute__((cleanup(__try_resume_node_delete)));
     412                __try_resume_node_new(&node, fee_handle1);
     413                {
     414                        fy();
     415                }
     416        }
     417}
     418
     419
     420// main: choose which tests to run
    86421int main(int argc, char * argv[]) {
    87422        raii_t a = {"main function"};
    88423
    89         foo();
    90 }
     424        foo(); printf("\n");
     425        alpha(); printf("\n");
     426        farewell(); printf("\n");
     427        fallback(); printf("\n");
     428        terminate_swapped(); printf("\n");
     429        resume_swapped(); printf("\n");
     430        reresume(); printf("\n");
     431        fee(); printf("\n");
     432        // Uncaught termination test.
     433        terminate(7);
     434}
Note: See TracChangeset for help on using the changeset viewer.