This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[C++ PATCH]: Fix 2914


Hi,
I've installed this on branch and mainline to fix high priority
bug 2914. We allow, as an extension, defining
structure types inside a c cast. when used in a static member initializer,
this causes xref_tag to inject a new TYPE_DECL node into an already
complete structure. Later, when trying to reenter that scope, things
go sadly wrong.

Now, this is a rather strange thing to do, except for this particular
example where we're type punning via an anonymous union. As it is an
anonymous union, nothing can have its tag, so it is safe to simply insert
it into the closest non-class scope. If it is not anonymous, then
the user might get confused later on, but I think that's their own
fault.

booted & tested on i686-pc-linux-gnu, approved by Mark.

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-06-06  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/2914
	* decl.c (pushtag): Don't push into a complete type's scope.

Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.747.2.27
diff -c -3 -p -r1.747.2.27 decl.c
*** decl.c	2001/05/25 01:22:13	1.747.2.27
--- decl.c	2001/06/06 12:19:48
*************** pushtag (name, type, globalize)
*** 2816,2822 ****
  
    b = current_binding_level;
    while (b->tag_transparent
! 	 || (globalize && b->parm_flag == 2))
      b = b->level_chain;
  
    b->tags = tree_cons (name, type, b->tags);
--- 2816,2828 ----
  
    b = current_binding_level;
    while (b->tag_transparent
! 	 || (b->parm_flag == 2
! 	     && (globalize
! 		 /* We may be defining a new type in the initializer
! 		    of a static member variable. We allow this when
! 		    not pedantic, and it is particularly useful for
! 		    type punning via an anonymous union. */
! 		 || COMPLETE_TYPE_P (b->this_class))))
      b = b->level_chain;
  
    b->tags = tree_cons (name, type, b->tags);
// Build don't link:

// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 6 Jun 2001 <nathan@codesourcery.com>

// Bug 2914. New types can be created in a static member
// initializer. These should not be injected into the member's class's
// scope.

class DoubleSupport
{
  public:
  static void toDouble();
  
  static const double s_NaN;
  static const double s_positiveInfinity;
  static const double s_negativeInfinity;
  static const double s_positiveZero;
  static const double s_negativeZero;
  static const unsigned long* s_NaNFirstDWORD;
  static const unsigned long* s_NaNSecondDWORD;
};

const double DoubleSupport::s_positiveInfinity =
(__extension__ ((union { unsigned char __c[8]; double __d; })
  { __c: { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }).__d);

struct other 
{
};


void
DoubleSupport::toDouble()
{
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]