Rework build_component_ref.
authorMark Mitchell <mark@codesourcery.com>
Thu, 8 Aug 2002 05:48:39 +0000 (05:48 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 8 Aug 2002 05:48:39 +0000 (05:48 +0000)
* call.c (build_vfield_ref): Do not go through build_component_ref.
(build_field_call): Use build_class_member_access_expr.
(build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
(build_object_call): Likewise.
* class.c (convert_to_base): New function.
(type_requires_array_cookie): Use BASELINK_FUNCTIONS.
(instantiate_type): Handle BASELINKs.
* cp-tree.def (BASELINK): New tree code.
* cp-tree.h (BASELINK_P): Reimplement.
(SET_BASELINK_P): Remove.
(BASELINK_BINFO): Reimplement.
(BASELINK_FUNCTIONS): Likewise.
(BASELINK_ACCESS_BINFO): Likewise.
(BASELINK_OPTYPE): Likewise.
(convert_to_base): New function.
(name_p): Likewise.
(build_object_ref): Remove.
(build_component_ref_1): Likewise.
(build_component_ref): Likewise.
(build_x_component_ref): Likewise.
(build_class_member_access_expr): New function.
(finish_class_member_access_expr): Likewise.
(build_ptrmemfunc_access_expr): Likewise.
* decl.c (grokdeclarator): Handle BASELINKs.
* decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
finish_class_member_access_expr.
(arg_assoc): Handle BASELINKs.
(do_class_using_decl): Likewise.
* error.c (dump_decl): Likewise.
(dump_expr): Use build_ptrmemfunc_access_expr.
* except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
destructors.
(build_throw): Use BASELINK_FUNCTIONS.
* init.c (perform_member_init): Use
build_class_member_access_expr.
(build_offset_ref): Handle BASELINKs.  Use
build_class_member_access_expr.
* method.c (hack_identifier): Likewise.
* parse.y (do_id): Use BASELINK, not TREE_LIST.
(primary): Remove uses of build_object_ref.
* pt.c (lookup_template_function): Handle BASELINKs.
(resolve_overloaded_unification): Likewise.
* search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
(lookup_field): Use BASELINK, not TREE_LIST.
(lookup_fnfiels): Likewise.
(setup_class_bindings): Likewise.
* semantics.c (finish_object_call_expr): Do not use
build_method_call when we already know what function is being
called.
* spew.c (identifier_type): Use BASELINK, not TREE_LIST.
* tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
TREE_CHAIN.
(name_p): New function.
* typeck.c (build_object_ref): Remove.
(build_component_ref_1): Likewise.
(build_x_component_ref): Likewise.
(build_class_member_access_expr): New function.
(finish_class_member_access_expr): Likewise.
(build_ptrmemfunc_access_expr): Likewise.
(get_member_function_from_ptrfunc): Use
build_ptrmemfunc_access_expr.
(build_binary_op): Likewise.
(build_unary_op): Likewise.
(build_ptrmemfunc): Likewise.
(pfn_from_ptrmemfunc): Likewise.
* typeck2.c (build_m_component_ref): Adjust comment.

* g++.dg/abi/offsetof.C: Tweak error messages.
* g++.old-deja/g++.mike/p10769a.C: Likewise.

From-SVN: r56117

22 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/cp/spew.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/offsetof.C
gcc/testsuite/g++.old-deja/g++.mike/p10769a.C

index f5fe87b8533c6277e5a40a8746c1d0d019b5956d..b5e51ed353847915b437049ce10cbabbae2aea67 100644 (file)
@@ -1,3 +1,73 @@
+2002-08-07  Mark Mitchell  <mark@codesourcery.com>
+
+       Rework build_component_ref.
+       * call.c (build_vfield_ref): Do not go through build_component_ref.
+       (build_field_call): Use build_class_member_access_expr.
+       (build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
+       (build_object_call): Likewise.
+       * class.c (convert_to_base): New function.
+       (type_requires_array_cookie): Use BASELINK_FUNCTIONS.
+       (instantiate_type): Handle BASELINKs.
+       * cp-tree.def (BASELINK): New tree code.
+       * cp-tree.h (BASELINK_P): Reimplement.
+       (SET_BASELINK_P): Remove.
+       (BASELINK_BINFO): Reimplement.
+       (BASELINK_FUNCTIONS): Likewise.
+       (BASELINK_ACCESS_BINFO): Likewise.
+       (BASELINK_OPTYPE): Likewise.
+       (convert_to_base): New function.
+       (name_p): Likewise.
+       (build_object_ref): Remove.
+       (build_component_ref_1): Likewise.
+       (build_component_ref): Likewise.
+       (build_x_component_ref): Likewise.
+       (build_class_member_access_expr): New function.
+       (finish_class_member_access_expr): Likewise.
+       (build_ptrmemfunc_access_expr): Likewise.
+       * decl.c (grokdeclarator): Handle BASELINKs.
+       * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
+       finish_class_member_access_expr.
+       (arg_assoc): Handle BASELINKs.
+       (do_class_using_decl): Likewise.
+       * error.c (dump_decl): Likewise.
+       (dump_expr): Use build_ptrmemfunc_access_expr.
+       * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
+       destructors.
+       (build_throw): Use BASELINK_FUNCTIONS.
+       * init.c (perform_member_init): Use
+       build_class_member_access_expr.
+       (build_offset_ref): Handle BASELINKs.  Use
+       build_class_member_access_expr.
+       * method.c (hack_identifier): Likewise.
+       * parse.y (do_id): Use BASELINK, not TREE_LIST.
+       (primary): Remove uses of build_object_ref.
+       * pt.c (lookup_template_function): Handle BASELINKs.
+       (resolve_overloaded_unification): Likewise.
+       * search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
+       (lookup_field): Use BASELINK, not TREE_LIST.
+       (lookup_fnfiels): Likewise.
+       (setup_class_bindings): Likewise.
+       * semantics.c (finish_object_call_expr): Do not use
+       build_method_call when we already know what function is being
+       called.
+       * spew.c (identifier_type): Use BASELINK, not TREE_LIST.
+       * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
+       TREE_CHAIN.
+       (name_p): New function.
+       * typeck.c (build_object_ref): Remove.
+       (build_component_ref_1): Likewise.
+       (build_x_component_ref): Likewise.
+       (build_class_member_access_expr): New function.
+       (finish_class_member_access_expr): Likewise.
+       (build_ptrmemfunc_access_expr): Likewise.
+       (get_member_function_from_ptrfunc): Use
+       build_ptrmemfunc_access_expr.
+       (build_binary_op): Likewise.
+       (build_unary_op): Likewise.
+       (build_ptrmemfunc): Likewise.
+       (pfn_from_ptrmemfunc): Likewise.
+       * typeck2.c (build_m_component_ref): Adjust comment.
+       
 2002-08-07  Neil Booth  <neil@daikokuya.co.uk>
 
        * Make-lang.in (CXX_C_OBJS): Update.
index 6dea0ddd52de157a1671d418d034d4ba9ec15428..7f6b32fc053f1cd18e48b74be80267b95c1ad743 100644 (file)
@@ -106,21 +106,18 @@ tree
 build_vfield_ref (datum, type)
      tree datum, type;
 {
-  tree rval;
-
   if (datum == error_mark_node)
     return error_mark_node;
 
   if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
     datum = convert_from_reference (datum);
 
-  if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type))
-    rval = build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
-                 datum, TYPE_VFIELD (type));
-  else
-    rval = build_component_ref (datum, DECL_NAME (TYPE_VFIELD (type)), NULL_TREE, 0);
+  if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
+      && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
+    datum = convert_to_base (datum, type, /*check_access=*/false);
 
-  return rval;
+  return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
+               datum, TYPE_VFIELD (type));
 }
 
 /* Build a call to a member of an object.  I.e., one that overloads
@@ -139,7 +136,9 @@ build_field_call (tree instance_ptr, tree decl, tree parms)
       /* If it's a field, try overloading operator (),
         or calling if the field is a pointer-to-function.  */
       instance = build_indirect_ref (instance_ptr, NULL);
-      instance = build_component_ref_1 (instance, decl, 0);
+      instance = build_class_member_access_expr (instance, decl, 
+                                                /*access_path=*/NULL_TREE,
+                                                /*preserve_reference=*/false);
 
       if (instance == error_mark_node)
        return error_mark_node;
@@ -2500,7 +2499,7 @@ build_user_type_conversion_1 (totype, expr, flags)
     {
       tree t;
 
-      ctors = TREE_VALUE (ctors);
+      ctors = BASELINK_FUNCTIONS (ctors);
 
       t = build_int_2 (0, 0);
       TREE_TYPE (t) = build_pointer_type (totype);
@@ -2796,10 +2795,10 @@ build_object_call (obj, args)
 
   if (fns)
     {
-      tree base = BINFO_TYPE (TREE_PURPOSE (fns));
+      tree base = BINFO_TYPE (BASELINK_BINFO (fns));
       mem_args = tree_cons (NULL_TREE, build_this (obj), args);
 
-      for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
+      for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
          if (TREE_CODE (fn) == TEMPLATE_DECL)
index 81b1a2c25f5ab5dab350186ae1c29af9e811be87..03f73f20561a3ec2bab006a0ae8418c620989e17 100644 (file)
@@ -358,6 +358,24 @@ build_base_path (code, expr, binfo, nonnull)
   return expr;
 }
 
+/* Convert OBJECT to the base TYPE.  If CHECK_ACCESS is true, an error
+   message is emitted if TYPE is inaccessible.  OBJECT is assumed to
+   be non-NULL.  */
+
+tree
+convert_to_base (tree object, tree type, bool check_access)
+{
+  tree binfo;
+
+  binfo = lookup_base (TREE_TYPE (object), type, 
+                      check_access ? ba_check : ba_ignore, 
+                      NULL);
+  if (!binfo || TREE_CODE (binfo) == error_mark_node)
+    return error_mark_node;
+
+  return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
+}
+
 \f
 /* Virtual function things.  */
 
@@ -4201,7 +4219,7 @@ type_requires_array_cookie (type)
   if (!fns || fns == error_mark_node)
     return false;
   /* Loop through all of the functions.  */
-  for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
+  for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
     {
       tree fn;
       tree second_parm;
@@ -6003,6 +6021,9 @@ instantiate_type (lhstype, rhs, flags)
       return error_mark_node;
     }
 
+  if (TREE_CODE (rhs) == BASELINK)
+    rhs = BASELINK_FUNCTIONS (rhs);
+
   /* We don't overwrite rhs if it is an overloaded function.
      Copying it would destroy the tree link.  */
   if (TREE_CODE (rhs) != OVERLOAD)
index a70ad50141247a411c81acbf371407c61424e83e..90685af50d4007adca53c24bd4d4c573cc4943db 100644 (file)
@@ -89,6 +89,20 @@ DEFTREECODE (THROW_EXPR, "throw_expr", 'e', 1)
    these to avoid actually creating instances of the empty classes.  */
 DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0)
 
+/* A reference to a member function or member functions from a base
+   class.  BASELINK_FUNCTIONS gives the FUNCTION_DECL,
+   TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
+   functions.  BASELINK_BINFO gives the base from which the functions
+   come, i.e., the base to which the `this' pointer must be converted
+   before the functions are called.  BASELINK_ACCESS_BINFO gives the
+   base used to name the functions.  
+
+   A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
+   the type of the expression.  This type is either a FUNCTION_TYPE,
+   METHOD_TYPE, or `unknown_type_node' indicating that the function is
+   overloaded. */
+DEFTREECODE (BASELINK, "baselink", 'e', 3)
+
 /* Template definition.  The following fields have the specified uses,
    although there are other macros in cp-tree.h that should be used for
    accessing this data.
index b1af9fbc56dae307afb6c8519fb090fae06c0d96..25b6e949d2d5dd1cb0d44061187c61595d85a0ac 100644 (file)
@@ -57,7 +57,6 @@ struct diagnostic_context;
       (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
       TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE).
       INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
-      BASELINK_P (in TREE_LIST)
       ICS_ELLIPSIS_FLAG (in _CONV)
       BINFO_ACCESS (in BINFO)
    2: IDENTIFIER_OPNAME_P.
@@ -361,32 +360,28 @@ struct tree_overload GTY(())
   tree function;
 };
 
-/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO
-   indicating a particular base class, and whose TREE_VALUE is a
-   (possibly overloaded) function from that base class.  */
+/* Returns true iff NODE is a BASELINK.  */
 #define BASELINK_P(NODE) \
-  (TREE_CODE (NODE) == TREE_LIST && TREE_LANG_FLAG_1 (NODE))
-#define SET_BASELINK_P(NODE) \
-  (TREE_LANG_FLAG_1 (NODE) = 1)
-/* The BINFO indicated the base from which the BASELINK_FUNCTIONS came.  */
+  (TREE_CODE (NODE) == BASELINK)
+/* The BINFO indicating the base from which the BASELINK_FUNCTIONS came.  */
 #define BASELINK_BINFO(NODE) \
-  (TREE_PURPOSE (NODE))
-/* The functions referred to by the BASELINK; either a FUNCTION_DECL
-   or an OVERLOAD.  */
+  (TREE_OPERAND (BASELINK_CHECK (NODE), 0))
+/* The functions referred to by the BASELINK; either a FUNCTION_DECL,
+   a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR.  */
 #define BASELINK_FUNCTIONS(NODE) \
-  (TREE_VALUE (NODE))
+  (TREE_OPERAND (BASELINK_CHECK (NODE), 1))
 /* The BINFO in which the search for the functions indicated by this baselink 
    began.  This base is used to determine the accessibility of functions 
    selected by overload resolution.  */
 #define BASELINK_ACCESS_BINFO(NODE) \
-  (TREE_TYPE (NODE))
+  (TREE_OPERAND (BASELINK_CHECK (NODE), 2))
 /* For a type-conversion operator, the BASELINK_OPTYPE indicates the type
    to which the conversion should occur.  This value is important if
    the BASELINK_FUNCTIONS include a template conversion operator --
    the BASELINK_OPTYPE can be used to determine what type the user
    requested.  */
 #define BASELINK_OPTYPE(NODE) \
-  (TREE_CHAIN (NODE))
+  (TREE_CHAIN (BASELINK_CHECK (NODE)))
 
 #define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)
 
@@ -3525,6 +3520,7 @@ extern tree perform_implicit_conversion         PARAMS ((tree, tree));
 
 /* in class.c */
 extern tree build_base_path                    PARAMS ((enum tree_code, tree, tree, int));
+extern tree convert_to_base                     (tree, tree, bool);
 extern tree build_vbase_path                   PARAMS ((enum tree_code, tree, tree, tree, int));
 extern tree build_vtbl_ref                     PARAMS ((tree, tree));
 extern tree build_vfn_ref                      PARAMS ((tree, tree));
@@ -4238,6 +4234,7 @@ extern tree cp_build_qualified_type_real        PARAMS ((tree, int, tsubst_flags
   cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
 extern tree build_shared_int_cst                PARAMS ((int));
 extern special_function_kind special_function_p PARAMS ((tree));
+extern bool name_p                              (tree);
 extern int count_trees                          PARAMS ((tree));
 extern int char_type_p                          PARAMS ((tree));
 extern void verify_stmt_tree                    PARAMS ((tree));
@@ -4277,10 +4274,8 @@ extern tree cxx_sizeof_or_alignof_type    PARAMS ((tree, enum tree_code, int));
 #define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
 extern tree inline_conversion                  PARAMS ((tree));
 extern tree decay_conversion                   PARAMS ((tree));
-extern tree build_object_ref                   PARAMS ((tree, tree, tree));
-extern tree build_component_ref_1              PARAMS ((tree, tree, int));
-extern tree build_component_ref                        PARAMS ((tree, tree, tree, int));
-extern tree build_x_component_ref              PARAMS ((tree, tree, tree));
+extern tree build_class_member_access_expr      (tree, tree, tree, bool);
+extern tree finish_class_member_access_expr     (tree, tree);
 extern tree build_x_indirect_ref               PARAMS ((tree, const char *));
 extern tree build_indirect_ref                 PARAMS ((tree, const char *));
 extern tree build_array_ref                    PARAMS ((tree, tree));
@@ -4321,6 +4316,7 @@ extern tree check_return_expr                   PARAMS ((tree));
   build_binary_op(code, arg1, arg2, 1)
 #define cxx_sizeof(T)  cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
 #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true)
+extern tree build_ptrmemfunc_access_expr       (tree, tree);
 
 /* in typeck2.c */
 extern void cxx_incomplete_type_diagnostic     PARAMS ((tree, tree, int));
index f64ba299cb5fde7b0152e1616298d1ae7798771c..fcf7e4536817e28a4007e4fdf0360cf64ff613aa 100644 (file)
@@ -10001,6 +10001,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            next = 0;
            break;
 
+         case BASELINK:
+           next = &BASELINK_FUNCTIONS (decl);
+           break;
+           
          default:
            internal_error ("`%D' as declarator", decl);
          }
@@ -11133,6 +11137,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          declarator = TREE_OPERAND (declarator, 0);
          break;
 
+       case BASELINK:
+         declarator = BASELINK_FUNCTIONS (declarator);
+         break;
+
        case RECORD_TYPE:
        case UNION_TYPE:
        case ENUMERAL_TYPE:
index 26442068c4e62939f9d7a807185ff31f447cd16b..bdd854f4d5a7ffb6baf1fd38efa992e50ed7a554 100644 (file)
@@ -3369,17 +3369,8 @@ build_expr_from_tree (t)
     case COMPONENT_REF:
       {
        tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
-       tree field = TREE_OPERAND (t, 1);
-       
-       /* We use a COMPONENT_REF to indicate things of the form `x.b'
-          and `x.A::b'.  We must distinguish between those cases
-          here.  */
-       if (TREE_CODE (field) == SCOPE_REF)
-         return build_object_ref (object, 
-                                  TREE_OPERAND (field, 0),
-                                  TREE_OPERAND (field, 1));
-       else
-         return build_x_component_ref (object, field, NULL_TREE);
+       return finish_class_member_access_expr (object, 
+                                               TREE_OPERAND (t, 1));
       }
 
     case THROW_EXPR:
@@ -4283,6 +4274,8 @@ arg_assoc (k, n)
     n = TREE_OPERAND (n, 1);
   while (TREE_CODE (n) == TREE_LIST)
     n = TREE_VALUE (n);
+  if (TREE_CODE (n) == BASELINK)
+    n = BASELINK_FUNCTIONS (n);
 
   if (TREE_CODE (n) == FUNCTION_DECL)
     return arg_assoc_type (k, TREE_TYPE (n));
@@ -4647,6 +4640,13 @@ do_class_using_decl (decl)
     }
   if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL)
     name = DECL_NAME (name);
+  else if (BASELINK_P (name))
+    {
+      name = BASELINK_FUNCTIONS (name);
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+       name = TREE_OPERAND (name, 0);
+      name = DECL_NAME (get_first_fn (name));
+    }
 
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
 
index bf55e25d1577318edccd0fc3ab0773424696995d..b6caac7d7892e84c8a61bb2f541b0e16bc096757 100644 (file)
@@ -990,6 +990,10 @@ dump_decl (t, flags)
       print_tree_identifier (scratch_buffer, DECL_NAME (t));
       break;
 
+    case BASELINK:
+      dump_decl (BASELINK_FUNCTIONS (t), flags);
+      break;
+
     default:
       sorry_for_unsupported_tree (t);
       /* Fallthrough to error.  */
@@ -1826,7 +1830,7 @@ dump_expr (t, flags)
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
        {
-         tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0);
+         tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
 
          if (integer_zerop (idx))
            {
index 321a142173bf3092200196681db6def43a02ac96..4b8b5ee85039b7049ace5e80f3187ea4d10aa83e 100644 (file)
@@ -174,17 +174,13 @@ static int
 dtor_nothrow (type)
      tree type;
 {
-  tree fn;
-
   if (type == NULL_TREE)
     return 0;
 
   if (! TYPE_HAS_DESTRUCTOR (type))
     return 1;
 
-  fn = lookup_member (type, dtor_identifier, 0, 0);
-  fn = TREE_VALUE (fn);
-  return TREE_NOTHROW (fn);
+  return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
 }
 
 /* Build up a call to __cxa_end_catch, to destroy the exception object
@@ -753,7 +749,7 @@ build_throw (exp)
        {
          cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
                                     complete_dtor_identifier, 0);
-         cleanup = TREE_VALUE (cleanup);
+         cleanup = BASELINK_FUNCTIONS (cleanup);
          mark_used (cleanup);
          cxx_mark_addressable (cleanup);
          /* Pretend it's a normal function.  */
index 6286a22775378e9f9c371a36ba69c7db1492d664..737cd9c15c11c111824f32d04882b3b0ddf8d06e 100644 (file)
@@ -232,8 +232,9 @@ perform_member_init (member, init, explicit)
   tree decl;
   tree type = TREE_TYPE (member);
 
-  decl = build_component_ref (current_class_ref, member, NULL_TREE, explicit);
-
+  decl = build_class_member_access_expr (current_class_ref, member,
+                                        /*access_path=*/NULL_TREE,
+                                        /*preserve_reference=*/true);
   if (decl == error_mark_node)
     return;
 
@@ -305,8 +306,9 @@ perform_member_init (member, init, explicit)
     {
       tree expr;
 
-      expr = build_component_ref (current_class_ref, member, NULL_TREE,
-                                 explicit);
+      expr = build_class_member_access_expr (current_class_ref, member,
+                                            /*access_path=*/NULL_TREE,
+                                            /*preserve_reference=*/false);
       expr = build_delete (type, expr, sfk_complete_destructor,
                           LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
 
@@ -1668,10 +1670,15 @@ build_offset_ref (type, name)
 
   decl = maybe_dummy_object (type, &basebinfo);
 
-  member = lookup_member (basebinfo, name, 1, 0);
-
-  if (member == error_mark_node)
-    return error_mark_node;
+  if (BASELINK_P (name))
+    member = name;
+  else
+    {
+      member = lookup_member (basebinfo, name, 1, 0);
+      
+      if (member == error_mark_node)
+       return error_mark_node;
+    }
 
   /* A lot of this logic is now handled in lookup_member.  */
   if (member && BASELINK_P (member))
@@ -1703,7 +1710,7 @@ build_offset_ref (type, name)
          return t;
        }
 
-      if (!really_overloaded_fn (t))
+      if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
        {
          /* Get rid of a potential OVERLOAD around it */
          t = OVL_CURRENT (t);
@@ -1848,7 +1855,9 @@ resolve_offset_ref (exp)
       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
        base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo);
 
-      return build_component_ref (base, member, binfo, 1);
+      return build_class_member_access_expr (base, member,
+                                            /*access_path=*/NULL_TREE,
+                                            /*preserve_reference=*/false);
     }
 
   /* Ensure that we have an object.  */
@@ -3332,9 +3341,10 @@ push_base_cleanups ()
        continue;
       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member)))
        {
-         tree this_member = (build_component_ref
-                             (current_class_ref, DECL_NAME (member),
-                              NULL_TREE, 0));
+         tree this_member = (build_class_member_access_expr 
+                             (current_class_ref, member, 
+                              /*access_path=*/NULL_TREE,
+                              /*preserve_reference=*/false));
          tree this_type = TREE_TYPE (member);
          expr = build_delete (this_type, this_member,
                               sfk_complete_destructor,
index 42d405f5e29433bf7177c992cf210980da0e69f3..5fa7433c8609ed0aa952f4e2a87d6ef38337b028 100644 (file)
@@ -161,12 +161,26 @@ hack_identifier (value, name)
          return error_mark_node;
        }
       TREE_USED (current_class_ptr) = 1;
+      if (processing_template_decl)
+       value = build_min_nt (COMPONENT_REF, current_class_ref, name);
+      else
+       {
+         tree access_type = current_class_type;
+         
+         while (!DERIVED_FROM_P (context_for_name_lookup (value), 
+                                 access_type))
+           {
+             access_type = TYPE_CONTEXT (access_type);
+             while (DECL_P (access_type))
+               access_type = DECL_CONTEXT (access_type);
+           }
 
-      /* Mark so that if we are in a constructor, and then find that
-        this field was initialized by a base initializer,
-        we can emit an error message.  */
-      TREE_USED (value) = 1;
-      value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
+         enforce_access (access_type, value);
+         value 
+           = build_class_member_access_expr (current_class_ref, value,
+                                             /*access_path=*/NULL_TREE,
+                                             /*preserve_reference=*/false);
+       }
     }
   else if ((TREE_CODE (value) == FUNCTION_DECL
            && DECL_FUNCTION_MEMBER_P (value))
@@ -179,7 +193,7 @@ hack_identifier (value, name)
        value = OVL_CURRENT (value);
 
       decl = maybe_dummy_object (DECL_CONTEXT (value), 0);
-      value = build_component_ref (decl, name, NULL_TREE, 1);
+      value = finish_class_member_access_expr (decl, name);
     }
   else if (really_overloaded_fn (value))
     ;
index b7b9d30c236c57ea5aea713cfcc20d8d34b852a1..01181d73b4c313ffd255e54a056ff2cd39ebe92b 100644 (file)
@@ -1520,11 +1520,11 @@ notype_unqualified_id:
 
 do_id:
                {
-                 /* If lastiddecl is a TREE_LIST, it's a baselink, which
-                    means that we're in an expression like S::f<int>, so
-                    don't do_identifier; we only do that for unqualified
+                 /* If lastiddecl is a BASELINK we're in an
+                    expression like S::f<int>, so don't
+                    do_identifier; we only do that for unqualified
                     identifiers.  */
-                 if (!lastiddecl || TREE_CODE (lastiddecl) != TREE_LIST)
+                 if (!lastiddecl || !BASELINK_P (lastiddecl))
                    $$ = do_identifier ($<ttype>-1, 1, NULL_TREE);
                  else
                    $$ = $<ttype>-1;
@@ -1718,20 +1718,15 @@ primary:
        | overqualified_id LEFT_RIGHT
                { $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
         | object object_template_id %prec UNARY
-                {
-                 $$ = build_x_component_ref ($$, $2, NULL_TREE);
-               }
+                { $$ = finish_class_member_access_expr ($$, $2); }
         | object object_template_id '(' nonnull_exprlist ')'
                 { $$ = finish_object_call_expr ($2, $1, $4); }
        | object object_template_id LEFT_RIGHT
                 { $$ = finish_object_call_expr ($2, $1, NULL_TREE); }
        | object unqualified_id  %prec UNARY
-               { $$ = build_x_component_ref ($$, $2, NULL_TREE); }
+               { $$ = finish_class_member_access_expr ($$, $2); }
        | object overqualified_id  %prec UNARY
-               { if (processing_template_decl)
-                   $$ = build_min_nt (COMPONENT_REF, $1, $2);
-                 else
-                   $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
+                { $$ = finish_class_member_access_expr ($1, $2); }
        | object unqualified_id '(' nonnull_exprlist ')'
                 { $$ = finish_object_call_expr ($2, $1, $4); }
        | object unqualified_id LEFT_RIGHT
@@ -4147,14 +4142,20 @@ parse_finish_call_expr (tree fn, tree args, int koenig)
              else 
                template_id = NULL_TREE;
 
-             if (TREE_CODE (name) == OVERLOAD)
-               name = DECL_NAME (get_first_fn (name));
-             fn = lookup_member (scope, name, /*protect=*/1, 
-                                 /*prefer_type=*/0);
-             if (BASELINK_P (fn) && template_id)
-               BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
-                                                   BASELINK_FUNCTIONS (fn),
-                                                   template_args);
+             if (BASELINK_P (name))
+               fn = name;
+             else 
+               {
+                 if (TREE_CODE (name) == OVERLOAD)
+                   name = DECL_NAME (get_first_fn (name));
+                 fn = lookup_member (scope, name, /*protect=*/1, 
+                                     /*prefer_type=*/0);
+                 if (BASELINK_P (fn) && template_id)
+                   BASELINK_FUNCTIONS (fn) 
+                     = build_nt (TEMPLATE_ID_EXPR,
+                                 BASELINK_FUNCTIONS (fn),
+                                 template_args);
+               }
              if (BASELINK_P (fn) 
                  && current_class_type 
                  && DERIVED_FROM_P (scope, current_class_type))
@@ -4216,9 +4217,19 @@ parse_finish_call_expr (tree fn, tree args, int koenig)
 
              if (DERIVED_FROM_P (scope, current_class_type)
                  && current_class_ref)
-               return finish_object_call_expr (fn,
-                                               current_class_ref,
-                                               args);
+               {
+                 fn = build_baselink (lookup_base (current_class_type,
+                                                   scope,
+                                                   ba_any,
+                                                   NULL),
+                                      TYPE_BINFO (current_class_type),
+                                      fn,
+                                      /*optype=*/NULL_TREE);
+                 return finish_object_call_expr (fn,
+                                                 current_class_ref,
+                                                 args);
+               }
+
 
              access_scope = current_class_type;
              while (!DERIVED_FROM_P (scope, access_scope))
index 406e54aa1b8c165df1947217b036c445f5d60211..af698747292755d229c485ebbc6f58f192c23698 100644 (file)
@@ -3833,10 +3833,20 @@ lookup_template_function (fns, arglist)
 
   my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
                      || TREE_CODE (fns) == OVERLOAD
+                     || BASELINK_P (fns)
                      || TREE_CODE (fns) == IDENTIFIER_NODE
                      || TREE_CODE (fns) == LOOKUP_EXPR,
                      20020730);
 
+  if (BASELINK_P (fns))
+    {
+      BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
+                                       unknown_type_node,
+                                       BASELINK_FUNCTIONS (fns),
+                                       arglist);
+      return fns;
+    }
+
   type = TREE_TYPE (fns);
   if (TREE_CODE (fns) == OVERLOAD || !type)
     type = unknown_type_node;
@@ -8193,8 +8203,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
     arg = TREE_OPERAND (arg, 1);
 
   /* Strip baselink information.  */
-  while (TREE_CODE (arg) == TREE_LIST)
-    arg = TREE_VALUE (arg);
+  if (BASELINK_P (arg))
+    arg = BASELINK_FUNCTIONS (arg);
 
   if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
     {
index 48c4f8fbe46f6ec05dd7a690743a73453f2df306..071a551fbe36b929f18a83d12fd2b8c9bb0c2ec6 100644 (file)
@@ -300,8 +300,10 @@ lookup_base_r (binfo, base, access, within_current_scope,
    canonical).  If KIND_PTR is non-NULL, fill with information about
    what kind of base we discovered.
 
-   If ba_quiet bit is set in ACCESS, then do not issue an error, and
-   return NULL_TREE for failure.  */
+   If the base is inaccessible, or ambiguous, and the ba_quiet bit is
+   not set in ACCESS, then an error is issued and error_mark_node is
+   returned.  If the ba_quiet bit is set, then no error is issued and
+   NULL_TREE is returned.  */
 
 tree
 lookup_base (t, base, access, kind_ptr)
@@ -1385,9 +1387,10 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
                      || TREE_CODE (functions) == OVERLOAD,
                      20020730);
   my_friendly_assert (!optype || TYPE_P (optype), 20020730);
+  my_friendly_assert (TREE_TYPE (functions), 20020805);
 
-  baselink = build_tree_list (NULL_TREE, NULL_TREE);
-  SET_BASELINK_P (baselink);
+  baselink = build (BASELINK, TREE_TYPE (functions), NULL_TREE,
+                   NULL_TREE, NULL_TREE);
   BASELINK_BINFO (baselink) = binfo;
   BASELINK_ACCESS_BINFO (baselink) = access_binfo;
   BASELINK_FUNCTIONS (baselink) = functions;
@@ -1522,7 +1525,7 @@ lookup_field (xbasetype, name, protect, want_type)
   tree rval = lookup_member (xbasetype, name, protect, want_type);
   
   /* Ignore functions.  */
-  if (rval && TREE_CODE (rval) == TREE_LIST)
+  if (rval && BASELINK_P (rval))
     return NULL_TREE;
 
   return rval;
@@ -1539,7 +1542,7 @@ lookup_fnfields (xbasetype, name, protect)
   tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/0);
 
   /* Ignore non-functions.  */
-  if (rval && TREE_CODE (rval) != TREE_LIST)
+  if (rval && !BASELINK_P (rval))
     return NULL_TREE;
 
   return rval;
@@ -2436,7 +2439,7 @@ setup_class_bindings (name, type_binding_p)
        {
          if (BASELINK_P (value_binding))
            /* NAME is some overloaded functions.  */
-           value_binding = TREE_VALUE (value_binding);
+           value_binding = BASELINK_FUNCTIONS (value_binding);
          pushdecl_class_level (value_binding);
        }
     }
index 58d1647cd681e5d0ecb143718e41d8c653574cec..a1b34d75c7852e2bc231105d4b8b0ab510aa8e08 100644 (file)
@@ -1400,7 +1400,10 @@ finish_object_call_expr (fn, object, args)
        }
     }
   
-  return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
+  if (name_p (fn))
+    return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
+  else
+    return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
 }
 
 /* Finish a qualified member function call using OBJECT and ARGS as
index 27bc572b3da7ed5a222e3ed72a3d51102f3a605f..efeae64a71122a4fbaa940e7d271f7e3939d1048 100644 (file)
@@ -595,8 +595,8 @@ identifier_type (decl)
   if (looking_for_template && really_overloaded_fn (decl))
     {
       /* See through a baselink.  */
-      if (TREE_CODE (decl) == TREE_LIST)
-       decl = TREE_VALUE (decl);
+      if (TREE_CODE (decl) == BASELINK)
+       decl = BASELINK_FUNCTIONS (decl);
 
       for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
        if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
index 369e46a9f25d064a46d89c1035a7f13dadaac43f..ef870765fe8e36a48605162c723946cb3ca584a8 100644 (file)
@@ -964,7 +964,7 @@ really_overloaded_fn (x)
   if (BASELINK_P (x))
     x = BASELINK_FUNCTIONS (x);
   return (TREE_CODE (x) == OVERLOAD 
-         && (TREE_CHAIN (x) != NULL_TREE
+         && (OVL_CHAIN (x)
              || DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x))));
 }
 
@@ -2446,8 +2446,8 @@ cxx_unsave_expr_now (tp)
 }
 
 /* Returns the kind of special function that DECL (a FUNCTION_DECL)
-   is.  Note that this sfk_none is zero, so this function can be used
-   as a predicate to test whether or not DECL is a special function.  */
+   is.  Note that sfk_none is zero, so this function can be used as a
+   predicate to test whether or not DECL is a special function.  */
 
 special_function_kind
 special_function_p (decl)
@@ -2476,6 +2476,22 @@ special_function_p (decl)
   return sfk_none;
 }
 
+/* Returns true if and only if NODE is a name, i.e., a node created
+   by the parser when processing an id-expression.  */
+
+bool
+name_p (tree node)
+{
+  if (TREE_CODE (node) == TEMPLATE_ID_EXPR)
+    node = TREE_OPERAND (node, 0);
+  return (/* An ordinary unqualified name.  */
+         TREE_CODE (node) == IDENTIFIER_NODE
+         /* A destructor name.  */
+         || TREE_CODE (node) == BIT_NOT_EXPR
+         /* A qualified name.  */
+         || TREE_CODE (node) == SCOPE_REF);
+}
+
 /* Returns non-zero if TYPE is a character type, including wchar_t.  */
 
 int
index 399005bc6910f85b1171c58c6fc0523b1820561e..6ac38224a248ea8455861f14de514575e1419e73 100644 (file)
@@ -1758,45 +1758,6 @@ string_conv_p (totype, exp, warn)
 
   return 1;
 }
-\f
-tree
-build_object_ref (datum, basetype, field)
-     tree datum, basetype, field;
-{
-  tree dtype;
-  if (datum == error_mark_node)
-    return error_mark_node;
-
-  dtype = TREE_TYPE (datum);
-  if (TREE_CODE (dtype) == REFERENCE_TYPE)
-    dtype = TREE_TYPE (dtype);
-  if (! IS_AGGR_TYPE_CODE (TREE_CODE (dtype)))
-    {
-      error ("request for member `%T::%D' in expression of non-aggregate type `%T'",
-               basetype, field, dtype);
-      return error_mark_node;
-    }
-  else if (is_aggr_type (basetype, 1))
-    {
-      tree binfo = NULL_TREE;
-      datum = build_scoped_ref (datum, basetype, &binfo);
-      return build_x_component_ref (datum, field, binfo);
-    }
-  return error_mark_node;
-}
-
-/* Like `build_component_ref, but uses an already found field, and converts
-   from a reference.  Must compute access for current_class_ref.
-   Otherwise, ok.  */
-
-tree
-build_component_ref_1 (datum, field, protect)
-     tree datum, field;
-     int protect;
-{
-  return convert_from_reference
-    (build_component_ref (datum, field, NULL_TREE, protect));
-}
 
 /* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we
    can, for example, use as an lvalue.  This code used to be in
@@ -1868,342 +1829,406 @@ lookup_anon_field (t, type)
   return NULL_TREE;
 }
 
-/* Build a COMPONENT_REF for a given DATUM, and it's member COMPONENT.
-   COMPONENT can be an IDENTIFIER_NODE that is the name of the member
-   that we are interested in, or it can be a FIELD_DECL.  */
+/* Build an expression representing OBJECT.MEMBER.  OBJECT is an
+   expression; MEMBER is a DECL or baselink.  If ACCESS_PATH is
+   non-NULL, it indicates the path to the base used to name MEMBER.
+   If PRESERVE_REFERENCE is true, the expression returned will have
+   REFERENCE_TYPE if the MEMBER does.  Otherwise, the expression
+   returned will have the type referred to by the reference. 
+
+   This function does not perform access control; that is either done
+   earlier by the parser when the name of MEMBER is resolved to MEMBER
+   itself, or later when overload resolution selects one of the
+   functions indicated by MEMBER.  */
 
 tree
-build_component_ref (datum, component, basetype_path, protect)
-     tree datum, component, basetype_path;
-     int protect;
+build_class_member_access_expr (tree object, tree member, 
+                               tree access_path, bool preserve_reference)
 {
-  register tree basetype;
-  register enum tree_code code;
-  register tree field = NULL;
-  register tree ref;
-  tree field_type;
-  int type_quals;
-  tree old_datum;
-  tree old_basetype;
+  tree object_type;
+  tree member_scope;
+  tree result = NULL_TREE;
 
-  if (processing_template_decl)
-    return build_min_nt (COMPONENT_REF, datum, component);
-  
-  if (datum == error_mark_node 
-      || TREE_TYPE (datum) == error_mark_node)
+  if (object == error_mark_node || member == error_mark_node)
     return error_mark_node;
 
-  /* BASETYPE holds the type of the class containing the COMPONENT.  */
-  basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
-    
-  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference
-     inside it.  */
-  switch (TREE_CODE (datum))
-    {
-    case COMPOUND_EXPR:
-      {
-       tree value = build_component_ref (TREE_OPERAND (datum, 1), component,
-                                         basetype_path, protect);
-       return build (COMPOUND_EXPR, TREE_TYPE (value),
-                     TREE_OPERAND (datum, 0), value);
-      }
-    case COND_EXPR:
-      return build_conditional_expr
-       (TREE_OPERAND (datum, 0),
-        build_component_ref (TREE_OPERAND (datum, 1), component,
-                             basetype_path, protect),
-        build_component_ref (TREE_OPERAND (datum, 2), component,
-                             basetype_path, protect));
-
-    case TEMPLATE_DECL:
-      error ("invalid use of `%D'", datum);
-      datum = error_mark_node;
-      break;
-
-    default:
-      break;
-    }
+  my_friendly_assert (DECL_P (member) || BASELINK_P (member),
+                     20020801);
 
-  code = TREE_CODE (basetype);
+  /* [expr.ref]
 
-  if (code == REFERENCE_TYPE)
-    {
-      datum = convert_from_reference (datum);
-      basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
-      code = TREE_CODE (basetype);
-    }
-  if (TREE_CODE (datum) == OFFSET_REF)
+     The type of the first expression shall be "class object" (of a
+     complete type).  */
+  object_type = TREE_TYPE (object);
+  if (!complete_type_or_else (object_type, object))
+    return error_mark_node;
+  if (!CLASS_TYPE_P (object_type))
     {
-      datum = resolve_offset_ref (datum);
-      basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
-      code = TREE_CODE (basetype);
+      error ("request for member `%D' in `%E', which is of non-class type `%T'", 
+            member, object, object_type);
+      return error_mark_node;
     }
 
-  /* First, see if there is a field or component with name COMPONENT.  */
-  if (TREE_CODE (component) == TREE_LIST)
+  /* The standard does not seem to actually say that MEMBER must be a
+     member of OBJECT_TYPE.  However, that is clearly what is
+     intended.  */
+  if (DECL_P (member))
     {
-      /* I could not trigger this code. MvL */
-      abort ();
-#ifdef DEAD
-      my_friendly_assert (!(TREE_CHAIN (component) == NULL_TREE
-               && DECL_CHAIN (TREE_VALUE (component)) == NULL_TREE), 309);
-#endif
-      return build (COMPONENT_REF, TREE_TYPE (component), datum, component);
+      member_scope = DECL_CLASS_CONTEXT (member);
+      mark_used (member);
+      if (TREE_DEPRECATED (member))
+       warn_deprecated_use (member);
+    }
+  else
+    member_scope = BINFO_TYPE (BASELINK_BINFO (member));
+  /* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
+     presently be the anonymous union.  Go outwards until we find a
+     type related to OBJECT_TYPE.  */
+  while (ANON_AGGR_TYPE_P (member_scope)
+        && !same_type_ignoring_top_level_qualifiers_p (member_scope,
+                                                       object_type))
+    member_scope = TYPE_CONTEXT (member_scope);
+  if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
+    {
+      error ("`%D' is not a member of `%T'", member, object_type);
+      return error_mark_node;
     }
 
-  if (! IS_AGGR_TYPE_CODE (code))
+  /* In [expr.ref], there is an explicit list of the valid choices for
+     MEMBER.  We check for each of those cases here.  */
+  if (TREE_CODE (member) == VAR_DECL)
     {
-      if (code != ERROR_MARK)
-       error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
-                 component, datum, basetype);
-      return error_mark_node;
+      /* A static data member.  */
+      result = member;
+      /* If OBJECT has side-effects, they are supposed to occur.  */
+      if (TREE_SIDE_EFFECTS (object))
+       result = build (COMPOUND_EXPR, TREE_TYPE (result), object, result);
     }
