Changeset 092528b


Ignore:
Timestamp:
Jan 23, 2017, 2:36:49 PM (8 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:
0bfaf80
Parents:
207c7e1d
Message:

fix copy constructing/destructing qualified argument/return temporaries

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r207c7e1d r092528b  
    2121#include <unordered_set>
    2222#include "InitTweak.h"
     23#include "GenInit.h"
    2324#include "FixInit.h"
    2425#include "FixGlobalInit.h"
     
    8687                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    8788                        Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    88                         Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
    8989                        /// true if type does not need to be copy constructed to ensure correctness
    9090                        bool skipCopyConstruct( Type * type );
    9191                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    92                         void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
     92                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    9393
    9494                        TypeSubstitution * env;
     
    398398                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    399399                        assert( var );
    400                         return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
    401                 }
    402 
    403                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
    404                         assert( thisArg );
    405                         UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    406                         untyped->get_args().push_back( thisArg );
    407                         if (cpArg) untyped->get_args().push_back( cpArg->clone() );
     400                        // arrays are not copy constructed, so this should always be an ExprStmt
     401                        ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
     402                        ExprStmt * exprStmt = safe_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
     403                        Expression * untyped = exprStmt->get_expr();
    408404
    409405                        // resolve copy constructor
     
    420416                        } // if
    421417
    422                         delete untyped;
     418                        delete stmt;
    423419                        return resolved;
    424420                }
     
    456452                }
    457453
    458                 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    459                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
     454                void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     455                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    460456                }
    461457
     
    487483                                if ( ! result->get_isLvalue() ) {
    488484                                        // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    489                                         destructRet( new VariableExpr( ret ), impCpCtorExpr );
     485                                        destructRet( ret, impCpCtorExpr );
    490486                                }
    491487                        } // for
     
    515511                                last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );
    516512
    517                                 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) );
     513                                stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    518514                        } // if
    519515
  • src/InitTweak/GenInit.cc

    r207c7e1d r092528b  
    247247                        managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
    248248                }
     249        }
     250
     251        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     252                // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
     253                assertf( objDecl, "genCtorDtor passed null objDecl" );
     254                std::list< Statement * > stmts;
     255                InitExpander srcParam( maybeClone( arg ) );
     256                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
     257                assert( stmts.size() <= 1 );
     258                return stmts.size() == 1 ? safe_dynamic_cast< ImplicitCtorDtorStmt * >( stmts.front() ) : nullptr;
    249259        }
    250260
  • src/InitTweak/GenInit.h

    r207c7e1d r092528b  
    2828        void genInit( std::list< Declaration * > & translationUnit );
    2929
     30  /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     31  ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     32
    3033        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    3134        ConstructorInit * genCtorInit( ObjectDecl * objDecl );
  • src/tests/.expect/32/declarationSpecifier.txt

    r207c7e1d r092528b  
    640640    int _tmp_cp_ret0;
    641641    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    642     ((void)(_tmp_cp_ret0) /* ^?{} */);
     642    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    643643    return ((int )___retval_main__i_1);
    644644}
  • src/tests/.expect/32/extension.txt

    r207c7e1d r092528b  
    9393    int _tmp_cp_ret0;
    9494    ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
    95     ((void)(_tmp_cp_ret0) /* ^?{} */);
     95    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    9696    ((void)__extension__ sizeof(3));
    9797    ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
  • src/tests/.expect/32/gccExtensions.txt

    r207c7e1d r092528b  
    177177    int _tmp_cp_ret0;
    178178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    179     ((void)(_tmp_cp_ret0) /* ^?{} */);
     179    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    180180    return ((int )___retval_main__i_1);
    181181}
  • src/tests/.expect/64/declarationSpecifier.txt

    r207c7e1d r092528b  
    640640    int _tmp_cp_ret0;
    641641    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    642     ((void)(_tmp_cp_ret0) /* ^?{} */);
     642    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    643643    return ((int )___retval_main__i_1);
    644644}
  • src/tests/.expect/64/extension.txt

    r207c7e1d r092528b  
    9393    int _tmp_cp_ret0;
    9494    ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
    95     ((void)(_tmp_cp_ret0) /* ^?{} */);
     95    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    9696    ((void)__extension__ sizeof(3));
    9797    ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
  • src/tests/.expect/64/gccExtensions.txt

    r207c7e1d r092528b  
    177177    int _tmp_cp_ret0;
    178178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    179     ((void)(_tmp_cp_ret0) /* ^?{} */);
     179    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    180180    return ((int )___retval_main__i_1);
    181181}
Note: See TracChangeset for help on using the changeset viewer.