Changes in / [ff2d1139:7a052e34]


Ignore:
Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    rff2d1139 r7a052e34  
    563563                        flatten( dcl->get_type(), back_inserter( types ) );
    564564                        for ( Type * t : types ) {
     565                                // outermost const, volatile, _Atomic qualifiers in parameters should not play a role in the unification of function types, since they do not determine whether a function is callable.
     566                                // Note: MUST consider at least mutex qualifier, since functions can be overloaded on outermost mutex and a mutex function has different requirements than a non-mutex function.
     567                                t->get_qualifiers() -= Type::Qualifiers(Type::Const | Type::Volatile | Type::Atomic);
     568
    565569                                dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) );
    566570                        }
     
    580584
    581585                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
    582                         if ( (flatFunc->get_parameters().size() == flatOther->get_parameters().size() && flatFunc->get_returnVals().size() == flatOther->get_returnVals().size()) || flatFunc->isTtype() || flatOther->isTtype() ) {
    583                                 if ( unifyDeclList( flatFunc->get_parameters().begin(), flatFunc->get_parameters().end(), flatOther->get_parameters().begin(), flatOther->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    584                                         if ( unifyDeclList( flatFunc->get_returnVals().begin(), flatFunc->get_returnVals().end(), flatOther->get_returnVals().begin(), flatOther->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     586                        if ( (flatFunc->parameters.size() == flatOther->parameters.size() && flatFunc->returnVals.size() == flatOther->returnVals.size()) || flatFunc->isTtype() || flatOther->isTtype() ) {
     587                                if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     588                                        if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    585589
    586590                                                // the original types must be used in mark assertions, since pointer comparisons are used
     
    599603                // check that other type is compatible and named the same
    600604                RefType *otherStruct = dynamic_cast< RefType* >( other );
    601                 result = otherStruct && inst->get_name() == otherStruct->get_name();
     605                result = otherStruct && inst->name == otherStruct->name;
    602606        }
    603607
     
    608612                if ( ! result ) return;
    609613                // Check that parameters of types unify, if any
    610                 std::list< Expression* > params = inst->get_parameters();
    611                 std::list< Expression* > otherParams = ((RefType*)other)->get_parameters();
     614                std::list< Expression* > params = inst->parameters;
     615                std::list< Expression* > otherParams = ((RefType*)other)->parameters;
    612616
    613617                std::list< Expression* >::const_iterator it = params.begin(), jt = otherParams.begin();
  • src/SymTab/FixFunction.cc

    rff2d1139 r7a052e34  
    3636        }
    3737
     38        // xxx - this passes on void[], e.g.
     39        //   void foo(void [10]);
     40        // does not cause an error
     41
    3842        Type * FixFunction::postmutate(ArrayType *arrayType) {
    3943                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
     
    6266        void FixFunction::premutate(ZeroType *) { visit_children = false; }
    6367        void FixFunction::premutate(OneType *) { visit_children = false; }
     68
     69        bool fixFunction( DeclarationWithType *& dwt ) {
     70                PassVisitor<FixFunction> fixer;
     71                dwt = dwt->acceptMutator( fixer );
     72                return fixer.pass.isVoid;
     73        }
    6474} // namespace SymTab
    6575
  • src/SymTab/FixFunction.h

    rff2d1139 r7a052e34  
    4747                bool isVoid;
    4848        };
     49
     50        bool fixFunction( DeclarationWithType *& );
    4951} // namespace SymTab
    5052
  • src/SymTab/Mangler.cc

    rff2d1139 r7a052e34  
    3737                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
    3838                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    39                                 Mangler( const Mangler & );
     39                                Mangler( const Mangler & ) = delete;
    4040
    4141                                void previsit( BaseSyntaxNode * ) { visit_children = false; }
  • src/SymTab/Validate.cc

    rff2d1139 r7a052e34  
    351351        namespace {
    352352                template< typename DWTList >
    353                 void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    354                         // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    355                         // entirely. other fix ups are handled by the FixFunction class
    356                         typedef typename DWTList::iterator DWTIterator;
    357                         DWTIterator begin( dwts.begin() ), end( dwts.end() );
    358                         if ( begin == end ) return;
    359                         PassVisitor<FixFunction> fixer;
    360                         DWTIterator i = begin;
    361                         *i = (*i)->acceptMutator( fixer );
    362                         if ( fixer.pass.isVoid ) {
    363                                 DWTIterator j = i;
    364                                 ++i;
    365                                 delete *j;
    366                                 dwts.erase( j );
    367                                 if ( i != end ) {
    368                                         throw SemanticError( "invalid type void in function type ", func );
    369                                 } // if
    370                         } else {
    371                                 ++i;
    372                                 for ( ; i != end; ++i ) {
    373                                         PassVisitor<FixFunction> fixer;
    374                                         *i = (*i)->acceptMutator( fixer );
    375                                         if ( fixer.pass.isVoid ) {
    376                                                 throw SemanticError( "invalid type void in function type ", func );
    377                                         } // if
    378                                 } // for
    379                         } // if
     353                void fixFunctionList( DWTList & dwts, bool isVarArgs, FunctionType * func ) {
     354                        auto nvals = dwts.size();
     355                        bool containsVoid = false;
     356                        for ( auto & dwt : dwts ) {
     357                                // fix each DWT and record whether a void was found
     358                                containsVoid |= fixFunction( dwt );
     359                        }
     360
     361                        // the only case in which "void" is valid is where it is the only one in the list
     362                        if ( containsVoid && ( nvals > 1 || isVarArgs ) ) {
     363                                throw SemanticError( "invalid type void in function type ", func );
     364                        }
     365
     366                        // one void is the only thing in the list; remove it.
     367                        if ( containsVoid ) {
     368                                delete dwts.front();
     369                                dwts.clear();
     370                        }
    380371                }
    381372        }
     
    383374        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    384375                // Fix up parameters and return types
    385                 fixFunctionList( func->get_parameters(), func );
    386                 fixFunctionList( func->get_returnVals(), func );
     376                fixFunctionList( func->parameters, func->isVarArgs, func );
     377                fixFunctionList( func->returnVals, false, func );
    387378        }
    388379
     
    626617                        // apply FixFunction to every assertion to check for invalid void type
    627618                        for ( DeclarationWithType *& assertion : type->assertions ) {
    628                                 PassVisitor<FixFunction> fixer;
    629                                 assertion = assertion->acceptMutator( fixer );
    630                                 if ( fixer.pass.isVoid ) {
     619                                bool isVoid = fixFunction( assertion );
     620                                if ( isVoid ) {
    631621                                        throw SemanticError( "invalid type void in assertion of function ", node );
    632622                                } // if
  • src/tests/tuple/tupleVariadic.c

    rff2d1139 r7a052e34  
    9595}
    9696
     97forall(ttype T | { void foo(T); }) void bar(T x) {}
     98void foo(int) {}
     99
    97100int main() {
    98101        array * x0 = new();
     
    117120        func(3, 2.0, 111, 4.145);
    118121        printf("finished func\n");
     122
     123        {
     124                // T = [const int] -- this ensures that void(*)(int) satisfies void(*)(const int)
     125                const int x;
     126                bar(x);
     127        }
    119128}
    120129
Note: See TracChangeset for help on using the changeset viewer.