This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR31863, OOM with C++ and virtual inheritance
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 8 Jan 2008 22:31:10 +0100 (CET)
- Subject: [PATCH] Fix PR31863, OOM with C++ and virtual inheritance
This fixes PR31863 by bailing out early from push_fields_onto_fieldstack
if we know the result will be not used anyway. This way we don't try
to allocate gigabytes of memory for that and not waste compile-time
either.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
mainline.
Richard.
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c (revision 131399)
--- tree-ssa-structalias.c (working copy)
*************** push_fields_onto_fieldstack (tree type,
*** 4062,4068 ****
{
tree field;
int count = 0;
! int first_element = VEC_length (fieldoff_s, *fieldstack);
if (TREE_CODE (type) == COMPLEX_TYPE)
{
--- 4062,4074 ----
{
tree field;
int count = 0;
! unsigned int first_element = VEC_length (fieldoff_s, *fieldstack);
!
! /* If the vector of fields is growing too big, bail out early.
! Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
! sure this fails. */
! if (first_element > MAX_FIELDS_FOR_FIELD_SENSITIVE)
! return 0;
if (TREE_CODE (type) == COMPLEX_TYPE)
{
Index: testsuite/g++.dg/torture/pr31863.C
===================================================================
*** testsuite/g++.dg/torture/pr31863.C (revision 0)
--- testsuite/g++.dg/torture/pr31863.C (revision 0)
***************
*** 0 ****
--- 1,776 ----
+ /* { dg-do link } */
+
+ namespace Loki
+ {
+ class NullType {};
+ template <class T, class U>
+ struct Typelist
+ {
+ typedef T Head;
+ typedef U Tail;
+ };
+
+
+
+ namespace TL
+ {
+ template
+ <
+ typename T1 = NullType, typename T2 = NullType, typename T3 =
+ NullType,
+ typename T4 = NullType, typename T5 = NullType, typename T6 =
+ NullType,
+ typename T7 = NullType, typename T8 = NullType, typename T9 =
+ NullType,
+ typename T10 = NullType, typename T11 = NullType, typename T12
+ = NullType,
+ typename T13 = NullType, typename T14 = NullType, typename T15
+ = NullType,
+ typename T16 = NullType, typename T17 = NullType, typename T18
+ = NullType,
+ typename T19 = NullType, typename T20 = NullType, typename T21
+ = NullType,
+ typename T22 = NullType, typename T23 = NullType, typename T24
+ = NullType,
+ typename T25 = NullType, typename T26 = NullType, typename T27
+ = NullType,
+ typename T28 = NullType, typename T29 = NullType, typename T30
+ = NullType,
+ typename T31 = NullType, typename T32 = NullType, typename T33
+ = NullType,
+ typename T34 = NullType, typename T35 = NullType, typename T36
+ = NullType,
+ typename T37 = NullType, typename T38 = NullType, typename T39
+ = NullType,
+ typename T40 = NullType
+ >
+ struct MakeTypelist
+ {
+ private:
+ typedef typename MakeTypelist
+ <
+ T2 , T3 , T4 ,
+ T5 , T6 , T7 ,
+ T8 , T9 , T10,
+ T11, T12, T13,
+ T14, T15, T16,
+ T17, T18, T19,
+ T20, T21, T22,
+ T23, T24, T25,
+ T26, T27, T28,
+ T29, T30, T31,
+ T32, T33, T34,
+ T35, T36, T37,
+ T38, T39, T40
+ >
+ ::Result TailResult;
+
+ public:
+ typedef Typelist<T1, TailResult> Result;
+ };
+
+ template<>
+ struct MakeTypelist<>
+ {
+ typedef NullType Result;
+ };
+
+ }
+ }
+ template <class Key>
+ class Factory;
+
+ template <class Key, bool iW>
+ struct Context
+ {
+ typedef Key KeyType;
+ enum
+ {
+ isWrite = iW
+ };
+ };
+
+ namespace detail
+ {
+
+ template <class Key, bool isWrite>
+ class CreatorUnitBaseImpl
+ {
+ public:
+ typedef Context<Key, isWrite> Context_;
+ private:
+ typedef void*(CreatorUnitBaseImpl::*CreateFun)(Context_&, unsigned&, const
+ Key&);
+ CreateFun createFun_;
+
+ protected:
+ virtual void* createUninitialized () = 0;
+ template <class Value>
+ void* createImpl (Context_& ctx, unsigned& ver, const Key& k)
+ {
+ return createUninitialized();
+ }
+ private:
+ CreatorUnitBaseImpl();
+ public:
+ template <class Value>
+ CreatorUnitBaseImpl (Value*) :
+ createFun_( &CreatorUnitBaseImpl::template createImpl<Value> )
+ {
+ }
+
+ virtual ~CreatorUnitBaseImpl () {}
+
+ CreatorUnitBaseImpl(const CreatorUnitBaseImpl& s)
+ : createFun_(s.createFun_)
+ {
+ }
+
+ CreatorUnitBaseImpl& operator=(const CreatorUnitBaseImpl& s)
+ {
+ createFun_ = s.createFun_;
+ return *this;
+ }
+ void* create (Context_& ctx, unsigned& ver, const Key& k)
+ {
+ return (this->*createFun_)(ctx, ver, k);
+ }
+ };
+
+ template <class Key>
+ class Creator : protected CreatorUnitBaseImpl<Key, true>, protected
+ CreatorUnitBaseImpl<Key, false>
+ {
+ public:
+ typedef void* (*CreatorFun) ();
+
+ private:
+ CreatorFun fun_;
+ protected:
+ virtual void* createUninitialized ()
+ {
+ if (fun_)
+ return (*fun_)();
+ return 0;
+ }
+ private:
+ Creator ();
+ public:
+ template <class Value>
+ Creator (CreatorFun f, Value*) :
+ CreatorUnitBaseImpl<Key, true>((Value*)0),
+ CreatorUnitBaseImpl<Key, false>((Value*)0),
+ fun_(f)
+ {
+ }
+
+ Creator(const Creator& s) :
+ CreatorUnitBaseImpl<Key, true>(s),
+ CreatorUnitBaseImpl<Key, false>(s),
+ fun_(s.fun_)
+ {
+
+ }
+
+ Creator& operator=(const Creator& s)
+ {
+ CreatorUnitBaseImpl<Key, true>::operator=(s);
+ CreatorUnitBaseImpl<Key, false>::operator=(s);
+ fun_ = s.fun_;
+ return *this;
+ }
+
+ virtual ~Creator ()
+ {
+ }
+
+ template <class Context>
+ void* createObject (Context& ctx, unsigned& ver, const Key& k)
+ {
+ void* r = CreatorUnitBaseImpl<Key, Context::isWrite>::create(ctx, ver,
+ k);
+ return r;
+ }
+ };
+
+ }
+
+ template <class Key>
+ class Factory
+ {
+ public:
+ typedef Key KeyType;
+ typedef void* (*CreatorFun) ();
+ typedef detail::Creator<Key> Creator;
+ public:
+ Factory () {}
+ ~Factory () {}
+
+ template <class Value>
+ bool registerCreator (const Key& k, CreatorFun fun)
+ {
+ return true;
+ }
+ template <class Context>
+ void* createObject (const Key& k, Context& ctx, unsigned& ver)
+ {
+ return 0;
+ }
+ };
+
+ template <class Key, class Base, Key key>
+ struct ClassSpec
+ {
+ typedef Key KeyType;
+ typedef Base BaseType;
+ enum {KeyValue = key};
+ };
+
+ template <class Key, class T>
+ class Serializer;
+
+ template <class Key, class Base, Key key>
+ class Serializer<Key, ClassSpec <Key, Base, key> >
+ : public virtual Factory<Key>
+ {
+ typedef Key KeyType;
+ typedef Base BaseType;
+ enum {KeyValue = key};
+ typedef Factory<Key> Inherited;
+ typedef Serializer<Key, ClassSpec< Key, Base, key > > SelfType;
+
+ static void* create ()
+ {
+ return (void*) (new BaseType);
+ }
+ public:
+ Serializer()
+ {
+ Inherited::template registerCreator<BaseType>(
+ KeyValue,
+ &SelfType::create);
+ }
+ };
+
+ template <class Key, class Head>
+ class Serializer<Key, Loki::Typelist<Head, Loki::NullType> >:
+ public Serializer<Key, Head>
+ {
+ };
+
+ template <class Key, class Head, class Tail>
+ class Serializer<Key, Loki::Typelist<Head, Tail> >:
+ public virtual Serializer<Key, Head>,
+ public virtual Serializer<Key, Tail>
+ {
+ };
+
+ template <class Key>
+ class Serializer<Key, Loki::NullType> : public virtual Factory<Key>
+ {
+ };
+
+
+
+
+ typedef unsigned KeyType;
+
+
+
+ typedef Factory<KeyType> FactoryType;
+
+ typedef KeyType Key;
+
+ struct A001
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 1; }
+ static const char* className () {return "A001";}
+ };
+
+ struct A002
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 2; }
+ static const char* className () {return "A002";}
+ };
+
+ struct A003
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 3; }
+ static const char* className () {return "A003";}
+ };
+
+ struct A004
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 4; }
+ static const char* className () {return "A004";}
+ };
+
+ struct A005
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 5; }
+ static const char* className () {return "A005";}
+ };
+
+ struct A006
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 6; }
+ static const char* className () {return "A006";}
+ };
+
+ struct A007
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 7; }
+ static const char* className () {return "A007";}
+ };
+
+ struct A008
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 8; }
+ static const char* className () {return "A008";}
+ };
+
+ struct A009
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 9; }
+ static const char* className () {return "A009";}
+ };
+
+ struct A010
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 10; }
+ static const char* className () {return "A010";}
+ };
+
+ struct A011
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 11; }
+ static const char* className () {return "A011";}
+ };
+
+ struct A012
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 12; }
+ static const char* className () {return "A012";}
+ };
+
+ struct A013
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 13; }
+ static const char* className () {return "A013";}
+ };
+
+ struct A014
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 14; }
+ static const char* className () {return "A014";}
+ };
+
+ struct A015
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 15; }
+ static const char* className () {return "A015";}
+ };
+
+ struct A016
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 16; }
+ static const char* className () {return "A016";}
+ };
+
+ struct A017
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 17; }
+ static const char* className () {return "A017";}
+ };
+
+ struct A018
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 18; }
+ static const char* className () {return "A018";}
+ };
+
+ struct A019
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 19; }
+ static const char* className () {return "A019";}
+ };
+
+ struct A020
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 20; }
+ static const char* className () {return "A020";}
+ };
+
+ struct A021
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 21; }
+ static const char* className () {return "A021";}
+ };
+
+ struct A022
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 22; }
+ static const char* className () {return "A022";}
+ };
+
+ struct A023
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 23; }
+ static const char* className () {return "A023";}
+ };
+
+ struct A024
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 24; }
+ static const char* className () {return "A024";}
+ };
+
+ struct A025
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 25; }
+ static const char* className () {return "A025";}
+ };
+
+ struct A026
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 26; }
+ static const char* className () {return "A026";}
+ };
+
+ struct A027
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 27; }
+ static const char* className () {return "A027";}
+ };
+
+ struct A028
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 28; }
+ static const char* className () {return "A028";}
+ };
+
+ struct A029
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 29; }
+ static const char* className () {return "A029";}
+ };
+
+ struct A030
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 30; }
+ static const char* className () {return "A030";}
+ };
+
+ struct A031
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 31; }
+ static const char* className () {return "A031";}
+ };
+
+ struct A032
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 32; }
+ static const char* className () {return "A032";}
+ };
+
+ struct A033
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 33; }
+ static const char* className () {return "A033";}
+ };
+
+ struct A034
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 34; }
+ static const char* className () {return "A034";}
+ };
+
+ struct A035
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 35; }
+ static const char* className () {return "A035";}
+ };
+
+ struct A036
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 36; }
+ static const char* className () {return "A036";}
+ };
+
+ struct A037
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 37; }
+ static const char* className () {return "A037";}
+ };
+
+ struct A038
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 38; }
+ static const char* className () {return "A038";}
+ };
+
+ struct A039
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 39; }
+ static const char* className () {return "A039";}
+ };
+
+ struct A040
+ {
+ template <class Context>
+ bool serialize(Context& ctx, unsigned& ver)
+ {
+ return true;
+ }
+ static Key classId() { return 40; }
+ static const char* className () {return "A040";}
+ };
+
+ Factory<Key>& getInstance()
+ {
+ static Serializer<Key,
+ Loki::TL::MakeTypelist<
+ ClassSpec<Key, A001, 1>,
+ ClassSpec<Key, A002, 2>,
+ ClassSpec<Key, A003, 3>,
+ ClassSpec<Key, A004, 4>,
+ ClassSpec<Key, A005, 5>,
+ ClassSpec<Key, A006, 6>,
+ ClassSpec<Key, A007, 7>,
+ ClassSpec<Key, A008, 8>,
+ ClassSpec<Key, A009, 9>,
+ ClassSpec<Key, A010, 10>,
+ ClassSpec<Key, A011, 11>,
+ ClassSpec<Key, A012, 12>,
+ ClassSpec<Key, A013, 13>,
+ ClassSpec<Key, A014, 14>,
+ ClassSpec<Key, A015, 15>,
+ ClassSpec<Key, A016, 16>,
+ ClassSpec<Key, A017, 17>,
+ ClassSpec<Key, A018, 18>,
+ ClassSpec<Key, A019, 19>,
+ ClassSpec<Key, A020, 20>,
+ ClassSpec<Key, A021, 21>,
+ ClassSpec<Key, A022, 22>,
+ ClassSpec<Key, A023, 23>,
+ ClassSpec<Key, A024, 24>,
+ ClassSpec<Key, A025, 25>,
+ ClassSpec<Key, A026, 26>,
+ ClassSpec<Key, A027, 27>,
+ ClassSpec<Key, A028, 28>,
+ ClassSpec<Key, A029, 29>,
+ ClassSpec<Key, A030, 30>,
+ ClassSpec<Key, A031, 31>,
+ ClassSpec<Key, A032, 32>,
+ ClassSpec<Key, A033, 33>,
+ ClassSpec<Key, A034, 34>,
+ ClassSpec<Key, A035, 35>,
+ ClassSpec<Key, A036, 36>,
+ ClassSpec<Key, A037, 37>,
+ ClassSpec<Key, A038, 38>,
+ ClassSpec<Key, A039, 39>,
+ ClassSpec<Key, A040, 40>
+ >::Result
+ > instance;
+ return instance;
+ }
+
+ int main ()
+ {
+ return 0;
+ }