Changeset 698ec72
- Timestamp:
- Sep 18, 2017, 3:05:47 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 80ac42d
- Parents:
- 9857e8d
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r9857e8d r698ec72 105 105 106 106 /// collects constructed object decls - used as a base class 107 class ObjDeclCollector : public AddStmtVisitor { 108 public: 109 typedef AddStmtVisitor Parent; 110 using Parent::visit; 107 struct ObjDeclCollector : public WithGuards, public WithShortCircuiting { 111 108 // use ordered data structure to maintain ordering for set_difference and for consistent error messages 112 109 typedef std::list< ObjectDecl * > ObjectSet; 113 v irtual void visit( CompoundStmt *compoundStmt ) override;114 v irtual void visit( DeclStmt *stmt ) override;110 void previsit( CompoundStmt *compoundStmt ); 111 void previsit( DeclStmt *stmt ); 115 112 116 113 // don't go into other functions 117 v irtual void visit( FunctionDecl * ) override {}114 void previsit( FunctionDecl * ) { visit_children = false; } 118 115 119 116 protected: … … 139 136 } 140 137 141 class LabelFinder final : public ObjDeclCollector { 142 public: 143 typedef ObjDeclCollector Parent; 138 struct LabelFinder final : public ObjDeclCollector { 144 139 typedef std::map< Label, ObjectSet > LabelMap; 145 140 // map of Label -> live variables at that label 146 141 LabelMap vars; 147 142 148 void handleStmt( Statement * stmt ); 149 150 // xxx - This needs to be done better. 151 // allow some generalization among different kinds of nodes with with similar parentage (e.g. all 152 // expressions, all statements, etc.) important to have this to provide a single entry point so that as new 153 // subclasses are added, there is only one place that the code has to be updated, rather than ensure that 154 // every specialized class knows about every new kind of statement that might be added. 155 using Parent::visit; 156 virtual void visit( CompoundStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 157 virtual void visit( ExprStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 158 virtual void visit( AsmStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 159 virtual void visit( IfStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 160 virtual void visit( WhileStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 161 virtual void visit( ForStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 162 virtual void visit( SwitchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 163 virtual void visit( CaseStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 164 virtual void visit( BranchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 165 virtual void visit( ReturnStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 166 virtual void visit( TryStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 167 virtual void visit( CatchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 168 virtual void visit( FinallyStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 169 virtual void visit( NullStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 170 virtual void visit( DeclStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 171 virtual void visit( ImplicitCtorDtorStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); } 143 typedef ObjDeclCollector Parent; 144 using Parent::previsit; 145 void previsit( Statement * stmt ); 146 147 void previsit( CompoundStmt *compoundStmt ); 148 void previsit( DeclStmt *stmt ); 172 149 }; 173 150 174 class InsertDtors final : public ObjDeclCollector { 175 public: 151 struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd { 176 152 /// insert destructor calls at the appropriate places. must happen before CtorInit nodes are removed 177 153 /// (currently by FixInit) 178 154 static void insert( std::list< Declaration * > & translationUnit ); 179 155 180 typedef ObjDeclCollector Parent;181 156 typedef std::list< ObjectDecl * > OrderedDecls; 182 157 typedef std::list< OrderedDecls > OrderedDeclsStack; 183 158 184 InsertDtors( LabelFinder & finder ) : finder( finder ), labelVars( finder.vars ) {} 185 186 using Parent::visit; 187 188 virtual void visit( ObjectDecl * objDecl ) override; 189 virtual void visit( FunctionDecl * funcDecl ) override; 190 191 virtual void visit( CompoundStmt * compoundStmt ) override; 192 virtual void visit( ReturnStmt * returnStmt ) override; 193 virtual void visit( BranchStmt * stmt ) override; 159 InsertDtors( PassVisitor<LabelFinder> & finder ) : finder( finder ), labelVars( finder.pass.vars ) {} 160 161 typedef ObjDeclCollector Parent; 162 using Parent::previsit; 163 164 void previsit( ObjectDecl * objDecl ); 165 void previsit( FunctionDecl * funcDecl ); 166 167 void previsit( CompoundStmt * compoundStmt ); 168 void postvisit( CompoundStmt * compoundStmt ); 169 void previsit( ReturnStmt * returnStmt ); 170 void previsit( BranchStmt * stmt ); 194 171 private: 195 172 void handleGoto( BranchStmt * stmt ); 196 173 197 LabelFinder& finder;174 PassVisitor<LabelFinder> & finder; 198 175 LabelFinder::LabelMap & labelVars; 199 176 OrderedDeclsStack reverseDeclOrder; … … 333 310 334 311 void InsertDtors::insert( std::list< Declaration * > & translationUnit ) { 335 LabelFinderfinder;336 InsertDtorsinserter( finder );312 PassVisitor<LabelFinder> finder; 313 PassVisitor<InsertDtors> inserter( finder ); 337 314 acceptAll( translationUnit, inserter ); 338 315 } … … 792 769 } 793 770 794 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) { 795 ObjectSet prevVars = curVars; 796 Parent::visit( compoundStmt ); 797 curVars = prevVars; 798 } 799 800 void ObjDeclCollector::visit( DeclStmt * stmt ) { 771 void ObjDeclCollector::previsit( CompoundStmt * ) { 772 GuardValue( curVars ); 773 } 774 775 void ObjDeclCollector::previsit( DeclStmt * stmt ) { 801 776 // keep track of all variables currently in scope 802 777 if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) { 803 778 curVars.push_back( objDecl ); 804 779 } // if 805 Parent::visit( stmt ); 806 } 807 808 void LabelFinder::handleStmt( Statement * stmt ) { 780 } 781 782 void LabelFinder::previsit( Statement * stmt ) { 809 783 // for each label, remember the variables in scope at that label. 810 784 for ( Label l : stmt->get_labels() ) { … … 812 786 } // for 813 787 } 788 789 void LabelFinder::previsit( CompoundStmt * stmt ) { 790 previsit( (Statement *)stmt ); 791 Parent::previsit( stmt ); 792 } 793 794 void LabelFinder::previsit( DeclStmt * stmt ) { 795 previsit( (Statement *)stmt ); 796 Parent::previsit( stmt ); 797 } 798 814 799 815 800 template<typename Iterator, typename OutputIterator> … … 827 812 } 828 813 829 void InsertDtors:: visit( ObjectDecl * objDecl ) {814 void InsertDtors::previsit( ObjectDecl * objDecl ) { 830 815 // remember non-static destructed objects so that their destructors can be inserted later 831 816 if ( ! objDecl->get_storageClasses().is_static ) { … … 841 826 } // if 842 827 } // if 843 Parent::visit( objDecl ); 844 } 845 846 template< typename Visitor > 847 void handleFuncDecl( FunctionDecl * funcDecl, Visitor & visitor ) { 848 maybeAccept( funcDecl->get_functionType(), visitor ); 849 maybeAccept( funcDecl->get_statements(), visitor ); 850 } 851 852 void InsertDtors::visit( FunctionDecl * funcDecl ) { 828 } 829 830 void InsertDtors::previsit( FunctionDecl * funcDecl ) { 853 831 // each function needs to have its own set of labels 854 ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars );832 GuardValue( labelVars ); 855 833 labelVars.clear(); 856 handleFuncDecl( funcDecl, finder ); 857 858 // all labels for this function have been collected, insert destructors as appropriate. 859 // can't be Parent::mutate, because ObjDeclCollector bottoms out on FunctionDecl 860 handleFuncDecl( funcDecl, *this ); 861 } 862 863 void InsertDtors::visit( CompoundStmt * compoundStmt ) { 834 maybeAccept( funcDecl->type, finder ); 835 maybeAccept( funcDecl->statements, finder ); 836 837 // all labels for this function have been collected, insert destructors as appropriate via implicit recursion. 838 } 839 840 void InsertDtors::previsit( CompoundStmt * compoundStmt ) { 864 841 // visit statements - this will also populate reverseDeclOrder list. don't want to dump all destructors 865 842 // when block is left, just the destructors associated with variables defined in this block, so push a new 866 843 // list to the top of the stack so that we can differentiate scopes 867 844 reverseDeclOrder.push_front( OrderedDecls() ); 868 Parent::visit( compoundStmt ); 869 845 Parent::previsit( compoundStmt ); 846 } 847 848 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) { 870 849 // add destructors for the current scope that we're exiting, unless the last statement is a return, which 871 850 // causes unreachable code warnings … … 877 856 } 878 857 879 void InsertDtors:: visit( __attribute((unused)) ReturnStmt * returnStmt) {858 void InsertDtors::previsit( ReturnStmt * ) { 880 859 // return exits all scopes, so dump destructors for all scopes 881 860 for ( OrderedDecls & od : reverseDeclOrder ) { 882 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );861 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) ); 883 862 } // for 884 863 } … … 928 907 copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } ); 929 908 } // for 930 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );909 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) ); 931 910 } // if 932 911 } 933 912 934 void InsertDtors:: visit( BranchStmt * stmt ) {913 void InsertDtors::previsit( BranchStmt * stmt ) { 935 914 switch( stmt->get_type() ) { 936 915 case BranchStmt::Continue: -
src/tests/.expect/dtor-early-exit-ERR1.txt
r9857e8d r698ec72 1 dtor-early-exit.c:1 42:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)1 dtor-early-exit.c:153:1 error: jump to label 'L1' crosses initialization of y Branch (Goto) 2 2 with target: L1 3 3 with original target: L1 -
src/tests/.expect/dtor-early-exit-ERR2.txt
r9857e8d r698ec72 1 dtor-early-exit.c: 142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)1 dtor-early-exit.c:220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto) 2 2 with target: L2 3 3 with original target: L2
Note: See TracChangeset
for help on using the changeset viewer.