Commit 2defb926 by Jason Merrill Committed by Jason Merrill

semantics.c (finish_non_static_data_member): Call maybe_dummy_object whenever object is NULL_TREE.

	* semantics.c (finish_non_static_data_member): Call maybe_dummy_object
	whenever object is NULL_TREE.  Don't do 'this' capture here.
	(finish_qualified_id_expr): Pass NULL_TREE.
	(finish_id_expression): Likewise.
	(lambda_expr_this_capture): Likewise.

From-SVN: r158809
parent 38f1276b
2010-04-27 Jason Merrill <jason@redhat.com> 2010-04-27 Jason Merrill <jason@redhat.com>
* semantics.c (finish_non_static_data_member): Call maybe_dummy_object
whenever object is NULL_TREE. Don't do 'this' capture here.
(finish_qualified_id_expr): Pass NULL_TREE.
(finish_id_expression): Likewise.
(lambda_expr_this_capture): Likewise.
* semantics.c (finish_qualified_id_expr): Use maybe_dummy_object * semantics.c (finish_qualified_id_expr): Use maybe_dummy_object
rather than checking current_class_ref directly. rather than checking current_class_ref directly.
(finish_call_expr): Likewise. (finish_call_expr): Likewise.
......
...@@ -1424,17 +1424,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) ...@@ -1424,17 +1424,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
{ {
gcc_assert (TREE_CODE (decl) == FIELD_DECL); 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; tree scope = qualifying_scope;
if (scope == NULL_TREE) if (scope == NULL_TREE)
scope = context_for_name_lookup (decl); scope = context_for_name_lookup (decl);
object = maybe_dummy_object (scope, NULL); 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 if (current_function_decl
&& DECL_STATIC_FUNCTION_P (current_function_decl)) && DECL_STATIC_FUNCTION_P (current_function_decl))
...@@ -1446,19 +1447,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) ...@@ -1446,19 +1447,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
return error_mark_node; 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) if (current_class_ptr)
TREE_USED (current_class_ptr) = 1; TREE_USED (current_class_ptr) = 1;
if (processing_template_decl && !qualifying_scope) if (processing_template_decl && !qualifying_scope)
...@@ -1494,21 +1482,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) ...@@ -1494,21 +1482,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
else else
{ {
tree access_type = TREE_TYPE (object); 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, perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
decl); decl);
...@@ -1683,7 +1656,7 @@ finish_qualified_id_expr (tree qualifying_class, ...@@ -1683,7 +1656,7 @@ finish_qualified_id_expr (tree qualifying_class,
else if (TREE_CODE (expr) == FIELD_DECL) else if (TREE_CODE (expr) == FIELD_DECL)
{ {
push_deferring_access_checks (dk_no_check); 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); qualifying_class);
pop_deferring_access_checks (); pop_deferring_access_checks ();
} }
...@@ -3062,7 +3035,7 @@ finish_id_expression (tree id_expression, ...@@ -3062,7 +3035,7 @@ finish_id_expression (tree id_expression,
already. Turn off checking to avoid duplicate errors. */ already. Turn off checking to avoid duplicate errors. */
push_deferring_access_checks (dk_no_check); push_deferring_access_checks (dk_no_check);
decl = finish_non_static_data_member decl = finish_non_static_data_member
(decl, current_class_ref, (decl, NULL_TREE,
/*qualifying_scope=*/NULL_TREE); /*qualifying_scope=*/NULL_TREE);
pop_deferring_access_checks (); pop_deferring_access_checks ();
return decl; return decl;
...@@ -3143,7 +3116,7 @@ finish_id_expression (tree id_expression, ...@@ -3143,7 +3116,7 @@ finish_id_expression (tree id_expression,
Access checking has been performed during name lookup Access checking has been performed during name lookup
already. Turn off checking to avoid duplicate errors. */ already. Turn off checking to avoid duplicate errors. */
push_deferring_access_checks (dk_no_check); 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); /*qualifying_scope=*/NULL_TREE);
pop_deferring_access_checks (); pop_deferring_access_checks ();
} }
...@@ -5844,7 +5817,7 @@ lambda_expr_this_capture (tree lambda) ...@@ -5844,7 +5817,7 @@ lambda_expr_this_capture (tree lambda)
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda)); gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
result = finish_non_static_data_member (this_capture, result = finish_non_static_data_member (this_capture,
current_class_ref, NULL_TREE,
/*qualifying_scope=*/NULL_TREE); /*qualifying_scope=*/NULL_TREE);
/* If 'this' is captured, each use of 'this' is transformed into an /* If 'this' is captured, each use of 'this' is transformed into an
......
2010-04-27 Jason Merrill <jason@redhat.com> 2010-04-27 Jason Merrill <jason@redhat.com>
* g++.dg/lookup/scoped5.C: Adjust.
* g++.dg/lookup/scoped8.C: Adjust.
* g++.dg/template/dependent-expr5.C: Adjust.
* g++.old-deja/g++.brendan/nest1.C: Adjust.
PR c++/43856 PR c++/43856
* g++.dg/cpp0x/lambda/lambda-this2.C: New. * g++.dg/cpp0x/lambda/lambda-this2.C: New.
......
...@@ -9,11 +9,11 @@ class A { ...@@ -9,11 +9,11 @@ class A {
public: public:
class B { class B {
public: public:
int a; // { dg-error "object missing" } int a;
}; };
}; };
class C { class C {
public: public:
void f(void) { sizeof(A::B::a); } // { dg-error "this location" } void f(void) { sizeof(A::B::a); }
}; };
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
struct A struct A
{ {
int i; // { dg-error "object missing" } int i; // { dg-error "non-static" }
}; };
template <int> struct B template <int> struct B
......
...@@ -18,7 +18,7 @@ template<class F, class T> void bindb(F (T::*f)(void)) {} // { dg-message "note" ...@@ -18,7 +18,7 @@ template<class F, class T> void bindb(F (T::*f)(void)) {} // { dg-message "note"
struct foo { struct foo {
static int baist; static int baist;
int bait; int bait; // { dg-error "non-static data member" }
void barf (); void barf ();
static void barf (int); static void barf (int);
...@@ -31,7 +31,7 @@ struct foo { ...@@ -31,7 +31,7 @@ struct foo {
bar() { bar() {
bind (&baist); bind (&baist);
bind (&foo::baist); bind (&foo::baist);
bind (&bait); // { dg-error "nonstatic data member" } bind (&bait); // { dg-error "from this location" }
bind (&foo::bait); bind (&foo::bait);
bind (&baikst); bind (&baikst);
...@@ -75,7 +75,7 @@ struct foo { ...@@ -75,7 +75,7 @@ struct foo {
barT() { barT() {
bind (&baist); bind (&baist);
bind (&foo::baist); bind (&foo::baist);
bind (&bait); // { dg-error "nonstatic data member" } bind (&bait); // { dg-error "from this location" }
bind (&foo::bait); bind (&foo::bait);
bind (&baikst); bind (&baikst);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
int x; int x;
class enclose { class enclose {
public: public:
int x; int x; // { dg-error "non-static" }
class inner { class inner {
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment