Re: [C++] Avoid producing duplicate binfos for member pointers

2014-06-30 Thread Jason Merrill
Hmm, I wonder why we need BINFOs at all for the ptrmemfunc RECORD_TYPEs, 
which are not classes.


Jason



Re: [C++] Avoid producing duplicate binfos for member pointers

2014-06-30 Thread Jason Merrill

On 06/30/2014 08:42 AM, Jason Merrill wrote:

Hmm, I wonder why we need BINFOs at all for the ptrmemfunc RECORD_TYPEs,
which are not classes.


I'm working on removing both BINFO and TYPE_LANG_SPECIFIC.

Jason



Re: [C++] Avoid producing duplicate binfos for member pointers

2014-06-30 Thread Jan Hubicka
 On 06/30/2014 08:42 AM, Jason Merrill wrote:
 Hmm, I wonder why we need BINFOs at all for the ptrmemfunc RECORD_TYPEs,
 which are not classes.
 
 I'm working on removing both BINFO and TYPE_LANG_SPECIFIC.

Works for me! :)

Thanks,
Honza


Re: [C++] Avoid producing duplicate binfos for member pointers

2014-06-30 Thread Jason Merrill

On 06/30/2014 11:58 AM, Jason Merrill wrote:

On 06/30/2014 08:42 AM, Jason Merrill wrote:

Hmm, I wonder why we need BINFOs at all for the ptrmemfunc RECORD_TYPEs,
which are not classes.


I'm working on removing both BINFO and TYPE_LANG_SPECIFIC.


Like so.  Applying to trunk.

commit 8988eb91d4be24fb630f4d8538110a5f83d44daa
Author: Jason Merrill ja...@redhat.com
Date:   Mon Jun 30 08:34:33 2014 -0400

	* decl.c (build_ptrmemfunc_type): Don't give a PMF RECORD_TYPE
	TYPE_BINFO or TYPE_LANG_SPECIFIC.
	* cp-tree.h (TYPE_PTRMEMFUNC_FLAG): Use TYPE_LANG_FLAG_2.
	(TYPE_PTRMEMFUNC_P): Don't expect TYPE_LANG_SPECIFIC.
	* typeck.c (build_ptrmemfunc_access_expr): Don't use lookup_member.
	* pt.c (unify): Also check whether the argument is a PMF.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c1bd7cf..1e9e1af 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -126,6 +126,7 @@ c-common.h, not after.
0: TYPE_DEPENDENT_P
1: TYPE_HAS_USER_CONSTRUCTOR.
2: TYPE_HAS_LATE_RETURN_TYPE (in FUNCTION_TYPE, METHOD_TYPE)
+  TYPE_PTRMEMFUNC_FLAG (in RECORD_TYPE)
3: TYPE_FOR_JAVA.
4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR
5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
@@ -3561,11 +3562,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
function type.  */
 #define TYPE_PTRMEMFUNC_P(NODE)		\
   (TREE_CODE (NODE) == RECORD_TYPE	\
-TYPE_LANG_SPECIFIC (NODE)		\
 TYPE_PTRMEMFUNC_FLAG (NODE))
 
 #define TYPE_PTRMEMFUNC_FLAG(NODE) \
-  (LANG_TYPE_CLASS_CHECK (NODE)-ptrmemfunc_flag)
+  (TYPE_LANG_FLAG_2 (RECORD_TYPE_CHECK (NODE)))
 
 /* Returns true if NODE is a pointer-to-member.  */
 #define TYPE_PTRMEM_P(NODE) \
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6902bb0..909f762 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8073,13 +8073,10 @@ build_ptrmemfunc_type (tree type)
 unqualified_variant
   = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
 
-  t = make_class_type (RECORD_TYPE);
-  xref_basetypes (t, NULL_TREE);
+  t = make_node (RECORD_TYPE);
 
-  /* Let the front end know this is a pointer to member function...  */
+  /* Let the front end know this is a pointer to member function.  */
   TYPE_PTRMEMFUNC_FLAG (t) = 1;
-  /* ... and not really a class type.  */
-  SET_CLASS_TYPE_P (t, 0);
 
   field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
   fields = field;
@@ -8109,7 +8106,6 @@ build_ptrmemfunc_type (tree type)
   TYPE_MAIN_VARIANT (t) = unqualified_variant;
   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
   TYPE_NEXT_VARIANT (unqualified_variant) = t;
-  TREE_TYPE (TYPE_BINFO (t)) = t;
 }
 
   /* Cache this pointer-to-member type so that we can find it again
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7f33b6d..70a946c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18104,6 +18104,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 			TYPE_PTRMEMFUNC_FN_TYPE (arg),
 			strict, explain_p);
 	}
+  else if (TYPE_PTRMEMFUNC_P (arg))
+	return unify_type_mismatch (explain_p, parm, arg);
 
   if (CLASSTYPE_TEMPLATE_INFO (parm))
 	{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 042e600..9758dfe 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2848,8 +2848,10 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
  type.  */
   ptrmem_type = TREE_TYPE (ptrmem);
   gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
-  member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
-			  /*want_type=*/false, tf_warning_or_error);
+  for (member = TYPE_FIELDS (ptrmem_type); member;
+   member = DECL_CHAIN (member))
+if (DECL_NAME (member) == member_name)
+  break;
   return build_simple_component_ref (ptrmem, member);
 }
 


[C++] Avoid producing duplicate binfos for member pointers

2014-06-28 Thread Jan Hubicka
Jason,
this is another case cought by the type variant checking.  
build_ptrmemfunc_type,
for qualified type, first calls itself recursively to produce member pointer 
type
for unqalified variant.

Subsequentely it produces the member pointer from scratch - I believe it is 
because
the field decl representing pointer should be qualified, so we have rather rare
case where we do not share fields in between type and variant (other is
Fortran when dropping restrict quantifiers deeply from the structure).

It however produces fresh BINFO for the variant and overwrites its BINFO_TYPE
pointer to t.  I do not see a reason for having duplicated binfo here: both
structures should be equivalent from type inheritance POV.

This patch just avoids the duplicated BINFO and copies one from unqalified 
variant,
if available.

Seems sane?

Bootstrapped/regtested x86_64-linux.

* decl.c (build_ptrmemfunc_type): Do not produce duplicated BINFO
for the variant.
Index: cp/decl.c
===
--- cp/decl.c   (revision 212098)
+++ cp/decl.c   (working copy)
@@ -8074,7 +8074,6 @@ build_ptrmemfunc_type (tree type)
   = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
 
   t = make_class_type (RECORD_TYPE);
-  xref_basetypes (t, NULL_TREE);
 
   /* Let the front end know this is a pointer to member function...  */
   TYPE_PTRMEMFUNC_FLAG (t) = 1;
@@ -8109,8 +8108,10 @@ build_ptrmemfunc_type (tree type)
   TYPE_MAIN_VARIANT (t) = unqualified_variant;
   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
   TYPE_NEXT_VARIANT (unqualified_variant) = t;
-  TREE_TYPE (TYPE_BINFO (t)) = t;
+  TYPE_BINFO (t) = TYPE_BINFO (unqualified_variant);
 }
+  else
+xref_basetypes (t, NULL_TREE);
 
   /* Cache this pointer-to-member type so that we can find it again
  later.  */