Changeset 7c70089 for src/InitTweak
- Timestamp:
- Mar 17, 2017, 1:36:27 PM (9 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:
- 31ce3d6
- Parents:
- b32ada31 (diff), 946bcca (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/InitTweak
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rb32ada31 r7c70089 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 08:08:04201713 // Update Count : 6712 // Last Modified On : Fri Mar 17 09:13:47 2017 13 // Update Count : 71 14 14 // 15 15 … … 232 232 void handleFirstParam( Expression * firstParam ); 233 233 template< typename... Params > 234 void emit( const Params &... params );234 void emit( CodeLocation, const Params &... params ); 235 235 236 236 FunctionDecl * function = 0; 237 std::set< DeclarationWithType * > unhandled, usedUninit; 237 std::set< DeclarationWithType * > unhandled; 238 std::map< DeclarationWithType *, CodeLocation > usedUninit; 238 239 ObjectDecl * thisParam = 0; 239 240 bool isCtor = false; // true if current function is a constructor … … 336 337 GenStructMemberCalls warner; 337 338 acceptAll( translationUnit, warner ); 338 339 // visitor doesn't throw so that it can collect all errors340 if ( ! warner.errors.isEmpty() ) {341 throw warner.errors;342 }343 339 } 344 340 … … 438 434 env->apply( result ); 439 435 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 440 tmp->get_type()->set_ isConst( false );436 tmp->get_type()->set_const( false ); 441 437 442 438 // create and resolve copy constructor … … 484 480 env->apply( result ); 485 481 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 486 ret->get_type()->set_ isConst( false );482 ret->get_type()->set_const( false ); 487 483 impCpCtorExpr->get_returnDecls().push_back( ret ); 488 484 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 489 if ( ! result->get_ isLvalue() ) {485 if ( ! result->get_lvalue() ) { 490 486 // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary 491 487 destructRet( ret, impCpCtorExpr ); … … 507 503 env->apply( result ); 508 504 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 509 ret->get_type()->set_ isConst( false );505 ret->get_type()->set_const( false ); 510 506 stmtExpr->get_returnDecls().push_front( ret ); 511 507 … … 588 584 589 585 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 590 if ( callExpr->get_result()->get_ isLvalue() ) {586 if ( callExpr->get_result()->get_lvalue() ) { 591 587 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 592 588 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 940 936 ValueGuard< FunctionDecl * > oldFunction( funcDecl ); 941 937 ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled ); 942 ValueGuard< std:: set< DeclarationWithType *> > oldUsedUninit( usedUninit );938 ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit ); 943 939 ValueGuard< ObjectDecl * > oldThisParam( thisParam ); 944 940 ValueGuard< bool > oldIsCtor( isCtor ); 945 941 ValueGuard< StructDecl * > oldStructDecl( structDecl ); 942 errors = SemanticError(); // clear previous errors 946 943 947 944 // need to start with fresh sets … … 972 969 // remove the unhandled objects from usedUninit, because a call is inserted 973 970 // to handle them - only objects that are later constructed are used uninitialized. 974 std::set< DeclarationWithType * > diff; 975 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) ); 976 for ( DeclarationWithType * member : diff ) { 977 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" ); 971 std::map< DeclarationWithType *, CodeLocation > diff; 972 // need the comparator since usedUninit and unhandled have different types 973 struct comp_t { 974 typedef decltype(usedUninit)::value_type usedUninit_t; 975 typedef decltype(unhandled)::value_type unhandled_t; 976 bool operator()(usedUninit_t x, unhandled_t y) { return x.first < y; } 977 bool operator()(unhandled_t x, usedUninit_t y) { return x < y.first; } 978 } comp; 979 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ), comp ); 980 for ( auto p : diff ) { 981 DeclarationWithType * member = p.first; 982 CodeLocation loc = p.second; 983 // xxx - make error message better by also tracking the location that the object is constructed at? 984 emit( loc, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" ); 978 985 } 979 986 … … 1020 1027 } 1021 1028 } catch ( SemanticError & error ) { 1022 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" );1029 emit( funcDecl->location, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" ); 1023 1030 } 1024 1031 } 1025 1032 } 1026 1033 leaveScope(); 1034 } 1035 if (! errors.isEmpty()) { 1036 throw errors; 1027 1037 } 1028 1038 } … … 1079 1089 if ( unhandled.count( memberExpr->get_member() ) ) { 1080 1090 // emit a warning because a member was used before it was constructed 1081 usedUninit.insert( memberExpr->get_member());1091 usedUninit.insert( { memberExpr->get_member(), memberExpr->location } ); 1082 1092 } 1083 1093 } … … 1089 1099 1090 1100 template< typename Visitor, typename... Params > 1091 void error( Visitor & v, const Params &... params ) { 1092 v.errors.append( toString( params... ) ); 1101 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1102 SemanticError err( toString( params... ) ); 1103 err.set_location( loc ); 1104 v.errors.append( err ); 1093 1105 } 1094 1106 1095 1107 template< typename... Params > 1096 void GenStructMemberCalls::emit( const Params &... params ) {1108 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1097 1109 // toggle warnings vs. errors here. 1098 1110 // warn( params... ); 1099 error( *this, params... );1111 error( *this, loc, params... ); 1100 1112 } 1101 1113 -
src/InitTweak/GenInit.cc
rb32ada31 r7c70089 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 08:01:25201713 // Update Count : 18 112 // Last Modified On : Fri Mar 17 09:12:36 2017 13 // Update Count : 183 14 14 // 15 15 … … 143 143 // is being returned 144 144 // Note: under the assumption that assignments return *this, checking for ?=? here is an optimization, since it shouldn't be necessary to copy construct `this`. This is a temporary optimization until reference types are added, at which point this should be removed, along with the analogous optimization in copy constructor generation. 145 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_ isLvalue() ) {145 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_lvalue() ) { 146 146 // explicitly construct the return value using the return expression and the retVal object 147 147 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); … … 195 195 196 196 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) ); 197 arrayDimension->get_type()->set_ isConst( true );197 arrayDimension->get_type()->set_const( true ); 198 198 199 199 arrayType->set_dimension( new VariableExpr( arrayDimension ) );
Note:
See TracChangeset
for help on using the changeset viewer.