Test and support all cpp operator types.
authorSami Wagiaalla <swagiaal@redhat.com>
Mon, 7 Jun 2010 16:11:35 +0000 (16:11 +0000)
committerSami Wagiaalla <swagiaal@redhat.com>
Mon, 7 Jun 2010 16:11:35 +0000 (16:11 +0000)
2010-06-07  Sami Wagiaalla  <swagiaal@redhat.com>

* value.h: Created oload_search_type enum.
(find_overload_match): Use oload_search_type enum.
* valops.c (find_overload_match): Support combined member and
non-member search.
* eval.c (evaluate_subexp_standard): Calls to
find_overload_match now use oload_search_type enum.
(oload_method_static): Verify index is a proper value.
* valarith.c (value_user_defined_cpp_op): Search for and handle
both member and non-member operators.
(value_user_defined_cpp_op): New function.
(value_user_defined_op): New function.
(value_x_unop): Use value_user_defined_op.
(value_x_binop): Ditto.
* cp-support.c (make_symbol_overload_list_using): Added block
iteration.
Add check for namespace aliases and imported declarations.

2010-06-07  Sami Wagiaalla  <swagiaal@redhat.com>

* gdb.cp/koenig.exp: Test for ADL operators.
* gdb.cp/koenig.cc: Added ADL operators.
* gdb.cp/operator.exp: New test.
* gdb.cp/operator.cc: New test.

gdb/ChangeLog
gdb/cp-support.c
gdb/eval.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/koenig.cc
gdb/testsuite/gdb.cp/koenig.exp
gdb/testsuite/gdb.cp/operator.cc [new file with mode: 0644]
gdb/testsuite/gdb.cp/operator.exp [new file with mode: 0644]
gdb/valarith.c
gdb/valops.c
gdb/value.h

index c64fb08..78d3199 100644 (file)
@@ -1,3 +1,22 @@
+2010-06-07  Sami Wagiaalla  <swagiaal@redhat.com>
+
+       * value.h: Created oload_search_type enum.
+       (find_overload_match): Use oload_search_type enum.
+       * valops.c (find_overload_match): Support combined member and
+       non-member search.
+       * eval.c (evaluate_subexp_standard): Calls to
+       find_overload_match now use oload_search_type enum.
+       (oload_method_static): Verify index is a proper value.
+       * valarith.c (value_user_defined_cpp_op): Search for and handle
+       both member and non-member operators.
+       (value_user_defined_cpp_op): New function.
+       (value_user_defined_op): New function.
+       (value_x_unop): Use value_user_defined_op.
+       (value_x_binop): Ditto.
+       * cp-support.c (make_symbol_overload_list_using): Added block
+       iteration.
+       Add check for namespace aliases and imported declarations.
+
 2010-06-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * breakpoint.h (owner): Extend the comment.
