lang-options.h: Add -fms-extensions.
authorJason Merrill <jason@yorick.cygnus.com>
Thu, 12 Aug 1999 06:52:30 +0000 (06:52 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 12 Aug 1999 06:52:30 +0000 (02:52 -0400)
* lang-options.h: Add -fms-extensions.
* cp-tree.h: Declare flag_ms_extensions.
* decl2.c: Define it.
* class.c (instantiate_type): Don't complain about taking the address
of a bound member function if -fms-extensions.
* typeck.c (build_unary_op): Likewise.
* decl.c (grokdeclarator): Or about implicit int.
* init.c (resolve_offset_ref): Or about implicit '&'.

From-SVN: r28684

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/lang-options.h
gcc/cp/typeck.c

index 013e425dc7ad390fc09152cfdf1ba24071df954a..d3cee0da0a8900806a41709c2853cae5b4b76b21 100644 (file)
@@ -1,3 +1,14 @@
+1999-08-11  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lang-options.h: Add -fms-extensions.
+       * cp-tree.h: Declare flag_ms_extensions.
+       * decl2.c: Define it.
+       * class.c (instantiate_type): Don't complain about taking the address
+       of a bound member function if -fms-extensions.
+       * typeck.c (build_unary_op): Likewise.
+       * decl.c (grokdeclarator): Or about implicit int.
+       * init.c (resolve_offset_ref): Or about implicit '&'.
+
 1999-08-11  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (minimal_parse_mode): Remove.
index bc1d58108fbbf86132b5078ccfd1a9cb15a77927..47f22a34b9b0a6addd61939a9e9f878b51cd1af1 100644 (file)
@@ -5123,32 +5123,27 @@ instantiate_type (lhstype, rhs, flags)
 
     case COMPONENT_REF:
       {
-       tree field = TREE_OPERAND (rhs, 1);
-       tree r;
+       tree r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
 
-       r = instantiate_type (lhstype, field, flags);
-
-       if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype))
+       if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
+           && complain && !flag_ms_extensions)
          {
-           if (complain)
-             {
-               tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype);
-
-               if (TREE_CODE (field) == OVERLOAD)
-                 field = OVL_FUNCTION (field);
-               if (TREE_CODE (field) == FUNCTION_DECL)
-                 {
-                   cp_pedwarn ("object-dependent reference `%E' can only be used in a call",
-                             DECL_NAME (field));
-                   cp_pedwarn ("  to form a pointer to member function, say `&%T::%E'",
-                             t, DECL_NAME (field));
-                 }
-               else
-                 cp_pedwarn ("object-dependent reference can only be used in a call");
-             }
-           return r;
+           /* Note: we check this after the recursive call to avoid
+              complaining about cases where overload resolution fails.  */
+
+           tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
+           tree fn = PTRMEM_CST_MEMBER (r);
+
+           my_friendly_assert (TREE_CODE (r) == PTRMEM_CST, 990811);
+
+           cp_pedwarn
+             ("object-dependent reference to `%E' can only be used in a call",
+              DECL_NAME (fn));
+           cp_pedwarn
+             ("  to form a pointer to member function, say `&%T::%E'",
+              t, DECL_NAME (fn));
          }
-       
+
        return r;
       }
 
index e42122c57465cbda2c705533b75f786ce01ad249..e752fdceced96eb30078f499f680facf46b20bae 100644 (file)
@@ -2149,6 +2149,9 @@ extern int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus;
    applies, use the value of the label.  */
 extern int flag_labels_ok;
 
+/* Nonzero means allow Microsoft extensions without a pedwarn.  */
+extern int flag_ms_extensions;
+
 /* Non-zero means to collect statistics which might be expensive
    and to print them when we are done.  */
 extern int flag_detailed_statistics;
