Changeset 5809461


Ignore:
Timestamp:
Sep 1, 2017, 6:59:48 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
b0dfbc4
Parents:
bc3127d
Message:

Fix handling of GCC label address and computed goto

Location:
src
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rbc3127d r5809461  
    546546                extension( addressExpr );
    547547                output << "(&";
    548                 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
    549                 if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
    550                         output << mangleName( variableExpr->get_var() );
    551                 } else {
    552                         addressExpr->get_arg()->accept( *this );
    553                 } // if
     548                addressExpr->arg->accept( *this );
    554549                output << ")";
     550        }
     551
     552        void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
     553                extension( addressExpr );
     554                output << "(&&" << addressExpr->arg << ")";
    555555        }
    556556
  • src/CodeGen/CodeGenerator.h

    rbc3127d r5809461  
    5959                virtual void visit( NameExpr *nameExpr );
    6060                virtual void visit( AddressExpr *addressExpr );
     61                virtual void visit( LabelAddressExpr *addressExpr );
    6162                virtual void visit( CastExpr *castExpr );
    6263                virtual void visit( VirtualCastExpr *castExpr );
  • src/CodeGen/OperatorTable.cc

    rbc3127d r5809461  
    6666                        {       "?^=?",         "^=",   "_operator_bitxorassign",               OT_INFIXASSIGN          },
    6767                        {       "?|=?",         "|=",   "_operator_bitorassign",                OT_INFIXASSIGN          },
    68                         {       "&&",           "&&",   "&&",                                                   OT_LABELADDRESS         }
    6968                };
    7069
  • src/InitTweak/FixInit.cc

    rbc3127d r5809461  
    127127
    128128                        // don't go into other functions
    129                         virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {}
     129                        virtual void visit( FunctionDecl * ) override {}
    130130
    131131                  protected:
     
    913913                // of the error.  See C++ Reference 6.6 Jump Statements for details.
    914914                void InsertDtors::handleGoto( BranchStmt * stmt ) {
    915                         assert( stmt->get_target() != "" && "BranchStmt missing a label" );
     915                        // can't do anything for computed goto
     916                        if ( stmt->computedTarget ) return;
     917
     918                        assertf( stmt->get_target() != "", "BranchStmt missing a label: %s", toString( stmt ).c_str() );
    916919                        // S_L = lvars = set of objects in scope at label definition
    917920                        // S_G = curVars = set of objects in scope at goto statement
  • src/InitTweak/InitTweak.cc

    rbc3127d r5809461  
    497497                using Visitor::visit;
    498498
    499                 virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
    500                 virtual void visit( __attribute((unused)) UntypedExpr *untypedExpr ) { isConstExpr = false; }
    501                 virtual void visit( NameExpr *nameExpr ) {
    502                         // xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today
    503                         if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false;
    504                 }
     499                virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
     500                virtual void visit( UntypedExpr * ) { isConstExpr = false; }
     501                virtual void visit( NameExpr * ) { isConstExpr = false; }
    505502                // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
    506503                virtual void visit( AddressExpr *addressExpr ) {
     
    509506                        if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
    510507                }
    511                 virtual void visit( __attribute((unused)) LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
    512                 virtual void visit( __attribute((unused)) UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
    513                 virtual void visit( __attribute((unused)) MemberExpr *memberExpr ) { isConstExpr = false; }
    514                 virtual void visit( __attribute((unused)) VariableExpr *variableExpr ) { isConstExpr = false; }
     508                virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
     509                virtual void visit( MemberExpr * ) { isConstExpr = false; }
     510                virtual void visit( VariableExpr * ) { isConstExpr = false; }
    515511                // these might be okay?
    516512                // virtual void visit( SizeofExpr *sizeofExpr );
     
    523519                // virtual void visit( LogicalExpr *logicalExpr );
    524520                // virtual void visit( ConditionalExpr *conditionalExpr );
    525                 virtual void visit( __attribute((unused)) TypeExpr *typeExpr ) { isConstExpr = false; }
    526                 virtual void visit( __attribute((unused)) AsmExpr *asmExpr ) { isConstExpr = false; }
    527                 virtual void visit( __attribute((unused)) UntypedValofExpr *valofExpr ) { isConstExpr = false; }
    528                 virtual void visit( __attribute((unused)) CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
    529                 virtual void visit( __attribute((unused)) UntypedTupleExpr *tupleExpr ) { isConstExpr = false; }
    530                 virtual void visit( __attribute((unused)) TupleExpr *tupleExpr ) { isConstExpr = false; }
    531                 virtual void visit( __attribute((unused)) TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
     521                virtual void visit( TypeExpr * ) { isConstExpr = false; }
     522                virtual void visit( AsmExpr * ) { isConstExpr = false; }
     523                virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
     524                virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
     525                virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
     526                virtual void visit( TupleExpr * ) { isConstExpr = false; }
     527                virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
    532528
    533529                bool isConstExpr;
  • src/Parser/ExpressionNode.cc

    rbc3127d r5809461  
    230230        //      ret = new UntypedExpr( new NameExpr( units, ret ) );
    231231        // } // if
    232                
     232
    233233        delete &str;                                                                            // created by lex
    234234        return ret;
     
    282282} // build_varref
    283283
    284 
     284// TODO: get rid of this and OperKinds and reuse code from OperatorTable
    285285static const char * OperName[] = {                                              // must harmonize with OperKinds
    286286        // diadic
     
    290290        "?[?]", "...",
    291291        // monadic
    292         "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
     292        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
    293293}; // OperName
    294294
  • src/Parser/ParseNode.h

    rbc3127d r5809461  
    154154        Index, Range,
    155155        // monadic
    156         UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
     156        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
    157157        Ctor, Dtor,
    158158}; // OperKinds
  • src/Parser/parser.yy

    rbc3127d r5809461  
    536536                                $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
    537537                                break;
     538                          case OperKinds::And:
     539                                $$ = new ExpressionNode( new AddressExpr( build_addressOf( $2 ) ) );
     540                                break;
    538541                          default:
    539542                                assert( false );
     
    562565        | ATTR_IDENTIFIER '(' type ')'
    563566                { $$ = new ExpressionNode( build_attrtype( build_varref( $1 ), $3 ) ); }
    564 //      | ANDAND IDENTIFIER                                                                     // GCC, address of label
    565 //              { $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2 ) ); }
    566567        ;
    567568
  • src/ResolvExpr/AlternativeFinder.cc

    rbc3127d r5809461  
    698698
    699699        void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
    700                 {
    701                         std::string fname = InitTweak::getFunctionName( untypedExpr );
    702                         if ( fname == "&&" ) {
    703                                 VoidType v = Type::Qualifiers();                // resolve to type void *
    704                                 PointerType pt( Type::Qualifiers(), v.clone() );
    705                                 UntypedExpr *vexpr = untypedExpr->clone();
    706                                 vexpr->set_result( pt.clone() );
    707                                 alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
    708                                 return;
    709                         }
    710                 }
    711 
    712700                AlternativeFinder funcFinder( indexer, env );
    713701                funcFinder.findWithAdjustment( untypedExpr->get_function() );
     
    856844                        } // if
    857845                } // for
     846        }
     847
     848        void AlternativeFinder::visit( LabelAddressExpr * expr ) {
     849                alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) );
    858850        }
    859851
  • src/ResolvExpr/AlternativeFinder.h

    rbc3127d r5809461  
    5454                virtual void visit( UntypedExpr *untypedExpr );
    5555                virtual void visit( AddressExpr *addressExpr );
     56                virtual void visit( LabelAddressExpr *labelExpr );
    5657                virtual void visit( CastExpr *castExpr );
    5758                virtual void visit( VirtualCastExpr *castExpr );
  • src/SymTab/Indexer.cc

    rbc3127d r5809461  
    398398        void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
    399399                acceptNewScope( labAddressExpr->get_result(), *this );
    400                 maybeAccept( labAddressExpr->get_arg(), *this );
    401400        }
    402401
  • src/SymTab/Validate.cc

    rbc3127d r5809461  
    244244        };
    245245
     246        struct LabelAddressFixer final : public WithGuards {
     247                std::set< Label > labels;
     248
     249                void premutate( FunctionDecl * funcDecl );
     250                Expression * postmutate( AddressExpr * addrExpr );
     251        };
    246252
    247253        FunctionDecl * dereferenceOperator = nullptr;
     
    257263                PassVisitor<ValidateGenericParameters> genericParams;
    258264                PassVisitor<FindSpecialDeclarations> finder;
     265                PassVisitor<LabelAddressFixer> labelAddrFixer;
    259266
    260267                EliminateTypedef::eliminateTypedef( translationUnit );
     
    274281                ArrayLength::computeLength( translationUnit );
    275282                acceptAll( translationUnit, finder );
     283                mutateAll( translationUnit, labelAddrFixer );
    276284        }
    277285
     
    977985        }
    978986
     987        struct LabelFinder {
     988                std::set< Label > & labels;
     989                LabelFinder( std::set< Label > & labels ) : labels( labels ) {}
     990                void previsit( Statement * stmt ) {
     991                        for ( Label & l : stmt->labels ) {
     992                                labels.insert( l );
     993                        }
     994                }
     995        };
     996
     997        void LabelAddressFixer::premutate( FunctionDecl * funcDecl ) {
     998                GuardValue( labels );
     999                PassVisitor<LabelFinder> finder( labels );
     1000                funcDecl->accept( finder );
     1001        }
     1002
     1003        Expression * LabelAddressFixer::postmutate( AddressExpr * addrExpr ) {
     1004                // convert &&label into label address
     1005                if ( AddressExpr * inner = dynamic_cast< AddressExpr * >( addrExpr->arg ) ) {
     1006                        if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
     1007                                if ( labels.count( nameExpr->name ) ) {
     1008                                        Label name = nameExpr->name;
     1009                                        delete addrExpr;
     1010                                        return new LabelAddressExpr( name );
     1011                                }
     1012                        }
     1013                }
     1014                return addrExpr;
     1015        }
     1016
    9791017        void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
    9801018                if ( ! dereferenceOperator ) {
  • src/SynTree/AddressExpr.cc

    rbc3127d r5809461  
    7070}
    7171
     72LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {
     73        // label address always has type void *
     74        result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
     75}
     76LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
     77LabelAddressExpr::~LabelAddressExpr() {}
     78
     79void LabelAddressExpr::print( std::ostream & os, int indent ) const {
     80        os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
     81}
     82
    7283// Local Variables: //
    7384// tab-width: 4 //
  • src/SynTree/Expression.h

    rbc3127d r5809461  
    2424#include "Constant.h"             // for Constant
    2525#include "Initializer.h"          // for Designation (ptr only), Initializer
     26#include "Label.h"                // for Label
    2627#include "Mutator.h"              // for Mutator
    2728#include "SynTree.h"              // for UniqueId
     
    173174};
    174175
    175 // xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack
     176// GCC &&label
     177// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html
    176178class LabelAddressExpr : public Expression {
    177179  public:
    178         Expression * arg;
    179 
    180         LabelAddressExpr( Expression * arg );
     180        Label arg;
     181
     182        LabelAddressExpr( const Label &arg );
    181183        LabelAddressExpr( const LabelAddressExpr & other );
    182184        virtual ~LabelAddressExpr();
    183 
    184         Expression * get_arg() const { return arg; }
    185         void set_arg(Expression * newValue ) { arg = newValue; }
    186185
    187186        virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
  • src/SynTree/Mutator.cc

    rbc3127d r5809461  
    246246        labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
    247247        labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
    248         labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
    249248        return labelAddressExpr;
    250249}
  • src/SynTree/Visitor.cc

    rbc3127d r5809461  
    205205void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
    206206        maybeAccept( labAddressExpr->get_result(), *this );
    207         maybeAccept( labAddressExpr->get_arg(), *this );
    208207}
    209208
  • src/tests/dtor-early-exit.c

    rbc3127d r5809461  
    220220}
    221221
     222// TODO: implement __label__ and uncomment these lines
     223void computedGoto() {
     224  // __label__ bar;
     225  void *ptr;
     226  ptr = &&foo;
     227  goto *ptr;
     228  assert(false);
     229foo: ;
     230//   void f() {
     231//     ptr = &&bar;
     232//     goto *ptr;
     233//     assert(false);
     234//   }
     235//   f();
     236//   assert(false);
     237// bar: ;
     238}
     239
    222240int main() {
    223241        sepDisable(sout);
     
    229247        sout | endl;
    230248        h();
     249
     250        computedGoto();
    231251}
    232252
Note: See TracChangeset for help on using the changeset viewer.