Changeset be5aa1b


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

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • Makefile.in

    r6aa5ec0f rbe5aa1b  
    3737        $(top_srcdir)/configure $(top_srcdir)/driver/Makefile.in \
    3838        $(top_srcdir)/libcfa/Makefile.in $(top_srcdir)/src/Makefile.in \
    39         $(top_srcdir)/src/examples/Makefile.in COPYING INSTALL \
    40         install-sh missing
     39        $(top_srcdir)/src/examples/Makefile.in INSTALL install-sh \
     40        missing
    4141ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    4242am__aclocal_m4_deps = $(top_srcdir)/configure.ac
  • configure

    r6aa5ec0f rbe5aa1b  
    23632363
    23642364
    2365 #AM_INIT_AUTOMAKE([foreign])            # do not follow GNU standard
    23662365am__api_version='1.11'
    23672366
  • 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
  • src/SynTree/Statement.cc

    r6aa5ec0f rbe5aa1b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:55:19 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed May 27 15:41:13 2015
     13// Update Count     : 8
    1414//
    1515
     
    4646
    4747BranchStmt::BranchStmt( std::list<Label> labels, Label _target, Type _type ) throw ( SemanticError ) :
    48         Statement( labels ), target(_target ), type(_type ) {
     48        Statement( labels ), originalTarget(_target ), target(_target ), type(_type ) {
    4949        //actually this is a syntactic error signaled by the parser
    5050        if ( type == BranchStmt::Goto && target.size() == 0 )
     
    200200
    201201void ForStmt::print( std::ostream &os, int indent ) {
     202        os << "\r" << string( indent, ' ') << "Labels: {";
     203        for (std::list<Label>::iterator it = get_labels().begin(); it != get_labels().end(); ++it) {
     204                os << *it << ",";
     205        }
     206        os << "}" << endl;
     207
    202208        os << "\r" << string( indent, ' ') << "For Statement" << endl ;
    203209
  • src/SynTree/Statement.h

    r6aa5ec0f rbe5aa1b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:57:40 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed May 27 15:40:43 2015
     13// Update Count     : 5
    1414//
    1515
     
    227227        virtual ~BranchStmt() {}
    228228
     229        Label get_originalTarget() { return originalTarget; }
    229230        Label get_target() { return target; }
    230231        void set_target( Label newValue ) { target = newValue; }
     
    242243  private:
    243244        static const char *brType[];
     245        Label originalTarget;  // can give better error messages if we remember the label name that the user entered
    244246        Label target;
    245247        Expression *computedTarget;
  • src/examples/control_structures.c

    r6aa5ec0f rbe5aa1b  
    11int main() {
    2   L1: {
    3       L2: switch ( 3_333_333 ) {        // underscores in constant
    4           case 1,2,3:                   // 4~8, 4...8 not working
    5           L3: for ( ;; ) {
    6               L4: for ( ;; ) {
    7                     break L1;           // labelled break
    8                     break L2;
    9                     break L3;
    10                     break L4;
    11 #if 0
    12                     continue L1;        // labelled continue
    13                     continue L2;
    14                     continue L3;
    15                     continue L4;
    16 #endif
    17                 } // for
    18             } // for
    19             break;
    20           default:
    21             break L1;
    22         } // switch
    23         3;
    24         int i, j;
    25         choose ( 7 ) {
    26           case 1,2,3:
    27             i = 3;
    28             fallthru;
    29           case 4,5,6:
    30             j = 3;
    31           default: ;
    32         } // choose
    33     } // block
     2        L1: {
     3                L2: switch ( 3_333_333 ) {  // underscores in constant
     4                        case 1,2,3:     // 4~8, 4...8 not working
     5                                L3: for ( ;; ) {
     6                                        L4: for ( ;; ) {
     7                                                break L1;   // labelled break
     8                                                break L2;
     9                                                break L3;
     10                                                break L4;
     11
     12                                                // continue L1; // labelled continue - should be an error
     13                                                // continue L2; // should be an error
     14                                                continue L3;
     15                                                continue L4;
     16                                        } // for
     17                                } // for
     18                                break;
     19                        default:
     20                                break L1;
     21                } // switch
     22                3;
     23                int i, j;
     24                choose ( 7 ) {
     25                        case 1,2,3:
     26                                i = 3;
     27                                fallthru;
     28                        case 4,5,6:
     29                                j = 3;
     30                        default: ;
     31                } // choose
     32        } // block
    3433
    3534#if 0
    36     try {
    37         int i = 3;
    38     } catch( int ) {
    39     } catch( double ) {
    40     } catch( ... ) {
    41     } finally {
    42     } // try
     35        try {
     36                int i = 3;
     37        } catch( int ) {
     38        } catch( double ) {
     39        } catch( ... ) {
     40        } finally {
     41        } // try
    4342#endif
    4443
Note: See TracChangeset for help on using the changeset viewer.