Changeset 6896548


Ignore:
Timestamp:
Jun 13, 2019, 3:56:24 PM (5 years ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6a1dfda
Parents:
d76f32c
Message:

Fixed convert-convert issues with strings, when conversion happens after resolve. Three specific issues fixed.

  1. String literals were not roundtripping new-old-new with the original type at the constant level, whereas the resolver changes the expression-level type from array to pointer.
  2. String literals were roundtripping with noise on a "--print astexpr" diff, with the char-array's index type coming up signed int (expecting unsigned long long int).
  3. Function calls that pass a foo[] variable as argument to a foo* formal were crashing on copy-constructor generation because convert-convert was changing the arg-expression type from foo* (set by the resolver, as expecteed) back to foo[], taken from the variable (switched to foo* taken from convert-src expression).
Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rd76f32c r6896548  
    733733        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
    734734                auto expr = new VariableExpr();
     735                expr->var = get<DeclarationWithType>().accept1(node->var);
    735736                visitBaseExpr( node, expr );
    736                 expr->var = get<DeclarationWithType>().accept1(node->var);
    737                 Type * type = expr->var->get_type()->clone();
    738                 if(FunctionType * ft = dynamic_cast<FunctionType*>(type)) {
    739                         if(node->result.as<ast::PointerType>()) {
    740                                 type = new PointerType({}, ft);
    741                         }
    742                 }
    743 
    744                 type->set_lvalue( true );
    745                 expr->result = type ;
    746737                this->node = expr;
    747738                return nullptr;
     
    766757                        break;
    767758                case ast::ConstantExpr::String:
    768                         rslt = new ConstantExpr{Constant{
    769                                 get<Type>().accept1( node->result ),
    770                                 node->rep,
    771                                 (long long unsigned int)0
    772                         }};
     759                        // Old world:   two types: rslt->constant.type, rslt->result
     760                        // New workd:   one type: node->result
     761                        // Both worlds: the outer, expression-level type can change during resolution
     762                        //              in case of string, that's char[k] before-resolve and char * after
     763                        // Old world:   the inner Constant type stays what it was built with
     764                        //              in case of string, that's char[k]
     765                        // Both worlds: the "rep" field of a string constant is the string value it was initialized from, wrapped in quotes, but not otherwise escaped
     766                        ast::ptr<ast::Type> charType = nullptr;
     767                        if (const ast::ArrayType *arrRslt = node->result.as<ast::ArrayType>()) {
     768                                charType = arrRslt->base;
     769                        } else {
     770                                const ast::PointerType *ptrRslt = node->result.as<ast::PointerType>();
     771                                assert(ptrRslt);
     772                                charType = ptrRslt->base;
     773                        }
     774                        rslt = new ConstantExpr(Constant::from_string(
     775                                node->rep, get<Type>().accept1(charType)));          // rslt->result is char[k]
     776                        rslt->set_result( get<Type>().accept1( node->result ) ); // rslt->result is [[ node->rsult ]]
    773777                        break;
    774778                }
     
    21522156                );
    21532157
    2154                 visitBaseExpr_SkipResultType( old,
    2155                         expr
    2156                 );
    2157 
    21582158                expr->var = GET_ACCEPT_1(var, DeclWithType);
    2159                 expr->result = expr->var->get_type();
    2160                 if(const ast::FunctionType * ft = expr->result.as<ast::FunctionType>()) {
    2161                         if(dynamic_cast<PointerType *>(old->result)) {
    2162                                 expr->result = new ast::PointerType(ft);
    2163                         }
    2164                 }
    2165                 add_qualifiers( expr->result, ast::CV::Lvalue );
     2159                visitBaseExpr( old, expr );
     2160
    21662161                this->node = expr;
    21672162        }
     
    22142209                        rslt = new ast::ConstantExpr(
    22152210                                old->location,
    2216                                 GET_ACCEPT_1(result, Type),
     2211                                GET_ACCEPT_1(result, Type), // preserve the expression-level type (old->result, not old->constant.type); see new-to-old
    22172212                                old->constant.get_value(),
    22182213                                0,
  • src/AST/Expr.cpp

    rd76f32c r6896548  
    238238}
    239239
    240 ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & s ) {
    241         return new ConstantExpr{
    242                 loc,
    243                 new ArrayType{
    244                         new BasicType{ BasicType::Char, CV::Const },
    245                         ConstantExpr::from_int( loc, s.size() + 1 /* null terminator */ ),
    246                         FixedLen, DynamicDim },
    247                 std::string{"\""} + s + "\"",
    248                 (unsigned long long)0,
    249                 ConstantExpr::String };
    250 }
    251 
    252240ConstantExpr * ConstantExpr::null( const CodeLocation & loc, const Type * ptrType ) {
    253241        return new ConstantExpr{
  • src/AST/Expr.hpp

    rd76f32c r6896548  
    381381        /// generates a floating point constant of the given double
    382382        static ConstantExpr * from_double( const CodeLocation & loc, double d );
    383         /// generates an array of chars constant of the given string
    384         static ConstantExpr * from_string( const CodeLocation & loc, const std::string & s );
    385383        /// generates a null pointer value for the given type. void * if omitted.
    386384        static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr );
  • src/Parser/ExpressionNode.cc

    rd76f32c r6896548  
    354354                strtype = new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char );
    355355        } // switch
    356         ArrayType * at = new ArrayType( noQualifiers, strtype,
    357                                                                         new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    358                                                                         false, false );
    359         Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
     356        Expression * ret = new ConstantExpr( Constant::from_string( str, strtype ) );
    360357        if ( units.length() != 0 ) {
    361358                ret = new UntypedExpr( new NameExpr( units ), { ret } );
  • src/SynTree/Constant.cc

    rd76f32c r6896548  
    5151}
    5252
    53 Constant Constant::from_string( std::string const & str ) {
    54         return Constant(
    55                 new ArrayType(
    56                         noQualifiers,
    57                         new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
    58                         new ConstantExpr( Constant::from_int( str.size() + 1 /* \0 */ )),
    59                         false, false ),
    60                 std::string("\"") + str + "\"", (unsigned long long int)0 );
     53Constant Constant::from_string( std::string const & cEscapedVal, Type *charType ) {
     54        assert(cEscapedVal.length() >= 2);
     55        assert(cEscapedVal.front() == '"');
     56        assert(cEscapedVal.back() == '"');
     57        ArrayType * at = new ArrayType( noQualifiers, charType,
     58                                                                        new ConstantExpr( Constant::from_ulong( cEscapedVal.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
     59                                                                        false, false );
     60        return Constant( at, cEscapedVal, (unsigned long long int)0 );
    6161}
    6262
  • src/SynTree/Constant.h

    rd76f32c r6896548  
    5252        static Constant from_double( double d );
    5353        /// generates an array of chars constant of the given string
    54         static Constant from_string( std::string const & s );
     54        static Constant from_string( std::string const & cEscapedVal, Type *charType );
    5555
    5656        /// generates a null pointer value for the given type. void * if omitted.
Note: See TracChangeset for help on using the changeset viewer.