Changes in / [ff2d1139:7a052e34]
- Location:
- src
- Files:
-
- 6 edited
-
ResolvExpr/Unify.cc (modified) (4 diffs)
-
SymTab/FixFunction.cc (modified) (2 diffs)
-
SymTab/FixFunction.h (modified) (1 diff)
-
SymTab/Mangler.cc (modified) (1 diff)
-
SymTab/Validate.cc (modified) (3 diffs)
-
tests/tuple/tupleVariadic.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
rff2d1139 r7a052e34 563 563 flatten( dcl->get_type(), back_inserter( types ) ); 564 564 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 565 569 dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) ); 566 570 } … … 580 584 581 585 // 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 ) ) { 585 589 586 590 // the original types must be used in mark assertions, since pointer comparisons are used … … 599 603 // check that other type is compatible and named the same 600 604 RefType *otherStruct = dynamic_cast< RefType* >( other ); 601 result = otherStruct && inst-> get_name() == otherStruct->get_name();605 result = otherStruct && inst->name == otherStruct->name; 602 606 } 603 607 … … 608 612 if ( ! result ) return; 609 613 // 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; 612 616 613 617 std::list< Expression* >::const_iterator it = params.begin(), jt = otherParams.begin(); -
src/SymTab/FixFunction.cc
rff2d1139 r7a052e34 36 36 } 37 37 38 // xxx - this passes on void[], e.g. 39 // void foo(void [10]); 40 // does not cause an error 41 38 42 Type * FixFunction::postmutate(ArrayType *arrayType) { 39 43 // need to recursively mutate the base type in order for multi-dimensional arrays to work. … … 62 66 void FixFunction::premutate(ZeroType *) { visit_children = false; } 63 67 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 } 64 74 } // namespace SymTab 65 75 -
src/SymTab/FixFunction.h
rff2d1139 r7a052e34 47 47 bool isVoid; 48 48 }; 49 50 bool fixFunction( DeclarationWithType *& ); 49 51 } // namespace SymTab 50 52 -
src/SymTab/Mangler.cc
rff2d1139 r7a052e34 37 37 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> { 38 38 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 39 Mangler( const Mangler & ) ;39 Mangler( const Mangler & ) = delete; 40 40 41 41 void previsit( BaseSyntaxNode * ) { visit_children = false; } -
src/SymTab/Validate.cc
rff2d1139 r7a052e34 351 351 namespace { 352 352 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 } 380 371 } 381 372 } … … 383 374 void EnumAndPointerDecay::previsit( FunctionType *func ) { 384 375 // 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 ); 387 378 } 388 379 … … 626 617 // apply FixFunction to every assertion to check for invalid void type 627 618 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 ) { 631 621 throw SemanticError( "invalid type void in assertion of function ", node ); 632 622 } // if -
src/tests/tuple/tupleVariadic.c
rff2d1139 r7a052e34 95 95 } 96 96 97 forall(ttype T | { void foo(T); }) void bar(T x) {} 98 void foo(int) {} 99 97 100 int main() { 98 101 array * x0 = new(); … … 117 120 func(3, 2.0, 111, 4.145); 118 121 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 } 119 128 } 120 129
Note:
See TracChangeset
for help on using the changeset viewer.