OSDN Git Service

PR c++/43875
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index cbbcf96..05c5168 100644 (file)
@@ -610,13 +610,6 @@ finish_expr_stmt (tree expr)
        {
          if (warn_sequence_point)
            verify_sequence_points (expr);
-         if (TREE_CODE (expr) != MODIFY_EXPR)
-           /* Expr is not being 'used' here, otherwise we whould have
-              called mark_{rl}value_use use here, which would have in turn
-              called mark_exp_read. Rather, we call mark_exp_read directly
-              to avoid some warnings when
-               -Wunused-but-set-{variable,parameter} is in effect.  */
-           mark_exp_read (expr);
          expr = convert_to_void (expr, "statement", tf_warning_or_error);
        }
       else if (!type_dependent_expression_p (expr))
@@ -1245,8 +1238,6 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
             otherwise we'll get an error.  Gross, but ...  */
          STRIP_NOPS (operand);
 
-         operand = mark_lvalue_use (operand);
-
          if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
            operand = error_mark_node;
 
@@ -1433,18 +1424,17 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 {
   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
-  if (!object)
+  if (!object && cp_unevaluated_operand != 0)
     {
+      /* 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);
     }
 
-  /* 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 (!object)
     {
       if (current_function_decl
          && DECL_STATIC_FUNCTION_P (current_function_decl))
@@ -1456,6 +1446,19 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       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)
@@ -1491,6 +1494,21 @@ finish_non_static_data_member (tree decl, tree object, tree 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);
@@ -1665,21 +1683,24 @@ finish_qualified_id_expr (tree qualifying_class,
   else if (TREE_CODE (expr) == FIELD_DECL)
     {
       push_deferring_access_checks (dk_no_check);
-      expr = finish_non_static_data_member (expr, NULL_TREE,
+      expr = finish_non_static_data_member (expr, current_class_ref,
                                            qualifying_class);
       pop_deferring_access_checks ();
     }
   else if (BASELINK_P (expr) && !processing_template_decl)
     {
-      tree ob;
+      tree fns;
 
       /* 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 (expr)
-         && (ob = maybe_dummy_object (qualifying_class, NULL),
-             !is_dummy_object (ob)))
+      if (!shared_member_p (fns)
+         && current_class_ref
+         && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref)))
        expr = (build_class_member_access_expr
-               (ob,
+               (maybe_dummy_object (qualifying_class, NULL),
                 expr,
                 BASELINK_ACCESS_BINFO (expr),
                 /*preserve_reference=*/false,
@@ -1981,18 +2002,31 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
           . operator.... [Otherwise] a contrived object of type T
           becomes the implied object argument.
 
-       In this situation:
+       This paragraph is unclear about this situation:
 
          struct A { void f(); };
          struct B : public A {};
          struct C : public A { void g() { B::f(); }};
 
-       "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.  */
+       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;
 
-      object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                                  NULL);
+         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));
+       }
 
       if (processing_template_decl)
        {
@@ -3039,7 +3073,7 @@ finish_id_expression (tree id_expression,
                 already.  Turn off checking to avoid duplicate errors.  */
              push_deferring_access_checks (dk_no_check);
              decl = finish_non_static_data_member
-                      (decl, NULL_TREE,
+                      (decl, current_class_ref,
                        /*qualifying_scope=*/NULL_TREE);
              pop_deferring_access_checks ();
              return decl;
@@ -3120,7 +3154,7 @@ finish_id_expression (tree id_expression,
             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, NULL_TREE,
+         decl = finish_non_static_data_member (decl, current_class_ref,
                                                /*qualifying_scope=*/NULL_TREE);
          pop_deferring_access_checks ();
        }
@@ -3128,7 +3162,10 @@ finish_id_expression (tree id_expression,
        {
          tree first_fn;
 
-         first_fn = get_first_fn (decl);
+         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);
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
@@ -3190,8 +3227,6 @@ finish_typeof (tree expr)
       return type;
     }
 
-  expr = mark_type_use (expr);
-
   type = unlowered_expr_type (expr);
 
   if (!type || type == unknown_type_node)
@@ -3279,7 +3314,7 @@ simplify_aggr_init_expr (tree *tp)
         expand_call{,_inline}.  */
       cxx_mark_addressable (slot);
       CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
-      call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr);
+      call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr);
     }
   else if (style == pcc)
     {
@@ -4869,7 +4904,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         case PARM_DECL:
         case RESULT_DECL:
         case TEMPLATE_PARM_INDEX:
-         expr = mark_type_use (expr);
           type = TREE_TYPE (expr);
           break;
 
@@ -4878,7 +4912,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
           break;
 
         case COMPONENT_REF:
-         mark_type_use (expr);
           type = is_bitfield_expr_with_lowered_type (expr);
           if (!type)
             type = TREE_TYPE (TREE_OPERAND (expr, 1));
@@ -5822,7 +5855,7 @@ lambda_expr_this_capture (tree lambda)
       gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
 
       result = finish_non_static_data_member (this_capture,
-                                              NULL_TREE,
+                                              current_class_ref,
                                               /*qualifying_scope=*/NULL_TREE);
 
       /* If 'this' is captured, each use of 'this' is transformed into an
@@ -5835,32 +5868,6 @@ lambda_expr_this_capture (tree lambda)
   return result;
 }
 
-/* Returns the method basetype of the innermost non-lambda function, or
-   NULL_TREE if none.  */
-
-tree
-nonlambda_method_basetype (void)
-{
-  tree fn, type;
-  if (!current_class_ref)
-    return NULL_TREE;
-
-  type = current_class_type;
-  if (!LAMBDA_TYPE_P (type))
-    return type;
-
-  /* Find the nearest enclosing non-lambda function.  */
-  fn = TYPE_NAME (type);
-  do
-    fn = decl_function_context (fn);
-  while (fn && LAMBDA_FUNCTION_P (fn));
-
-  if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
-    return NULL_TREE;
-
-  return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
-}
-
 /* If the closure TYPE has a static op(), also add a conversion to function
    pointer.  */