Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cc

    r85b2300 r6b8c4a8  
    146146
    147147        namespace {
    148                 // true for intrinsic function calls that return an lvalue in C
     148                // true for intrinsic function calls that return a reference
    149149                bool isIntrinsicReference( Expression * expr ) {
    150                         // known intrinsic-reference prelude functions
    151                         static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
    152150                        if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
    153151                                std::string fname = InitTweak::getFunctionName( untyped );
    154                                 return lvalueFunctions.count(fname);
     152                                // known intrinsic-reference prelude functions
     153                                return fname == "*?" || fname == "?[?]";
    155154                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
    156155                                if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
    157                                         return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
     156                                        // use type of return variable rather than expr result type, since it may have been changed to a pointer type
     157                                        FunctionType * ftype = GenPoly::getFunctionType( func->get_type() );
     158                                        Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type();
     159                                        return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret );
    158160                                }
    159161                        }
     
    210212                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    211213
    212                                                 if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
     214                                                if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    213215                                                        // 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
     
    226228                                                        arg = new AddressExpr( arg );
    227229                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    228                                                 } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
     230                                                } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    229231                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
    230232                                                        PRINT(
Note: See TracChangeset for help on using the changeset viewer.