Changeset be5aa1b for src/ControlStruct


Ignore:
Timestamp:
May 27, 2015, 4:40:05 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
46cbfe1, 52ac3b4
Parents:
6aa5ec0f
Message:

error if continue statement targets a location that is not an enclosing loop, better error messages for branch statements with labels, formatting, refactoring

Location:
src/ControlStruct
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r6aa5ec0f rbe5aa1b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 15:25:59 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed May 27 16:16:14 2015
     13// Update Count     : 4
    1414//
    1515
     
    4040
    4141        void LabelFixer::visit( FunctionDecl *functionDecl ) {
    42                 if ( functionDecl->get_statements() != 0 )
    43                         functionDecl->get_statements()->accept( *this );
     42                maybeAccept( functionDecl->get_statements(), *this );
    4443
    4544                MLEMutator mlemut( resolveJumps(), generator );
     
    102101                        Entry *e = i->second;
    103102
    104                         if ( def_us.find ( e->get_definition() ) == def_us.end() )
    105                                 def_us[ e->get_definition() ] = e;
    106                         else
     103                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
     104                                def_us[ e->get_definition() ] = e;                             
     105                        } else {
    107106                                if ( e->used() )
    108107                                        def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     108                        }
    109109                }
    110110
  • src/ControlStruct/LabelFixer.h

    r6aa5ec0f rbe5aa1b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 15:31:55 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue May 26 12:55:10 2015
     13// Update Count     : 4
    1414//
    1515
     
    6666
    6767                        Label get_label() const { return label; }
     68                        void set_label( Label lab ) { label = lab; }
     69
    6870                        Statement *get_definition() const { return definition; }
     71                        void set_definition( Statement *def ) { definition = def; }
     72
    6973                        std::list< Statement *> &get_uses() { return usage; }
    70 
    7174                        void add_use ( Statement *use ) { usage.push_back( use ); }
    7275                        void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
    73                         void set_definition( Statement *def ) { definition = def; }
    74 
    75                         void set_label( Label lab ) { label = lab; }
    76                         Label gset_label() const { return label; }
    7776                  private:
    7877                        Label label; 
  • src/ControlStruct/MLEMutator.cc

    r6aa5ec0f rbe5aa1b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 15:32:26 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed May 27 16:19:32 2015
     13// Update Count     : 44
    1414//
    1515
     
    2828        CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
    2929                bool labeledBlock = false;
    30                 if ( !((cmpndStmt->get_labels()).empty()) ) {
     30                if ( !(cmpndStmt->get_labels().empty()) ) {
    3131                        labeledBlock = true;
    3232                        enclosingBlocks.push_back( Entry( cmpndStmt ) );
     
    4242                                        std::list<Label> ls; ls.push_back( get_breakLabel() );
    4343                                        kids.push_back( new NullStmt( ls ) );
    44                                 } else
     44                                } else {
    4545                                        (*next)->get_labels().push_back( get_breakLabel() );
     46                                }
    4647
    4748                                set_breakLabel("");
     
    5152                if ( labeledBlock ) {
    5253                        assert( ! enclosingBlocks.empty() );
    53                         if ( ! enclosingBlocks.back().get_breakExit().empty() )
     54                        if ( ! enclosingBlocks.back().get_breakExit().empty() ) {
    5455                                set_breakLabel( enclosingBlocks.back().get_breakExit() );
     56                        }
    5557                        enclosingBlocks.pop_back();
    5658                } // if
     
    8587
    8688        Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
     89                std::string originalTarget = branchStmt->get_originalTarget();
     90
    8791                if ( branchStmt->get_type() == BranchStmt::Goto )
    8892                        return branchStmt;
    8993
    9094                // test if continue target is a loop
    91                 if ( branchStmt->get_type() == BranchStmt::Continue && enclosingLoops.empty() )
    92                         throw SemanticError( "'continue' outside a loop" );
     95                if ( branchStmt->get_type() == BranchStmt::Continue) {
     96                        if ( enclosingLoops.empty() ) {
     97                                throw SemanticError( "'continue' outside a loop" );
     98                        } else if ( std::find( enclosingLoops.begin(), enclosingLoops.end(), (*targetTable)[branchStmt->get_target()] ) == enclosingLoops.end() ) {
     99                                throw SemanticError( "'continue' target label must be an enclosing loop: " + originalTarget );
     100                        }
     101                }
    93102
    94103                if ( branchStmt->get_type() == BranchStmt::Break && (enclosingLoops.empty() && enclosingSwitches.empty() && enclosingBlocks.empty() ) )
     
    98107
    99108                if ( targetTable->find( branchStmt->get_target() ) == targetTable->end() )
    100                         throw SemanticError("The label defined in the exit loop statement does not exist." );  // shouldn't happen (since that's already checked)
     109                        throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget );  // shouldn't happen (since that's already checked)
    101110
    102111                std::list< Entry >::iterator check;
     
    106115                                // neither in loop nor in block, checking if in switch/choose
    107116                                if ( (check = std::find( enclosingSwitches.begin(), enclosingSwitches.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingSwitches.end() )
    108                                         throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing loop.");
     117                                        throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget );
    109118
    110119                if ( enclosingLoops.back() == (*check) )
     
    114123                switch ( branchStmt->get_type() ) {
    115124                  case BranchStmt::Break:
    116                         if ( check->get_breakExit() != "" )
    117                                 newLabel = check->get_breakExit();
    118                         else {
    119                                 newLabel = generator->newLabel();
    120                                 check->set_breakExit( newLabel );
    121                         } // if
    122                         break;
     125                                if ( check->get_breakExit() != "" ) {
     126                                        newLabel = check->get_breakExit();
     127                                } else {
     128                                        newLabel = generator->newLabel();
     129                                        check->set_breakExit( newLabel );
     130                                } // if
     131                                break;
    123132                  case BranchStmt::Continue:
    124                         if ( check->get_contExit() != "" )
    125                                 newLabel = check->get_contExit();
    126                         else {
    127                                 newLabel = generator->newLabel();
    128                                 check->set_contExit( newLabel );
    129                         } // if
    130                         break;
     133                                if ( check->get_contExit() != "" ) {
     134                                        newLabel = check->get_contExit();
     135                                } else {
     136                                        newLabel = generator->newLabel();
     137                                        check->set_contExit( newLabel );
     138                                } // if
     139                                break;
    131140                  default:
    132                         return 0;                                       // shouldn't be here
     141                                return 0;                                       // shouldn't be here
    133142                } // switch
    134143
     
    136145        }
    137146
    138 
    139         Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
     147        template< typename SwitchClass >
     148        Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator ) {
     149                // set up some aliases so that the rest of the code isn't messy
     150                typedef MLEMutator::Entry Entry;
     151                LabelGenerator *generator = mutator.generator;
     152                std::list< Entry > &enclosingSwitches = mutator.enclosingSwitches;
     153
    140154                Label brkLabel = generator->newLabel();
    141155                enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
    142                 mutateAll( switchStmt->get_branches(), *this ); {
     156                mutateAll( switchStmt->get_branches(), mutator ); {
    143157                        // check if this is necessary (if there is a break to this point, otherwise do not generate
    144158                        std::list<Label> temp; temp.push_back( brkLabel );
     
    150164        }
    151165
     166        Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
     167                return handleSwitchStmt( switchStmt, *this );
     168        }
     169
    152170        Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
    153                 Label brkLabel = generator->newLabel();
    154                 enclosingSwitches.push_back( Entry(switchStmt,"", brkLabel) );
    155                 mutateAll( switchStmt->get_branches(), *this ); {
    156                         // check if this is necessary (if there is a break to this point, otherwise do not generate
    157                         std::list<Label> temp; temp.push_back( brkLabel );
    158                         switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
    159                 }
    160                 assert ( enclosingSwitches.back() == switchStmt );
    161                 enclosingSwitches.pop_back();
    162                 return switchStmt;
     171                return handleSwitchStmt( switchStmt, *this );           
    163172        }
    164173
  • src/ControlStruct/MLEMutator.h

    r6aa5ec0f rbe5aa1b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 15:32:39 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue May 26 15:04:21 2015
     13// Update Count     : 7
    1414//
    1515
     
    7575                Label breakLabel;
    7676                LabelGenerator *generator;
     77
     78                template< typename SwitchClass >
     79                friend Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator );
    7780        };
    7881} // namespace ControlStruct
Note: See TracChangeset for help on using the changeset viewer.