Changeset deda7e6 for src


Ignore:
Timestamp:
Sep 21, 2023, 10:15:58 PM (16 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
62c6cfa
Parents:
c1e66d9 (diff), 5a1ae14 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Util.cpp

    rc1e66d9 rdeda7e6  
    104104        }
    105105        assertf( false, "Member not found." );
     106}
     107
     108template<typename node_t>
     109void oneOfExprOrType( const node_t * node ) {
     110        if ( node->expr ) {
     111                assertf( node->expr && !node->type, "Exactly one of expr or type should be set." );
     112        } else {
     113                assertf( !node->expr && node->type, "Exactly one of expr or type should be set." );
     114        }
    106115}
    107116
     
    152161        }
    153162
     163        void previsit( const SizeofExpr * node ) {
     164                previsit( (const ParseNode *)node );
     165                oneOfExprOrType( node );
     166        }
     167
     168        void previsit( const AlignofExpr * node ) {
     169                previsit( (const ParseNode *)node );
     170                oneOfExprOrType( node );
     171        }
     172
    154173        void previsit( const StructInstType * node ) {
    155174                previsit( (const Node *)node );
     
    181200/// referring to is in scope by the structural rules of code.
    182201// Any escapes marked with a bug should be removed once the bug is fixed.
     202// This is a separate pass because of it changes the visit pattern and
     203// must always be run on the entire translation unit.
    183204struct InScopeCore : public ast::WithShortCircuiting {
    184205        ScopedSet<DeclWithType const *> typedDecls;
  • src/ControlStruct/MultiLevelExit.cpp

    rc1e66d9 rdeda7e6  
    1010// Created On       : Mon Nov  1 13:48:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep  6 12:00:00 2023
    13 // Update Count     : 35
     12// Last Modified On : Fri Sep  8 17:04:00 2023
     13// Update Count     : 36
    1414//
    1515
     
    2727
    2828namespace {
     29
     30/// The return context is used to remember if returns are allowed and if
     31/// not, why not. It is the nearest local control flow blocking construct.
     32enum ReturnContext {
     33        MayReturn,
     34        InTryWithHandler,
     35        InResumeHandler,
     36        InTerminateHandler,
     37        InFinally,
     38};
    2939
    3040class Entry {
     
    126136        void previsit( const TryStmt * );
    127137        void postvisit( const TryStmt * );
     138        void previsit( const CatchClause * );
    128139        void previsit( const FinallyClause * );
    129140
     
    134145        vector<Entry> enclosing_control_structures;
    135146        Label break_label;
    136         bool inFinally;
     147        ReturnContext ret_context;
    137148
    138149        template<typename LoopNode>
     
    144155                const list<ptr<Stmt>> & kids, bool caseClause );
    145156
     157        void enterSealedContext( ReturnContext );
     158
    146159        template<typename UnaryPredicate>
    147160        auto findEnclosingControlStructure( UnaryPredicate pred ) {
     
    157170MultiLevelExitCore::MultiLevelExitCore( const LabelToStmt & lt ) :
    158171        target_table( lt ), break_label( CodeLocation(), "" ),
    159         inFinally( false )
     172        ret_context( ReturnContext::MayReturn )
    160173{}
    161174
     
    488501
    489502void MultiLevelExitCore::previsit( const ReturnStmt * stmt ) {
    490         if ( inFinally ) {
    491                 SemanticError( stmt->location, "'return' may not appear in a finally clause" );
    492         }
     503        char const * context;
     504        switch ( ret_context ) {
     505        case ReturnContext::MayReturn:
     506                return;
     507        case ReturnContext::InTryWithHandler:
     508                context = "try statement with a catch clause";
     509                break;
     510        case ReturnContext::InResumeHandler:
     511                context = "catchResume clause";
     512                break;
     513        case ReturnContext::InTerminateHandler:
     514                context = "catch clause";
     515                break;
     516        case ReturnContext::InFinally:
     517                context = "finally clause";
     518                break;
     519        default:
     520                assert(0);
     521        }
     522        SemanticError( stmt->location, toString( "'return' may not appear in a ", context ) );
    493523}
    494524
     
    500530                GuardAction([this](){ enclosing_control_structures.pop_back(); } );
    501531        }
     532
     533        // Try statements/try blocks are only sealed with a termination handler.
     534        for ( auto clause : stmt->handlers ) {
     535                if ( ast::Terminate == clause->kind ) {
     536                        return enterSealedContext( ReturnContext::InTryWithHandler );
     537                }
     538        }
    502539}
    503540
     
    512549}
    513550
     551void MultiLevelExitCore::previsit( const CatchClause * clause ) {
     552        ReturnContext context = ( ast::Terminate == clause->kind )
     553                ? ReturnContext::InTerminateHandler : ReturnContext::InResumeHandler;
     554        enterSealedContext( context );
     555}
     556
    514557void MultiLevelExitCore::previsit( const FinallyClause * ) {
    515         GuardAction([this, old = std::move( enclosing_control_structures)](){ enclosing_control_structures = std::move(old); });
    516         enclosing_control_structures = vector<Entry>();
    517         GuardValue( inFinally ) = true;
     558        enterSealedContext( ReturnContext::InFinally );
    518559}
    519560
     
    617658}
    618659
     660void MultiLevelExitCore::enterSealedContext( ReturnContext enter_context ) {
     661        GuardAction([this, old = std::move(enclosing_control_structures)](){ enclosing_control_structures = std::move(old); });
     662        enclosing_control_structures = vector<Entry>();
     663        GuardValue( ret_context ) = enter_context;
     664}
     665
    619666} // namespace
    620667
  • src/GenPoly/GenPoly.cc

    rc1e66d9 rdeda7e6  
    4848                }
    4949
    50                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) {
    51                         for (auto &param : params) {
    52                                 auto paramType = param.strict_as<ast::TypeExpr>();
    53                                 if (isPolyType(paramType->type, env)) return true;
     50                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) {
     51                        for ( auto &param : params ) {
     52                                auto paramType = param.as<ast::TypeExpr>();
     53                                assertf( paramType, "Aggregate parameters should be type expressions" );
     54                                if ( isPolyType( paramType->type, env ) ) return true;
    5455                        }
    5556                        return false;
     
    6263                                assertf(paramType, "Aggregate parameters should be type expressions");
    6364                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
     65                        }
     66                        return false;
     67                }
     68
     69                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) {
     70                        for ( auto & param : params ) {
     71                                auto paramType = param.as<ast::TypeExpr>();
     72                                assertf( paramType, "Aggregate parameters should be type expressions" );
     73                                if ( isPolyType( paramType->type, typeVars, env ) ) return true;
    6474                        }
    6575                        return false;
     
    185195        }
    186196
    187         const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    188                 type = replaceTypeInst( type, env );
    189 
    190                 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
    191                         if ( tyVars.contains( typeInst->typeString() ) ) return type;
    192                 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
    193                         return isPolyType( arrayType->base, env );
    194                 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
    195                         if ( hasPolyParams( structType->params, env ) ) return type;
    196                 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
    197                         if ( hasPolyParams( unionType->params, env ) ) return type;
    198                 }
    199                 return nullptr;
    200         }
    201 
    202197const ast::Type * isPolyType( const ast::Type * type,
    203198                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     
    207202                if ( typeVars.contains( *inst ) ) return type;
    208203        } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
    209                 return isPolyType( array->base, subst );
     204                return isPolyType( array->base, typeVars, subst );
    210205        } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) {
    211                 if ( hasPolyParams( sue->params, subst ) ) return type;
     206                if ( hasPolyParams( sue->params, typeVars, subst ) ) return type;
    212207        } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) {
    213                 if ( hasPolyParams( sue->params, subst ) ) return type;
     208                if ( hasPolyParams( sue->params, typeVars, subst ) ) return type;
    214209        }
    215210        return nullptr;
Note: See TracChangeset for help on using the changeset viewer.