+  else if (TREE_CODE (member) == FIELD_DECL)
+    {
+      /* A non-static data member.  */
+      bool null_object_p;
+      int type_quals;
+      tree member_type;
 
-  if (!complete_type_or_else (basetype, datum))
-    return error_mark_node;
+      null_object_p = (TREE_CODE (object) == INDIRECT_REF
+                      && integer_zerop (TREE_OPERAND (object, 0)));
 
-  if (TREE_CODE (component) == BIT_NOT_EXPR)
-    {
-      if (TYPE_IDENTIFIER (basetype) != TREE_OPERAND (component, 0))
+      /* Convert OBJECT to the type of MEMBER.  */
+      if (!same_type_p (object_type, member_scope))
        {
-         error ("destructor specifier `%T::~%T' must have matching names",
-                   basetype, TREE_OPERAND (component, 0));
-         return error_mark_node;
+         tree binfo;
+         base_kind kind;
+
+         binfo = lookup_base (access_path ? access_path : object_type,
+                              member_scope, ba_ignore,  &kind);
+         if (binfo == error_mark_node)
+           return error_mark_node;
+
+         /* It is invalid to use to try to get to a virtual base of a
+            NULL object.  The most common cause is invalid use of
+            offsetof macro.  */
+         if (null_object_p && kind == bk_via_virtual)
+           {
+             error ("invalid access to non-static data member `%D' of NULL object",
+                    member);
+             error ("(perhaps the `offsetof' macro was used incorrectly)");
+             return error_mark_node;
+           }
+
+         /* Convert to the base.  */
+         object = build_base_path (PLUS_EXPR, object, binfo, 
+                                   /*nonnull=*/1);
+         /* If we found the base successfully then we should be able
+            to convert to it successfully.  */
+         my_friendly_assert (object != error_mark_node,
+                             20020801);
        }
-      if (! TYPE_HAS_DESTRUCTOR (basetype))
+      
+      /* Issue a warning about access a member of a NULL object.  */
+      if (null_object_p && CLASSTYPE_NON_POD_P (object_type))
        {
-         error ("type `%T' has no destructor", basetype);
+         warning ("invalid access to non-static data member `%D' of NULL object", 
+                  member);
+         warning  ("(perhaps the `offsetof' macro was used incorrectly)");
          return error_mark_node;
        }
-      return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1);
-    }
 
-  /* Look up component name in the structure type definition.  */
-  if (TYPE_VFIELD (basetype)
-      && DECL_NAME (TYPE_VFIELD (basetype)) == component)
-    /* Special-case this because if we use normal lookups in an ambiguous
-       hierarchy, the compiler will abort (because vptr lookups are
-       not supposed to be ambiguous.  */
-    field = TYPE_VFIELD (basetype);
-  else if (TREE_CODE (component) == FIELD_DECL)
-    field = component;
-  else if (TREE_CODE (component) == TYPE_DECL)
+      /* If MEMBER is from an anonymous aggregate, we have converted
+        OBJECT so that it refers to the class containing the
+        anonymous union.  Generate a reference to the anonymous union
+        itself, and recur to find MEMBER.  */
+      if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member)))
+       {
+         tree anonymous_union;
+
+         anonymous_union = lookup_anon_field (TREE_TYPE (object),
+                                              DECL_CONTEXT (member));
+         object = build_class_member_access_expr (object,
+                                                  anonymous_union,
+                                                  /*access_path=*/NULL_TREE,
+                                                  preserve_reference);
+       }
+
+      /* Compute the type of the field, as described in [expr.ref].  */
+      type_quals = TYPE_UNQUALIFIED;
+      member_type = TREE_TYPE (member);
+      if (TREE_CODE (member_type) != REFERENCE_TYPE)
+       {
+         type_quals = (cp_type_quals (member_type)  
+                       | cp_type_quals (object_type));
+         
+         /* A field is const (volatile) if the enclosing object, or the
+            field itself, is const (volatile).  But, a mutable field is
+            not const, even within a const object.  */
+         if (DECL_MUTABLE_P (member))
+           type_quals &= ~TYPE_QUAL_CONST;
+         member_type = cp_build_qualified_type (member_type, type_quals);
+       }
+
+      result = fold (build (COMPONENT_REF, member_type, object, member));
+
+      /* Mark the expression const or volatile, as appropriate.  Even
+        though we've dealt with the type above, we still have to mark the
+        expression itself.  */
+      if (type_quals & TYPE_QUAL_CONST)
+       TREE_READONLY (result) = 1;
+      else if (type_quals & TYPE_QUAL_VOLATILE)
+       TREE_THIS_VOLATILE (result) = 1;
+    }
+  else if (BASELINK_P (member))
     {
-      error ("invalid use of type decl `%#D' as expression", component);
-      return error_mark_node;
+      /* The member is a (possibly overloaded) member function.  */
+      tree functions;
+
+      /* If the MEMBER is exactly one static member function, then we
+        know the type of the expression.  Otherwise, we must wait
+        until overload resolution has been performed.  */
+      functions = BASELINK_FUNCTIONS (member);
+      if (TREE_CODE (functions) == FUNCTION_DECL
+         && DECL_STATIC_FUNCTION_P (functions))
+       {
+         /* A static member function.  */
+         result = functions;
+         mark_used (result);
+         /* If OBJECT has side-effects, they are supposed to occur.  */
+         if (TREE_SIDE_EFFECTS (object))
+           result = build (COMPOUND_EXPR, TREE_TYPE (result),
+                           object, result);
+       }
+      else
+       /* Note that we do not convert OBJECT to the BASELINK_BINFO
+          base.  That will happen when the function is called.  */
+       result = build (COMPONENT_REF, unknown_type_node, object, member);
     }
-  else if (TREE_CODE (component) == TEMPLATE_DECL)
+  else if (TREE_CODE (member) == CONST_DECL)
     {
-      error ("invalid use of template `%#D' as expression", component);
-      return error_mark_node;
+      /* The member is an enumerator.  */
+      result = member;
+      /* If OBJECT has side-effects, they are supposed to occur.  */
+      if (TREE_SIDE_EFFECTS (object))
+       result = build (COMPOUND_EXPR, TREE_TYPE (result),
+                       object, result);
     }
   else
     {
-      tree name = component;
-      
-      if (TREE_CODE (component) == TEMPLATE_ID_EXPR)
-       name = TREE_OPERAND (component, 0);
-      else if (TREE_CODE (component) == VAR_DECL)
-       name = DECL_NAME (component);
-      if (TREE_CODE (component) == NAMESPACE_DECL)
-        /* Source is in error, but produce a sensible diagnostic.  */
-        name = DECL_NAME (component);
-      if (basetype_path == NULL_TREE)
-       basetype_path = TYPE_BINFO (basetype);
-      field = lookup_field (basetype_path, name,
-                           protect && !VFIELD_NAME_P (name), 0);
-      if (field == error_mark_node)
-       return error_mark_node;
+      error ("invalid use of `%D'", member);
+      return error_mark_node;
+    }
 
-      if (field == NULL_TREE)
-       {
-         /* Not found as a data field, look for it as a method.  If found,
-            then if this is the only possible one, return it, else
-            report ambiguity error.  */
-         tree fndecls = lookup_fnfields (basetype_path, name, 1);
-         if (fndecls == error_mark_node)
-           return error_mark_node;
-         if (fndecls)
-           {
-             /* If the function is unique and static, we can resolve it
-                now.  Otherwise, we have to wait and see what context it is
-                used in; a component_ref involving a non-static member
-                function can only be used in a call (expr.ref).  */
-             
-             if (TREE_CHAIN (fndecls) == NULL_TREE
-                 && TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL)
-               {
-                 if (DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls)))
-                   {
-                     tree fndecl = TREE_VALUE (fndecls);
-                     enforce_access (basetype_path, fndecl);
-                     mark_used (fndecl);
-                     return fndecl;
-                   }
-                 else
-                   {
-                     /* A unique non-static member function.  Other parts
-                        of the compiler expect something with
-                        unknown_type_node to be really overloaded, so
-                        let's oblige.  */
-                     TREE_VALUE (fndecls)
-                       = ovl_cons (TREE_VALUE (fndecls), NULL_TREE);
-                   }
-               }
+  if (!preserve_reference)
+    /* [expr.ref]
+       
+       If E2 is declared to have type "reference to T", then ... the
+       type of E1.E2 is T.  */
+    result = convert_from_reference (result);
 
-             fndecls = TREE_VALUE (fndecls);
-             
-             if (IDENTIFIER_TYPENAME_P (name))
-               {
-                 /* We want for a conversion op. We need to remember
-                    the actual type we wanted, in case we got a set of
-                    templated conversion operators back.  */
-                 fndecls = ovl_cons (OVL_CURRENT (fndecls),
-                                     OVL_NEXT (fndecls));
-                 TREE_TYPE (fndecls) = TREE_TYPE (name);
-               }
-             else if (TREE_CODE (component) == TEMPLATE_ID_EXPR)
-               fndecls = build_nt (TEMPLATE_ID_EXPR,
-                                   fndecls, TREE_OPERAND (component, 1));
-             
-             ref = build (COMPONENT_REF, unknown_type_node,
-                          datum, fndecls);
-             return ref;
-           }
+  return result;
+}
 
-         error ("`%#T' has no member named `%D'", basetype, name);
-         return error_mark_node;
-       }
-      else if (TREE_TYPE (field) == error_mark_node)
-       return error_mark_node;
+/* This function is called by the parser to process a class member
+   access expression of the form OBJECT.NAME.  NAME is a node used by
+   the parser to represent a name; it is not yet a DECL.  It may,
+   however, be a BASELINK where the BASELINK_FUNCTIONS is a
+   TEMPLATE_ID_EXPR.  Templates must be looked up by the parser, and
+   there is no reason to do the lookup twice, so the parser keeps the
+   BASELINK.  */
 
-      if (TREE_CODE (field) != FIELD_DECL)
-       {
-         if (TREE_CODE (field) == TYPE_DECL)
-           pedwarn ("invalid use of type decl `%#D' as expression", field);
-         else if (DECL_RTL (field) != 0)
-           mark_used (field);
-         else
-           TREE_USED (field) = 1;
+tree
+finish_class_member_access_expr (tree object, tree name)
+{
+  tree object_type;
+  tree member;
+  tree access_path = NULL_TREE;
+
+  if (object == error_mark_node || name == error_mark_node)
+    return error_mark_node;
 
-         /* Do evaluate the object when accessing a static member.  */
-         if (TREE_SIDE_EFFECTS (datum))
-           field = build (COMPOUND_EXPR, TREE_TYPE (field), datum, field);
+  if (processing_template_decl)
+    return build_min_nt (COMPONENT_REF, object, name);
+  
+  if (TREE_CODE (object) == OFFSET_REF)
+    object = resolve_offset_ref (object);
 
-         return field;
-       }
+  object_type = TREE_TYPE (object);
+  if (TREE_CODE (object_type) == REFERENCE_TYPE)
+    {
+      object = convert_from_reference (object);
+      object_type = TREE_TYPE (object);
     }
 
-  if (TREE_DEPRECATED (field))
-    warn_deprecated_use (field);
+  /* [expr.ref]
 
-  old_datum = datum;
-  old_basetype = basetype;
+     The type of the first expression shall be "class object" (of a
+     complete type).  */
+  if (!complete_type_or_else (object_type, object))
+    return error_mark_node;
+  if (!CLASS_TYPE_P (object_type))
+    {
+      error ("request for member `%D' in `%E', which is of non-class type `%T'", 
+            name, object, object_type);
+      return error_mark_node;
+    }
 
-  /* See if we have to do any conversions so that we pick up the field from the
-     right context.  */
-  if (DECL_FIELD_CONTEXT (field) != basetype)
+  if (BASELINK_P (name))
     {
-      tree context = DECL_FIELD_CONTEXT (field);
-      tree base = context;
-      while (!same_type_p (base, basetype) && TYPE_NAME (base)
-            && ANON_AGGR_TYPE_P (base))
-       base = TYPE_CONTEXT (base);
+      /* A member function that has already been looked up.  */
+      my_friendly_assert ((TREE_CODE (BASELINK_FUNCTIONS (name)) 
+                          == TEMPLATE_ID_EXPR), 
+                         20020805);
+      member = name;
+    }
+  else
+    {
+      bool is_template_id = false;
+      tree template_args = NULL_TREE;
 
-      /* Handle base classes here...  */
-      if (base != basetype && TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype))
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        {
-         base_kind kind;
-         tree binfo = lookup_base (TREE_TYPE (datum), base, ba_check, &kind);
+         is_template_id = true;
+         template_args = TREE_OPERAND (name, 1);
+         name = TREE_OPERAND (name, 0);
+       }
 
-         /* Complain about use of offsetof which will break.  */
-         if (TREE_CODE (datum) == INDIRECT_REF
-             && integer_zerop (TREE_OPERAND (datum, 0))
-             && kind == bk_via_virtual)
+      if (TREE_CODE (name) == SCOPE_REF)
+       {
+         tree scope;
+
+         /* A qualified name.  The qualifying class or namespace `S' has
+            already been looked up; it is either a TYPE or a
+            NAMESPACE_DECL.  The member name is either an IDENTIFIER_NODE
+            or a BIT_NOT_EXPR.  */
+         scope = TREE_OPERAND (name, 0);
+         name = TREE_OPERAND (name, 1);
+         my_friendly_assert ((CLASS_TYPE_P (scope) 
+                              || TREE_CODE (scope) == NAMESPACE_DECL),
+                             20020804);
+         my_friendly_assert ((TREE_CODE (name) == IDENTIFIER_NODE
+                              || TREE_CODE (name) == BIT_NOT_EXPR),
+                             20020804);
+
+         /* If SCOPE is a namespace, then the qualified name does not
+            name a member of OBJECT_TYPE.  */
+         if (TREE_CODE (scope) == NAMESPACE_DECL)
            {
-             error ("\
-invalid offsetof from non-POD type `%#T'; use pointer to member instead",
-                    basetype);
+             error ("`%D::%D' is not a member of `%T'", 
+                    scope, member, object_type);
              return error_mark_node;
            }
-         datum = build_base_path (PLUS_EXPR, datum, binfo, 1);
-         if (datum == error_mark_node)
+
+         /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
+         access_path = lookup_base (object_type, scope, ba_check, NULL);
+         if (!access_path || access_path == error_mark_node)
+           return error_mark_node;
+
+         /* Look up the member.  */
+         member = lookup_member (access_path, name, /*protect=*/1, 
+                                 /*want_type=*/0);
+         if (member == error_mark_node)
            return error_mark_node;
        }
-      basetype = base;
-      /* Handle things from anon unions here...  */
-      if (TYPE_NAME (context) && ANON_AGGR_TYPE_P (context))
+      else if (TREE_CODE (name) == BIT_NOT_EXPR)
+       {
+         /* A destructor.  */
+         if (TYPE_IDENTIFIER (object_type) != TREE_OPERAND (name, 0))
+           {
+             error ("destructor specifier `%T::~%T' must have matching names",
+                    object_type, TREE_OPERAND (name, 0));
+             return error_mark_node;
+           }
+         if (! TYPE_HAS_DESTRUCTOR (object_type))
+           {
+             error ("type `%T' has no destructor", object_type);
+             return error_mark_node;
+           }
+         member = CLASSTYPE_DESTRUCTORS (object_type);
+       }
+      else if (TREE_CODE (name) == IDENTIFIER_NODE)
        {
-         tree subfield = lookup_anon_field (basetype, context);
-         tree subdatum = build_component_ref (datum, subfield,
-                                              basetype_path, protect);
-         return build_component_ref (subdatum, field, basetype_path, protect);
+         /* An unqualified name.  */
+         member = lookup_member (object_type, name, /*protect=*/1, 
+                                 /*want_type=*/0);
+         if (member == error_mark_node)
+           return error_mark_node;
+       }
+      else
+       {
+         /* The YACC parser sometimes gives us things that are not names.
+            These always indicate errors.  The recursive-descent parser
+            does not do this, so this code can go away once that parser
+            replaces the YACC parser.  */
+         error ("invalid use of `%D'", name);
+         return error_mark_node;
+       }
+      
+      if (is_template_id)
+       {
+         tree template = member;
+         
+         if (BASELINK_P (template))
+           BASELINK_FUNCTIONS (template) 
+             = build_nt (TEMPLATE_ID_EXPR,
+                         BASELINK_FUNCTIONS (template),
+                         template_args);
+         else
+           {
+             error ("`%D' is not a member template function", name);
+             return error_mark_node;
+           }
        }
     }
 
