summaryrefslogtreecommitdiff
path: root/gcc/cp/typeck2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/typeck2.c')
-rw-r--r--gcc/cp/typeck2.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 6d9012fa7da..a3d06a8956f 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -265,9 +265,13 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
return 0;
type = TYPE_MAIN_VARIANT (type);
+#if 0
+ /* Instantiation here seems to be required by the standard,
+ but breaks e.g. boost::bind. FIXME! */
/* In SFINAE, non-N3276 context, force instantiation. */
if (!(complain & (tf_error|tf_decltype)))
complete_type (type);
+#endif
/* If the type is incomplete, we register it within a hash table,
so that we can check again once it is completed. This makes sense
@@ -1708,7 +1712,32 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
return datum;
}
else
- return build2 (OFFSET_REF, type, datum, component);
+ {
+ /* 5.5/6: In a .* expression whose object expression is an rvalue, the
+ program is ill-formed if the second operand is a pointer to member
+ function with ref-qualifier &. In a .* expression whose object
+ expression is an lvalue, the program is ill-formed if the second
+ operand is a pointer to member function with ref-qualifier &&. */
+ if (FUNCTION_REF_QUALIFIED (type))
+ {
+ bool lval = real_lvalue_p (datum);
+ if (lval && FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an rvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
+ {
+ if (complain & tf_error)
+ error ("pointer-to-member-function type %qT requires an lvalue",
+ ptrmem_type);
+ return error_mark_node;
+ }
+ }
+ return build2 (OFFSET_REF, type, datum, component);
+ }
}
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */