Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r64ac636 r68fe077a  
    232232                        void handleFirstParam( Expression * firstParam );
    233233                        template< typename... Params >
    234                         void emit( CodeLocation, const Params &... params );
     234                        void emit( const Params &... params );
    235235
    236236                        FunctionDecl * function = 0;
    237                         std::set< DeclarationWithType * > unhandled;
    238                         std::map< DeclarationWithType *, CodeLocation > usedUninit;
     237                        std::set< DeclarationWithType * > unhandled, usedUninit;
    239238                        ObjectDecl * thisParam = 0;
    240239                        bool isCtor = false; // true if current function is a constructor
     
    337336                        GenStructMemberCalls warner;
    338337                        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                        }
    339343                }
    340344
     
    936940                        ValueGuard< FunctionDecl * > oldFunction( funcDecl );
    937941                        ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );
    938                         ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );
     942                        ValueGuard< std::set< DeclarationWithType * > > oldUsedUninit( usedUninit );
    939943                        ValueGuard< ObjectDecl * > oldThisParam( thisParam );
    940944                        ValueGuard< bool > oldIsCtor( isCtor );
    941945                        ValueGuard< StructDecl * > oldStructDecl( structDecl );
    942                         errors = SemanticError();  // clear previous errors
    943946
    944947                        // need to start with fresh sets
     
    969972                        // remove the unhandled objects from usedUninit, because a call is inserted
    970973                        // 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" );
    985978                        }
    986979
     
    10271020                                                        }
    10281021                                                } 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" );
    10301023                                                }
    10311024                                        }
    10321025                                }
    10331026                                leaveScope();
    1034                         }
    1035                         if (! errors.isEmpty()) {
    1036                                 throw errors;
    10371027                        }
    10381028                }
     
    10891079                                                        if ( unhandled.count( memberExpr->get_member() ) ) {
    10901080                                                                // 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() );
    10921082                                                        }
    10931083                                                }
     
    10991089
    11001090                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... ) );
    11051093                }
    11061094
    11071095                template< typename... Params >
    1108                 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) {
     1096                void GenStructMemberCalls::emit( const Params &... params ) {
    11091097                        // toggle warnings vs. errors here.
    11101098                        // warn( params... );
    1111                         error( *this, loc, params... );
     1099                        error( *this, params... );
    11121100                }
    11131101
Note: See TracChangeset for help on using the changeset viewer.