-  /* Complain about other invalid uses of offsetof, even though they will
-     give the right answer.  Note that we complain whether or not they
-     actually used the offsetof macro, since there's no way to know at this
-     point.  So we just give a warning, instead of a pedwarn.  */
-  if (protect
-      && CLASSTYPE_NON_POD_P (old_basetype)
-      && TREE_CODE (old_datum) == INDIRECT_REF
-      && integer_zerop (TREE_OPERAND (old_datum, 0)))
-    warning ("\
-invalid offsetof from non-POD type `%#T'; use pointer to member instead",
-            basetype);
-
-  /* Compute the type of the field, as described in [expr.ref].  */
-  type_quals = TYPE_UNQUALIFIED;
-  field_type = TREE_TYPE (field);
-  if (TREE_CODE (field_type) == REFERENCE_TYPE)
-    /* The standard says that the type of the result should be the
-       type referred to by the reference.  But for now, at least, we
-       do the conversion from reference type later.  */
-    ;
-  else
-    {
-      type_quals = (cp_type_quals (field_type)  
-                   | cp_type_quals (TREE_TYPE (datum)));
-
-      /* A field is const (volatile) if the enclosing object, or the
-        field itself, is const (volatile).  But, a mutable field is
-        not const, even within a const object.  */
-      if (DECL_MUTABLE_P (field))
-       type_quals &= ~TYPE_QUAL_CONST;
-      field_type = cp_build_qualified_type (field_type, type_quals);
-    }
-
-  ref = fold (build (COMPONENT_REF, field_type, datum, field));
-
-  /* Mark the expression const or volatile, as appropriate.  Even
-     though we've dealt with the type above, we still have to mark the
-     expression itself.  */
-  if (type_quals & TYPE_QUAL_CONST)
-    TREE_READONLY (ref) = 1;
-  else if (type_quals & TYPE_QUAL_VOLATILE)
-    TREE_THIS_VOLATILE (ref) = 1;
-
-  return ref;
+  return build_class_member_access_expr (object, member, access_path,
+                                        /*preserve_reference=*/false);
 }
 
-/* Variant of build_component_ref for use in expressions, which should
-   never have REFERENCE_TYPE.  */
+/* Return an expression for the MEMBER_NAME field in the internal
+   representation of PTRMEM, a pointer-to-member function.  (Each
+   pointer-to-member function type gets its own RECORD_TYPE so it is
+   more convenient to access the fields by name than by FIELD_DECL.)
+   This routine converts the NAME to a FIELD_DECL and then creates the
+   node for the complete expression.  */
 
 tree
-build_x_component_ref (datum, component, basetype_path)
-     tree datum, component, basetype_path;
+build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
 {
-  tree t = build_component_ref (datum, component, basetype_path, 
-                               /*protect=*/1);
-
-  if (! processing_template_decl)
-    t = convert_from_reference (t);
-
-  return t;
+  tree ptrmem_type;
+  tree member;
+  tree member_type;
+
+  /* This code is a stripped down version of
+     build_class_member_access_expr.  It does not work to use that
+     routine directly because it expects the object to be of class
+     type.  */
+  ptrmem_type = TREE_TYPE (ptrmem);
+  my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804);
+  member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
+                         /*want_type=*/0);
+  member_type = cp_build_qualified_type (TREE_TYPE (member),
+                                        cp_type_quals (ptrmem_type));
+  return fold (build (COMPONENT_REF, member_type, ptrmem, member));
 }
-\f
+
 /* Given an expression PTR for a pointer, return an expression
    for the value pointed to.
    ERRORSTRING is the name of the operator to appear in error messages.
@@ -2505,7 +2530,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
 
       /* Start by extracting all the information from the PMF itself.  */
       e3 = PFN_FROM_PTRMEMFUNC (function);
-      delta = build_component_ref (function, delta_identifier, NULL_TREE, 0);
+      delta = build_ptrmemfunc_access_expr (function, delta_identifier);
       idx = build1 (NOP_EXPR, vtable_index_type, e3);
       switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
        {
@@ -3219,7 +3244,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
        }
       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
        {
-         op0 = build_component_ref (op0, pfn_identifier, NULL_TREE, 0);
+         op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
          op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
          result_type = TREE_TYPE (op0);
        }
@@ -3253,10 +3278,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
             DELTA field is unspecified.  */
          pfn0 = pfn_from_ptrmemfunc (op0);
          pfn1 = pfn_from_ptrmemfunc (op1);
-         delta0 = build_component_ref (op0, delta_identifier,
-                                       NULL_TREE, 0);
-         delta1 = build_component_ref (op1, delta_identifier,
-                                       NULL_TREE, 0);
+         delta0 = build_ptrmemfunc_access_expr (op0,
+                                                delta_identifier);
+         delta1 = build_ptrmemfunc_access_expr (op1,
+                                                delta_identifier);
          e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
          e2 = cp_build_binary_op (EQ_EXPR, 
                                   pfn0,
@@ -4191,7 +4216,7 @@ build_unary_op (code, xarg, noconvert)
        }
 
       if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
-          && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
+         && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
         {
          /* They're trying to take the address of a unique non-static
             member function.  This is ill-formed (except in MS-land),
@@ -4204,7 +4229,7 @@ build_unary_op (code, xarg, noconvert)
             a useful error here.  */
 
          tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
-         tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
+         tree name = DECL_NAME (get_first_fn (TREE_OPERAND (arg, 1)));
 
          if (! flag_ms_extensions)
            {
@@ -5595,8 +5620,8 @@ build_ptrmemfunc (type, pfn, force)
        expand_ptrmemfunc_cst (pfn, &delta, &npfn);
       else
        {
-         npfn = build_component_ref (pfn, pfn_identifier, NULL_TREE, 0);
-         delta = build_component_ref (pfn, delta_identifier, NULL_TREE, 0);
+         npfn = build_ptrmemfunc_access_expr (pfn, pfn_identifier);
+         delta = build_ptrmemfunc_access_expr (pfn, delta_identifier);
        }
 
       /* Just adjust the DELTA field.  */
@@ -5711,7 +5736,7 @@ pfn_from_ptrmemfunc (t)
        return pfn;
     }
 
-  return build_component_ref (t, pfn_identifier, NULL_TREE, 0);
+  return build_ptrmemfunc_access_expr (t, pfn_identifier);
 }
 
 /* Expression EXPR is about to be implicitly converted to TYPE.  Warn
index fac68e917d6ef28568183fd829aa84dcd8e8598a..e4d7e3eb0a2a429c632655374144073aade1ceaf 100644 (file)
@@ -1196,8 +1196,8 @@ build_m_component_ref (datum, component)
                        | cp_type_quals (TREE_TYPE (datum)));
 
          /* There's no such thing as a mutable pointer-to-member, so
-            we don't need to deal with that here like we do in
-            build_component_ref.  */
+            things are not as complex as they are for references to
+            non-static data members.  */
          field_type = cp_build_qualified_type (field_type, type_quals);
        }
     }
index 014919ddd33717e1154945d515eb190decfe701d..c458f430f887826cb33b7dd1adb4fcef2a1e0bd8 100644 (file)
@@ -1,3 +1,8 @@
+2002-08-07  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/abi/offsetof.C: Tweak error messages.
+       * g++.old-deja/g++.mike/p10769a.C: Likewise.
+       
 2002-08-08  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.dg/bitfld-3.c: New test.
index 96f5796ec95462845ef39e9e9ec142708a7eec2e..0085e57dd9815e3e9a33c82f0cb3d757b8f261cd 100644 (file)
@@ -18,5 +18,5 @@ struct C: public B { };
 
 int main ()
 {
-  return ((unsigned long) &((C*)0)->i) != sizeof(void*); // { dg-warning "offsetof" "" }
+  return ((unsigned long) &((C*)0)->i) != sizeof(void*); // { dg-warning "offsetof|invalid" "" }
 }
index 3dd5dc27e0a692887da326be7fd107000663506a..cb49ab7501a0a78f7f032eddd40d6fb7e5f0c2ad 100644 (file)
@@ -9,7 +9,7 @@ class A {
 public:
   void f1a() { ok += 3; }
   void f1b() { ok += 5; }
-  void f2a() { ok += 7; }      // gets bogus error XFAIL *-*-*
+  void f2a() { ok += 7; }
   void f2b() { }
   static void (*table[2][2])();
   void main();