Changeset 81e768d


Ignore:
Timestamp:
Nov 28, 2024, 4:34:08 PM (10 months ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
46c4dea
Parents:
f5e37a4
Message:

Fix #276; add support for c-array parameters using dependent lengths.

Without this fix, declarations like

void f( int m, int n, float[m][n] );

would either

  • generate bad C code, with unmangled variable names appearing in the function definition, or
  • refuse to resolve a valid-c call of such a function.

tests/array-collections/c-dependent: add direct tests of such cases
tests/tuplearray: activate and expand cases which were blocked on #276
tests/array: activate case fm5y, which was blocked on #276; [noise] adjust source line numbers in .expect
tests/typedefRedef: expand coverage of "error, an array detail is different" cases; [noise] adjust source line numbers in .expect
tests/functions: [noise] adjust .expect to have resolved array sizes (extra casts) in the diffed code dump

The fix is:

  • (ResolvExpr/ResolveTypeof, ResolvExpr/Resolver) Resolve the dimension expressions, where they were missed.
  • (ResolvExpr/Resolver) Prevent dimension expressions that are bound to other parameters from escaping in the function's type, to where they are out of scope. In the f example above, redact the type shown to callers from void (*)(int, int, float[m][n]) to void (*)(int, int, float[][*]).
  • (ResolvExpr/Unify) Relax the matching rules for such a type, when used at a call site, letting the patameters wildcard type match with the concrete type in scope at the caller's side.
  • (Validate/ReplaceTypedef) Apply the former, stricter matching rules to the one place where they are still needed: detecting inconsistent typedefs.
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ResolveTypeof.cpp

    rf5e37a4 r81e768d  
    8888        FixArrayDimension(const ResolveContext & context) : context( context ) {}
    8989
    90         const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
    91                 if (!arrayType->dimension) return arrayType;
    92                 auto mutType = mutate(arrayType);
     90        template< typename PtrType >
     91        const PtrType * previsitImpl( const PtrType * type ) {
     92                // Note: resolving dimension expressions seems to require duplicate logic,
     93                // here and Resolver.cpp: handlePtrType
     94
     95                if (!type->dimension) return type;
     96                auto mutType = mutate(type);
    9397                auto globalSizeType = context.global.sizeType;
    9498                ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType( ast::BasicKind::LongUnsignedInt );
    95                 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
     99                mutType->dimension = findSingleExpression(type->dimension, sizetype, context );
    96100
    97101                if (InitTweak::isConstExpr(mutType->dimension)) {
     
    102106                }
    103107                return mutType;
     108        }
     109
     110        const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
     111                return previsitImpl( arrayType );
     112        }
     113
     114        const ast::PointerType * previsit (const ast::PointerType * pointerType) {
     115                return previsitImpl( pointerType );
    104116        }
    105117};
  • src/ResolvExpr/Resolver.cpp

    rf5e37a4 r81e768d  
    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;
  • src/ResolvExpr/Unify.cpp

    rf5e37a4 r81e768d  
    292292                if ( !array2 ) return;
    293293
    294                 if ( array->isVarLen != array2->isVarLen ) return;
    295                 if ( (array->dimension != nullptr) != (array2->dimension != nullptr) ) return;
    296 
    297                 if ( array->dimension ) {
     294                // Permit cases where one side has a dimension or isVarLen,
     295                // while the other side is the opposite.
     296                // Acheves a wildcard-iterpretation semantics, where lack of
     297                // dimension (`float a[]` or `float a[25][*]`) means
     298                // "anything here is fine."
     299                // Sole known case where a verbatim-match semantics is intended
     300                // is typedef redefinition, for which extra checking is added
     301                // in src/Validate/ReplaceTypedef.cpp.
     302
     303                if ( array->dimension && array2->dimension ) {
    298304                        assert( array2->dimension );
    299305                        // type unification calls expression unification (mutual recursion)
  • src/Validate/ReplaceTypedef.cpp

    rf5e37a4 r81e768d  
    120120        }
    121121}
    122 
    123122struct VarLenChecker : public ast::WithShortCircuiting {
    124123        bool result = false;
     
    126125        void previsit( ast::ArrayType const * at ) { result |= at->isVarLen; }
    127126};
    128 
     127static bool hasVarLen( const ast::Type * t ) {
     128        return ast::Pass<VarLenChecker>::read( t );
     129}
     130struct ArrayTypeExtractor {
     131        std::vector<const ast::ArrayType *> result;
     132        void postvisit( const ast::ArrayType * at ) {
     133                result.push_back( at );
     134        }
     135};
     136static bool dimensionPresenceMismatched( const ast::Type * t0, const ast::Type * t1) {
     137        std::vector<const ast::ArrayType *> at0s = std::move(
     138                ast::Pass<ArrayTypeExtractor>::read( t0 ) );
     139        std::vector<const ast::ArrayType *> at1s = std::move(
     140                ast::Pass<ArrayTypeExtractor>::read( t1 ) );
     141        assert( at0s.size() == at1s.size() );
     142        for (size_t i = 0; i < at0s.size(); i++) {
     143                const ast::ArrayType * at0 = at0s[i];
     144                const ast::ArrayType * at1 = at1s[i];
     145                assert( ResolvExpr::typesCompatible( at0, at1 ) );
     146                if ( (at0->dimension != nullptr) != (at1->dimension != nullptr) ) return true;
     147        }
     148        return false;
     149}
    129150ast::Decl const * ReplaceTypedefCore::postvisit(
    130151                ast::TypedefDecl const * decl ) {
     
    133154                ast::Type const * t0 = decl->base;
    134155                ast::Type const * t1 = typedefNames[ decl->name ].first->base;
     156                // [hasVarLen]
    135157                // Cannot redefine VLA typedefs. Note: this is slightly incorrect,
    136158                // because our notion of VLAs at this point in the translator is
     
    139161                // constant/enumerator. The effort required to fix this corner case
    140162                // likely outweighs the utility of allowing it.
     163                // [dimensionPresenceMismatched]
     164                // Core typesCompatible logic interprets absent dimensions as wildcards,
     165                // i.e. float[][*] matches float[][42].
     166                // For detecting incompatible typedefs, we have to interpret them verbatim,
     167                // i.e. float[] is different than float[42].
     168                // But typesCompatible does assure that the pair of types is structurally
     169                // consistent, outside of the dimension expressions.  This assurance guards
     170                // the dimension-presence traversal.  So this traversal logic can (and does)
     171                // assume that ArrayTypes will be encountered in analogous places.
    141172                if ( !ResolvExpr::typesCompatible( t0, t1 )
    142                                 || ast::Pass<VarLenChecker>::read( t0 )
    143                                 || ast::Pass<VarLenChecker>::read( t1 ) ) {
     173                                || hasVarLen( t0 )
     174                                || hasVarLen( t1 )
     175                                || dimensionPresenceMismatched( t0, t1 ) ) {
    144176                        SemanticError( decl->location, "Cannot redefine typedef %s", decl->name.c_str() );
    145177                }
  • tests/.expect/array-ERR1.txt

    rf5e37a4 r81e768d  
    1 array.cfa:119:25: warning: Preprocessor started
     1array.cfa:125:25: warning: Preprocessor started
    22array.cfa:40:22: error: '[*]' not allowed in other than function prototype scope
    33array.cfa:46:24: error: '[*]' not allowed in other than function prototype scope
     
    55array.cfa:52:16: error: array size missing in '_X2a1A0i_2'
    66array.cfa:53:26: error: '[*]' not allowed in other than function prototype scope
     7array.cfa: At top level:
     8array.cfa:64:1: error: '[*]' not allowed in other than function prototype scope
  • tests/.expect/array-ERR2.txt

    rf5e37a4 r81e768d  
    1 array.cfa:119:25: warning: Preprocessor started
    2 array.cfa:109:32: error: syntax error, unexpected STATIC before token "static"
     1array.cfa:125:25: warning: Preprocessor started
     2array.cfa:117:32: error: syntax error, unexpected STATIC before token "static"
  • tests/.expect/array-ERR3.txt

    rf5e37a4 r81e768d  
    1 array.cfa:119:25: warning: Preprocessor started
    2 array.cfa:110:32: error: syntax error, unexpected ']' before token "]"
     1array.cfa:125:25: warning: Preprocessor started
     2array.cfa:118:32: error: syntax error, unexpected ']' before token "]"
  • tests/.expect/array.txt

    rf5e37a4 r81e768d  
    1 array.cfa:119:25: warning: Preprocessor started
     1array.cfa:125:25: warning: Preprocessor started
  • tests/.expect/functions.arm64.txt

    rf5e37a4 r81e768d  
    310310    __attribute__ ((unused)) const struct _conc__tuple2_3 _X10_retval_f5KT2PiKi_1;
    311311}
    312 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[10], signed int **__anonymous_object49, signed int *__anonymous_object50[10], signed int ***__anonymous_object51, signed int **__anonymous_object52[10], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[10], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[10]);
    313 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[10], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[10], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[10], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[10], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[10]){
     312signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[((unsigned long int )10)], signed int **__anonymous_object49, signed int *__anonymous_object50[((unsigned long int )10)], signed int ***__anonymous_object51, signed int **__anonymous_object52[((unsigned long int )10)], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[((unsigned long int )10)], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[((unsigned long int )10)]);
     313signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[((unsigned long int )10)], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[((unsigned long int )10)], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[((unsigned long int )10)], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[((unsigned long int )10)], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[((unsigned long int )10)]){
    314314    __attribute__ ((unused)) signed int _X9_retval_fi_1;
    315315}
  • tests/.expect/functions.x64.txt

    rf5e37a4 r81e768d  
    310310    __attribute__ ((unused)) const struct _conc__tuple2_3 _X10_retval_f5KT2PiKi_1;
    311311}
    312 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[10], signed int **__anonymous_object49, signed int *__anonymous_object50[10], signed int ***__anonymous_object51, signed int **__anonymous_object52[10], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[10], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[10]);
    313 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[10], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[10], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[10], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[10], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[10]){
     312signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[((unsigned long int )10)], signed int **__anonymous_object49, signed int *__anonymous_object50[((unsigned long int )10)], signed int ***__anonymous_object51, signed int **__anonymous_object52[((unsigned long int )10)], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[((unsigned long int )10)], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[((unsigned long int )10)]);
     313signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[((unsigned long int )10)], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[((unsigned long int )10)], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[((unsigned long int )10)], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[((unsigned long int )10)], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[((unsigned long int )10)]){
    314314    __attribute__ ((unused)) signed int _X9_retval_fi_1;
    315315}
  • tests/.expect/functions.x86.txt

    rf5e37a4 r81e768d  
    310310    __attribute__ ((unused)) const struct _conc__tuple2_3 _X10_retval_f5KT2PiKi_1;
    311311}
    312 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[10], signed int **__anonymous_object49, signed int *__anonymous_object50[10], signed int ***__anonymous_object51, signed int **__anonymous_object52[10], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[10], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[10]);
    313 signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[10], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[10], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[10], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[10], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[10]){
     312signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(signed int (*__anonymous_object42)(void), signed int *(*__anonymous_object43)(void), signed int **(*__anonymous_object44)(void), signed int *const *(*__anonymous_object45)(void), signed int *const *const (*__anonymous_object46)(void), signed int *__anonymous_object47, signed int __anonymous_object48[((unsigned long int )10)], signed int **__anonymous_object49, signed int *__anonymous_object50[((unsigned long int )10)], signed int ***__anonymous_object51, signed int **__anonymous_object52[((unsigned long int )10)], signed int *const **__anonymous_object53, signed int *const *__anonymous_object54[((unsigned long int )10)], signed int *const *const *__anonymous_object55, signed int *const *const __anonymous_object56[((unsigned long int )10)]);
     313signed int _X1fFi_Fi__FPi__FPPi__FPKPi__FPKPi__PiPiPPiPPiPPPiPPPiPPKPiPPKPiPKPKPiPKPKPi__1(__attribute__ ((unused)) signed int (*__anonymous_object57)(void), __attribute__ ((unused)) signed int *(*__anonymous_object58)(void), __attribute__ ((unused)) signed int **(*__anonymous_object59)(void), __attribute__ ((unused)) signed int *const *(*__anonymous_object60)(void), __attribute__ ((unused)) signed int *const *const (*__anonymous_object61)(void), __attribute__ ((unused)) signed int *__anonymous_object62, __attribute__ ((unused)) signed int __anonymous_object63[((unsigned long int )10)], __attribute__ ((unused)) signed int **__anonymous_object64, __attribute__ ((unused)) signed int *__anonymous_object65[((unsigned long int )10)], __attribute__ ((unused)) signed int ***__anonymous_object66, __attribute__ ((unused)) signed int **__anonymous_object67[((unsigned long int )10)], __attribute__ ((unused)) signed int *const **__anonymous_object68, __attribute__ ((unused)) signed int *const *__anonymous_object69[((unsigned long int )10)], __attribute__ ((unused)) signed int *const *const *__anonymous_object70, __attribute__ ((unused)) signed int *const *const __anonymous_object71[((unsigned long int )10)]){
    314314    __attribute__ ((unused)) signed int _X9_retval_fi_1;
    315315}
  • tests/.expect/tuplearray.txt

    rf5e37a4 r81e768d  
    991, 2
    10101, 2
     112, 4
     122, 4
     132, 4
     142, 4
     152, 4
     162, 4
     172, 4
     182, 4
     192, 4
     202, 4
  • tests/.expect/typedefRedef-ERR1.txt

    rf5e37a4 r81e768d  
    1 typedefRedef.cfa:75:25: warning: Compiled
     1typedefRedef.cfa:87:25: warning: Compiled
    22typedefRedef.cfa:4:1 error: Cannot redefine typedef Foo
    33typedefRedef.cfa:31:1 error: Cannot redefine typedef ARR
    4 typedefRedef.cfa:65:1 error: Cannot redefine typedef ARR
     4typedefRedef.cfa:37:1 error: Cannot redefine typedef ARRSa
     5typedefRedef.cfa:43:1 error: Cannot redefine typedef ARRSb
     6typedefRedef.cfa:77:1 error: Cannot redefine typedef ARR
  • tests/.expect/typedefRedef.txt

    rf5e37a4 r81e768d  
    1 typedefRedef.cfa:75:25: warning: Compiled
     1typedefRedef.cfa:87:25: warning: Compiled
  • tests/array.cfa

    rf5e37a4 r81e768d  
    5757    }
    5858
     59    int fred2(int n,
     60        int a1[],
     61E1(     int a2[*],   )
     62        int a4[3],
     63        int T[3],
     64        int a5[n]
     65    ) {}
     66
    5967    int mary( int T[3],                                 // same as: int *T
    6068              int p1[const 3],                          // same as: int const *p1
     
    110118E3( int fm4( int r, int c, int m[][] );            )    // m's immediate element type is incomplete
    111119    int fm5x( int, int, int[*][*] );                    // same as fm1 decl
    112                                                         #ifndef __cforall
    113     int fm5y( int r, int c, int m[r][c] ) {}            // BUG 276: CFA chokes but should accept
    114                                                         // C: same as fm1 defn
    115                                                         #endif
     120    int fm5y( int r, int c, int m[r][c] ) {}            // same as fm1 defn
     121
    116122
    117123
  • tests/tuplearray.cfa

    rf5e37a4 r81e768d  
    2020[void] bar12( * [3][10] [int,int] f );
    2121
    22 //[void] foo( size_t size, [size] [int,int] f ) {
    23 [void] foo( size_t size, [10] [int,int] f ) {
    24         for ( i; size ) f[i] = [1, 2];
     22[void] foo1( [10] [int,int] f ) {
     23        for ( i; 10 ) f[i] = [1, 2];
     24}
     25[void] foo2( size_t size, [size] [int,int] f ) {
     26        for ( i; size ) f[i] = [2, 4];
    2527}
    2628
     
    2931//      [int,int] arr[10];      // unimplemented
    3032
    31         foo( 10, arr );
     33        foo1( arr );
     34        for ( i; 10 ) sout | arr[i];
     35
     36        foo2( 10, arr );
    3237        for ( i; 10 ) sout | arr[i];
    3338}
  • tests/typedefRedef.cfa

    rf5e37a4 r81e768d  
    3030// if a typedef has an array dimension, it can only be redefined to the same dimension
    3131typedef int ARR[2];
     32#endif
     33
     34typedef [ float[], char[], int[] ] ARRSa;
     35typedef [ float[], char[], int[] ] ARRSa;
     36#ifdef ERR1
     37typedef [ float[], char[2], int[] ] ARRSa;
     38#endif
     39
     40typedef int ARRSb[][1][2][3];
     41typedef int ARRSb[][1][2][3];
     42#ifdef ERR1
     43typedef int ARRSb[][1][2][99];
    3244#endif
    3345
Note: See TracChangeset for help on using the changeset viewer.