Changes in / [5527759:b9f383f]


Ignore:
Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    r5527759 rb9f383f  
    211211                                                )
    212212                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    213 
    214213                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    215                                                         // needed for definition of prelude functions, etc.
    216214                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
    217215
     
    227225                                                        )
    228226                                                        arg = new AddressExpr( arg );
    229                                                 // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    230227                                                } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    231228                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
     
    237234                                                        PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() );
    238235                                                        delete arg->result;
    239                                                         arg->result = ptrType;
     236                                                        arg->set_result( ptrType );
    240237                                                        arg = mkDeref( arg );
    241                                                         // assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
     238                                                        assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
    242239                                                }
    243240                                        }
     
    301298                                }
    302299
    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; )
     300                                if ( addCast ) {
     301                                        PRINT( std::cerr << "adding cast..." << std::endl; )
    311302                                        return new CastExpr( ret, addrExpr->result->clone() );
    312303                                }
     
    422413                                for ( int i = 0; i < diff; ++i ) {
    423414                                        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.
    425415                                }
    426416                                if ( ! ResolvExpr::typesCompatibleIgnoreQualifiers( destType->stripReferences(), srcType->stripReferences(), SymTab::Indexer() ) ) {
  • src/InitTweak/InitTweak.cc

    r5527759 rb9f383f  
    528528                }
    529529                if ( dynamic_cast< ReferenceType * >( dst->result ) ) {
    530                         for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {
    531                                 dst = new AddressExpr( dst );
    532                         }
     530                        dst = new AddressExpr( dst );
    533531                } else {
    534532                        dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) );
    535533                }
    536534                if ( dynamic_cast< ReferenceType * >( src->result ) ) {
    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() ) );
     535                        src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
    541536                }
    542537                return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } );
  • src/ResolvExpr/CommonType.cc

    r5527759 rb9f383f  
    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

    r5527759 rb9f383f  
    7575        printf("%d %d\n", r1, x);
    7676
    77         r3 = 6;                               // change x, ***r3
     77        ((int&)r3) = 6;                       // change x, ***r3
    7878        printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
    79         &r3 = &x2;                            // change r1 to refer to x2, (&*)**r3
    80         r3 = 999;                             // modify x2
     79        ((int*&)&r3) = &x2;                   // change r1 to refer to x2, (&*)**r3
     80        ((int&)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, ensure explicit cast to reference works
    83         r3 = 12345;                           // modify x
     82        ((int**&)&&r3) = p2;                  // change r2, (&(&*)*)*r3
     83        ((int&)r3) = 12345;                   // modify x
    8484        printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
    85         &&&r3 = p3;                           // change r3 to p3, (&(&(&*)*)*)r3
    86         ((int&)r3) = 22222;                   // modify x, ensure explicit cast to reference works
     85        ((int***&)&&&r3) = p3;                // change r3 to p3, (&(&(&*)*)*)r3
     86        ((int&)r3) = 22222;                   // modify x
    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.