Changes in / [f39096c:0555f4b]


Ignore:
Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/GenType.h

    rf39096c r0555f4b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenType.h -- 
     7// GenType.h --
    88//
    99// Author           : Richard C. Bilson
  • src/Common/utility.h

    rf39096c r0555f4b  
    144144
    145145template < typename T >
    146 std::string toString ( T value ) {
     146void toString_single ( std::ostream & os, const T & value ) {
     147        os << value;
     148}
     149
     150template < typename T, typename... Params >
     151void toString_single ( std::ostream & os, const T & value, const Params & ... params ) {
     152        os << value;
     153        toString_single( os, params ... );
     154}
     155
     156template < typename ... Params >
     157std::string toString ( const Params & ... params ) {
    147158        std::ostringstream os;
    148         os << value; // << std::ends;
     159        toString_single( os, params... );
    149160        return os.str();
    150161}
     
    218229}
    219230
     231template< typename T >
     232void warn_single( const T & arg ) {
     233        std::cerr << arg << std::endl;
     234}
     235
     236template< typename T, typename... Params >
     237void warn_single(const T & arg, const Params & ... params ) {
     238        std::cerr << arg;
     239        warn_single( params... );
     240}
     241
     242template< typename... Params >
     243void warn( const Params & ... params ) {
     244        std::cerr << "Warning: ";
     245        warn_single( params... );
     246}
     247
    220248#endif // _UTILITY_H
    221249
  • src/InitTweak/FixInit.cc

    rf39096c r0555f4b  
    3333#include "GenPoly/PolyMutator.h"
    3434#include "SynTree/AddStmtVisitor.h"
     35#include "CodeGen/GenType.h"  // for warnings
    3536
    3637bool ctordtorp = false;
     
    174175                        virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr );
    175176                };
     177
     178                class WarnStructMembers : public Visitor {
     179                  public:
     180                        typedef Visitor Parent;
     181                        /// warn if a user-defined constructor or destructor is missing calls for
     182                        /// a struct member or if a member is used before constructed
     183                        static void warnings( std::list< Declaration * > & translationUnit );
     184
     185                        virtual void visit( FunctionDecl * funcDecl );
     186
     187                        virtual void visit( MemberExpr * memberExpr );
     188                        virtual void visit( ApplicationExpr * appExpr );
     189
     190                  private:
     191                        void handleFirstParam( Expression * firstParam );
     192
     193                        FunctionDecl * function = 0;
     194                        std::set< DeclarationWithType * > unhandled;
     195                        ObjectDecl * thisParam = 0;
     196                };
    176197        } // namespace
    177198
     
    187208                // FixCopyCtors must happen after FixInit, so that destructors are placed correctly
    188209                FixCopyCtors::fixCopyCtors( translationUnit );
     210
     211                WarnStructMembers::warnings( translationUnit );
    189212        }
    190213
     
    231254                }
    232255
     256                void WarnStructMembers::warnings( std::list< Declaration * > & translationUnit ) {
     257                        if ( true ) { // fix this condition to skip this pass if warnings aren't enabled
     258                                WarnStructMembers warner;
     259                                acceptAll( translationUnit, warner );
     260                        }
     261                }
     262
    233263                Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    234264                        appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
     
    242272                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    243273                                        assert( ftype );
    244                                         if ( (funcDecl->get_name() == "?{}" || funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) {
     274                                        if ( (isConstructor( funcDecl->get_name() ) || funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) {
    245275                                                Type * t1 = ftype->get_parameters().front()->get_type();
    246276                                                Type * t2 = ftype->get_parameters().back()->get_type();
     
    253283                                                        return appExpr;
    254284                                                } // if
    255                                         } else if ( funcDecl->get_name() == "^?{}" ) {
     285                                        } else if ( isDestructor( funcDecl->get_name() ) ) {
    256286                                                // correctness: never copy construct arguments to a destructor
    257287                                                return appExpr;
     
    670700                        } // switch
    671701                }
     702
     703                bool checkWarnings( FunctionDecl * funcDecl ) {
     704                        // only check for warnings if the current function is a user-defined
     705                        // constructor or destructor
     706                        if ( ! funcDecl ) return false;
     707                        if ( ! funcDecl->get_statements() ) return false;
     708                        return isCtorDtor( funcDecl->get_name() ) && ! LinkageSpec::isOverridable( funcDecl->get_linkage() );
     709                }
     710
     711                void WarnStructMembers::visit( FunctionDecl * funcDecl ) {
     712                        WarnStructMembers old = *this;
     713                        *this = WarnStructMembers();
     714
     715                        function = funcDecl;
     716                        if ( checkWarnings( funcDecl ) ) {
     717                                FunctionType * type = funcDecl->get_functionType();
     718                                assert( ! type->get_parameters().empty() );
     719                                thisParam = safe_dynamic_cast< ObjectDecl * >( type->get_parameters().front() );
     720                                PointerType * ptrType = safe_dynamic_cast< PointerType * > ( thisParam->get_type() );
     721                                StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() );
     722                                if ( structType ) {
     723                                        StructDecl * structDecl = structType->get_baseStruct();
     724                                        for ( Declaration * member : structDecl->get_members() ) {
     725                                                if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     726                                                        // record all of the struct type's members that need to be constructed or
     727                                                        // destructed by the end of the function
     728                                                        unhandled.insert( field );
     729                                                }
     730                                        }
     731                                }
     732                        }
     733                        Parent::visit( funcDecl );
     734
     735                        for ( DeclarationWithType * member : unhandled ) {
     736                                // emit a warning for each unhandled member
     737                                warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name() ), ", member ", member->get_name(), " may not have been ", isConstructor( funcDecl->get_name() ) ? "constructed" : "destructed" );
     738                        }
     739
     740                        *this = old;
     741                }
     742
     743                void WarnStructMembers::visit( ApplicationExpr * appExpr ) {
     744                        if ( ! checkWarnings( function ) ) return;
     745
     746                        std::string fname = getFunctionName( appExpr );
     747                        if ( fname == function->get_name() ) {
     748                                // call to same kind of function
     749                                Expression * firstParam = appExpr->get_args().front();
     750
     751                                if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( firstParam ) ) {
     752                                        // if calling another constructor on thisParam, assume that function handles
     753                                        // all members - if it doesn't a warning will appear in that function.
     754                                        if ( varExpr->get_var() == thisParam ) {
     755                                                unhandled.clear();
     756                                        }
     757                                } else {
     758                                        // if first parameter is a member expression then
     759                                        // remove the member from unhandled set.
     760                                        handleFirstParam( firstParam );
     761                                }
     762                        } else if ( fname == "?=?" && isIntrinsicCallExpr( appExpr ) ) {
     763                                // forgive use of intrinsic assignment to construct, since instrinsic constructors
     764                                // codegen as assignment anyway.
     765                                assert( appExpr->get_args().size() == 2 );
     766                                handleFirstParam( appExpr->get_args().front() );
     767                        }
     768
     769                        Parent::visit( appExpr );
     770                }
     771
     772                void WarnStructMembers::handleFirstParam( Expression * firstParam ) {
     773                        using namespace std;
     774                        if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( firstParam ) ) {
     775                                if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( addrExpr->get_arg() ) ) {
     776                                        if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
     777                                                if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
     778                                                        if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
     779                                                                if ( varExpr->get_var() == thisParam ) {
     780                                                                        unhandled.erase( memberExpr->get_member() );
     781                                                                }
     782                                                        }
     783                                                }
     784                                        }
     785                                }
     786                        }
     787                }
     788
     789                void WarnStructMembers::visit( MemberExpr * memberExpr ) {
     790                        if ( ! checkWarnings( function ) ) return;
     791                        if ( ! isConstructor( function->get_name() ) );
     792
     793                        if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
     794                                if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
     795                                        if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
     796                                                if ( varExpr->get_var() == thisParam ) {
     797                                                        if ( unhandled.count( memberExpr->get_member() ) ) {
     798                                                                // emit a warning because a member was used before it was constructed
     799                                                                warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name() ), ", member ", memberExpr->get_member()->get_name(), " used before being constructed" );
     800                                                        }
     801                                                }
     802                                        }
     803                                }
     804                        }
     805                        Parent::visit( memberExpr );
     806                }
    672807        } // namespace
    673808} // namespace InitTweak
  • src/InitTweak/InitTweak.cc

    rf39096c r0555f4b  
    291291        }
    292292
     293        namespace {
     294                template <typename Predicate>
     295                bool allofCtorDtor( Statement * stmt, const Predicate & pred ) {
     296                        std::list< Expression * > callExprs;
     297                        collectCtorDtorCalls( stmt, callExprs );
     298                        // if ( callExprs.empty() ) return false; // xxx - do I still need this check?
     299                        return std::all_of( callExprs.begin(), callExprs.end(), pred);
     300                }
     301        }
     302
    293303        bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
    294                 std::list< Expression * > callExprs;
    295                 collectCtorDtorCalls( stmt, callExprs );
    296                 // if ( callExprs.empty() ) return false; // xxx - do I still need this check?
    297                 return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){
     304                return allofCtorDtor( stmt, []( Expression * callExpr ){
    298305                        if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
    299306                                assert( ! appExpr->get_function()->get_results().empty() );
     
    303310                        }
    304311                        return false;
     312                });
     313        }
     314
     315        bool isIntrinsicCallStmt( Statement * stmt ) {
     316                return allofCtorDtor( stmt, []( Expression * callExpr ) {
     317                        return isIntrinsicCallExpr( callExpr );
    305318                });
    306319        }
     
    420433        }
    421434
     435        bool isConstructor( const std::string & str ) { return str == "?{}"; }
     436        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
     437        bool isCtorDtor( const std::string & str ) { return isConstructor( str ) || isDestructor( str ); }
    422438}
  • src/InitTweak/InitTweak.h

    rf39096c r0555f4b  
    2626// helper functions for initialization
    2727namespace InitTweak {
     28        bool isConstructor( const std::string & );
     29        bool isDestructor( const std::string & );
     30        bool isCtorDtor( const std::string & );
     31
    2832        /// transform Initializer into an argument list that can be passed to a call expression
    2933        std::list< Expression * > makeInitList( Initializer * init );
     
    4145        /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
    4246        /// Currently has assertions that make it less than fully general.
    43         bool isIntrinsicSingleArgCallStmt( Statement * expr );
     47        bool isIntrinsicSingleArgCallStmt( Statement * stmt );
     48
     49        /// True if stmt is a call statement where the function called is intrinsic.
     50        bool isIntrinsicCallStmt( Statement * stmt );
    4451
    4552        /// get all Ctor/Dtor call expressions from a Statement
  • src/Parser/LinkageSpec.cc

    rf39096c r0555f4b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // LinkageSpec.cc -- 
    8 // 
     7// LinkageSpec.cc --
     8//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:22:09 2015
     
    1212// Last Modified On : Sun Aug 21 12:32:53 2016
    1313// Update Count     : 17
    14 // 
     14//
    1515
    1616#include <string>
     
    3232
    3333std::string LinkageSpec::toString( LinkageSpec::Spec linkage ) {
     34        assert( linkage >= 0 && linkage < LinkageSpec::NoOfSpecs );
    3435        static const char *linkageKinds[LinkageSpec::NoOfSpecs] = {
    3536                "intrinsic", "Cforall", "C", "automatically generated", "compiler built-in",
     
    3940
    4041bool LinkageSpec::isDecoratable( Spec spec ) {
     42        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
    4143        static bool decoratable[LinkageSpec::NoOfSpecs] = {
    4244                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler
    43                         true,           true,           false,  true,           false, 
     45                        true,           true,           false,  true,           false,
    4446        };
    4547        return decoratable[spec];
     
    4749
    4850bool LinkageSpec::isGeneratable( Spec spec ) {
     51        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
    4952        static bool generatable[LinkageSpec::NoOfSpecs] = {
    5053                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler
    51                         true,           true,           true,   true,           false, 
     54                        true,           true,           true,   true,           false,
    5255        };
    5356        return generatable[spec];
     
    5558
    5659bool LinkageSpec::isOverridable( Spec spec ) {
     60        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
    5761        static bool overridable[LinkageSpec::NoOfSpecs] = {
    5862                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler
    59                         true,           false,          false,  true,           false, 
     63                        true,           false,          false,  true,           false,
    6064        };
    6165        return overridable[spec];
     
    6367
    6468bool LinkageSpec::isBuiltin( Spec spec ) {
     69        assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );
    6570        static bool builtin[LinkageSpec::NoOfSpecs] = {
    6671                //      Intrinsic,      Cforall,        C,              AutoGen,        Compiler
    67                         true,           false,          false,  false,          true, 
     72                        true,           false,          false,  false,          true,
    6873        };
    6974        return builtin[spec];
  • src/ResolvExpr/AlternativeFinder.cc

    rf39096c r0555f4b  
    244244                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    245245                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    246                                 alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
     246                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    247247                                renameTypes( alternatives.back().expr );
    248248                        } else {
     
    418418        // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included
    419419        //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;
    420        
     420
    421421        static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
    422422        //static const unsigned recursionParentLimit = 1;  ///< Limit to the number of times an assertion can recursively use itself
     
    429429                }
    430430        }
    431        
     431
    432432        template< typename ForwardIterator, typename OutputIterator >
    433         void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 
     433        void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/
    434434                                                 int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    435435                if ( begin == end ) {
     
    469469                                std::cerr << std::endl;
    470470                        )
    471                        
     471
    472472                        AssertionSet newHave, newerNeed( newNeed );
    473473                        TypeEnvironment newEnv( newAlt.env );
     
    847847                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    848848                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    849                                 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) );
     849                                alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) );
    850850                                renameTypes( alternatives.back().expr );
    851851                        } else {
  • src/ResolvExpr/Resolver.cc

    rf39096c r0555f4b  
    446446                } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
    447447                        resolveAggrInit( st->get_baseStruct(), iter, end );
    448                 } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) {
     448                } else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {
    449449                        resolveAggrInit( st->get_baseUnion(), iter, end );
     450                } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     451                        Type * base = tt->get_baseType()->get_base();
     452                        if ( base ) {
     453                                // know the implementation type, so try using that as the initContext
     454                                initContext = base;
     455                                visit( listInit );
     456                        } else {
     457                                // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     458                                Visitor::visit( listInit );
     459                        }
    450460                } else {
     461                        assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) );
    451462                        // basic types are handled here
    452463                        Visitor::visit( listInit );
     
    539550                }
    540551
    541                 // xxx - todo
    542                 // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
    543                 //      // can reduce the constructor down to a SingleInit using the
    544                 //      // second argument from the ctor call
    545                 // }
    546 
    547552                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
    548553                        delete ctorInit->get_dtor();
    549554                        ctorInit->set_dtor( NULL );
    550555                }
     556
     557                // xxx - todo -- what about arrays?
     558                // if ( dtor == NULL && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
     559                //      // can reduce the constructor down to a SingleInit using the
     560                //      // second argument from the ctor call, since
     561                //      delete ctorInit->get_ctor();
     562                //      ctorInit->set_ctor( NULL );
     563
     564                //      Expression * arg =
     565                //      ctorInit->set_init( new SingleInit( arg ) );
     566                // }
    551567        }
    552568} // namespace ResolvExpr
  • src/ResolvExpr/TypeEnvironment.cc

    rf39096c r0555f4b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeEnvironment.cc -- 
     7// TypeEnvironment.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2323
    2424namespace ResolvExpr {
     25        // adding this comparison operator significantly improves assertion resolution run time for
     26        // some cases. The current resolution algorithm's speed partially depends on the order of
     27        // assertions. Assertions which have fewer possible matches should appear before
     28        // assertions which have more possible matches. This seems to imply that this could
     29        // be further improved by providing an indexer as an additional argument and ordering based
     30        // on the number of matches of the same kind (object, function) for the names of the
     31        // declarations.
     32        //
     33        // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
     34        bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) {
     35                        // Objects are always less than functions
     36                        if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {
     37                                if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {
     38                                        // objects are ordered by name then type pointer, in that order
     39                                        int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );
     40                                        return cmp < 0 ||
     41                                                ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );
     42                                } else {
     43                                        return true;
     44                                }
     45                        } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {
     46                                if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {
     47                                        // functions are ordered by name, # parameters, # returnVals, type pointer in that order
     48                                        FunctionType * ftype1 = funcDecl1->get_functionType();
     49                                        FunctionType * ftype2 = funcDecl2->get_functionType();
     50                                        int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();
     51                                        int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();
     52                                        if ( numThings1 < numThings2 ) return true;
     53                                        if ( numThings1 > numThings2 ) return false;
     54
     55                                        // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;
     56                                        // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;
     57                                        // // same number of parameters
     58                                        // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;
     59                                        // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;
     60                                        // same number of return vals
     61                                        // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
     62                                        // if ( cmp < 0 ) return true;
     63                                        // else if ( cmp > 0 ) return false;
     64                                        // // same name
     65                                        return ftype1 < ftype2;
     66                                } else {
     67                                        return false;
     68                                }
     69                        } else {
     70                                assert( false );
     71                        }
     72                }
     73
    2574        void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
    2675                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
  • src/ResolvExpr/TypeEnvironment.h

    rf39096c r0555f4b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeEnvironment.h -- 
     7// TypeEnvironment.h --
    88//
    99// Author           : Richard C. Bilson
     
    2828
    2929namespace ResolvExpr {
    30         typedef std::map< DeclarationWithType*, bool > AssertionSet;
     30        struct AssertCompare {
     31                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 );
     32        };
     33        typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
    3134        typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
    3235
     
    3942                bool allowWidening;
    4043                TypeDecl::Kind kind;
    41  
     44
    4245                void initialize( const EqvClass &src, EqvClass &dest );
    4346                EqvClass();
     
    6265                void extractOpenVars( OpenVarSet &openVars ) const;
    6366                TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
    64  
     67
    6568                typedef std::list< EqvClass >::iterator iterator;
    6669                iterator begin() { return env.begin(); }
  • src/ResolvExpr/Unify.cc

    rf39096c r0555f4b  
    484484                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    485485                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    486 
    487                         if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    488 
    489                                 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    490 
    491                                         markAssertions( haveAssertions, needAssertions, functionType );
    492                                         markAssertions( haveAssertions, needAssertions, otherFunction );
    493 
    494                                         result = true;
     486                        if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) {
     487                                if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     488                                        if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     489
     490                                                markAssertions( haveAssertions, needAssertions, functionType );
     491                                                markAssertions( haveAssertions, needAssertions, otherFunction );
     492
     493                                                result = true;
     494                                        } // if
    495495                                } // if
    496496                        } // if
  • src/SymTab/Autogen.cc

    rf39096c r0555f4b  
    6868                copy->get_args().push_back( new VariableExpr( dstParam ) );
    6969                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    70                 copy->get_args().push_back( new SizeofExpr( unionType ) );
     70                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
    7171
    7272                *out++ = new ExprStmt( noLabels, copy );
     
    420420                copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
    421421
     422                // create a constructor which takes the first member type as a parameter.
     423                // for example, for Union A { int x; double y; }; generate
     424                // void ?{}(A *, int)
     425                // This is to mimic C's behaviour which initializes the first member of the union.
     426                std::list<Declaration *> memCtors;
     427                for ( Declaration * member : aggregateDecl->get_members() ) {
     428                        if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) {
     429                                ObjectDecl * srcParam = new ObjectDecl( "src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 );
     430
     431                                FunctionType * memCtorType = ctorType->clone();
     432                                memCtorType->get_parameters().push_back( srcParam );
     433                                FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType, new CompoundStmt( noLabels ), true, false );
     434                                ctor->fixUniqueId();
     435
     436                                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );
     437                                memCtors.push_back( ctor );
     438                                // only generate a ctor for the first field
     439                                break;
     440                        }
     441                }
     442
    422443                declsToAdd.push_back( assignDecl );
    423444                declsToAdd.push_back( ctorDecl );
    424445                declsToAdd.push_back( copyCtorDecl );
    425446                declsToAdd.push_back( dtorDecl );
     447                declsToAdd.splice( declsToAdd.end(), memCtors );
    426448        }
    427449
  • src/SymTab/Validate.cc

    rf39096c r0555f4b  
    5858#include "Autogen.h"
    5959#include "ResolvExpr/typeops.h"
     60#include <algorithm>
    6061
    6162#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    162163
    163164                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
     165                typedef std::map< std::string, TypeDecl * > TypeDeclMap;
    164166                TypedefMap typedefNames;
     167                TypeDeclMap typedeclNames;
    165168                int scopeLevel;
    166169        };
     
    370373                } // if
    371374
    372                 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
     375                // need to clone members of the context for ownership purposes
     376                std::list< Declaration * > members;
     377                std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
     378
     379                applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
    373380        }
    374381
     
    521528                        delete typeInst;
    522529                        return ret;
     530                } else {
     531                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
     532                        assert( base != typedeclNames.end() );
     533                        typeInst->set_baseType( base->second->clone() );
    523534                } // if
    524535                return typeInst;
     
    565576                        typedefNames.erase( i ) ;
    566577                } // if
     578
     579                typedeclNames[ typeDecl->get_name() ] = typeDecl;
    567580                return typeDecl;
    568581        }
  • src/SynTree/AggregateDecl.cc

    rf39096c r0555f4b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AggregateDecl.cc -- 
     7// AggregateDecl.cc --
    88//
    99// Author           : Richard C. Bilson
  • src/SynTree/Expression.cc

    rf39096c r0555f4b  
    200200
    201201OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
    202         Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {}
     202        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
    203203
    204204OffsetofExpr::~OffsetofExpr() {
    205205        delete type;
    206         delete member;
    207206}
    208207
     
    359358        assert( member );
    360359        os << std::string( indent + 2, ' ' );
     360        os << (void*)member << " ";
    361361        member->print( os, indent + 2 );
    362362        os << std::endl;
  • src/SynTree/TypeSubstitution.h

    rf39096c r0555f4b  
    169169        TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
    170170        for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) {
    171                 Declaration *newdecl = (*i)->clone();
    172                 sub.apply( newdecl );
    173                 *out++ = newdecl;
     171                sub.apply( *i );
     172                *out++ = *i;
    174173        } // for
    175174}
  • src/tests/.expect/32/extension.txt

    rf39096c r0555f4b  
    7070static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
    7171}
     72static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
     73    void *_tmp_cp_ret2;
     74    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
     75    ((void)(_tmp_cp_ret2) /* ^?{} */);
     76}
    7277__extension__ enum E {
    7378    __R__C2eE_1,
     
    8994    __extension__ int __c__i_2;
    9095    ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
    91     int _tmp_cp_ret2;
    92     ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
    93     ((void)(_tmp_cp_ret2) /* ^?{} */);
     96    int _tmp_cp_ret3;
     97    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
     98    ((void)(_tmp_cp_ret3) /* ^?{} */);
    9499    ((void)__extension__ sizeof(3));
    95100    ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
  • src/tests/.expect/64/extension.txt

    rf39096c r0555f4b  
    7070static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
    7171}
     72static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
     73    void *_tmp_cp_ret2;
     74    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
     75    ((void)(_tmp_cp_ret2) /* ^?{} */);
     76}
    7277__extension__ enum E {
    7378    __R__C2eE_1,
     
    8994    __extension__ int __c__i_2;
    9095    ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
    91     int _tmp_cp_ret2;
    92     ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
    93     ((void)(_tmp_cp_ret2) /* ^?{} */);
     96    int _tmp_cp_ret3;
     97    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
     98    ((void)(_tmp_cp_ret3) /* ^?{} */);
    9499    ((void)__extension__ sizeof(3));
    95100    ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
Note: See TracChangeset for help on using the changeset viewer.