index 799b707..d9a59f3 100644 (file)
@@ -803,21 +803,26 @@ make_symbol_overload_list_using (const char *func_name,
                                 const char *namespace)
 {
   const struct using_direct *current;
+  const struct block *block;
 
   /* First, go through the using directives.  If any of them apply,
      look in the appropriate namespaces for new functions to match
      on.  */
 
-  for (current = block_using (get_selected_block (0));
-       current != NULL;
-       current = current->next)
-    {
-      if (strcmp (namespace, current->import_dest) == 0)
-       {
-         make_symbol_overload_list_using (func_name,
-                                          current->import_src);
-       }
-    }
+  for (block = get_selected_block (0);
+       block != NULL;
+       block = BLOCK_SUPERBLOCK (block))
+    for (current = block_using (block);
+       current != NULL;
+       current = current->next)
+      {
+        /* If this is a namespace alias or imported declaration ignore it.  */
+        if (current->alias != NULL || current->declaration != NULL)
+          continue;
+
+        if (strcmp (namespace, current->import_dest) == 0)
+          make_symbol_overload_list_using (func_name, current->import_src);
+      }
 
   /* Now, add names for this namespace.  */
   make_symbol_overload_list_namespace (func_name, namespace);
index 8efb45a..9a60616 100644 (file)
@@ -1535,7 +1535,7 @@ evaluate_subexp_standard (struct type *expect_type,
             arg_types[ix - 1] = value_type (argvec[ix]);
 
           find_overload_match (arg_types, nargs, func_name,
-                               0 /* not method */ , 0 /* strict match */ ,
+                               NON_METHOD /* not method */ , 0 /* strict match */ ,
                                NULL, NULL /* pass NULL symbol since symbol is unknown */ ,
                                NULL, &symp, NULL, 0);
 
@@ -1572,7 +1572,7 @@ evaluate_subexp_standard (struct type *expect_type,
                arg_types[ix - 1] = value_type (argvec[ix]);
 
              (void) find_overload_match (arg_types, nargs, tstr,
-                                    1 /* method */ , 0 /* strict match */ ,
+                                         METHOD /* method */ , 0 /* strict match */ ,
                                          &arg2 /* the object */ , NULL,
                                          &valp, NULL, &static_memfuncp, 0);
 
@@ -1642,8 +1642,8 @@ evaluate_subexp_standard (struct type *expect_type,
                arg_types[ix - 1] = value_type (argvec[ix]);
 
              (void) find_overload_match (arg_types, nargs, NULL /* no need for name */ ,
-                                0 /* not method */ , 0 /* strict match */ ,
-                     NULL, function /* the function */ ,
+                                         NON_METHOD /* not method */ , 0 /* strict match */ ,
+                                         NULL, function /* the function */ ,
                                          NULL, &symp, NULL, no_adl);
 
              if (op == OP_VAR_VALUE)
index d0bb484..291175b 100644 (file)
@@ -1,3 +1,10 @@
+2010-06-07  Sami Wagiaalla  <swagiaal@redhat.com>
+
+       * gdb.cp/koenig.exp: Test for ADL operators.
+       * gdb.cp/koenig.cc: Added ADL operators.
+       * gdb.cp/operator.exp: New test.
+       * gdb.cp/operator.cc: New test.
+
 2010-06-04  Michael Snyder  <msnyder@vmware.com>
 
        * gdb.base/attach.exp: Replace gdb_test_multiple with gdb_test.
index fb4ecb1..c91dbf9 100644 (file)
@@ -175,6 +175,7 @@ typedef O::A TOA;
 typedef TOA  TTOA;
 
 //------------
+
 static union {
     int  a;
     char b;
@@ -182,6 +183,49 @@ static union {
 
 //------------
 
+namespace P {
+  class Q{
+  public:
+    int operator== (int)
+      {
+        return 24;
+      }
+
+    int operator== (float)
+      {
+        return 25;
+      }
+
+    int operator+ (float)
+      {
+        return 26;
+      }
+
+  };
+
+  int operator!= (Q, int)
+    {
+      return 27;
+    }
+
+  int operator!= (Q, double)
+    {
+      return 28;
+    }
+
+  int operator+ (Q, int)
+    {
+      return 29;
+    }
+
+  int operator++ (Q)
+    {
+      return 30;
+    }
+}
+
+//------------
+
 int
 main ()
 {
@@ -245,6 +289,16 @@ main ()
   TTOA ttoa;
   foo (ttoa, 'a');
 
+  P::Q q;
+  q == 5;
+  q == 5.0f;
+  q != 5;
+  q != 5.0f;
+  q + 5;
+  q + 5.0f;
+
+  ++q;
+
   return first (0, c) + foo (eo) +
          foo (eo, eo) + foo (eo, eo, 1)  +
          foo (fo, eo) + foo (1  ,fo, eo) +
index 57be745..d5e6c3f 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-if $tracelevel then {
-    strace $tracelevel
-}
-
 set testfile koenig
 set srcfile ${testfile}.cc
-set binfile ${objdir}/${subdir}/${testfile}
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
-    untested "Couldn't compile test program"
-    return -1
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+     return -1
 }
 
-# Get things started.
-
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
-
 ############################################
 
 if ![runto_main] then {
@@ -109,3 +96,22 @@ gdb_test "p foo(ttoa, 'a')" "= 23"
 #test that lookup is not thwarted by anonymous types
 gdb_test "p foo (p_union)" \
   "Cannot resolve function foo to any overloaded instance"
+
+# test lookup of namespace user-defined operators
+# and overload resolution:
+
+# within class
+gdb_test "p q == 5" "= 24"
+gdb_test "p q == 5.0f" "= 25"
+
+# within namespace
+gdb_test "p q != 5" "= 27"
+gdb_test "p q != 5.0f" "= 28"
+
+# across namespace and class
+gdb_test "p q + 5.0f" "= 26"
+gdb_test "p q + 5" "= 29"
+
+# some unary operators for good measure
+# Cannot resolve function operator++ to any overloaded instance
+gdb_test "p ++q" "= 30"
diff --git a/gdb/testsuite/gdb.cp/operator.cc b/gdb/testsuite/gdb.cp/operator.cc
new file mode 100644 (file)
index 0000000..cc925a0
--- /dev/null
@@ -0,0 +1,195 @@
+class A
+{
+};
+
+int operator== (A, int)
+{
+  return 11;
+}
+
+int operator== (A, char)
+{
+  return 12;
+}
+
+//------------------
+
+namespace B
+{
+  class C
+  {
+  };
+
+  int operator== (C, int)
+  {
+    return 22;
+  }
+
+  int operator== (C, char)
+  {
+    return 23;
+  }
+
+  namespace BD
+  {
+    int operator== (C, int)
+    {
+      return 24;
+    }
+  }
+}
+
+//------------------
+
+class D
+{
+};
+namespace
+{
+  int operator== (D, int)
+  {
+    return 33;
+  }
+
+  int operator== (D, char)
+  {
+    return 34;
+  }
+}
+
+int operator== (D, float)
+{
+  return 35;
+}
+
+//------------------
+
+class E
+{
+};
+namespace F
+{
+  int operator== (E, int)
+  {
+    return 44;
+  }
+
+  int operator== (E, char)
+  {
+    return 45;
+  }
+}
+
+int operator== (E, float)
+{
+  return 46;
+}
+
+using namespace F;
+
+//-----------------
+
+class G
+{
+public:
+  int operator== (int)
+  {
+    return 55;
+  }
+};
+
+int operator== (G, char)
+{
+  return 56;
+}
+
+//------------------
+
+class H
+{
+};
+namespace I
+{
+  int operator== (H, int)
+  {
+    return 66;
+  }
+}
+
+namespace ALIAS = I;
+
+//------------------
+
+class J
+{
+};
+
+namespace K
+{
+  int i;
+  int operator== (J, int)
+  {
+    return 77;
+  }
+}
+
+using K::i;
+
+//------------------
+
+class L
+{
+};
+namespace M
+{
+  int operator== (L, int)
+  {
+    return 88;
+  }
+}
+
+namespace N
+{
+  using namespace M;
+}
+
+using namespace N;
+
+//------------------
+
+int main ()
+{
+  A a;
+  a == 1;
+  a == 'a';
+
+  B::C bc;
+  bc == 1;
+  bc == 'a';
+  B::BD::operator== (bc,'a');
+
+  D d;
+  d == 1;
+  d == 'a';
+  d == 1.0f;
+
+  E e;
+  e == 1;
+  e == 'a';
+  e == 1.0f;
+
+  G g;
+  g == 1;
+  g == 'a';
+
+  H h;
+  I::operator== (h, 1);
+
+  J j;
+  K::operator== (j, 1);
+
+  L l;
+  l == 1;
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/operator.exp b/gdb/testsuite/gdb.cp/operator.exp
new file mode 100644 (file)
index 0000000..ac89d2b
--- /dev/null
@@ -0,0 +1,58 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set testfile operator
+set srcfile ${testfile}.cc
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+    return -1
+}
+
+############################################
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+# Test global operator
+gdb_test "p a == 1" "= 11" "global operator"
+gdb_test "p a == 'a'" "= 12" "global operator overload"
+
+# Test ADL operator
+gdb_test "p bc == 1" "= 22" "ADL operator"
+gdb_test "p bc == 'a'" "= 23" "ADL operator overload"
+gdb_test "p B::BD::operator== (bc,'a')" "= 24" "Fully qualified explicit operator call"
+
+# Test operator imported from anonymous namespace
+gdb_test "p d == 1" "= 33" "anonymous namespace operator"
+gdb_test "p d == 'a'" "= 34" "anonymous namespace operator overload"
+gdb_test "p d == 1.0f" "= 35" "anonymous namespace operator overload float"
+
+# Test operator imported by using directive
+gdb_test "p e == 1" "= 44" "imported operator"
+gdb_test "p e == 'a'" "= 45" "imported operator overload"
+gdb_test "p e == 1.0f" "= 46" "imported operator overload float"
+
+# Test member operator
+gdb_test "p g == 1" "= 55" "member operator"
+gdb_test "p g == 'a'" "= 56" "member operator overload"
+
+# Test that operators are not wrongly imported
+# by import declarations and namespace aliases
+gdb_test "p h == 1" "Cannot resolve function operator== to any overloaded instance" "namespace alias"
+gdb_test "p j == 1" "Cannot resolve function operator== to any overloaded instance" "imported declaration"
+
+# Test that indirectly imported operators work
+gdb_test "p l == 1" "= 88"
index 745d960..0c40905 100644 (file)
@@ -31,6 +31,7 @@
 #include "dfp.h"
 #include <math.h>
 #include "infcall.h"
+#include "exceptions.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C). */
@@ -319,6 +320,67 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
     }
 }
 
+/* Try to find an operator named OPERATOR which takes NARGS arguments
+   specified in ARGS.  If the operator found is a static member operator
+   *STATIC_MEMFUNP will be set to 1, and otherwise 0.
+   The search if performed through find_overload_match which will handle
+   member operators, non member operators, operators imported implicitly or
+   explicitly, and perform correct overload resolution in all of the above
+   situations or combinations thereof.  */
+
+static struct value *
+value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
+                           int *static_memfuncp)
+{
+
+  struct symbol *symp = NULL;
+  struct value *valp = NULL;
+  struct type **arg_types;
+  int i;
+
+  arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
+  /* Prepare list of argument types for overload resolution */
+  for (i = 0; i < nargs; i++)
+    arg_types[i] = value_type (args[i]);
+
+  find_overload_match (arg_types, nargs, operator, BOTH /* could be method */,
+                       0 /* strict match */, &args[0], /* objp */
+                       NULL /* pass NULL symbol since symbol is unknown */,
+                       &valp, &symp, static_memfuncp, 0);
+
+  if (valp)
+    return valp;
+
+  if (symp)
+    {
+      /* This is a non member function and does not
+         expect a reference as its first argument
+         rather the explicit structure.  */
+      args[0] = value_ind (args[0]);
+      return value_of_variable (symp, 0);
+    }
+
+  error (_("Could not find %s."), operator);
+}
+
+/* Lookup user defined operator NAME.  Return a value representing the
+   function, otherwise return NULL.  */
+
+static struct value *
+value_user_defined_op (struct value **argp, struct value **args, char *name,
+                       int *static_memfuncp, int nargs)
+{
+  struct value *result = NULL;
+
+  if (current_language->la_language == language_cplus)
+    result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp);
+  else
+    result = value_struct_elt (argp, args, name, static_memfuncp,
+                               "structure");
+
+  return result;
+}
+
 /* We know either arg1 or arg2 is a structure, so try to find the right
    user defined function.  Create an argument vector that calls 
    arg1.operator @ (arg1,arg2) and return that value (where '@' is any
@@ -459,7 +521,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
       error (_("Invalid binary operation specified."));
     }
 
-  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+  argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+                                     &static_memfuncp, 2);
 
   if (argvec[0])
     {
@@ -557,7 +620,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
       error (_("Invalid unary operation specified."));
     }
 
-  argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+  argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+                                     &static_memfuncp, nargs);
 
   if (argvec[0])
     {
index 6cd66dd..08a64ce 100644 (file)
@@ -2315,6 +2315,16 @@ value_find_oload_method_list (struct value **argp, const char *method,
    matches on the argument types according to the overload resolution
    rules.
 
+   METHOD can be one of three values:
+     NON_METHOD for non-member functions.
+     METHOD: for member functions.
+     BOTH: used for overload resolution of operators where the
+       candidates are expected to be either member or non member
+       functions. In this case the first argument ARGTYPES
+       (representing 'this') is expected to be a reference to the
+       target object, and will be dereferenced when attempting the
+       non-member search.
+
    In the case of class methods, the parameter OBJ is an object value
    in which to search for overloaded methods.
 
@@ -2342,16 +2352,20 @@ value_find_oload_method_list (struct value **argp, const char *method,
 
 int
 find_overload_match (struct type **arg_types, int nargs, 
-                    const char *name, int method, int lax, 
-                    struct value **objp, struct symbol *fsym,
+                    const char *name, enum oload_search_type method,
+                    int lax, struct value **objp, struct symbol *fsym,
                     struct value **valp, struct symbol **symp, 
                     int *staticp, const int no_adl)
 {
   struct value *obj = (objp ? *objp : NULL);
   /* Index of best overloaded function.  */
-  int oload_champ;
+  int func_oload_champ = -1;
+  int method_oload_champ = -1;
+
   /* The measure for the current best match.  */
-  struct badness_vector *oload_champ_bv = NULL;
+  struct badness_vector *method_badness = NULL;
+  struct badness_vector *func_badness = NULL;
+
   struct value *temp = obj;
   /* For methods, the list of overloaded methods.  */
   struct fn_field *fns_ptr = NULL;
@@ -2367,9 +2381,11 @@ find_overload_match (struct type **arg_types, int nargs,
   const char *obj_type_name = NULL;
   const char *func_name = NULL;
   enum oload_classification match_quality;
+  enum oload_classification method_match_quality = INCOMPATIBLE;
+  enum oload_classification func_match_quality = INCOMPATIBLE;
 
   /* Get the list of overloaded methods or functions.  */
-  if (method)
+  if (method == METHOD || method == BOTH)
     {
       gdb_assert (obj);
 
@@ -2392,10 +2408,13 @@ find_overload_match (struct type **arg_types, int nargs,
            }
        }
 
+      /* Retrieve the list of methods with the name NAME.  */
       fns_ptr = value_find_oload_method_list (&temp, name, 
                                              0, &num_fns, 
                                              &basetype, &boffset);
-      if (!fns_ptr || !num_fns)
+      /* If this is a method only search, and no methods were found
+         the search has faild.  */
+      if (method == METHOD && (!fns_ptr || !num_fns))
        error (_("Couldn't find method %s%s%s"),
               obj_type_name,
               (obj_type_name && *obj_type_name) ? "::" : "",
@@ -2403,15 +2422,33 @@ find_overload_match (struct type **arg_types, int nargs,
       /* If we are dealing with stub method types, they should have
         been resolved by find_method_list via
         value_find_oload_method_list above.  */
-      gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
-      oload_champ = find_oload_champ (arg_types, nargs, method, 
-                                     num_fns, fns_ptr, 
-                                     oload_syms, &oload_champ_bv);
+      if (fns_ptr)
+       {
+         gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
+         method_oload_champ = find_oload_champ (arg_types, nargs, method,
+                                                num_fns, fns_ptr,
+                                                oload_syms, &method_badness);
+
+         method_match_quality =
+             classify_oload_match (method_badness, nargs,
+                                   oload_method_static (method, fns_ptr,
+                                                        method_oload_champ));
+
+         make_cleanup (xfree, method_badness);
+       }
+
     }
-  else
+
+  if (method == NON_METHOD || method == BOTH)
     {
       const char *qualified_name = NULL;
 
+      /* If the the overload match is being search for both
+         as a method and non member function, the first argument
+         must now be dereferenced.  */
+      if (method == BOTH)
+       arg_types[0] = TYPE_TARGET_TYPE (arg_types[0]);
+
       if (fsym)
         {
           qualified_name = SYMBOL_NATURAL_NAME (fsym);
@@ -2454,30 +2491,67 @@ find_overload_match (struct type **arg_types, int nargs,
           return 0;
         }
 
-      make_cleanup (xfree, oload_syms);
-      make_cleanup (xfree, oload_champ_bv);
+      func_oload_champ = find_oload_champ_namespace (arg_types, nargs,
+                                                     func_name,
+                                                     qualified_name,
+                                                     &oload_syms,
+                                                     &func_badness,
+                                                     no_adl);
 
-      oload_champ = find_oload_champ_namespace (arg_types, nargs,
-                                               func_name,
-                                               qualified_name,
-                                               &oload_syms,
-                                               &oload_champ_bv,
-                                               no_adl);
+      if (func_oload_champ >= 0)
+       func_match_quality = classify_oload_match (func_badness, nargs, 0);
+
+      make_cleanup (xfree, oload_syms);
+      make_cleanup (xfree, func_badness);
     }
 
   /* Did we find a match ?  */
-  if (oload_champ == -1)
+  if (method_oload_champ == -1 && func_oload_champ == -1)
     error (_("No symbol \"%s\" in current context."), name);
 
-  /* Check how bad the best match is.  */
-  match_quality =
-    classify_oload_match (oload_champ_bv, nargs,
-                         oload_method_static (method, fns_ptr,
-                                              oload_champ));
+  /* If we have found both a method match and a function
+     match, find out which one is better, and calculate match
+     quality.  */
+  if (method_oload_champ >= 0 && func_oload_champ >= 0)
+    {
+      switch (compare_badness (func_badness, method_badness))
+        {
+         case 0: /* Top two contenders are equally good.  */
+           /* FIXME: GDB does not support the general ambiguous
+            case.  All candidates should be collected and presented
+            the the user.  */
+           error (_("Ambiguous overload resolution"));
+           break;
+         case 1: /* Incomparable top contenders.  */
+           /* This is an error incompatible candidates
+              should not have been proposed.  */
+           error (_("Internal error: incompatible overload candidates proposed"));
+           break;
+         case 2: /* Function champion.  */
+           method_oload_champ = -1;
+           match_quality = func_match_quality;
+           break;
+         case 3: /* Method champion.  */
+           func_oload_champ = -1;
+           match_quality = method_match_quality;
+           break;
+         default:
+           error (_("Internal error: unexpected overload comparison result"));
+           break;
+        }
+    }
+  else
+    {
+      /* We have either a method match or a function match.  */
+      if (method_oload_champ >= 0)
+       match_quality = method_match_quality;
+      else
+       match_quality = func_match_quality;
+    }
 
   if (match_quality == INCOMPATIBLE)
     {
-      if (method)
+      if (method == METHOD)
        error (_("Cannot resolve method %s%s%s to any overloaded instance"),
               obj_type_name,
               (obj_type_name && *obj_type_name) ? "::" : "",
@@ -2488,7 +2562,7 @@ find_overload_match (struct type **arg_types, int nargs,
     }
   else if (match_quality == NON_STANDARD)
     {
-      if (method)
+      if (method == METHOD)
        warning (_("Using non-standard conversion to match method %s%s%s to supplied arguments"),
                 obj_type_name,
                 (obj_type_name && *obj_type_name) ? "::" : "",
@@ -2498,21 +2572,20 @@ find_overload_match (struct type **arg_types, int nargs,
                 func_name);
     }
 
-  if (method)
+  if (staticp != NULL)
+    *staticp = oload_method_static (method, fns_ptr, method_oload_champ);
+
+  if (method_oload_champ >= 0)
     {
-      if (staticp != NULL)
-       *staticp = oload_method_static (method, fns_ptr, oload_champ);
-      if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
-       *valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, 
+      if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ))
+       *valp = value_virtual_fn_field (&temp, fns_ptr, method_oload_champ,
                                        basetype, boffset);
       else
-       *valp = value_fn_field (&temp, fns_ptr, oload_champ, 
+       *valp = value_fn_field (&temp, fns_ptr, method_oload_champ,
                                basetype, boffset);
     }
   else
-    {
-      *symp = oload_syms[oload_champ];
-    }
+    *symp = oload_syms[func_oload_champ];
 
   if (objp)
     {
@@ -2801,7 +2874,8 @@ find_oload_champ (struct type **arg_types, int nargs, int method,
 static int
 oload_method_static (int method, struct fn_field *fns_ptr, int index)
 {
-  if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
+  if (method && fns_ptr && index >= 0
+      && TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
     return 1;
   else
     return 0;
index 57b4dd7..7f71dc4 100644 (file)
@@ -447,8 +447,11 @@ extern struct fn_field *value_find_oload_method_list (struct value **,
                                                      int, int *,
                                                      struct type **, int *);
 
+enum oload_search_type { NON_METHOD, METHOD, BOTH };
+
 extern int find_overload_match (struct type **arg_types, int nargs,
-                               const char *name, int method, int lax,
+                               const char *name,
+                               enum oload_search_type method, int lax,
                                struct value **objp, struct symbol *fsym,
                                struct value **valp, struct symbol **symp,
                                int *staticp, const int no_adl);