Changeset de91427b


Ignore:
Timestamp:
Dec 18, 2015, 3:40:22 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
083cf31, 1cced28
Parents:
8762501
Message:

emit a compiler error if a void function returns a value or if a non-void returning function returns nothing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r8762501 rde91427b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Validate.cc -- 
     7// Validate.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Nov 20 16:33:52 2015
    13 // Update Count     : 201
     12// Last Modified On : Fri Dec 18 15:34:05 2015
     13// Update Count     : 218
    1414//
    1515
     
    6363                /// Flattens nested struct types
    6464                static void hoistStruct( std::list< Declaration * > &translationUnit );
    65  
     65
    6666                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    67  
     67
    6868                virtual void visit( StructDecl *aggregateDecl );
    6969                virtual void visit( UnionDecl *aggregateDecl );
     
    8686        };
    8787
    88         /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers
     88        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    8989        class Pass1 : public Visitor {
    9090                typedef Visitor Parent;
     
    107107
    108108                const Indexer *indexer;
    109  
     109
    110110                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    111111                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     
    132132
    133133                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    134  
     134
    135135                virtual void visit( EnumDecl *enumDecl );
    136136                virtual void visit( StructDecl *structDecl );
     
    142142                virtual void visit( FunctionType *ftype );
    143143                virtual void visit( PointerType *ftype );
    144  
     144
    145145                virtual void visit( CompoundStmt *compoundStmt );
    146146                virtual void visit( IfStmt *ifStmt );
     
    155155          private:
    156156                template< typename StmtClass > void visitStatement( StmtClass *stmt );
    157  
     157
    158158                std::list< Declaration * > declsToAdd;
    159159                std::set< std::string > structsDone;
     
    161161        };
    162162
     163        class ReturnChecker : public Visitor {
     164          public:
     165                /// Checks that return statements return nothing if their return type is void
     166                /// and return something if the return type is non-void.
     167                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
     168
     169          private:
     170                virtual void visit( FunctionDecl * functionDecl );
     171
     172                virtual void visit( ReturnStmt * returnStmt );
     173
     174                std::list< DeclarationWithType * > returnVals;
     175        };
     176
    163177        class EliminateTypedef : public Mutator {
    164178          public:
    165           EliminateTypedef() : scopeLevel( 0 ) {}
    166             /// Replaces typedefs by forward declarations
     179                EliminateTypedef() : scopeLevel( 0 ) {}
     180                /// Replaces typedefs by forward declarations
    167181                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    168182          private:
     
    196210                acceptAll( translationUnit, pass1 );
    197211                acceptAll( translationUnit, pass2 );
     212                ReturnChecker::checkFunctionReturns( translationUnit );
    198213                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    199214                acceptAll( translationUnit, pass3 );
    200215        }
    201        
     216
    202217        void validateType( Type *type, const Indexer *indexer ) {
    203218                Pass1 pass1;
     
    307322        void Pass1::visit( EnumDecl *enumDecl ) {
    308323                // Set the type of each member of the enumeration to be EnumConstant
    309  
     324
    310325                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    311326                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
     
    331346                                ++i;
    332347                                func->get_parameters().erase( j );
    333                                 if ( i != end ) { 
     348                                if ( i != end ) {
    334349                                        throw SemanticError( "invalid type void in function type ", func );
    335350                                } // if
     
    512527
    513528                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    514  
     529
    515530                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    516531                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    517  
     532
    518533                // do something special for unnamed members
    519534                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    520535                assignExpr->get_args().push_back( dstselect );
    521  
     536
    522537                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    523538                assignExpr->get_args().push_back( srcselect );
    524  
     539
    525540                *out++ = new ExprStmt( noLabels, assignExpr );
    526541        }
     
    529544        void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    530545                static UniqueName indexName( "_index" );
    531  
     546
    532547                // for a flexible array member nothing is done -- user must define own assignment
    533548                if ( ! array->get_dimension() ) return;
    534  
     549
    535550                ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    536551                *out++ = new DeclStmt( noLabels, index );
    537  
     552
    538553                UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    539554                init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     
    542557                std::list<Statement *> initList;
    543558                initList.push_back( initStmt );
    544  
     559
    545560                UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    546561                cond->get_args().push_back( new VariableExpr( index ) );
    547562                cond->get_args().push_back( array->get_dimension()->clone() );
    548  
     563
    549564                UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    550565                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    551  
     566
    552567                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    553  
     568
    554569                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    555570                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    556  
     571
    557572                Expression *dstselect = new MemberExpr( member, derefExpr );
    558573                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
     
    560575                dstIndex->get_args().push_back( new VariableExpr( index ) );
    561576                assignExpr->get_args().push_back( dstIndex );
    562  
     577
    563578                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    564579                UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     
    566581                srcIndex->get_args().push_back( new VariableExpr( index ) );
    567582                assignExpr->get_args().push_back( srcIndex );
    568  
     583
    569584                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    570585        }
    571586
    572         //E ?=?(E volatile*, int), 
     587        //E ?=?(E volatile*, int),
    573588        //  ?=?(E _Atomic volatile*, int);
    574589        void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    575590                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    576  
     591
    577592                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    578593                assignType->get_returnVals().push_back( returnVal );
     
    593608                // E ?=?(E volatile *, int)
    594609                assignType2->get_parameters().push_back( dstParam->clone() );
    595                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 
     610                BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    596611                ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    597612                assignType2->get_parameters().push_back( srcParam2 );
     
    645660                        structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    646661                }
    647  
     662
    648663                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    649664                assignType->get_returnVals().push_back( returnVal );
    650  
     665
    651666                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    652667                assignType->get_parameters().push_back( dstParam );
    653  
     668
    654669                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    655670                assignType->get_parameters().push_back( srcParam );
     
    659674                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    660675                assignDecl->fixUniqueId();
    661  
     676
    662677                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    663678                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    664                                 // query the type qualifiers of this field and skip assigning it if it is marked const. 
     679                                // query the type qualifiers of this field and skip assigning it if it is marked const.
    665680                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
    666681                                Type * type = dwt->get_type();
     
    682697                } // for
    683698                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    684  
     699
    685700                return assignDecl;
    686701        }
     
    697712                        unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    698713                }
    699  
     714
    700715                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    701716                assignType->get_returnVals().push_back( returnVal );
    702  
     717
    703718                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    704719                assignType->get_parameters().push_back( dstParam );
    705  
     720
    706721                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    707722                assignType->get_parameters().push_back( srcParam );
    708  
     723
    709724                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    710725                // because each unit generates copies of the default routines for each aggregate.
    711726                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    712727                assignDecl->fixUniqueId();
    713  
     728
    714729                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    715730                copy->get_args().push_back( new VariableExpr( dstParam ) );
     
    719734                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
    720735                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    721  
     736
    722737                return assignDecl;
    723738        }
     
    727742                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    728743                        // enumInst->set_baseEnum( enumDecl );
    729                         // declsToAdd.push_back( 
     744                        // declsToAdd.push_back(
    730745                        makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    731746                }
     
    836851        }
    837852
     853        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
     854                ReturnChecker checker;
     855                acceptAll( translationUnit, checker );
     856        }
     857
     858        void ReturnChecker::visit( FunctionDecl * functionDecl ) {
     859                std::list< DeclarationWithType * > oldReturnVals = returnVals;
     860                returnVals = functionDecl->get_functionType()->get_returnVals();
     861                Visitor::visit( functionDecl );
     862                returnVals = oldReturnVals;
     863        }
     864
     865        void ReturnChecker::visit( ReturnStmt * returnStmt ) {
     866                if ( returnStmt->get_expr() == NULL && returnVals.size() != 0 ) {
     867                        throw SemanticError( "Non-void function returns no values: " , returnStmt );
     868                } else if ( returnStmt->get_expr() != NULL && returnVals.size() == 0 ) {
     869                        throw SemanticError( "void function returns values: " , returnStmt );
     870                }
     871        }
     872
     873
    838874        bool isTypedef( Declaration *decl ) {
    839875                return dynamic_cast< TypedefDecl * >( decl );
     
    847883
    848884        Type *EliminateTypedef::mutate( TypeInstType * typeInst ) {
    849                 // instances of typedef types will come here. If it is an instance 
     885                // instances of typedef types will come here. If it is an instance
    850886                // of a typdef type, link the instance to its actual type.
    851887                TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     
    871907                Declaration *ret = Mutator::mutate( tyDecl );
    872908                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    873                         // typedef to the same name from the same scope 
     909                        // typedef to the same name from the same scope
    874910                        // must be from the same type
    875911
Note: See TracChangeset for help on using the changeset viewer.