tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE for v3 ABI.
authorJason Merrill <jason@redhat.com>
Tue, 2 Jan 2001 19:48:02 +0000 (14:48 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 2 Jan 2001 19:48:02 +0000 (14:48 -0500)
        * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
        for v3 ABI.

        * typeck.c (cp_truthvalue_conversion): New fn.
        * cvt.c (ocp_convert): Use it.

        * cp-tree.h: Lose c-common.c decls.

        * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
        * cvt.c (convert_to_void): Use type_unknown_p.

From-SVN: r38636

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.other/pmf7.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C [new file with mode: 0644]

index 43ca3b4..61bd1f2 100644 (file)
@@ -1,5 +1,16 @@
 2001-01-02  Jason Merrill  <jason@redhat.com>
 
+       * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
+       for v3 ABI.
+
+       * typeck.c (cp_truthvalue_conversion): New fn.
+       * cvt.c (ocp_convert): Use it.
+
+       * cp-tree.h: Lose c-common.c decls.
+
+       * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
+       * cvt.c (convert_to_void): Use type_unknown_p.
+
        * typeck.c (strip_all_pointer_quals): Also strip quals from 
        pointer-to-member types.
 
index 10afa32..b0802e1 100644 (file)
@@ -3190,40 +3190,6 @@ extern int warn_multichar;
    flag_guiding_decls in do_friend. */
 extern int warn_nontemplate_friend;
 
-/* in c-common.c */
-extern void declare_function_name               PARAMS ((void));
-extern void decl_attributes                     PARAMS ((tree, tree, tree));
-extern void init_function_format_info          PARAMS ((void));
-extern void record_function_format             PARAMS ((tree, tree, int, int, int));
-extern void check_function_format              PARAMS ((int *, tree, tree, tree));
-/* Print an error message for invalid operands to arith operation CODE.
-   NOP_EXPR is used as a special case (see truthvalue_conversion).  */
-extern void binary_op_error                     PARAMS ((enum tree_code));
-extern tree canonical_type_variant              PARAMS ((tree));
-/* Validate the expression after `case' and apply default promotions.  */
-extern tree check_case_value                    PARAMS ((tree));
-/* Concatenate a list of STRING_CST nodes into one STRING_CST.  */
-extern tree combine_strings                     PARAMS ((tree));
-extern void constant_expression_warning         PARAMS ((tree));
-extern tree convert_and_check                  PARAMS ((tree, tree));
-extern void overflow_warning                   PARAMS ((tree));
-extern void unsigned_conversion_warning                PARAMS ((tree, tree));
-extern void c_apply_type_quals_to_decl          PARAMS ((int, tree));
-
-/* Read the rest of the current #-directive line.  */
-extern char *get_directive_line                 PARAMS ((void));
-#define GET_DIRECTIVE_LINE() get_directive_line ()
-
-/* Subroutine of build_binary_op, used for comparison operations.
-   See if the operands have both been converted from subword integer types
-   and, if so, perhaps change them both back to their original type.  */
-extern tree shorten_compare                     PARAMS ((tree *, tree *, tree *, enum tree_code *));
-/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
-   or validate its data type for an `if' or `while' statement or ?..: exp.  */
-extern tree truthvalue_conversion               PARAMS ((tree));
-extern tree type_for_mode                       PARAMS ((enum machine_mode, int));
-extern tree type_for_size                       PARAMS ((unsigned, int));
-
 /* in decl{2}.c */
 /* A node that is a list (length 1) of error_mark_nodes.  */
 extern tree error_mark_list;
@@ -4391,6 +4357,7 @@ extern tree frob_opname                         PARAMS ((tree));
 /* in tree.c */
 extern void init_tree                          PARAMS ((void));
 extern int pod_type_p                          PARAMS ((tree));
+extern tree canonical_type_variant              PARAMS ((tree));
 extern void unshare_base_binfos                        PARAMS ((tree));
 extern int member_p                            PARAMS ((tree));
 extern cp_lvalue_kind real_lvalue_p            PARAMS ((tree));
@@ -4470,6 +4437,7 @@ extern linkage_kind decl_linkage                PARAMS ((tree));
 
 /* in typeck.c */
 extern int string_conv_p                       PARAMS ((tree, tree, int));
+extern tree cp_truthvalue_conversion           PARAMS ((tree));
 extern tree condition_conversion               PARAMS ((tree));
 extern tree target_type                                PARAMS ((tree));
 extern tree require_complete_type              PARAMS ((tree));
index b428a96..7936983 100644 (file)
@@ -787,7 +787,7 @@ ocp_convert (type, expr, convtype, flags)
            fn = TREE_OPERAND (expr, 0);
          if (fn)
            cp_warning ("the address of `%D', will always be `true'", fn);
-         return truthvalue_conversion (e);
+         return cp_truthvalue_conversion (e);
        }
       return fold (convert_to_integer (type, e));
     }
