Changeset 9d6317f


Ignore:
Timestamp:
Jan 22, 2020, 3:40:27 PM (5 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
69e398f
Parents:
5518719
Message:

Added checks for returning from a finally clause. And breaking from a nested function.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r5518719 r9d6317f  
    4545        void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
    4646                PassVisitor<MultiLevelExitMutator> mlem( resolveJumps(), generator );
    47                 functionDecl->acceptMutator( mlem );
     47                // We start in the body so we can stop when we hit another FunctionDecl.
     48                maybeMutate( functionDecl->statements, mlem );
    4849        }
    4950
  • src/ControlStruct/MLEMutator.cc

    r5518719 r9d6317f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jan 21 10:33:00 2020
    13 // Update Count     : 222
     12// Last Modified On : Wed Jan 22 11:50:00 2020
     13// Update Count     : 223
    1414//
    1515
     
    6060                }
    6161        } // namespace
     62
     63        void MultiLevelExitMutator::premutate( FunctionDecl * ) {
     64                visit_children = false;
     65        }
    6266
    6367        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
     
    352356                });
    353357                enclosingControlStructures = std::list<Entry>();
     358                GuardValue( inFinally );
     359                inFinally = true;
     360        }
     361
     362        void MultiLevelExitMutator::premutate( ReturnStmt *returnStmt ) {
     363                if ( inFinally ) {
     364                        SemanticError( returnStmt->location, "'return' may not appear in a finally clause" );
     365                }
    354366        }
    355367
  • src/ControlStruct/MLEMutator.h

    r5518719 r9d6317f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jan 21 10:33:00 2020
    13 // Update Count     : 47
     12// Last Modified On : Wed Jan 22 11:50:00 2020
     13// Update Count     : 48
    1414//
    1515
     
    3838                ~MultiLevelExitMutator();
    3939
     40                void premutate( FunctionDecl * );
     41
    4042                void premutate( CompoundStmt *cmpndStmt );
    4143                Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException );
     
    4951                void premutate( SwitchStmt *switchStmt );
    5052                Statement * postmutate( SwitchStmt *switchStmt );
     53                void premutate( ReturnStmt *returnStmt );
    5154                void premutate( TryStmt *tryStmt );
    5255                Statement * postmutate( TryStmt *tryStmt );
     
    113116                Label breakLabel;
    114117                LabelGenerator *generator;
     118                bool inFinally = false;
    115119
    116120                template< typename LoopClass >
  • tests/.expect/except-finally-error.txt

    r5518719 r9d6317f  
    1111except-finally-error.cfa:111:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
    1212except-finally-error.cfa:124:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
     13except-finally-error.cfa:133:1 error: 'return' may not appear in a finally clause
     14except-finally-error.cfa:139:1 error: 'return' may not appear in a finally clause
     15except-finally-error.cfa:148:1 error: 'break' outside a loop, 'switch', or labelled block
  • tests/except-finally-error.cfa

    r5518719 r9d6317f  
    142142}
    143143
     144// Checked in the same place, make sure it does't break.
     145void break_in_function() {
     146        while (true) {
     147                void inner() {
     148                        break;
     149                }
     150        }
     151}
     152
    144153void main() {
    145154        // Should not compile.
Note: See TracChangeset for help on using the changeset viewer.