Ignore:
Timestamp:
Dec 1, 2024, 9:04:12 PM (10 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
eae8b37
Parents:
3e2e9b2 (diff), 1c0a3a4 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cpp

    r3e2e9b2 r509ec82  
    494494}
    495495
     496// Returns a version of `ty`, with some detail redacted.
     497// `ty` is that of a parameter or return of `functionDecl`.
     498// Redaction:
     499//   - concerns the dimension expression, when `ty` is a pointer or array
     500//   - prevents escape of variables bound by other parameter declarations
     501//   - replaces the whole dimension with `*` if it uses such a variable
     502//   - produces the caller's view of `functionDecl`, where `ty` is from the callee/body's view
     503// Example 1
     504//   functionDecl:     void   f( int n, float a[][5][n + 1] );
     505//   outcome:      f : void (*)( int  , float  [][5][*]     ), redaction on deepest ArrayType
     506// Example 2
     507//   functionDecl:     void   f( int n, float a[n] );
     508//   outcome:      f : void (*)( int  , float  [*]     ), redaction on PointerType
     509// Example 3
     510//   in scope:         int n;
     511//   functionDecl:     void   f( float a[][n] );
     512//   outcome:      f : void (*)( float  [][n] ), no redaction
     513static const ast::Type * redactBoundDimExprs(
     514        const ast::Type * ty,
     515        const ast::FunctionDecl * functionDecl
     516);
     517struct UsesParams {
     518        const ast::FunctionDecl * functionDecl;
     519        UsesParams( const ast::FunctionDecl * functionDecl ) : functionDecl(functionDecl) {}
     520        bool result = false;
     521        void postvisit( const ast::VariableExpr * e ) {
     522                for ( auto p : functionDecl->params ) {
     523                        if ( p.get() == e->var ) result = true;
     524                }
     525        }
     526};
     527struct Redactor {
     528        const ast::FunctionDecl * functionDecl;
     529        Redactor( const ast::FunctionDecl * functionDecl ) : functionDecl(functionDecl) {}
     530        template< typename PtrType >
     531        const PtrType * postvisitImpl( const PtrType * type ) {
     532                if ( type->dimension && ast::Pass<UsesParams>::read( type->dimension.get(), functionDecl ) ) {
     533                        // PtrType * newtype = ast::shallowCopy( type );
     534                        // newtype->dimension = nullptr;
     535                        // type = newtype;
     536                        auto mutType = mutate(type);
     537                        mutType->dimension = nullptr;
     538                        type = mutType;
     539                }
     540                return type;
     541        }
     542
     543        const ast::ArrayType * postvisit (const ast::ArrayType * arrayType) {
     544                return postvisitImpl( arrayType );
     545        }
     546
     547        const ast::PointerType * postvisit (const ast::PointerType * pointerType) {
     548                return postvisitImpl( pointerType );
     549        }
     550};
     551static const ast::Type * redactBoundDimExprs(
     552        const ast::Type * ty,
     553        const ast::FunctionDecl * functionDecl
     554) {
     555        if ( ast::Pass<UsesParams>::read( ty, functionDecl ) ) {
     556                ast::Type * newty = ast::deepCopy( ty );
     557                ast::Pass<Redactor> visitor(functionDecl);
     558                ty = newty->accept(visitor);
     559        }
     560        return ty;
     561}
     562
    496563const ast::FunctionDecl * Resolver::previsit( const ast::FunctionDecl * functionDecl ) {
    497564        GuardValue( functionReturn );
     
    534601                        param = fixObjectType(param.strict_as<ast::ObjectDecl>(), context);
    535602                        symtab.addId(param);
    536                         paramTypes.emplace_back(param->get_type());
     603                        auto exportParamT = redactBoundDimExprs( param->get_type(), mutDecl );
     604                        paramTypes.emplace_back( exportParamT );
    537605                }
    538606                for (auto & ret : mutDecl->returns) {
    539607                        ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), context);
    540                         returnTypes.emplace_back(ret->get_type());
     608                        auto exportRetT = redactBoundDimExprs( ret->get_type(), mutDecl );
     609                        returnTypes.emplace_back( exportRetT );
    541610                }
    542611                // since function type in decl is just a view of param types, need to update that as well
     
    699768template< typename PtrType >
    700769const PtrType * handlePtrType( const PtrType * type, const ResolveContext & context ) {
     770        // Note: resolving dimension expressions seems to require duplicate logic,
     771        // here and ResolveTypeof.cpp:fixArrayType.
    701772        if ( type->dimension ) {
    702773                const ast::Type * sizeType = context.global.sizeType.get();
     
    704775                assertf(dimension->env->empty(), "array dimension expr has nonempty env");
    705776                dimension.get_and_mutate()->env = nullptr;
    706                 ast::mutate_field( type, &PtrType::dimension, dimension );
     777                type = ast::mutate_field( type, &PtrType::dimension, dimension );
    707778        }
    708779        return type;
Note: See TracChangeset for help on using the changeset viewer.