Changeset adcc065


Ignore:
Timestamp:
Jul 6, 2016, 6:06:27 PM (5 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
3f869f0
Parents:
e04c5ff
Message:

add labelled break to if statement, update comment formatting, add random number test

Location:
src
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/MLEMutator.cc

    re04c5ff radcc065  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Jul 20 13:58:35 2015
    13 // Update Count     : 176
    14 //
    15 
    16 // NOTE: There are two known subtle differences from the code that uC++
    17 // generates for the same input
    18 // -CFA puts the break label inside at the end of a switch, uC++ puts it after
    19 // -CFA puts the break label after a block, uC++ puts it inside at the end
    20 // we don't yet know if these differences are important, but if they are then
    21 // the fix would go in this file, since this is where these labels are generated.
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul  6 17:40:02 2016
     13// Update Count     : 196
     14//
     15
     16// NOTE: There are two known subtle differences from the code that uC++ generates for the same input
     17//   -CFA puts the break label inside at the end of a switch, uC++ puts it after
     18//   -CFA puts the break label after a block, uC++ puts it inside at the end
     19// It is unclear if these differences are important, but if they are, then the fix would go in this file, since this is
     20// where these labels are generated.
    2221
    2322#include <cassert>
     
    3837        }
    3938
    40         // break labels have to come after the statement they break out of,
    41         // so mutate a statement, then if they inform us through the breakLabel field
    42         // tha they need a place to jump to on a break statement, add the break label
    43         // to the body of statements
     39        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
     40        // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the
     41        // body of statements
    4442        void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
    4543                for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
     
    6260                } // if
    6361
    64                 // a child statement may set the break label
    65                 // - if they do, attach it to the next statement
     62                // a child statement may set the break label - if they do, attach it to the next statement
    6663                std::list< Statement * > &kids = cmpndStmt->get_kids();
    6764                fixBlock( kids );
     
    7168                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
    7269                                set_breakLabel( enclosingControlStructures.back().useBreakExit() );
    73                         }
     70                        } // if
    7471                        enclosingControlStructures.pop_back();
    7572                } // if
     
    8077        template< typename LoopClass >
    8178        Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
    82                 // remember this as the most recent enclosing loop, then mutate
    83                 // the body of the loop -- this will determine whether brkLabel
    84                 // and contLabel are used with branch statements
    85                 // and will recursively do the same to nested loops
     79                // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
     80                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
     81                // loops
    8682                Label brkLabel = generator->newLabel("loopBreak");
    8783                Label contLabel = generator->newLabel("loopContinue");
     
    8985                loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
    9086
     87                Entry &e = enclosingControlStructures.back();
    9188                // sanity check that the enclosing loops have been popped correctly
    92                 Entry &e = enclosingControlStructures.back();
    9389                assert ( e == loopStmt );
    9490
    95                 // this will take the necessary steps to add definitions of the previous
    96                 // two labels, if they are used.
     91                // this will take the necessary steps to add definitions of the previous two labels, if they are used.
    9792                loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
    9893                enclosingControlStructures.pop_back();
     
    106101
    107102                return caseStmt;
     103        }
     104
     105        template< typename IfClass >
     106        Statement *MLEMutator::handleIfStmt( IfClass *ifStmt ) {
     107                // generate a label for breaking out of a labeled if
     108                bool labeledBlock = !(ifStmt->get_labels().empty());
     109                if ( labeledBlock ) {
     110                        Label brkLabel = generator->newLabel("blockBreak");
     111                        enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
     112                } // if
     113
     114                Parent::mutate( ifStmt );
     115               
     116                if ( labeledBlock ) {
     117                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
     118                                set_breakLabel( enclosingControlStructures.back().useBreakExit() );
     119                        } // if
     120                        enclosingControlStructures.pop_back();
     121                } // if
     122                return ifStmt;
    108123        }
    109124
     
    119134
    120135                // only generate break label if labeled break is used
    121                 if (e.isBreakUsed()) {
    122                         // for the purposes of keeping switch statements uniform (i.e. all statements that are
    123                         // direct children of a switch should be CastStmts), append the exit label + break to the
    124                         // last case statement; create a default case if there are no cases
     136                if ( e.isBreakUsed() ) {
     137                        // for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a
     138                        // switch should be CastStmts), append the exit label + break to the last case statement; create a default
     139                        // case if there are no cases
    125140                        std::list< Statement * > &branches = switchStmt->get_branches();
    126141                        if ( branches.empty() ) {
    127142                                branches.push_back( CaseStmt::makeDefault() );
    128                         }
     143                        } // if
    129144
    130145                        if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) {
     
    132147                                c->get_statements().push_back( new BranchStmt( temp, Label("brkLabel"), BranchStmt::Break ) );
    133148                        } else assert(0); // as of this point, all branches of a switch are still CaseStmts
    134                 }
     149                } // if
    135150
    136151                assert ( enclosingControlStructures.back() == switchStmt );
     
    152167                                // labelled continue - lookup label in table ot find attached control structure
    153168                                targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] );
    154                         }
     169                        } // if
    155170                        if ( targetEntry == enclosingControlStructures.rend() || ! isLoop( targetEntry->get_controlStructure() ) ) {
    156171                                throw SemanticError( "'continue' target must be an enclosing loop: " + originalTarget );
    157                         }
     172                        } // if
    158173                } else if ( branchStmt->get_type() == BranchStmt::Break ) {
    159174                        if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" );
     
    161176                } else {
    162177                        assert( false );
    163                 }
     178                } // if
    164179
    165180                if ( branchStmt->get_target() != "" && targetTable->find( branchStmt->get_target() ) == targetTable->end() ) {
    166181                        throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget );  // shouldn't happen (since that's already checked)
    167                 }
     182                } // if
    168183
    169184                // branch error checks, get the appropriate label name and create a goto
     
    191206                        delete branchStmt;
    192207                        return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
    193                 }
     208                } // if
    194209        }
    195210
     
    208223                        std::list< Label > labels; labels.push_back( e.useContExit() );
    209224                        newBody->get_kids().push_back( new NullStmt( labels ) );
    210                 }
     225                } // if
    211226
    212227                if ( e.isBreakUsed() ) {
    213                         // break label goes after the loop -- it'll get set by the
    214                         // outer mutator if we do this
     228                        // break label goes after the loop -- it'll get set by the outer mutator if we do this
    215229                        set_breakLabel( e.useBreakExit() );
    216                 }
     230                } // if
    217231
    218232                return newBody;
     
    227241        }
    228242
     243        Statement *MLEMutator::mutate( IfStmt *ifStmt ) {
     244                return handleIfStmt( ifStmt );
     245        }
     246
    229247        Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
    230248                return handleSwitchStmt( switchStmt );
     
    234252                return handleSwitchStmt( switchStmt );
    235253        }
    236 
    237254} // namespace ControlStruct
    238255
  • src/ControlStruct/MLEMutator.h

    re04c5ff radcc065  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jun 03 15:06:36 2015
    13 // Update Count     : 25
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul  6 16:49:52 2016
     13// Update Count     : 31
    1414//
    1515
     
    3030        class MLEMutator : public Mutator {
    3131                class Entry;
     32                typedef Mutator Parent;
    3233          public:
    3334                MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
     
    3536
    3637                CompoundStmt *mutate( CompoundStmt *cmpndStmt );
    37                 Statement *mutate( WhileStmt *whileStmt );
    38                 Statement *mutate( ForStmt *forStmt );
    39                 Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
     38                virtual Statement *mutate( WhileStmt *whileStmt ) override;
     39                virtual Statement *mutate( ForStmt *forStmt ) override;
     40                virtual Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError ) override;
    4041
    41                 Statement *mutate( CaseStmt *caseStmt );
    42                 Statement *mutate( SwitchStmt *switchStmt );
    43                 Statement *mutate( ChooseStmt *switchStmt );
     42                virtual Statement *mutate( CaseStmt *caseStmt ) override;
     43                virtual Statement *mutate( IfStmt *ifStmt ) override;
     44                virtual Statement *mutate( SwitchStmt *switchStmt ) override;
     45                virtual Statement *mutate( ChooseStmt *switchStmt ) override;
    4446
    4547                Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     
    6567                        bool isContUsed() const { return contUsed; }
    6668                        bool isBreakUsed() const { return breakUsed; }
    67 
    6869                  private:
    6970                        Statement *loop;
     
    7980                template< typename LoopClass >
    8081                Statement *handleLoopStmt( LoopClass *loopStmt );
     82
     83                template< typename IfClass >
     84                Statement *handleIfStmt( IfClass *switchStmt );
    8185
    8286                template< typename SwitchClass >
  • src/InitTweak/FixInit.cc

    re04c5ff radcc065  
    99// Author           : Rob Schluntz
    1010// Created On       : Wed Jan 13 16:29:30 2016
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 13 11:44:26 2016
    13 // Update Count     : 30
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul  6 17:34:46 2016
     13// Update Count     : 33
    1414//
    1515
     
    4747                class InsertImplicitCalls : public GenPoly::PolyMutator {
    4848                public:
    49                         /// wrap function application expressions as ImplicitCopyCtorExpr nodes
    50                         /// so that it is easy to identify which function calls need their parameters
    51                         /// to be copy constructed
     49                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
     50                        /// function calls need their parameters to be copy constructed
    5251                        static void insert( std::list< Declaration * > & translationUnit );
    5352
     
    5756                class ResolveCopyCtors : public SymTab::Indexer {
    5857                public:
    59                         /// generate temporary ObjectDecls for each argument and return value of each
    60                         /// ImplicitCopyCtorExpr, generate/resolve copy construction expressions for each,
    61                         /// and generate/resolve destructors for both arguments and return value temporaries
     58                        /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr,
     59                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
     60                        /// arguments and return value temporaries
    6261                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
    6362
     
    9392                        for ( ObjectDecl * obj : set.objs ) {
    9493                                out << obj->get_name() << ", " ;
    95                         }
     94                        } // for
    9695                        out << " }";
    9796                        return out;
     
    108107
    109108                        // xxx - This needs to be done better.
    110                         // allow some generalization among different kinds of nodes with
    111                         // with similar parentage (e.g. all expressions, all statements, etc.)
    112                         // important to have this to provide a single entry point so that as
    113                         // new subclasses are added, there is only one place that the code has
    114                         // to be updated, rather than ensure that every specialized class knows
    115                         // about every new kind of statement that might be added.
     109                        // allow some generalization among different kinds of nodes with with similar parentage (e.g. all
     110                        // expressions, all statements, etc.)  important to have this to provide a single entry point so that as new
     111                        // subclasses are added, there is only one place that the code has to be updated, rather than ensure that
     112                        // every specialized class knows about every new kind of statement that might be added.
    116113                        virtual void visit( CompoundStmt *stmt ) { handleStmt( stmt ); return Parent::visit( stmt ); }
    117114                        virtual void visit( ExprStmt *stmt ) { handleStmt( stmt ); return Parent::visit( stmt ); }
     
    136133                class InsertDtors : public ObjDeclCollector {
    137134                public:
    138                         /// insert destructor calls at the appropriate places.
    139                         /// must happen before CtorInit nodes are removed (currently by FixInit)
     135                        /// insert destructor calls at the appropriate places.  must happen before CtorInit nodes are removed
     136                        /// (currently by FixInit)
    140137                        static void insert( std::list< Declaration * > & translationUnit );
    141138
     
    168165                class FixCopyCtors : public GenPoly::PolyMutator {
    169166                  public:
    170                         /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors,
    171                         /// call expression, and destructors
     167                        /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors, call expression,
     168                        /// and destructors
    172169                        static void fixCopyCtors( std::list< Declaration * > &translationUnit );
    173170
     
    235232                                                        // assignment operator
    236233                                                        return appExpr;
    237                                                 }
     234                                                } // if
    238235                                        } else if ( funcDecl->get_name() == "^?{}" ) {
    239236                                                // correctness: never copy construct arguments to a destructor
    240237                                                return appExpr;
    241                                         }
    242                                 }
    243                         }
     238                                        } // if
     239                                } // if
     240                        } // if
    244241                        CP_CTOR_PRINT( std::cerr << "InsertImplicitCalls: adding a wrapper " << appExpr << std::endl; )
    245242
     
    270267
    271268                        // resolve copy constructor
    272                         // should only be one alternative for copy ctor and dtor expressions, since
    273                         // all arguments are fixed (VariableExpr and already resolved expression)
     269                        // should only be one alternative for copy ctor and dtor expressions, since all arguments are fixed
     270                        // (VariableExpr and already resolved expression)
    274271                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    275272                        ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
    276273                        if ( resolved->get_env() ) {
    277274                                env->add( *resolved->get_env() );
    278                         }
     275                        } // if
    279276
    280277                        assert( resolved );
     
    319316                                        impCpCtorExpr->get_tempDecls().push_back( tmp );
    320317                                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
    321                                 }
    322                         }
    323 
    324                         // each return value from the call needs to be connected with an ObjectDecl
    325                         // at the call site, which is initialized with the return value and is destructed
    326                         // later
     318                                } // if
     319                        } // for
     320
     321                        // each return value from the call needs to be connected with an ObjectDecl at the call site, which is
     322                        // initialized with the return value and is destructed later
    327323                        // xxx - handle multiple return values
    328324                        ApplicationExpr * callExpr = impCpCtorExpr->get_callExpr();
    329                         // xxx - is this right? callExpr may not have the right environment, because it was attached
    330                         // at a higher level. Trying to pass that environment along.
     325                        // xxx - is this right? callExpr may not have the right environment, because it was attached at a higher
     326                        // level. Trying to pass that environment along.
    331327                        callExpr->set_env( impCpCtorExpr->get_env()->clone() );
    332328                        for ( Type * result : appExpr->get_results() ) {
     
    338334                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    339335                                impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    340                         }
     336                        } // for
    341337                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
    342338                }
     
    356352                        for ( ObjectDecl * obj : tempDecls ) {
    357353                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    358                         }
     354                        } // for
    359355                        for ( ObjectDecl * obj : returnDecls ) {
    360356                                stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
    361                         }
     357                        } // for
    362358
    363359                        // add destructors after current statement
    364360                        for ( Expression * dtor : dtors ) {
    365361                                stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
    366                         }
     362                        } // for
    367363
    368364                        // xxx - update to work with multiple return values
     
    390386                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    391387                                if ( callExpr->get_results().front()->get_isLvalue() ) {
    392                                         // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any
    393                                         // lvalue returning non-intrinsic function. Add an AddressExpr to the call to negate
    394                                         // the derefence and change the type of the return temporary from T to T* to properly
    395                                         // capture the return value. Then dereference the result of the comma expression, since
    396                                         // the lvalue returning call was originally wrapped with an AddressExpr.
    397                                         // Effectively, this turns
     388                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
     389                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     390                                        // type of the return temporary from T to T* to properly capture the return value. Then dereference
     391                                        // the result of the comma expression, since the lvalue returning call was originally wrapped with
     392                                        // an AddressExpr.  Effectively, this turns
    398393                                        //   lvalue T f();
    399394                                        //   &*f()
     
    410405                                        deref->add_result( resultType );
    411406                                        retExpr = deref;
    412                                 }
     407                                } // if
    413408                                // xxx - might need to set env on retExpr...
    414409                                // retExpr->set_env( env->clone() );
     
    416411                        } else {
    417412                                return callExpr;
    418                         }
     413                        } // if
    419414                }
    420415
    421416                DeclarationWithType *FixInit::mutate( ObjectDecl *objDecl ) {
    422                         // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors
    423                         // when the init is removed from the ObjectDecl
     417                        // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init
     418                        // is removed from the ObjectDecl
    424419                        objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( objDecl ) );
    425420
     
    474469                                        } else {
    475470                                                stmtsToAddAfter.push_back( ctor );
    476                                         }
     471                                        } // if
    477472                                        objDecl->set_init( NULL );
    478473                                        ctorInit->set_ctor( NULL );
     
    483478                                        // no constructor and no initializer, which is okay
    484479                                        objDecl->set_init( NULL );
    485                                 }
     480                                } // if
    486481                                delete ctorInit;
    487                         }
     482                        } // if
    488483                        return objDecl;
    489484                }
     
    499494                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    500495                                curVars.insert( objDecl );
    501                         }
     496                        } // if
    502497                        Parent::visit( stmt );
    503498                }
     
    507502                        for ( Label l : stmt->get_labels() ) {
    508503                                vars[l] = curVars;
    509                         }
     504                        } // for
    510505                }
    511506
     
    513508                void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {
    514509                        for ( Iterator it = begin ; it != end ; ++it ) {
    515                                 // extract destructor statement from the object decl and
    516                                 // insert it into the output. Note that this is only called
    517                                 // on lists of non-static objects with implicit non-intrinsic
    518                                 // dtors, so if the user manually calls an intrinsic dtor
    519                                 // then the call must (and will) still be generated since
    520                                 // the argument may contain side effects.
     510                                // extract destructor statement from the object decl and insert it into the output. Note that this is
     511                                // only called on lists of non-static objects with implicit non-intrinsic dtors, so if the user manually
     512                                // calls an intrinsic dtor then the call must (and will) still be generated since the argument may
     513                                // contain side effects.
    521514                                ObjectDecl * objDecl = *it;
    522515                                ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() );
    523516                                assert( ctorInit && ctorInit->get_dtor() );
    524517                                *out++ = ctorInit->get_dtor()->clone();
    525                         }
     518                        } // for
    526519                }
    527520
     
    537530                                                // non-intrinsic dtors must be called
    538531                                                reverseDeclOrder.front().push_front( objDecl );
    539                                         }
    540                                 }
    541                         }
     532                                        } // if
     533                                } // if
     534                        } // if
    542535                        Parent::visit( objDecl );
    543536                }
    544537
    545538                void InsertDtors::visit( CompoundStmt * compoundStmt ) {
    546                         // visit statements - this will also populate reverseDeclOrder list.
    547                         // don't want to dump all destructors when block is left,
    548                         // just the destructors associated with variables defined in this block,
    549                         // so push a new list to the top of the stack so that we can differentiate scopes
     539                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
     540                        // when block is left, just the destructors associated with variables defined in this block, so push a new
     541                        // list to the top of the stack so that we can differentiate scopes
    550542                        reverseDeclOrder.push_front( OrderedDecls() );
    551543                        Parent::visit( compoundStmt );
     
    561553                        for ( OrderedDecls & od : reverseDeclOrder ) {
    562554                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );
    563                         }
    564                 }
    565 
    566                 // Handle break/continue/goto in the same manner as C++.
    567                 // Basic idea: any objects that are in scope at the BranchStmt
    568                 // but not at the labelled (target) statement must be destructed.
    569                 // If there are any objects in scope at the target location but
    570                 // not at the BranchStmt then those objects would be uninitialized
    571                 // so notify the user of the error.
    572                 // See C++ Reference 6.6 Jump Statements for details.
     555                        } // for
     556                }
     557
     558                // Handle break/continue/goto in the same manner as C++.  Basic idea: any objects that are in scope at the
     559                // BranchStmt but not at the labelled (target) statement must be destructed.  If there are any objects in scope
     560                // at the target location but not at the BranchStmt then those objects would be uninitialized so notify the user
     561                // of the error.  See C++ Reference 6.6 Jump Statements for details.
    573562                void InsertDtors::handleGoto( BranchStmt * stmt ) {
    574563                        assert( stmt->get_target() != "" && "BranchStmt missing a label" );
     
    591580                        if ( ! diff.empty() ) {
    592581                                throw SemanticError( std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " ", stmt );
    593                         }
     582                        } // if
    594583                        // S_G-S_L results in set of objects that must be destructed
    595584                        diff.clear();
     
    604593                                        // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
    605594                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );
    606                                 }
     595                                } // for
    607596                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
    608                         }
     597                        } // if
    609598                }
    610599
    611600                void InsertDtors::visit( BranchStmt * stmt ) {
    612601                        switch( stmt->get_type() ) {
    613                                 case BranchStmt::Continue:
    614                                 case BranchStmt::Break:
    615                                 // could optimize the break/continue case, because the S_L-S_G check
    616                                 // is unnecessary (this set should always be empty), but it serves
    617                                 // as a small sanity check.
    618                                 case BranchStmt::Goto:
    619                                         handleGoto( stmt );
    620                                         break;
    621                                 default:
    622                                         assert( false );
    623                         }
     602                          case BranchStmt::Continue:
     603                          case BranchStmt::Break:
     604                                // could optimize the break/continue case, because the S_L-S_G check is unnecessary (this set should
     605                                // always be empty), but it serves as a small sanity check.
     606                          case BranchStmt::Goto:
     607                                handleGoto( stmt );
     608                                break;
     609                          default:
     610                                assert( false );
     611                        } // switch
    624612                }
    625613        } // namespace
  • src/tests/random.c

    re04c5ff radcc065  
    1010// Created On       : Tue Jul  5 21:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 21:29:54 2016
    13 // Update Count     : 1
     12// Last Modified On : Wed Jul  6 18:00:29 2016
     13// Update Count     : 3
    1414//
    1515
     
    1919
    2020int main() {
    21         rand48seed( getpid() );                                                         // set random seed
     21        //rand48seed( getpid() );                                                               // set random seed
     22        rand48seed( 1003 );                                                                     // fixed seed for repeatable tests
    2223
    2324        // test polymorphic calls to random and stream
Note: See TracChangeset for help on using the changeset viewer.