Changeset c2ad3c9


Ignore:
Timestamp:
Jun 23, 2016, 3:46:10 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
2de162d, 8f62de7, c6b1105, e757af2
Parents:
d56c05d0
Message:

fix explicit cast error for returning polymorphic types, also potential infinite loop in findGeneric

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rd56c05d0 rc2ad3c9  
    197197                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    198198                        /// Stores assignment operators from assertion list in local map of assignment operations
    199                         void findAssignOps( const std::list< TypeDecl *> &forall );
     199                        void findTypeOps( const std::list< TypeDecl *> &forall );
    200200                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    201201                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     
    205205                        ObjectDecl *makeTemporary( Type *type );
    206206
    207                         ScopedMap< std::string, DeclarationWithType *> assignOps;    ///< Currently known type variable assignment operators
     207                        ScopedMap< std::string, DeclarationWithType* > assignOps;    ///< Currently known type variable assignment operators
     208                        ScopedMap< std::string, DeclarationWithType* > ctorOps;      ///< Currently known type variable constructors
     209                        ScopedMap< std::string, DeclarationWithType* > copyOps;      ///< Currently known type variable copy constructors
     210                        ScopedMap< std::string, DeclarationWithType* > dtorOps;      ///< Currently known type variable destructors
    208211                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
     212                        ResolvExpr::TypeMap< DeclarationWithType > scopedCtorOps;    ///< Currently known assignment operators
     213                        ResolvExpr::TypeMap< DeclarationWithType > scopedCopyOps;    ///< Currently known assignment operators
     214                        ResolvExpr::TypeMap< DeclarationWithType > scopedDtorOps;    ///< Currently known assignment operators
    209215                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210216
     
    600606                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
    601607
    602                 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
    603                 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
    604                         if ( decl->get_name() == "?=?" ) {
    605                                 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    606                                         if ( funType->get_parameters().size() == 2 ) {
    607                                                 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    608                                                         if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
    609                                                                 if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
    610                                                                         if ( refType->get_name() == refType2->get_name() ) {
    611                                                                                 return refType;
    612                                                                         } // if
     608                /// Returns T if the given declaration is a function with parameter (T*) for some TypeInstType T, NULL otherwise
     609                TypeInstType *isTypeInstPtrFn( DeclarationWithType *decl ) {
     610                        if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     611                                if ( funType->get_parameters().size() == 1 ) {
     612                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     613                                                if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     614                                                        return refType;
     615                                                } // if
     616                                        } // if
     617                                } // if
     618                        } // if
     619                        return 0;
     620                }
     621               
     622                /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise
     623                TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) {
     624                        if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     625                                if ( funType->get_parameters().size() == 2 ) {
     626                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     627                                                if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     628                                                        if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     629                                                                if ( refType->get_name() == refType2->get_name() ) {
     630                                                                        return refType;
    613631                                                                } // if
    614632                                                        } // if
     
    619637                        return 0;
    620638                }
    621 
    622                 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    623                 /// Only picks assignments where neither parameter is cv-qualified
    624                 Type *isAssignment( DeclarationWithType *decl ) {
    625                         if ( decl->get_name() == "?=?" ) {
    626                                 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    627                                         if ( funType->get_parameters().size() == 2 ) {
    628                                                 Type::Qualifiers defaultQualifiers;
    629                                                 Type *paramType1 = funType->get_parameters().front()->get_type();
    630                                                 if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
    631                                                 Type *paramType2 = funType->get_parameters().back()->get_type();
    632                                                 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
    633 
    634                                                 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
    635                                                         Type *baseType1 = pointerType->get_base();
    636                                                         if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
    637                                                         SymTab::Indexer dummy;
    638                                                         if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
    639                                                                 return baseType1;
    640                                                         } // if
     639               
     640                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     641                TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) {
     642                        return decl->get_name() == "?=?" ? isTypeInstPtrValFn( decl ) : 0;
     643                }
     644
     645                /// Returns T if the given declaration is (*?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     646                TypeInstType *isTypeInstCtor( DeclarationWithType *decl ) {
     647                        return decl->get_name() == "?{}" ? isTypeInstPtrFn( decl ) : 0;
     648                }
     649
     650                /// Returns T if the given declaration is (*?{})(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     651                TypeInstType *isTypeInstCopy( DeclarationWithType *decl ) {
     652                        return decl->get_name() == "?{}" ? isTypeInstPtrValFn( decl ) : 0;
     653                }
     654
     655                /// Returns T if the given declaration is (*^?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     656                TypeInstType *isTypeInstDtor( DeclarationWithType *decl ) {
     657                        return decl->get_name() == "^?{}" ? isTypeInstPtrFn( decl ) : 0;
     658                }
     659
     660                /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
     661                /// NULL otherwise
     662                Type *isNoCvPtrFn( DeclarationWithType *decl ) {
     663                        if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     664                                if ( funType->get_parameters().size() == 1 ) {
     665                                        Type::Qualifiers defaultQualifiers;
     666                                        Type *paramType = funType->get_parameters().front()->get_type();
     667                                        if ( paramType->get_qualifiers() != defaultQualifiers ) return 0;
     668
     669                                        if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType ) ) {
     670                                                Type *baseType = pointerType->get_base();
     671                                                if ( baseType->get_qualifiers() == defaultQualifiers ) {
     672                                                        return baseType;
    641673                                                } // if
    642674                                        } // if
     
    645677                        return 0;
    646678                }
    647 
    648                 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) {
     679               
     680                /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified,
     681                /// NULL otherwise
     682                Type *isNoCvPtrValFn( DeclarationWithType *decl ) {
     683                        if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     684                                if ( funType->get_parameters().size() == 2 ) {
     685                                        Type::Qualifiers defaultQualifiers;
     686                                        Type *paramType1 = funType->get_parameters().front()->get_type();
     687                                        if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0;
     688                                        Type *paramType2 = funType->get_parameters().back()->get_type();
     689                                        if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
     690
     691                                        if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
     692                                                Type *baseType1 = pointerType->get_base();
     693                                                if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0;
     694                                                SymTab::Indexer dummy;
     695                                                if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) {
     696                                                        return baseType1;
     697                                                } // if
     698                                        } // if
     699                                } // if
     700                        } // if
     701                        return 0;
     702                }
     703
     704                /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
     705                /// Only picks assignments where neither parameter is cv-qualified
     706                Type *isAssignment( DeclarationWithType *decl ) {
     707                        return decl->get_name() == "?=?" ? isNoCvPtrValFn( decl ) : 0;
     708                }
     709
     710                /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
     711                /// Only picks ctors where the parameter is not cv-qualified
     712                Type *isCtor( DeclarationWithType *decl ) {
     713                        return decl->get_name() == "?{}" ? isNoCvPtrFn( decl ) : 0;
     714                }
     715
     716                /// returns T if the given declaration is: (*?{})(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
     717                /// Only picks copy constructors where neither parameter is cv-qualified
     718                Type *isCopy( DeclarationWithType *decl ) {
     719                        return decl->get_name() == "?{}" ? isNoCvPtrValFn( decl ) : 0;
     720                }
     721
     722                /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise
     723                /// Only picks ctors where the parameter is not cv-qualified
     724                Type *isDtor( DeclarationWithType *decl ) {
     725                        return decl->get_name() == "^?{}" ? isNoCvPtrFn( decl ) : 0;
     726                }
     727
     728                void Pass1::findTypeOps( const std::list< TypeDecl *> &forall ) {
    649729                        // what if a nested function uses an assignment operator?
    650730                        // assignOps.clear();
     
    654734                                        if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) {
    655735                                                assignOps[ typeInst->get_name() ] = *assert;
     736                                        } else if ( TypeInstType *typeInst = isTypeInstCtor( *assert ) ) {
     737                                                ctorOps[ typeInst->get_name() ] = *assert;
     738                                        } else if ( TypeInstType *typeInst = isTypeInstCopy( *assert ) ) {
     739                                                copyOps[ typeInst->get_name() ] = *assert;
     740                                        } else if ( TypeInstType *typeInst = isTypeInstDtor( *assert ) ) {
     741                                                dtorOps[ typeInst->get_name() ] = *assert;
    656742                                        } // if
    657743                                } // for
     
    661747                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    662748                        // if this is a assignment function, put it in the map for this scope
    663                         if ( Type *assignedType = isAssignment( functionDecl ) ) {
    664                                 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) {
    665                                         scopedAssignOps.insert( assignedType, functionDecl );
     749                        if ( Type *paramType = isAssignment( functionDecl ) ) {
     750                                if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
     751                                        scopedAssignOps.insert( paramType, functionDecl );
     752                                }
     753                        } else if ( Type *paramType = isCtor( functionDecl ) ) {
     754                                if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
     755                                        scopedCtorOps.insert( paramType, functionDecl );
     756                                }
     757                        } else if ( Type *paramType = isCopy( functionDecl ) ) {
     758                                if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
     759                                        scopedCopyOps.insert( paramType, functionDecl );
     760                                }
     761                        } else if ( Type *paramType = isDtor( functionDecl ) ) {
     762                                if ( ! dynamic_cast< TypeInstType* >( paramType ) ) {
     763                                        scopedDtorOps.insert( paramType, functionDecl );
    666764                                }
    667765                        }
     
    671769                                scopeTyVars.beginScope();
    672770                                assignOps.beginScope();
     771                                ctorOps.beginScope();
     772                                copyOps.beginScope();
     773                                dtorOps.beginScope();
     774                               
    673775                                DeclarationWithType *oldRetval = retval;
    674776                                bool oldUseRetval = useRetval;
     
    688790                                FunctionType *functionType = functionDecl->get_functionType();
    689791                                makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    690                                 findAssignOps( functionDecl->get_functionType()->get_forall() );
     792                                findTypeOps( functionDecl->get_functionType()->get_forall() );
    691793
    692794                                std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    713815                                scopeTyVars.endScope();
    714816                                assignOps.endScope();
     817                                ctorOps.endScope();
     818                                copyOps.endScope();
     819                                dtorOps.endScope();
    715820                                retval = oldRetval;
    716821                                useRetval = oldUseRetval;
     
    13721477                }
    13731478
     1479                /// Finds the operation declaration for a given type in one of the two maps
     1480                DeclarationWithType* findOpForType( Type *formalType, const ScopedMap< std::string, DeclarationWithType* >& ops, ResolvExpr::TypeMap< DeclarationWithType >& scopedOps ) {
     1481                        if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1482                                ScopedMap< std::string, DeclarationWithType *>::const_iterator opIt = ops.find( formalTypeInstType->get_name() );
     1483                                return opIt == ops.end() ? 0 : opIt->second;
     1484                        } else {
     1485                                return scopedOps.find( formalType );
     1486                        }
     1487                }
     1488
     1489                /// Adds an assertion parameter to the application expression for the actual assertion declaration valued with the assert op
     1490                void addAssertionFor( ApplicationExpr *appExpr, DeclarationWithType *actualDecl, DeclarationWithType *assertOp ) {
     1491                        appExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1492                                        = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) );
     1493                }
     1494               
    13741495                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    13751496                        if ( retval && returnStmt->get_expr() ) {
     
    14181539                                                assignExpr->get_env()->add( (*forallIt)->get_name(), formalType );
    14191540
    1420                                                 // skip types with no assign op (ftype/dtype)
     1541                                                // skip non-otype parameters (ftype/dtype)
    14211542                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue;
    14221543
    1423                                                 // find assignment operator for formal type
    1424                                                 DeclarationWithType *assertAssign = 0;
    1425                                                 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1426                                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
    1427                                                         if ( assertAssignIt == assignOps.end() ) {
    1428                                                                 throw SemanticError( "No assignment operation found for ", formalTypeInstType );
    1429                                                         }
    1430                                                         assertAssign = assertAssignIt->second;
    1431                                                 } else {
    1432                                                         assertAssign = scopedAssignOps.find( formalType );
    1433                                                         if ( ! assertAssign ) {
    1434                                                                 throw SemanticError( "No assignment operation found for ", formalType );
    1435                                                         }
    1436                                                 }
    1437 
    1438                                                 // add inferred parameter for field assignment operator to assignment expression
     1544                                                // find otype operators for formal type
     1545                                                DeclarationWithType *assertAssign = findOpForType( formalType, assignOps, scopedAssignOps );
     1546                                                if ( ! assertAssign ) throw SemanticError( "No assignment operation found for ", formalType );
     1547
     1548                                                DeclarationWithType *assertCtor = findOpForType( formalType, ctorOps, scopedCtorOps );
     1549                                                if ( ! assertCtor ) throw SemanticError( "No default constructor found for ", formalType );
     1550
     1551                                                DeclarationWithType *assertCopy = findOpForType( formalType, copyOps, scopedCopyOps );
     1552                                                if ( ! assertCopy ) throw SemanticError( "No copy constructor found for ", formalType );
     1553
     1554                                                DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps );
     1555                                                if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType );
     1556                                               
     1557                                                // add inferred parameters for otype operators to assignment expression
     1558                                                // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order
    14391559                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
    1440                                                 assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
    1441                                                 DeclarationWithType *actualDecl = asserts.front();
    1442                                                 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
    1443                                                         = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1560                                                assert( asserts.size() >= 4 && "Type param needs otype operator assertions" );
     1561
     1562                                                std::list< DeclarationWithType* >::iterator actualIt = asserts.begin();
     1563                                                addAssertionFor( assignExpr, *actualIt, assertAssign );
     1564                                                ++actualIt;
     1565                                                addAssertionFor( assignExpr, *actualIt, assertCtor );
     1566                                                ++actualIt;
     1567                                                addAssertionFor( assignExpr, *actualIt, assertCopy );
     1568                                                ++actualIt;
     1569                                                addAssertionFor( assignExpr, *actualIt, assertDtor );
     1570                                               
     1571                                                //DeclarationWithType *actualDecl = asserts.front();
     1572                                                //assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1573                                                //      = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
    14441574                                        }
    14451575                                }
     
    14871617                        adapters.beginScope();
    14881618                        scopedAssignOps.beginScope();
     1619                        scopedCtorOps.beginScope();
     1620                        scopedCopyOps.beginScope();
     1621                        scopedDtorOps.beginScope();
    14891622                }
    14901623
     
    14921625                        adapters.endScope();
    14931626                        scopedAssignOps.endScope();
     1627                        scopedCtorOps.endScope();
     1628                        scopedCopyOps.endScope();
     1629                        scopedDtorOps.endScope();
    14941630                }
    14951631
     
    20442180
    20452181                bool PolyGenericCalculator::findGeneric( Type *ty ) {
     2182                        ty = replaceTypeInst( ty, env );
     2183                       
    20462184                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
    2047                                 // duplicate logic from isPolyType()
    2048                                 if ( env ) {
    2049                                         if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    2050                                                 return findGeneric( newType );
    2051                                         } // if
    2052                                 } // if
    20532185                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
    20542186                                        // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
  • src/GenPoly/GenPoly.cc

    rd56c05d0 rc2ad3c9  
    6464                        return false;
    6565                }
    66 
    67                 /// Replaces a TypeInstType by its referrent in the environment, if applicable
    68                 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ) {
    69                         if ( ! env ) return type;
    70                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    71                                 Type *newType = env->lookup( typeInst->get_name() );
    72                                 if ( newType ) return newType;
    73                         }
    74                         return type;
    75                 }
     66        }
     67
     68        Type* replaceTypeInst( Type* type, const TypeSubstitution* env ) {
     69                if ( ! env ) return type;
     70                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     71                        Type *newType = env->lookup( typeInst->get_name() );
     72                        if ( newType ) return newType;
     73                }
     74                return type;
    7675        }
    7776
  • src/GenPoly/GenPoly.h

    rd56c05d0 rc2ad3c9  
    3939        ReferenceToType *isPolyRet( FunctionType *function );
    4040
     41        /// Replaces a TypeInstType by its referrent in the environment, if applicable
     42        Type* replaceTypeInst( Type* type, const TypeSubstitution* env );
     43       
    4144        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
    4245        Type *isPolyType( Type *type, const TypeSubstitution *env = 0 );
Note: See TracChangeset for help on using the changeset viewer.