- Timestamp:
- Jul 22, 2016, 3:55:51 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- aedfd91
- Parents:
- ccb447e
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rccb447e r72e9222 161 161 162 162 virtual DeclarationWithType * mutate( ObjectDecl *objDecl ); 163 164 std::list< Declaration * > staticDtorDecls; 163 165 }; 164 166 … … 199 201 void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) { 200 202 FixInit fixer; 201 mutateAll( translationUnit, fixer ); 203 204 // can't use mutateAll, because need to insert declarations at top-level 205 // can't use DeclMutator, because sometimes need to insert IfStmt, etc. 206 SemanticError errors; 207 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 208 try { 209 *i = maybeMutate( *i, fixer ); 210 // if (! fixer.staticDtorDecls.empty() ) { 211 translationUnit.splice( i, fixer.staticDtorDecls ); 212 // } 213 } catch( SemanticError &e ) { 214 errors.append( e ); 215 } // try 216 } // for 217 if ( ! errors.isEmpty() ) { 218 throw errors; 219 } // if 202 220 } 203 221 … … 427 445 if ( Statement * ctor = ctorInit->get_ctor() ) { 428 446 if ( objDecl->get_storageClass() == DeclarationNode::Static ) { 447 // originally wanted to take advantage of gcc nested functions, but 448 // we get memory errors with this approach. To remedy this, create a 449 // global static pointer that is set to refer to the object and make 450 // the dtor-caller function global so that. 451 // 429 452 // generate: 430 // static bool __objName_uninitialized = true; 431 // if (__objName_uninitialized) { 432 // __ctor(__objName); 433 // void dtor_atexit() { 434 // __dtor(__objName); 453 // T * __objName_static_ptrN; 454 // void __objName_dtor_atexitN() { 455 // __dtor(__objName_static_ptrN); 456 // } 457 // int f(...) { 458 // ... 459 // static T __objName; 460 // static bool __objName_uninitialized = true; 461 // if (__objName_uninitialized) { 462 // __objName_ptr = &__objName; 463 // __ctor(__objName); 464 // on_exit(__objName_dtor_atexitN, &__objName); 465 // __objName_uninitialized = false; 435 466 // } 436 // on_exit(dtorOnExit, &__objName); 437 // __objName_uninitialized = false; 467 // ... 438 468 // } 439 469 440 // generate first line 470 static UniqueName ptrNamer( "_static_ptr" ); 471 static UniqueName dtorCallerNamer( "_dtor_atexit" ); 472 473 // T * __objName_ptrN 474 ObjectDecl * objPtr = new ObjectDecl( objDecl->get_mangleName() + ptrNamer.newName(), DeclarationNode::Static, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), objDecl->get_type()->clone() ), 0 ); 475 objPtr->fixUniqueId(); 476 477 // void __objName_dtor_atexitN(...) {...} 478 // need to modify dtor call so that it refers to objPtr, since function will be global 479 Statement * dtorStmt = ctorInit->get_dtor()->clone(); 480 ApplicationExpr * dtor = dynamic_cast< ApplicationExpr * >( InitTweak::getCtorDtorCall( dtorStmt ) ); 481 assert( dtor ); 482 delete dtor->get_args().front(); 483 dtor->get_args().front() = new VariableExpr( objPtr ); 484 485 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false ); 486 dtorCaller->fixUniqueId(); 487 dtorCaller->get_statements()->get_kids().push_back( dtorStmt ); 488 489 // static bool __objName_uninitialized = true 441 490 BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool ); 442 491 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators ); … … 444 493 isUninitializedVar->fixUniqueId(); 445 494 446 // void dtor_atexit(...) {...}447 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false);448 dtorCaller->fixUniqueId();449 dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor()->clone() );450 451 // on_exit(dtor_atexit);495 // __objName_static_ptrN = &__objName; 496 UntypedExpr * ptrAssign = new UntypedExpr( new NameExpr( "?=?" ) ); 497 ptrAssign->get_args().push_back( new VariableExpr( objPtr ) ); 498 ptrAssign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 499 500 // atexit(dtor_atexit); 452 501 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) ); 453 502 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) ); … … 462 511 std::list< Statement * > & body = initStmts->get_kids(); 463 512 body.push_back( ctor ); 464 body.push_back( new DeclStmt( noLabels, dtorCaller) );513 body.push_back( new ExprStmt( noLabels, ptrAssign ) ); 465 514 body.push_back( new ExprStmt( noLabels, callAtexit ) ); 466 515 body.push_back( new ExprStmt( noLabels, setTrue ) ); … … 470 519 stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) ); 471 520 stmtsToAddAfter.push_back( ifStmt ); 521 522 // add pointer and dtor caller decls to list of decls that will be added into global scope 523 staticDtorDecls.push_back( objPtr ); 524 staticDtorDecls.push_back( dtorCaller ); 472 525 } else { 473 526 stmtsToAddAfter.push_back( ctor ); -
src/tests/init_once.c
rccb447e r72e9222 92 92 init_once y = x; 93 93 94 void static_variable() { 95 static init_once x; 96 } 97 94 98 int main() { 95 99 // local variables … … 179 183 } 180 184 } 185 186 // function-scoped static variable 187 for (int i = 0; i < 10; i++) { 188 static_variable(); 189 } 181 190 } 182 191
Note: See TracChangeset
for help on using the changeset viewer.