@@ -976,19 +976,17 @@ convert_to_void (expr, implicit)
   
     if (TREE_CODE (probe) == ADDR_EXPR)
       probe = TREE_OPERAND (expr, 0);
-    if (!is_overloaded_fn (probe))
-      ;/* OK */
-    else if (really_overloaded_fn (probe))
-        {
-          /* [over.over] enumerates the places where we can take the address
-             of an overloaded function, and this is not one of them.  */
-          cp_pedwarn ("%s has no context for overloaded function name `%E'",
-                      implicit ? implicit : "void cast", expr);
-        }
-    else if (implicit && probe == expr)
+    if (type_unknown_p (probe))
+      {
+       /* [over.over] enumerates the places where we can take the address
+          of an overloaded function, and this is not one of them.  */
+       cp_pedwarn ("%s cannot resolve address of overloaded function",
+                   implicit ? implicit : "void cast");
+      }
+    else if (implicit && probe == expr && is_overloaded_fn (probe))
       /* Only warn when there is no &.  */
       cp_warning ("%s is a reference, not call, to function `%E'",
-                    implicit, expr);
+                 implicit, expr);
   }
   
   if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
index a1089ce..4f55c70 100644 (file)
@@ -2259,7 +2259,9 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
          return 0;
        }
 
-      CLASSTYPE_COM_INTERFACE (type) = 1;
+      if (!flag_new_abi)
+       /* The v3 ABI is already COM compliant; don't set this flag.  */
+       CLASSTYPE_COM_INTERFACE (type) = 1;
       return 1;
     }
   else if (is_attribute_p ("init_priority", attr_name))
index 443fb2d..947a1db 100644 (file)
@@ -4348,7 +4348,21 @@ build_x_unary_op (code, xarg)
   return exp;
 }
 
-/* Just like truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
+/* Like truthvalue_conversion, but handle pointer-to-member constants, where
+   a null value is represented by an INTEGER_CST of -1.  */
+
+tree
+cp_truthvalue_conversion (expr)
+     tree expr;
+{
+  tree type = TREE_TYPE (expr);
+  if (TYPE_PTRMEM_P (type))
+    return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
+  else
+    return truthvalue_conversion (expr);
+}
+
+/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
    
 tree
 condition_conversion (expr)
@@ -4682,15 +4696,31 @@ build_unary_op (code, xarg, noconvert)
          return build1 (ADDR_EXPR, unknown_type_node, arg);
        }
 
-      if (TREE_CODE (arg) == COMPONENT_REF && flag_ms_extensions
-          && type_unknown_p (arg)
+      if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
           && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
         {
          /* They're trying to take the address of a unique non-static
-            member function.  This is ill-formed, except in microsoft-land.  */
+            member function.  This is ill-formed (except in MS-land),
+            but let's try to DTRT.
+            Note: We only handle unique functions here because we don't
+            want to complain if there's a static overload; non-unique
+            cases will be handled by instantiate_type.  But we need to
+            handle this case here to allow casts on the resulting PMF.
+            We could defer this in non-MS mode, but it's easier to give
+            a useful error here.  */
 
          tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
          tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
+
+         if (! flag_ms_extensions)
+           {
+             if (current_class_type
+                 && TREE_OPERAND (arg, 0) == current_class_ref)
+               /* An expression like &memfn.  */
+               cp_pedwarn ("ISO C++ forbids taking the address of a non-static member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+             else
+               cp_pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+           }
          arg = build_offset_ref (base, name);
         }
         
diff --git a/gcc/testsuite/g++.old-deja/g++.other/pmf7.C b/gcc/testsuite/g++.old-deja/g++.other/pmf7.C
new file mode 100644 (file)
index 0000000..e33ee2c
--- /dev/null
@@ -0,0 +1,15 @@
+// Test for proper diagnostics on trying to take the address of a non-static
+// member function.
+
+struct A {
+  void f ();
+  void f (int);
+  void g ();
+};
+
+int main ()
+{
+  A a;
+  &a.f;                                // ERROR - overloaded
+  &a.g;                                // ERROR - can't write a pmf like this
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C b/gcc/testsuite/g++.old-deja/g++.other/ptrmem10.C
new file mode 100644 (file)
index 0000000..21deeb5
--- /dev/null
@@ -0,0 +1,10 @@
+// Test that we properly convert a constant ptm to bool.
+
+class A { };
+
+int main()
+{
+  int A::*const p = 0;
+  if (p)
+    return 1;
+}