index f4d345a8b0fde773357d3e113c49d90a273450c7..b6e66a954ec4156fe37be21b103694883a608cea 100644 (file)
@@ -9426,7 +9426,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                         && in_namespace == NULL_TREE
                         && current_namespace == global_namespace);
 
-         if (in_system_header)
+         if (in_system_header || flag_ms_extensions)
            /* Allow it, sigh.  */;
          else if (pedantic || ! is_main)
            cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type",
index 8141d7619a2d28e455b0209a27b833e413b8939d..217b7831d86b9efb910c963af70640378d7bf1b0 100644 (file)
@@ -369,6 +369,10 @@ int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus = 1;
 
 int flag_labels_ok;
 
+/* Nonzero means allow Microsoft extensions without a pedwarn.  */
+
+int flag_ms_extensions;
+
 /* Non-zero means to collect statistics which might be expensive
    and to print them when we are done.  */
 int flag_detailed_statistics;
@@ -510,6 +514,7 @@ lang_f_options[] =
   {"implicit-inline-templates", &flag_implicit_inline_templates, 1},
   {"implicit-templates", &flag_implicit_templates, 1},
   {"labels-ok", &flag_labels_ok, 1},
+  {"ms-extensions", &flag_ms_extensions, 1},
   {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
   {"operator-names", &flag_operator_names, 1},
   {"optional-diags", &flag_optional_diags, 1},
index 3a70672495e7135053901d985a902cf38509c1f9..98b67eecf5e6b4655c6a3696cdf1e002b5a906ad 100644 (file)
@@ -1755,13 +1755,15 @@ resolve_offset_ref (exp)
 
   if (BASELINK_P (member))
     {
-      cp_pedwarn ("assuming & on overloaded member function");
+      if (! flag_ms_extensions)
+       cp_pedwarn ("assuming & on overloaded member function");
       return build_unary_op (ADDR_EXPR, exp, 0);
     }
 
   if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
     {
-      cp_pedwarn ("assuming & on `%E'", member);
+      if (! flag_ms_extensions)
+       cp_pedwarn ("assuming & on `%E'", member);
       return build_unary_op (ADDR_EXPR, exp, 0);
     }
 
index c0a4a34680cd7d57ffbd4634a014af9b0f300e9f..ca7e436dd757638d506e77abc9016d2855315a4d 100644 (file)
@@ -72,6 +72,8 @@ DEFINE_LANG_NAME ("C++")
   { "-fno-labels-ok", "" },
   { "-fmemoize-lookups", "" },
   { "-fno-memoize-lookups", "" },
+  { "-fms-extensions", "Don't pedwarn about uses of Microsoft extensions" },
+  { "-fno-ms-extensions", "" },
   { "-fname-mangling-version-", "" },
   { "-fnew-abi", "Enable experimental ABI changes" },
   { "-fno-new-abi", "" },
index 0b71e72d85cbbf3cd1394b6651cc915a8e10b23d..37239365a8cb4806deeba3b30e889b3d679d76a3 100644 (file)
@@ -4795,21 +4795,29 @@ build_unary_op (code, xarg, noconvert)
          && 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, but let's try to DTRT.  */
-         tree base, name;
+            member function.  This is ill-formed, 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.  */
 
-         if (current_class_type
-             && TREE_OPERAND (arg, 0) == current_class_ref)
-           /* An expression like &memfn.  */
-           pedwarn ("taking the address of a non-static member function");
-         else
-           pedwarn ("taking the address of a bound member function");
+         tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
+         tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
 
-         base = TREE_TYPE (TREE_OPERAND (arg, 0));
-         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.  */
+               pedwarn ("taking the address of a non-static member function");
+             else
+               pedwarn ("taking the address of a bound member function");
+
+             cp_pedwarn
+               ("  to form a pointer to member function, say `&%T::%D'",
+                base, name);
+           }
 
-         cp_pedwarn ("  to form a pointer to member function, say `&%T::%D'",
-                     base, name);
          arg = build_offset_ref (base, name);
        }