{
gcc_assert (TREE_CODE (decl) == FIELD_DECL);
- if (!object && cp_unevaluated_operand != 0)
+ if (!object)
{
- /* DR 613: Can use non-static data members without an associated
- object in sizeof/decltype/alignof. */
tree scope = qualifying_scope;
if (scope == NULL_TREE)
scope = context_for_name_lookup (decl);
object = maybe_dummy_object (scope, NULL);
}
- if (!object)
+ /* DR 613: Can use non-static data members without an associated
+ object in sizeof/decltype/alignof. */
+ if (is_dummy_object (object) && cp_unevaluated_operand == 0
+ && (!processing_template_decl || !current_class_ref))
{
if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl))
return error_mark_node;
}
- /* If decl is a non-capture field and object has a lambda type,
- then we have a reference to a member of 'this' from a
- lambda inside a non-static member function, and we must get to decl
- through the 'this' capture. If decl is not a member of that object,
- either, then its access will still fail later. */
- if (LAMBDA_TYPE_P (TREE_TYPE (object))
- && !LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
- object = cp_build_indirect_ref (lambda_expr_this_capture
- (CLASSTYPE_LAMBDA_EXPR
- (TREE_TYPE (object))),
- RO_NULL,
- /*complain=*/tf_warning_or_error);
-
if (current_class_ptr)
TREE_USED (current_class_ptr) = 1;
if (processing_template_decl && !qualifying_scope)
else
{
tree access_type = TREE_TYPE (object);
- tree lookup_context = context_for_name_lookup (decl);
-
- while (!DERIVED_FROM_P (lookup_context, access_type))
- {
- access_type = TYPE_CONTEXT (access_type);
- while (access_type && DECL_P (access_type))
- access_type = DECL_CONTEXT (access_type);
-
- if (!access_type)
- {
- error ("object missing in reference to %q+D", decl);
- error ("from this location");
- return error_mark_node;
- }
- }
perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
decl);
else if (TREE_CODE (expr) == FIELD_DECL)
{
push_deferring_access_checks (dk_no_check);
- expr = finish_non_static_data_member (expr, current_class_ref,
+ expr = finish_non_static_data_member (expr, NULL_TREE,
qualifying_class);
pop_deferring_access_checks ();
}
else if (BASELINK_P (expr) && !processing_template_decl)
{
- tree fns;
+ tree ob;
/* See if any of the functions are non-static members. */
- fns = BASELINK_FUNCTIONS (expr);
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- fns = TREE_OPERAND (fns, 0);
/* If so, the expression may be relative to 'this'. */
- if (!shared_member_p (fns)
- && current_class_ref
- && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref)))
+ if (!shared_member_p (expr)
+ && (ob = maybe_dummy_object (qualifying_class, NULL),
+ !is_dummy_object (ob)))
expr = (build_class_member_access_expr
- (maybe_dummy_object (qualifying_class, NULL),
+ (ob,
expr,
BASELINK_ACCESS_BINFO (expr),
/*preserve_reference=*/false,
. operator.... [Otherwise] a contrived object of type T
becomes the implied object argument.
- This paragraph is unclear about this situation:
+ In this situation:
struct A { void f(); };
struct B : public A {};
struct C : public A { void g() { B::f(); }};
- In particular, for `B::f', this paragraph does not make clear
- whether "the class of that member function" refers to `A' or
- to `B'. We believe it refers to `B'. */
- if (current_class_type
- && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
- current_class_type)
- && current_class_ref)
- object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
- NULL);
- else
- {
- tree representative_fn;
+ "the class of that member function" refers to `A'. But 11.2
+ [class.access.base] says that we need to convert 'this' to B* as
+ part of the access, so we pass 'B' to maybe_dummy_object. */
- representative_fn = BASELINK_FUNCTIONS (fn);
- if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
- representative_fn = TREE_OPERAND (representative_fn, 0);
- representative_fn = get_first_fn (representative_fn);
- object = build_dummy_object (DECL_CONTEXT (representative_fn));
- }
+ object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+ NULL);
if (processing_template_decl)
{
already. Turn off checking to avoid duplicate errors. */
push_deferring_access_checks (dk_no_check);
decl = finish_non_static_data_member
- (decl, current_class_ref,
+ (decl, NULL_TREE,
/*qualifying_scope=*/NULL_TREE);
pop_deferring_access_checks ();
return decl;
Access checking has been performed during name lookup
already. Turn off checking to avoid duplicate errors. */
push_deferring_access_checks (dk_no_check);
- decl = finish_non_static_data_member (decl, current_class_ref,
+ decl = finish_non_static_data_member (decl, NULL_TREE,
/*qualifying_scope=*/NULL_TREE);
pop_deferring_access_checks ();
}
{
tree first_fn;
- first_fn = decl;
- if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
- first_fn = TREE_OPERAND (first_fn, 0);
- first_fn = get_first_fn (first_fn);
+ first_fn = get_first_fn (decl);
if (TREE_CODE (first_fn) == TEMPLATE_DECL)
first_fn = DECL_TEMPLATE_RESULT (first_fn);
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
result = finish_non_static_data_member (this_capture,
- current_class_ref,
+ NULL_TREE,
/*qualifying_scope=*/NULL_TREE);
/* If 'this' is captured, each use of 'this' is transformed into an