Changes in / [b9f383f:5527759]


Ignore:
Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    rb9f383f r5527759  
    211211                                                )
    212212                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
     213
    213214                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
     215                                                        // needed for definition of prelude functions, etc.
    214216                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
    215217
     
    225227                                                        )
    226228                                                        arg = new AddressExpr( arg );
     229                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    227230                                                } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    228231                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
     
    234237                                                        PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() );
    235238                                                        delete arg->result;
    236                                                         arg->set_result( ptrType );
     239                                                        arg->result = ptrType;
    237240                                                        arg = mkDeref( arg );
    238                                                         assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
     241                                                        // assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
    239242                                                }
    240243                                        }
     
    298301                                }
    299302
    300                                 if ( addCast ) {
    301                                         PRINT( std::cerr << "adding cast..." << std::endl; )
     303                                // if addrExpr depth is 0, then the result is a pointer because the arg was depth 1 and not lvalue.
     304                                // This means the dereference result is not a reference, is lvalue, and one less pointer depth than
     305                                // the addrExpr. Thus the cast is meaningless.
     306                                // TODO: One thing to double check is whether it is possible for the types to differ outside of the single
     307                                // pointer level (i.e. can the base type of addrExpr differ from the type of addrExpr-arg?).
     308                                // If so then the cast might need to be added, conditional on a more sophisticated check.
     309                                if ( addCast && addrExpr->result->referenceDepth() != 0 ) {
     310                                        PRINT( std::cerr << "adding cast to " << addrExpr->result << std::endl; )
    302311                                        return new CastExpr( ret, addrExpr->result->clone() );
    303312                                }
     
    413422                                for ( int i = 0; i < diff; ++i ) {
    414423                                        ret = mkDeref( ret );
     424                                        // xxx - try removing one reference here? actually, looks like mkDeref already does this, so more closely look at the types generated.
    415425                                }
    416426                                if ( ! ResolvExpr::typesCompatibleIgnoreQualifiers( destType->stripReferences(), srcType->stripReferences(), SymTab::Indexer() ) ) {
  • src/InitTweak/InitTweak.cc

    rb9f383f r5527759  
    528528                }
    529529                if ( dynamic_cast< ReferenceType * >( dst->result ) ) {
    530                         dst = new AddressExpr( dst );
     530                        for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {
     531                                dst = new AddressExpr( dst );
     532                        }
    531533                } else {
    532534                        dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) );
    533535                }
    534536                if ( dynamic_cast< ReferenceType * >( src->result ) ) {
    535                         src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
     537                        for (int depth = src->result->referenceDepth(); depth > 0; depth--) {
     538                                src = new AddressExpr( src );
     539                        }
     540                        // src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
    536541                }
    537542                return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } );
  • src/ResolvExpr/CommonType.cc

    rb9f383f r5527759  
    101101                        int diff = depth1-depth2;
    102102                        // TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
    103                         if ( diff > 1 || diff < -1 ) return nullptr;
     103                        // if ( diff > 1 || diff < -1 ) return nullptr;
    104104
    105105                        // special case where one type has a reference depth of 1 larger than the other
  • src/tests/references.c

    rb9f383f r5527759  
    7575        printf("%d %d\n", r1, x);
    7676
    77         ((int&)r3) = 6;                       // change x, ***r3
     77        r3 = 6;                               // change x, ***r3
    7878        printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
    79         ((int*&)&r3) = &x2;                   // change r1 to refer to x2, (&*)**r3
    80         ((int&)r3) = 999;                     // modify x2
     79        &r3 = &x2;                            // change r1 to refer to x2, (&*)**r3
     80        r3 = 999;                             // modify x2
    8181        printf("x = %d ; x2 = %d\n", x, x2);  // check that x2 was changed
    82         ((int**&)&&r3) = p2;                  // change r2, (&(&*)*)*r3
    83         ((int&)r3) = 12345;                   // modify x
     82        ((int**&)&&r3) = p2;                  // change r2, (&(&*)*)*r3, ensure explicit cast to reference works
     83        r3 = 12345;                           // modify x
    8484        printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
    85         ((int***&)&&&r3) = p3;                // change r3 to p3, (&(&(&*)*)*)r3
    86         ((int&)r3) = 22222;                   // modify x
     85        &&&r3 = p3;                           // change r3 to p3, (&(&(&*)*)*)r3
     86        ((int&)r3) = 22222;                   // modify x, ensure explicit cast to reference works
    8787        printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
    8888
Note: See TracChangeset for help on using the changeset viewer.