Changes in / [dbc733e:ba2a68b]
- Location:
- src
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rdbc733e rba2a68b 546 546 extension( addressExpr ); 547 547 output << "(&"; 548 addressExpr->arg->accept( *this ); 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 549 554 output << ")"; 550 }551 552 void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {553 extension( addressExpr );554 output << "(&&" << addressExpr->arg << ")";555 555 } 556 556 -
src/CodeGen/CodeGenerator.h
rdbc733e rba2a68b 59 59 virtual void visit( NameExpr *nameExpr ); 60 60 virtual void visit( AddressExpr *addressExpr ); 61 virtual void visit( LabelAddressExpr *addressExpr );62 61 virtual void visit( CastExpr *castExpr ); 63 62 virtual void visit( VirtualCastExpr *castExpr ); -
src/CodeGen/OperatorTable.cc
rdbc733e rba2a68b 66 66 { "?^=?", "^=", "_operator_bitxorassign", OT_INFIXASSIGN }, 67 67 { "?|=?", "|=", "_operator_bitorassign", OT_INFIXASSIGN }, 68 { "&&", "&&", "&&", OT_LABELADDRESS } 68 69 }; 69 70 -
src/InitTweak/FixInit.cc
rdbc733e rba2a68b 127 127 128 128 // don't go into other functions 129 virtual void visit( FunctionDecl *) override {}129 virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {} 130 130 131 131 protected: … … 913 913 // of the error. See C++ Reference 6.6 Jump Statements for details. 914 914 void InsertDtors::handleGoto( BranchStmt * stmt ) { 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() ); 915 assert( stmt->get_target() != "" && "BranchStmt missing a label" ); 919 916 // S_L = lvars = set of objects in scope at label definition 920 917 // S_G = curVars = set of objects in scope at goto statement -
src/InitTweak/InitTweak.cc
rdbc733e rba2a68b 497 497 using Visitor::visit; 498 498 499 virtual void visit( ApplicationExpr * ) { isConstExpr = false; } 500 virtual void visit( UntypedExpr * ) { isConstExpr = false; } 501 virtual void visit( NameExpr * ) { isConstExpr = false; } 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 } 502 505 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 503 506 virtual void visit( AddressExpr *addressExpr ) { … … 506 509 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 507 510 } 508 virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; } 509 virtual void visit( MemberExpr * ) { isConstExpr = false; } 510 virtual void visit( VariableExpr * ) { isConstExpr = false; } 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; } 511 515 // these might be okay? 512 516 // virtual void visit( SizeofExpr *sizeofExpr ); … … 519 523 // virtual void visit( LogicalExpr *logicalExpr ); 520 524 // virtual void visit( ConditionalExpr *conditionalExpr ); 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; }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; } 528 532 529 533 bool isConstExpr; -
src/Parser/ExpressionNode.cc
rdbc733e rba2a68b 230 230 // ret = new UntypedExpr( new NameExpr( units ), { ret } ); 231 231 // } // if 232 232 233 233 delete &str; // created by lex 234 234 return ret; … … 282 282 } // build_varref 283 283 284 // TODO: get rid of this and OperKinds and reuse code from OperatorTable 284 285 285 static const char * OperName[] = { // must harmonize with OperKinds 286 286 // diadic … … 290 290 "?[?]", "...", 291 291 // monadic 292 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", 292 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&" 293 293 }; // OperName 294 294 -
src/Parser/ParseNode.h
rdbc733e rba2a68b 154 154 Index, Range, 155 155 // monadic 156 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, 156 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress, 157 157 Ctor, Dtor, 158 158 }; // OperKinds -
src/Parser/parser.yy
rdbc733e rba2a68b 536 536 $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); 537 537 break; 538 case OperKinds::And:539 $$ = new ExpressionNode( new AddressExpr( build_addressOf( $2 ) ) );540 break;541 538 default: 542 539 assert( false ); … … 565 562 | ATTR_IDENTIFIER '(' type ')' 566 563 { $$ = 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 ) ); } 567 566 ; 568 567 -
src/ResolvExpr/AlternativeFinder.cc
rdbc733e rba2a68b 698 698 699 699 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 700 712 AlternativeFinder funcFinder( indexer, env ); 701 713 funcFinder.findWithAdjustment( untypedExpr->get_function() ); … … 844 856 } // if 845 857 } // for 846 }847 848 void AlternativeFinder::visit( LabelAddressExpr * expr ) {849 alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) );850 858 } 851 859 -
src/ResolvExpr/AlternativeFinder.h
rdbc733e rba2a68b 54 54 virtual void visit( UntypedExpr *untypedExpr ); 55 55 virtual void visit( AddressExpr *addressExpr ); 56 virtual void visit( LabelAddressExpr *labelExpr );57 56 virtual void visit( CastExpr *castExpr ); 58 57 virtual void visit( VirtualCastExpr *castExpr ); -
src/SymTab/Indexer.cc
rdbc733e rba2a68b 398 398 void Indexer::visit( LabelAddressExpr *labAddressExpr ) { 399 399 acceptNewScope( labAddressExpr->get_result(), *this ); 400 maybeAccept( labAddressExpr->get_arg(), *this ); 400 401 } 401 402 -
src/SymTab/Validate.cc
rdbc733e rba2a68b 244 244 }; 245 245 246 struct LabelAddressFixer final : public WithGuards {247 std::set< Label > labels;248 249 void premutate( FunctionDecl * funcDecl );250 Expression * postmutate( AddressExpr * addrExpr );251 };252 246 253 247 FunctionDecl * dereferenceOperator = nullptr; … … 263 257 PassVisitor<ValidateGenericParameters> genericParams; 264 258 PassVisitor<FindSpecialDeclarations> finder; 265 PassVisitor<LabelAddressFixer> labelAddrFixer;266 259 267 260 EliminateTypedef::eliminateTypedef( translationUnit ); … … 281 274 ArrayLength::computeLength( translationUnit ); 282 275 acceptAll( translationUnit, finder ); 283 mutateAll( translationUnit, labelAddrFixer );284 276 } 285 277 … … 985 977 } 986 978 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 address1005 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 1017 979 void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) { 1018 980 if ( ! dereferenceOperator ) { -
src/SynTree/AddressExpr.cc
rdbc733e rba2a68b 70 70 } 71 71 72 LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {73 // label address always has type void *74 result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );75 }76 LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}77 LabelAddressExpr::~LabelAddressExpr() {}78 79 void LabelAddressExpr::print( std::ostream & os, int indent ) const {80 os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;81 }82 83 72 // Local Variables: // 84 73 // tab-width: 4 // -
src/SynTree/Expression.h
rdbc733e rba2a68b 24 24 #include "Constant.h" // for Constant 25 25 #include "Initializer.h" // for Designation (ptr only), Initializer 26 #include "Label.h" // for Label27 26 #include "Mutator.h" // for Mutator 28 27 #include "SynTree.h" // for UniqueId … … 174 173 }; 175 174 176 // GCC &&label 177 // https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html 175 // xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack 178 176 class LabelAddressExpr : public Expression { 179 177 public: 180 Labelarg;181 182 LabelAddressExpr( const Label &arg );178 Expression * arg; 179 180 LabelAddressExpr( Expression * arg ); 183 181 LabelAddressExpr( const LabelAddressExpr & other ); 184 182 virtual ~LabelAddressExpr(); 183 184 Expression * get_arg() const { return arg; } 185 void set_arg(Expression * newValue ) { arg = newValue; } 185 186 186 187 virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); } -
src/SynTree/Mutator.cc
rdbc733e rba2a68b 246 246 labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) ); 247 247 labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) ); 248 labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) ); 248 249 return labelAddressExpr; 249 250 } -
src/SynTree/Statement.cc
rdbc733e rba2a68b 89 89 90 90 BranchStmt::BranchStmt( std::list<Label> labels, Label target, Type type ) throw ( SemanticError ) : 91 Statement( labels ), originalTarget( target ), target( target ), computedTarget( nullptr), type( type ) {91 Statement( labels ), originalTarget( target ), target( target ), computedTarget( NULL ), type( type ) { 92 92 //actually this is a syntactic error signaled by the parser 93 if ( type == BranchStmt::Goto && target.empty() ) {93 if ( type == BranchStmt::Goto && target.empty() ) 94 94 throw SemanticError("goto without target"); 95 }96 95 } 97 96 98 97 BranchStmt::BranchStmt( std::list<Label> labels, Expression *computedTarget, Type type ) throw ( SemanticError ) : 99 98 Statement( labels ), computedTarget( computedTarget ), type( type ) { 100 if ( type != BranchStmt::Goto || computedTarget == nullptr ) {99 if ( type != BranchStmt::Goto || computedTarget == 0 ) 101 100 throw SemanticError("Computed target not valid in branch statement"); 102 }103 101 } 104 102 105 103 void BranchStmt::print( std::ostream &os, int indent ) const { 106 104 os << string( indent, ' ' ) << "Branch (" << brType[type] << ")" << endl ; 107 if ( target != "" ) os << string( indent+2, ' ' ) << "with target: " << target << endl;108 if ( originalTarget != "" ) os << string( indent+2, ' ' ) << "with original target: " << originalTarget << endl;109 if ( computedTarget != nullptr ) os << string( indent+2, ' ' ) << "with computed target: " << computedTarget << endl;110 105 } 111 106 -
src/SynTree/Visitor.cc
rdbc733e rba2a68b 205 205 void Visitor::visit( LabelAddressExpr *labAddressExpr ) { 206 206 maybeAccept( labAddressExpr->get_result(), *this ); 207 maybeAccept( labAddressExpr->get_arg(), *this ); 207 208 } 208 209 -
src/tests/.expect/dtor-early-exit-ERR1.txt
rdbc733e rba2a68b 1 1 dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto) 2 with target: L13 with original target: L14 2 -
src/tests/.expect/dtor-early-exit-ERR2.txt
rdbc733e rba2a68b 1 1 dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto) 2 with target: L23 with original target: L24 2 -
src/tests/dtor-early-exit.c
rdbc733e rba2a68b 220 220 } 221 221 222 // TODO: implement __label__ and uncomment these lines223 void computedGoto() {224 // __label__ bar;225 void *ptr;226 ptr = &&foo;227 goto *ptr;228 assert(false);229 foo: ;230 // void f() {231 // ptr = &&bar;232 // goto *ptr;233 // assert(false);234 // }235 // f();236 // assert(false);237 // bar: ;238 }239 240 222 int main() { 241 223 sepDisable(sout); … … 247 229 sout | endl; 248 230 h(); 249 250 computedGoto();251 231 } 252 232
Note: See TracChangeset
for help on using the changeset viewer.