Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r6f326b1 rcdb990a  
    127127
    128128        namespace {
    129                 void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     129                struct StripCasts {
     130                        Expression * postmutate( CastExpr * castExpr ) {
     131                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     132                                        // generated cast is to the same type as its argument, so it's unnecessary -- remove it
     133                                        Expression * expr = castExpr->arg;
     134                                        castExpr->arg = nullptr;
     135                                        std::swap( expr->env, castExpr->env );
     136                                        return expr;
     137                                }
     138                                return castExpr;
     139                        }
     140
     141                        static void strip( Expression *& expr ) {
     142                                PassVisitor<StripCasts> stripper;
     143                                expr = expr->acceptMutator( stripper );
     144                        }
     145                };
     146
     147                void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
    130148                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    131                         env.makeSubstitution( *expr->get_env() );
     149                        env.makeSubstitution( *expr->env );
     150                        StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
    132151                }
    133152
     
    414433
    415434        void Resolver::previsit( CaseStmt *caseStmt ) {
    416                 if ( caseStmt->get_condition() ) {
     435                if ( caseStmt->condition ) {
    417436                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    418437                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     
    420439                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
    421440                        findSingleExpression( newExpr, indexer );
    422                         CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    423                         caseStmt->condition = castExpr->arg;
    424                         castExpr->arg = nullptr;
    425                         delete castExpr;
     441                        // case condition cannot have a cast in C, so it must be removed, regardless of whether it performs a conversion.
     442                        // Ideally we would perform the conversion internally here.
     443                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( newExpr ) ) {
     444                                newExpr = castExpr->arg;
     445                                castExpr->arg = nullptr;
     446                                std::swap( newExpr->env, castExpr->env );
     447                                delete castExpr;
     448                        }
     449                        caseStmt->condition = newExpr;
    426450                }
    427451        }
     
    718742                initExpr->expr = nullptr;
    719743                std::swap( initExpr->env, newExpr->env );
    720                 std::swap( initExpr->inferParams, newExpr->inferParams ) ;
     744                // InitExpr may have inferParams in the case where the expression specializes a function pointer,
     745                // and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
     746                newExpr->spliceInferParams( initExpr );
    721747                delete initExpr;
    722748
Note: See TracChangeset for help on using the changeset viewer.