Changeset ae1b9ea for src/InitTweak


Ignore:
Timestamp:
Oct 19, 2017, 11:15:36 AM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
a365e0d
Parents:
aabc60c
git-author:
Rob Schluntz <rschlunt@…> (10/17/17 17:10:04)
git-committer:
Rob Schluntz <rschlunt@…> (10/19/17 11:15:36)
Message:

Always copy construct arguments that require boxing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/InitTweak/FixInit.cc

    raabc60c rae1b9ea  
    9393                        /// true if type does not need to be copy constructed to ensure correctness
    9494                        bool skipCopyConstruct( Type * type );
    95                         void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
     95                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal );
    9696                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    9797
     
    260260
    261261                GenStructMemberCalls::generate( translationUnit );
     262
    262263                // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
    263264                // hack in the way untyped assignments are generated, where the first argument cannot have
     
    384385                }
    385386
    386                 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     387                void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) {
    387388                        static UniqueName tempNamer("_tmp_cp");
    388389                        assert( env );
    389390                        CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; )
    390391                        assert( arg->result );
    391                         Type * result = arg->get_result();
     392                        Type * result = arg->result;
    392393                        if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
    393394
    394                         // type may involve type variables, so apply type substitution to get temporary variable's actual type
     395                        // type may involve type variables, so apply type substitution to get temporary variable's actual type.
     396                        // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T).
    395397                        result = result->clone();
    396                         env->apply( result );
     398                        env->applyFree( result );
    397399                        ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
    398400                        tmp->get_type()->set_const( false );
     
    405407                                // if the chosen constructor is intrinsic, the copy is unnecessary, so
    406408                                // don't create the temporary and don't call the copy constructor
    407                                 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
    408                                 assert( function );
    409                                 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
     409                                VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function );
     410                                if ( function->var->linkage == LinkageSpec::Intrinsic ) {
     411                                        // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic,
     412                                        // so that the object isn't changed inside of the polymorphic function
     413                                        if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return;
     414                                }
    410415                        }
    411416
     
    415420                        // replace argument to function call with temporary
    416421                        arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    417                         impCpCtorExpr->get_tempDecls().push_back( tmp );
    418                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
     422                        impCpCtorExpr->tempDecls.push_back( tmp );
     423                        impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) );
    419424                }
    420425
     
    426431                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    427432
    428                         ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     433                        ApplicationExpr * appExpr = impCpCtorExpr->callExpr;
    429434
    430435                        // take each argument and attempt to copy construct it.
    431                         for ( Expression * & arg : appExpr->get_args() ) {
    432                                 copyConstructArg( arg, impCpCtorExpr );
     436                        FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result );
     437                        assert( ftype );
     438                        auto & params = ftype->parameters;
     439                        auto iter = params.begin();
     440                        for ( Expression * & arg : appExpr->args ) {
     441                                Type * formal = nullptr;
     442                                if ( iter != params.end() ) {
     443                                        DeclarationWithType * param = *iter++;
     444                                        formal = param->get_type();
     445                                }
     446
     447                                copyConstructArg( arg, impCpCtorExpr, formal );
    433448                        } // for
    434449
     
    436451                        // initialized with the return value and is destructed later
    437452                        // xxx - handle named return values?
    438                         Type * result = appExpr->get_result();
     453                        Type * result = appExpr->result;
    439454                        if ( ! result->isVoid() ) {
    440455                                static UniqueName retNamer("_tmp_cp_ret");
     
    442457                                env->apply( result );
    443458                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    444                                 ret->get_type()->set_const( false );
    445                                 impCpCtorExpr->get_returnDecls().push_back( ret );
     459                                ret->type->set_const( false );
     460                                impCpCtorExpr->returnDecls.push_back( ret );
    446461                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    447462                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
Note: See TracChangeset for help on using the changeset viewer.