Changes in src/InitTweak/FixInit.cc [64ac636:615a096]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r64ac636 r615a096 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( CodeLocation,const Params &... params );234 void emit( const Params &... params ); 235 235 236 236 FunctionDecl * function = 0; 237 std::set< DeclarationWithType * > unhandled; 238 std::map< DeclarationWithType *, CodeLocation > usedUninit; 237 std::set< DeclarationWithType * > unhandled, usedUninit; 239 238 ObjectDecl * thisParam = 0; 240 239 bool isCtor = false; // true if current function is a constructor … … 337 336 GenStructMemberCalls warner; 338 337 acceptAll( translationUnit, warner ); 338 339 // visitor doesn't throw so that it can collect all errors 340 if ( ! warner.errors.isEmpty() ) { 341 throw warner.errors; 342 } 339 343 } 340 344 … … 434 438 env->apply( result ); 435 439 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 436 tmp->get_type()->set_ isConst( false );440 tmp->get_type()->set_const( false ); 437 441 438 442 // create and resolve copy constructor … … 480 484 env->apply( result ); 481 485 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 482 ret->get_type()->set_ isConst( false );486 ret->get_type()->set_const( false ); 483 487 impCpCtorExpr->get_returnDecls().push_back( ret ); 484 488 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 485 if ( ! result->get_ isLvalue() ) {489 if ( ! result->get_lvalue() ) { 486 490 // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary 487 491 destructRet( ret, impCpCtorExpr ); … … 503 507 env->apply( result ); 504 508 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 ); 505 ret->get_type()->set_ isConst( false );509 ret->get_type()->set_const( false ); 506 510 stmtExpr->get_returnDecls().push_front( ret ); 507 511 … … 584 588 585 589 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 586 if ( callExpr->get_result()->get_ isLvalue() ) {590 if ( callExpr->get_result()->get_lvalue() ) { 587 591 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 588 592 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 936 940 ValueGuard< FunctionDecl * > oldFunction( funcDecl ); 937 941 ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled ); 938 ValueGuard< std:: map< DeclarationWithType *, CodeLocation> > oldUsedUninit( usedUninit );942 ValueGuard< std::set< DeclarationWithType * > > oldUsedUninit( usedUninit ); 939 943 ValueGuard< ObjectDecl * > oldThisParam( thisParam ); 940 944 ValueGuard< bool > oldIsCtor( isCtor ); 941 945 ValueGuard< StructDecl * > oldStructDecl( structDecl ); 942 errors = SemanticError(); // clear previous errors943 946 944 947 // need to start with fresh sets … … 969 972 // remove the unhandled objects from usedUninit, because a call is inserted 970 973 // to handle them - only objects that are later constructed are used uninitialized. 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" ); 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" ); 985 978 } 986 979 … … 1027 1020 } 1028 1021 } catch ( SemanticError & error ) { 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" );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" ); 1030 1023 } 1031 1024 } 1032 1025 } 1033 1026 leaveScope(); 1034 }1035 if (! errors.isEmpty()) {1036 throw errors;1037 1027 } 1038 1028 } … … 1089 1079 if ( unhandled.count( memberExpr->get_member() ) ) { 1090 1080 // emit a warning because a member was used before it was constructed 1091 usedUninit.insert( { memberExpr->get_member(), memberExpr->location });1081 usedUninit.insert( memberExpr->get_member() ); 1092 1082 } 1093 1083 } … … 1099 1089 1100 1090 template< typename Visitor, typename... 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 ); 1091 void error( Visitor & v, const Params &... params ) { 1092 v.errors.append( toString( params... ) ); 1105 1093 } 1106 1094 1107 1095 template< typename... Params > 1108 void GenStructMemberCalls::emit( CodeLocation loc,const Params &... params ) {1096 void GenStructMemberCalls::emit( const Params &... params ) { 1109 1097 // toggle warnings vs. errors here. 1110 1098 // warn( params... ); 1111 error( *this, loc,params... );1099 error( *this, params... ); 1112 1100 } 1113 1101
Note:
See TracChangeset
for help on using the changeset viewer.