comparison dmd/statement.c @ 875:330f999ade44

Merged DMD 1.038
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 06 Jan 2009 16:33:51 +0100
parents bc982f1ad106
children d51551cb3a85
comparison
equal deleted inserted replaced
874:2ddee23bd70e 875:330f999ade44
122 printf("%s\n", toChars()); 122 printf("%s\n", toChars());
123 assert(0); 123 assert(0);
124 return BEany; 124 return BEany;
125 } 125 }
126 126
127 // TRUE if statement may fall off the end without a throw or return
128
129 int Statement::fallOffEnd()
130 {
131 return TRUE;
132 }
133
134 // TRUE if statement 'comes from' somewhere else, like a goto 127 // TRUE if statement 'comes from' somewhere else, like a goto
135 128
136 int Statement::comeFrom() 129 int Statement::comeFrom()
137 { 130 {
138 //printf("Statement::comeFrom()\n"); 131 //printf("Statement::comeFrom()\n");
225 result |= BEthrow; 218 result |= BEthrow;
226 } 219 }
227 return result; 220 return result;
228 } 221 }
229 222
230 int ExpStatement::fallOffEnd()
231 {
232 if (exp)
233 {
234 if (exp->op == TOKassert)
235 { AssertExp *a = (AssertExp *)exp;
236
237 if (a->e1->isBool(FALSE)) // if it's an assert(0)
238 return FALSE;
239 }
240 else if (exp->op == TOKhalt)
241 return FALSE;
242 }
243 return TRUE;
244 }
245 223
246 /******************************** CompileStatement ***************************/ 224 /******************************** CompileStatement ***************************/
247 225
248 CompileStatement::CompileStatement(Loc loc, Expression *exp) 226 CompileStatement::CompileStatement(Loc loc, Expression *exp)
249 : Statement(loc) 227 : Statement(loc)
572 } 550 }
573 } 551 }
574 return result; 552 return result;
575 } 553 }
576 554
577 int CompoundStatement::fallOffEnd()
578 { int falloff = TRUE;
579
580 //printf("CompoundStatement::fallOffEnd() %s\n", toChars());
581 for (int i = 0; i < statements->dim; i++)
582 { Statement *s = (Statement *)statements->data[i];
583
584 if (!s)
585 continue;
586
587 if (!falloff && global.params.warnings && !s->comeFrom())
588 {
589 warning("%s: statement is not reachable", s->loc.toChars());
590 }
591 falloff = s->fallOffEnd();
592 }
593 return falloff;
594 }
595
596 int CompoundStatement::comeFrom() 555 int CompoundStatement::comeFrom()
597 { int comefrom = FALSE; 556 { int comefrom = FALSE;
598 557
599 //printf("CompoundStatement::comeFrom()\n"); 558 //printf("CompoundStatement::comeFrom()\n");
600 for (int i = 0; i < statements->dim; i++) 559 for (int i = 0; i < statements->dim; i++)
708 } 667 }
709 } 668 }
710 return result; 669 return result;
711 } 670 }
712 671
713 int UnrolledLoopStatement::fallOffEnd()
714 {
715 //printf("UnrolledLoopStatement::fallOffEnd()\n");
716 for (size_t i = 0; i < statements->dim; i++)
717 { Statement *s = (Statement *)statements->data[i];
718
719 if (s)
720 s->fallOffEnd();
721 }
722 return TRUE;
723 }
724
725 int UnrolledLoopStatement::comeFrom() 672 int UnrolledLoopStatement::comeFrom()
726 { int comefrom = FALSE; 673 { int comefrom = FALSE;
727 674
728 //printf("UnrolledLoopStatement::comeFrom()\n"); 675 //printf("UnrolledLoopStatement::comeFrom()\n");
729 for (size_t i = 0; i < statements->dim; i++) 676 for (size_t i = 0; i < statements->dim; i++)
811 758
812 int ScopeStatement::blockExit() 759 int ScopeStatement::blockExit()
813 { 760 {
814 //printf("ScopeStatement::blockExit(%p)\n", statement); 761 //printf("ScopeStatement::blockExit(%p)\n", statement);
815 return statement ? statement->blockExit() : BEfallthru; 762 return statement ? statement->blockExit() : BEfallthru;
816 }
817
818 int ScopeStatement::fallOffEnd()
819 {
820 return statement ? statement->fallOffEnd() : TRUE;
821 } 763 }
822 764
823 int ScopeStatement::comeFrom() 765 int ScopeStatement::comeFrom()
824 { 766 {
825 //printf("ScopeStatement::comeFrom()\n"); 767 //printf("ScopeStatement::comeFrom()\n");
943 } 885 }
944 result &= ~(BEbreak | BEcontinue); 886 result &= ~(BEbreak | BEcontinue);
945 return result; 887 return result;
946 } 888 }
947 889
948 int WhileStatement::fallOffEnd()
949 {
950 if (body)
951 body->fallOffEnd();
952 return TRUE;
953 }
954
955 int WhileStatement::comeFrom() 890 int WhileStatement::comeFrom()
956 { 891 {
957 if (body) 892 if (body)
958 return body->comeFrom(); 893 return body->comeFrom();
959 return FALSE; 894 return FALSE;
1036 if (!(result & BEbreak) && condition->isBool(TRUE)) 971 if (!(result & BEbreak) && condition->isBool(TRUE))
1037 result &= ~BEfallthru; 972 result &= ~BEfallthru;
1038 } 973 }
1039 result &= ~(BEbreak | BEcontinue); 974 result &= ~(BEbreak | BEcontinue);
1040 return result; 975 return result;
1041 }
1042
1043 int DoStatement::fallOffEnd()
1044 {
1045 if (body)
1046 body->fallOffEnd();
1047 return TRUE;
1048 } 976 }
1049 977
1050 int DoStatement::comeFrom() 978 int DoStatement::comeFrom()
1051 { 979 {
1052 if (body) 980 if (body)
1173 result |= r & ~(BEbreak | BEcontinue); 1101 result |= r & ~(BEbreak | BEcontinue);
1174 } 1102 }
1175 if (increment && increment->canThrow()) 1103 if (increment && increment->canThrow())
1176 result |= BEthrow; 1104 result |= BEthrow;
1177 return result; 1105 return result;
1178 }
1179
1180 int ForStatement::fallOffEnd()
1181 {
1182 if (body)
1183 body->fallOffEnd();
1184 return TRUE;
1185 } 1106 }
1186 1107
1187 int ForStatement::comeFrom() 1108 int ForStatement::comeFrom()
1188 { 1109 {
1189 //printf("ForStatement::comeFrom()\n"); 1110 //printf("ForStatement::comeFrom()\n");
1876 result |= body->blockExit() & ~(BEbreak | BEcontinue); 1797 result |= body->blockExit() & ~(BEbreak | BEcontinue);
1877 } 1798 }
1878 return result; 1799 return result;
1879 } 1800 }
1880 1801
1881 int ForeachStatement::fallOffEnd()
1882 {
1883 if (body)
1884 body->fallOffEnd();
1885 return TRUE;
1886 }
1887
1888 int ForeachStatement::comeFrom() 1802 int ForeachStatement::comeFrom()
1889 { 1803 {
1890 if (body) 1804 if (body)
1891 return body->comeFrom(); 1805 return body->comeFrom();
1892 return FALSE; 1806 return FALSE;
2039 result |= BEfallthru; 1953 result |= BEfallthru;
2040 } 1954 }
2041 //printf("IfStatement::blockExit(%p) = x%x\n", this, result); 1955 //printf("IfStatement::blockExit(%p) = x%x\n", this, result);
2042 return result; 1956 return result;
2043 } 1957 }
2044
2045 int IfStatement::fallOffEnd()
2046 {
2047 if (!ifbody || ifbody->fallOffEnd() ||
2048 !elsebody || elsebody->fallOffEnd())
2049 return TRUE;
2050 return FALSE;
2051 }
2052
2053 1958
2054 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1959 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2055 { 1960 {
2056 buf->writestring("if ("); 1961 buf->writestring("if (");
2057 if (arg) 1962 if (arg)
2266 result |= body->blockExit(); 2171 result |= body->blockExit();
2267 #endif 2172 #endif
2268 return result; 2173 return result;
2269 } 2174 }
2270 2175
2271 int PragmaStatement::fallOffEnd()
2272 {
2273 if (body)
2274 return body->fallOffEnd();
2275 return TRUE;
2276 }
2277
2278 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2176 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2279 { 2177 {
2280 buf->writestring("pragma ("); 2178 buf->writestring("pragma (");
2281 buf->writestring(ident->toChars()); 2179 buf->writestring(ident->toChars());
2282 if (args && args->dim) 2180 if (args && args->dim)
2471 } 2369 }
2472 else 2370 else
2473 result |= BEfallthru; 2371 result |= BEfallthru;
2474 2372
2475 return result; 2373 return result;
2476 }
2477
2478 int SwitchStatement::fallOffEnd()
2479 {
2480 if (body)
2481 body->fallOffEnd();
2482 return TRUE; // need to do this better
2483 } 2374 }
2484 2375
2485 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2376 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2486 { 2377 {
2487 buf->writestring("switch ("); 2378 buf->writestring("switch (");
2584 int CaseStatement::blockExit() 2475 int CaseStatement::blockExit()
2585 { 2476 {
2586 return statement->blockExit(); 2477 return statement->blockExit();
2587 } 2478 }
2588 2479
2589 int CaseStatement::fallOffEnd()
2590 {
2591 return statement->fallOffEnd();
2592 }
2593
2594 int CaseStatement::comeFrom() 2480 int CaseStatement::comeFrom()
2595 { 2481 {
2596 return TRUE; 2482 return TRUE;
2597 } 2483 }
2598 2484
2648 int DefaultStatement::blockExit() 2534 int DefaultStatement::blockExit()
2649 { 2535 {
2650 return statement->blockExit(); 2536 return statement->blockExit();
2651 } 2537 }
2652 2538
2653 int DefaultStatement::fallOffEnd()
2654 {
2655 return statement->fallOffEnd();
2656 }
2657
2658 int DefaultStatement::comeFrom() 2539 int DefaultStatement::comeFrom()
2659 { 2540 {
2660 return TRUE; 2541 return TRUE;
2661 } 2542 }
2662 2543
2691 } 2572 }
2692 2573
2693 int GotoDefaultStatement::blockExit() 2574 int GotoDefaultStatement::blockExit()
2694 { 2575 {
2695 return BEgoto; 2576 return BEgoto;
2696 }
2697
2698 int GotoDefaultStatement::fallOffEnd()
2699 {
2700 return FALSE;
2701 } 2577 }
2702 2578
2703 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2579 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2704 { 2580 {
2705 buf->writestring("goto default;\n"); 2581 buf->writestring("goto default;\n");
2747 int GotoCaseStatement::blockExit() 2623 int GotoCaseStatement::blockExit()
2748 { 2624 {
2749 return BEgoto; 2625 return BEgoto;
2750 } 2626 }
2751 2627
2752 int GotoCaseStatement::fallOffEnd()
2753 {
2754 return FALSE;
2755 }
2756
2757 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2628 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2758 { 2629 {
2759 buf->writestring("goto case"); 2630 buf->writestring("goto case");
2760 if (exp) 2631 if (exp)
2761 { buf->writebyte(' '); 2632 { buf->writebyte(' ');
2773 } 2644 }
2774 2645
2775 int SwitchErrorStatement::blockExit() 2646 int SwitchErrorStatement::blockExit()
2776 { 2647 {
2777 return BEthrow; 2648 return BEthrow;
2778 }
2779
2780 int SwitchErrorStatement::fallOffEnd()
2781 {
2782 return FALSE;
2783 } 2649 }
2784 2650
2785 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2651 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2786 { 2652 {
2787 buf->writestring("SwitchErrorStatement::toCBuffer()"); 2653 buf->writestring("SwitchErrorStatement::toCBuffer()");
3052 { int result = BEreturn; 2918 { int result = BEreturn;
3053 2919
3054 if (exp && exp->canThrow()) 2920 if (exp && exp->canThrow())
3055 result |= BEthrow; 2921 result |= BEthrow;
3056 return result; 2922 return result;
3057 }
3058
3059 int ReturnStatement::fallOffEnd()
3060 {
3061 return FALSE;
3062 } 2923 }
3063 2924
3064 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2925 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3065 { 2926 {
3066 buf->printf("return "); 2927 buf->printf("return ");
3153 { 3014 {
3154 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); 3015 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak);
3155 return ident ? BEgoto : BEbreak; 3016 return ident ? BEgoto : BEbreak;
3156 } 3017 }
3157 3018
3158 int BreakStatement::fallOffEnd()
3159 {
3160 return FALSE;
3161 }
3162
3163 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3019 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3164 { 3020 {
3165 buf->writestring("break"); 3021 buf->writestring("break");
3166 if (ident) 3022 if (ident)
3167 { buf->writebyte(' '); 3023 { buf->writebyte(' ');
3261 int ContinueStatement::blockExit() 3117 int ContinueStatement::blockExit()
3262 { 3118 {
3263 return ident ? BEgoto : BEcontinue; 3119 return ident ? BEgoto : BEcontinue;
3264 } 3120 }
3265 3121
3266 int ContinueStatement::fallOffEnd()
3267 {
3268 return FALSE;
3269 }
3270
3271 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3122 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3272 { 3123 {
3273 buf->writestring("continue"); 3124 buf->writestring("continue");
3274 if (ident) 3125 if (ident)
3275 { buf->writebyte(' '); 3126 { buf->writebyte(' ');
3354 } 3205 }
3355 3206
3356 int SynchronizedStatement::blockExit() 3207 int SynchronizedStatement::blockExit()
3357 { 3208 {
3358 return body ? body->blockExit() : BEfallthru; 3209 return body ? body->blockExit() : BEfallthru;
3359 }
3360
3361 int SynchronizedStatement::fallOffEnd()
3362 {
3363 return body ? body->fallOffEnd() : TRUE;
3364 } 3210 }
3365 3211
3366 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3212 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3367 { 3213 {
3368 buf->writestring("synchronized"); 3214 buf->writestring("synchronized");
3478 else 3324 else
3479 result |= BEfallthru; 3325 result |= BEfallthru;
3480 return result; 3326 return result;
3481 } 3327 }
3482 3328
3483 int WithStatement::fallOffEnd()
3484 {
3485 return body ? body->fallOffEnd() : TRUE;
3486 }
3487
3488 /******************************** TryCatchStatement ***************************/ 3329 /******************************** TryCatchStatement ***************************/
3489 3330
3490 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) 3331 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches)
3491 : Statement(loc) 3332 : Statement(loc)
3492 { 3333 {
3550 3391
3551 for (size_t i = 0; i < catches->dim; i++) 3392 for (size_t i = 0; i < catches->dim; i++)
3552 { 3393 {
3553 Catch *c = (Catch *)catches->data[i]; 3394 Catch *c = (Catch *)catches->data[i];
3554 result |= c->blockExit(); 3395 result |= c->blockExit();
3555 }
3556 return result;
3557 }
3558
3559 int TryCatchStatement::fallOffEnd()
3560 {
3561 int result = FALSE;
3562
3563 if (body)
3564 result = body->fallOffEnd();
3565 for (int i = 0; i < catches->dim; i++)
3566 { Catch *c;
3567
3568 c = (Catch *)catches->data[i];
3569 if (c->handler)
3570 result |= c->handler->fallOffEnd();
3571 } 3396 }
3572 return result; 3397 return result;
3573 } 3398 }
3574 3399
3575 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3400 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3726 return TRUE; 3551 return TRUE;
3727 } 3552 }
3728 3553
3729 int TryFinallyStatement::blockExit() 3554 int TryFinallyStatement::blockExit()
3730 { 3555 {
3731 int result = body->blockExit(); 3556 if (body)
3732 return result; 3557 return body->blockExit();
3733 } 3558 return BEfallthru;
3734 3559 }
3735 int TryFinallyStatement::fallOffEnd() 3560
3736 { int result;
3737
3738 result = body ? body->fallOffEnd() : TRUE;
3739 // if (finalbody)
3740 // result = finalbody->fallOffEnd();
3741 return result;
3742 }
3743 3561
3744 /****************************** OnScopeStatement ***************************/ 3562 /****************************** OnScopeStatement ***************************/
3745 3563
3746 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement) 3564 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement)
3747 : Statement(loc) 3565 : Statement(loc)
3859 int ThrowStatement::blockExit() 3677 int ThrowStatement::blockExit()
3860 { 3678 {
3861 return BEthrow; // obviously 3679 return BEthrow; // obviously
3862 } 3680 }
3863 3681
3864 int ThrowStatement::fallOffEnd()
3865 {
3866 return FALSE;
3867 }
3868
3869 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3682 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3870 { 3683 {
3871 buf->printf("throw "); 3684 buf->printf("throw ");
3872 exp->toCBuffer(buf, hgs); 3685 exp->toCBuffer(buf, hgs);
3873 buf->writeByte(';'); 3686 buf->writeByte(';');
3920 } 3733 }
3921 3734
3922 int VolatileStatement::blockExit() 3735 int VolatileStatement::blockExit()
3923 { 3736 {
3924 return statement ? statement->blockExit() : BEfallthru; 3737 return statement ? statement->blockExit() : BEfallthru;
3925 }
3926
3927 int VolatileStatement::fallOffEnd()
3928 {
3929 return statement ? statement->fallOffEnd() : TRUE;
3930 } 3738 }
3931 3739
3932 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3740 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3933 { 3741 {
3934 buf->writestring("volatile"); 3742 buf->writestring("volatile");
3989 3797
3990 int GotoStatement::blockExit() 3798 int GotoStatement::blockExit()
3991 { 3799 {
3992 //printf("GotoStatement::blockExit(%p)\n", this); 3800 //printf("GotoStatement::blockExit(%p)\n", this);
3993 return BEgoto; 3801 return BEgoto;
3994 }
3995
3996 int GotoStatement::fallOffEnd()
3997 {
3998 return FALSE;
3999 } 3802 }
4000 3803
4001 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3804 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4002 { 3805 {
4003 buf->writestring("goto "); 3806 buf->writestring("goto ");
4085 { 3888 {
4086 //printf("LabelStatement::blockExit(%p)\n", this); 3889 //printf("LabelStatement::blockExit(%p)\n", this);
4087 return statement ? statement->blockExit() : BEfallthru; 3890 return statement ? statement->blockExit() : BEfallthru;
4088 } 3891 }
4089 3892
4090 int LabelStatement::fallOffEnd()
4091 {
4092 return statement ? statement->fallOffEnd() : TRUE;
4093 }
4094
4095 int LabelStatement::comeFrom() 3893 int LabelStatement::comeFrom()
4096 { 3894 {
4097 //printf("LabelStatement::comeFrom()\n"); 3895 //printf("LabelStatement::comeFrom()\n");
4098 return TRUE; 3896 return TRUE;
4099 } 3897 }