Changeset 64ac636
- Timestamp:
- Mar 17, 2017, 1:14:07 PM (8 years ago)
- 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:
- b2f5082
- Parents:
- 1fbab5a
- Location:
- src
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r1fbab5a r64ac636 232 232 void handleFirstParam( Expression * firstParam ); 233 233 template< typename... Params > 234 void emit( const Params &... params );234 void emit( CodeLocation, const Params &... params ); 235 235 236 236 FunctionDecl * function = 0; 237 std::set< DeclarationWithType * > unhandled, usedUninit; 237 std::set< DeclarationWithType * > unhandled; 238 std::map< DeclarationWithType *, CodeLocation > usedUninit; 238 239 ObjectDecl * thisParam = 0; 239 240 bool isCtor = false; // true if current function is a constructor … … 336 337 GenStructMemberCalls warner; 337 338 acceptAll( translationUnit, warner ); 338 339 // visitor doesn't throw so that it can collect all errors340 if ( ! warner.errors.isEmpty() ) {341 throw warner.errors;342 }343 339 } 344 340 … … 940 936 ValueGuard< FunctionDecl * > oldFunction( funcDecl ); 941 937 ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled ); 942 ValueGuard< std:: set< DeclarationWithType *> > oldUsedUninit( usedUninit );938 ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit ); 943 939 ValueGuard< ObjectDecl * > oldThisParam( thisParam ); 944 940 ValueGuard< bool > oldIsCtor( isCtor ); 945 941 ValueGuard< StructDecl * > oldStructDecl( structDecl ); 942 errors = SemanticError(); // clear previous errors 946 943 947 944 // need to start with fresh sets … … 972 969 // remove the unhandled objects from usedUninit, because a call is inserted 973 970 // to handle them - only objects that are later constructed are used uninitialized. 974 std::set< DeclarationWithType * > diff; 975 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) ); 976 for ( DeclarationWithType * member : diff ) { 977 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" ); 971 std::map< DeclarationWithType *, CodeLocation > diff; 972 // need the comparator since usedUninit and unhandled have different types 973 struct comp_t { 974 typedef decltype(usedUninit)::value_type usedUninit_t; 975 typedef decltype(unhandled)::value_type unhandled_t; 976 bool operator()(usedUninit_t x, unhandled_t y) { return x.first < y; } 977 bool operator()(unhandled_t x, usedUninit_t y) { return x < y.first; } 978 } comp; 979 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ), comp ); 980 for ( auto p : diff ) { 981 DeclarationWithType * member = p.first; 982 CodeLocation loc = p.second; 983 // xxx - make error message better by also tracking the location that the object is constructed at? 984 emit( loc, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" ); 978 985 } 979 986 … … 1020 1027 } 1021 1028 } catch ( SemanticError & error ) { 1022 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" );1029 emit( funcDecl->location, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" ); 1023 1030 } 1024 1031 } 1025 1032 } 1026 1033 leaveScope(); 1034 } 1035 if (! errors.isEmpty()) { 1036 throw errors; 1027 1037 } 1028 1038 } … … 1079 1089 if ( unhandled.count( memberExpr->get_member() ) ) { 1080 1090 // emit a warning because a member was used before it was constructed 1081 usedUninit.insert( memberExpr->get_member());1091 usedUninit.insert( { memberExpr->get_member(), memberExpr->location } ); 1082 1092 } 1083 1093 } … … 1089 1099 1090 1100 template< typename Visitor, typename... Params > 1091 void error( Visitor & v, const Params &... params ) { 1092 v.errors.append( toString( params... ) ); 1101 void error( Visitor & v, CodeLocation loc, const Params &... params ) { 1102 SemanticError err( toString( params... ) ); 1103 err.set_location( loc ); 1104 v.errors.append( err ); 1093 1105 } 1094 1106 1095 1107 template< typename... Params > 1096 void GenStructMemberCalls::emit( const Params &... params ) {1108 void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) { 1097 1109 // toggle warnings vs. errors here. 1098 1110 // warn( params... ); 1099 error( *this, params... );1111 error( *this, loc, params... ); 1100 1112 } 1101 1113 -
src/Parser/ExpressionNode.cc
r1fbab5a r64ac636 254 254 Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) { 255 255 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 256 deref->location = expr_node->location; 256 257 deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) ); 257 258 UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref ); -
src/Parser/ParseNode.h
r1fbab5a r64ac636 134 134 Expression * p = orig->build(); 135 135 p->set_extension( orig->get_extension() ); 136 p->location = orig->location; 136 137 return p; 137 138 } else { -
src/ResolvExpr/AlternativeFinder.cc
r1fbab5a r64ac636 200 200 } 201 201 202 // Central location to handle gcc extension keyword for all expression types.202 // Central location to handle gcc extension keyword, etc. for all expression types. 203 203 for ( Alternative &iter: alternatives ) { 204 204 iter.expr->set_extension( expr->get_extension() ); 205 iter.expr->location = expr->location; 205 206 } // for 206 207 } -
src/SynTree/Declaration.cc
r1fbab5a r64ac636 32 32 33 33 Declaration::Declaration( const Declaration &other ) 34 : name( other.name ), storageClasses( other.storageClasses ), linkage( other.linkage ), uniqueId( other.uniqueId ) {34 : BaseSyntaxNode( other ), name( other.name ), storageClasses( other.storageClasses ), linkage( other.linkage ), uniqueId( other.uniqueId ) { 35 35 } 36 36 -
src/SynTree/Expression.cc
r1fbab5a r64ac636 33 33 Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {} 34 34 35 Expression::Expression( const Expression &other ) : result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {35 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) { 36 36 } 37 37 -
src/SynTree/Initializer.cc
r1fbab5a r64ac636 20 20 21 21 Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {} 22 Initializer::Initializer( const Initializer & other ) : maybeConstructed( other.maybeConstructed ) {22 Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) { 23 23 } 24 24 -
src/SynTree/Initializer.h
r1fbab5a r64ac636 112 112 // ConstructorInit represents an initializer that is either a constructor expression or 113 113 // a C-style initializer. 114 // It should not be necessary to create ConstructorInit nodes manually. Instead, set maybeConstructed 115 // to true on SingleInit or ListInit constructors if object should be constructed. 114 116 class ConstructorInit : public Initializer { 115 117 public: -
src/SynTree/Type.cc
r1fbab5a r64ac636 49 49 Type::Type( const Qualifiers &tq, const std::list< Attribute * > & attributes ) : tq( tq ), attributes( attributes ) {} 50 50 51 Type::Type( const Type &other ) : tq( other.tq ) {51 Type::Type( const Type &other ) : BaseSyntaxNode( other ), tq( other.tq ) { 52 52 cloneAll( other.forall, forall ); 53 53 cloneAll( other.attributes, attributes ); … … 75 75 printAll( attributes, os, indent+4 ); 76 76 } // if 77 77 78 78 tq.print( os ); 79 79 } -
src/Tuples/TupleExpansion.cc
r1fbab5a r64ac636 126 126 /// given a expression representing the member and an expression representing the aggregate, 127 127 /// reconstructs a flattened UntypedMemberExpr with the right precedence 128 Expression * reconstructMemberExpr( Expression * member, Expression * aggr ) {128 Expression * reconstructMemberExpr( Expression * member, Expression * aggr, CodeLocation & loc ) { 129 129 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( member ) ) { 130 130 // construct a new UntypedMemberExpr with the correct structure , and recursively 131 131 // expand that member expression. 132 132 MemberTupleExpander expander; 133 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() ) ); 134 133 UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() ); 134 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), inner ); 135 inner->location = newMemberExpr->location = loc; 135 136 memberExpr->set_member(nullptr); 136 137 memberExpr->set_aggregate(nullptr); … … 139 140 } else { 140 141 // not a member expression, so there is nothing to do but attach and return 141 return new UntypedMemberExpr( member, aggr->clone() ); 142 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( member, aggr->clone() ); 143 newMemberExpr->location = loc; 144 return newMemberExpr; 142 145 } 143 146 } … … 152 155 aggr = new UniqueExpr( aggr ); 153 156 for ( Expression *& expr : tupleExpr->get_exprs() ) { 154 expr = reconstructMemberExpr( expr, aggr ); 157 expr = reconstructMemberExpr( expr, aggr, memberExpr->location ); 158 expr->location = memberExpr->location; 155 159 } 156 160 delete aggr; 161 tupleExpr->location = memberExpr->location; 157 162 return tupleExpr; 158 163 } else { 159 164 // there may be a tuple expr buried in the aggregate 160 165 // xxx - this is a memory leak 161 return new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) ); 166 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) ); 167 newMemberExpr->location = memberExpr->location; 168 return newMemberExpr; 162 169 } 163 170 } -
src/tests/.expect/memberCtors-ERR1.txt
r1fbab5a r64ac636 1 error: in void ?{}(struct B *b), field a2 used before being constructed1 memberCtors.c:62 error: in void ?{}(struct B *b), field a2 used before being constructed 2 2 make: *** [memberCtors-ERR1] Error 1
Note: See TracChangeset
for help on using the changeset viewer.