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]
Other format: [Raw text]

[PATCH] Fix PR c++/34059: ICE with invalid base type for class member


Hi all.

The following invalid snippet triggers an ICE in 4.1, 4.2 and mainline:

=== cut here ===
struct A
{
          template<int> void foo();
};
struct B : A {};
struct C : A {};
void bar()
{
          B().C::foo<0>();
}
=== cut here ===

The problem is that 'build_class_member_access_expr' computes the scope
of the member being processed from the BINFO_TYPE of its BASELINK_BINFO
(i.e. B) instead of this of its BASELINK_ACCESS_BINFO (i.e. C). As a
result, the expression is accepted, and there is an ICE when converting
the B instance into an instance of C. The attached patch fixes this.

I have successfully regtested it on x86_64-apple-darwin-9 with no new
regression. Is it OK for the mainline? For 4.2?

Best regards,
Simon

:ADDPATCH c++:

2007-11-26  Simon Martin  <simartin@users.sourceforge.net>

	PR c++/34059
	* typeck.c (build_class_member_access_expr): Compute MEMBER_SCOPE from
	MEMBER's BASELINK_ACCESS_BINFO instead of its BASELINK_BINFO.





Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 130402)
+++ gcc/cp/typeck.c	(working copy)
@@ -1798,7 +1798,7 @@ build_class_member_access_expr (tree obj
 	warn_deprecated_use (member);
     }
   else
-    member_scope = BINFO_TYPE (BASELINK_BINFO (member));
+    member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
   /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
      presently be the anonymous union.  Go outwards until we find a
      type related to OBJECT_TYPE.  */





2007-11-26  Simon Martin  <simartin@users.sourceforge.net>

	PR c++/34059
	* g++.dg/parse/crash40.C: New test.





/* PR c++/34059 */
/* { dg-do "compile" } */

struct A
{
  template<int> void foo();
};
struct B : A {};
struct C : A {};

class AA
{
  template<int> void foo(); /* { dg-error "is private" } */
};
struct BB : AA {};

class AAA {
  int get() const {}
};
struct BBB {
  static BBB *foo();
private:
  int get() const {} /* { dg-error "is private" } */
};
template<bool> struct S {
  S(unsigned int = BBB::foo()->AAA::get()); /* { dg-error "is not a base of" } */
};
template<bool> struct SS {
  SS(unsigned int = BBB::foo()->get());
};

void bar()
{
  B().C::foo<0>(); /* { dg-error "is not a member of" } */
  BB().AA::foo<0>(); /* { dg-error "within this context" } */

  int i;
  i.C::foo<0>(); /* { dg-error "which is of non-class type" } */

  S<false> s;
  SS<false> ss; /* { dg-error "within this context" } */
}






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