diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 213e9c26613c1a18e89ad5f8e0be19a66928718c..fe2cedddfc6c3d804f92f3f083d8f0718f2f2164 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2011-02-28  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	* objc.dg/gnu-api-2-sel.m: Test that sel_getTypedSelector return
+	NULL in case of a selector with conflicting types.
+	* obj-c++.dg/gnu-api-2-sel.mm: Same change.
+	
 2011-02-28  Kazu Hirata  <kazu@codesourcery.com>
 
 	* gcc.target/arm/vfp-ldmdbd.c, gcc.target/arm/vfp-ldmdbs.c,
diff --git a/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm b/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
index b00588c9360121002e8faec9e78bfc26d69264b0..ff50058566b4d5a5ecfc99dc617db3eaceeffdc9 100644
--- a/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
+++ b/gcc/testsuite/obj-c++.dg/gnu-api-2-sel.mm
@@ -46,6 +46,21 @@
 - (void) method { return; }
 @end
 
+@interface ClassA : MyRootClass
+- (id) conflictingSelectorMethod;
+@end
+
+@implementation ClassA
+- (id) conflictingSelectorMethod { return nil; }
+@end
+
+@interface ClassB : MyRootClass
+- (void) conflictingSelectorMethod;
+@end
+
+@implementation ClassB
+- (void) conflictingSelectorMethod { return; }
+@end
 
 int main ()
 {
@@ -132,6 +147,13 @@ int main ()
        untyped.  */
     selector = sel_getTypedSelector ("registered_with_no_types");
 
+    if (selector != NULL)
+      abort ();
+
+    /* Now try a selector with multiple, conflicting types.  NULL
+       should be returned.  */
+    selector = sel_getTypedSelector ("conflictingSelectorMethod");
+
     if (selector != NULL)
       abort ();
   }
diff --git a/gcc/testsuite/objc.dg/gnu-api-2-sel.m b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
index 9a6aef282627c55c5def450551732c8a064a71e0..b71fdfab48cbf4e5390d609ef3db719d4f9517f8 100644
--- a/gcc/testsuite/objc.dg/gnu-api-2-sel.m
+++ b/gcc/testsuite/objc.dg/gnu-api-2-sel.m
@@ -46,6 +46,21 @@
 - (void) method { return; }
 @end
 
+@interface ClassA : MyRootClass
+- (id) conflictingSelectorMethod;
+@end
+
+@implementation ClassA
+- (id) conflictingSelectorMethod { return nil; }
+@end
+
+@interface ClassB : MyRootClass
+- (void) conflictingSelectorMethod;
+@end
+
+@implementation ClassB
+- (void) conflictingSelectorMethod { return; }
+@end
 
 int main(int argc, void **args)
 {
@@ -132,6 +147,13 @@ int main(int argc, void **args)
        untyped.  */
     selector = sel_getTypedSelector ("registered_with_no_types");
 
+    if (selector != NULL)
+      abort ();
+
+    /* Now try a selector with multiple, conflicting types.  NULL
+       should be returned.  */
+    selector = sel_getTypedSelector ("conflictingSelectorMethod");
+
     if (selector != NULL)
       abort ();
   }
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index a9399e6bea982eb931f995005ca7e4770f632940..485d2a4b5133d3af59ba4aa5ffb2e00be670302a 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,9 @@
+2011-02-28  Nicola Pero  <nicola.pero@meta-innovation.com>
+	
+	* selector.c (sel_getTypedSelector): Return NULL if there are
+	multiple selectors with conflicting types.
+	* objc/runtime.h (sel_getTypedSelector): Updated documentation.
+	
 2011-02-28  Richard Frith-Macdonald <rfm@gnu.org>
 
 	PR libobjc/47922
diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h
index 551c348d3074cb58100f4eea734d054eaec1edeb..6e1f1ec36e816499a75d9fa27526008e7cadd821 100644
--- a/libobjc/objc/runtime.h
+++ b/libobjc/objc/runtime.h
@@ -226,14 +226,16 @@ objc_EXPORT SEL * sel_copyTypedSelectorList (const char *name,
 					     unsigned int *numberOfReturnedSelectors);
 
 /* Return a selector with name 'name' and a non-zero type encoding, if
-   any such selector is registered with the runtime.  If there is no
-   such selector, NULL is returned.  Return NULL if 'name' is NULL.
+   there is a single selector with a type, and with that name,
+   registered with the runtime.  If there is no such selector, or if
+   there are multiple selectors with the same name but conflicting
+   types, NULL is returned.  Return NULL if 'name' is NULL.
 
    This is useful if you have the name of the selector, and would
    really like to get a selector for it that includes the type
    encoding.  Unfortunately, if the program contains multiple selector
-   with the same name but different types, sel_getTypedSelector
-   returns a random one of them, which may not be the right one.
+   with the same name but different types, sel_getTypedSelector can
+   not possibly know which one you need, and so will return NULL.
 
    Compatibility Note: the Apple/NeXT runtime has untyped selectors,
    so it does not have this function, which is specific to the GNU
diff --git a/libobjc/selector.c b/libobjc/selector.c
index 99efcf87e6cb24cf3e4de0a4363dcd69b658d83b..80d2d8004227dd091c8afdd7e906a10ee01eeefe 100644
--- a/libobjc/selector.c
+++ b/libobjc/selector.c
@@ -369,6 +369,7 @@ sel_getTypedSelector (const char *name)
   if (i != 0)
     {
       struct objc_list *l;
+      SEL returnValue = NULL;
 
       for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
 	   l; l = l->tail)
@@ -376,10 +377,40 @@ sel_getTypedSelector (const char *name)
 	  SEL s = (SEL) l->head;
 	  if (s->sel_types)
 	    {
-	      objc_mutex_unlock (__objc_runtime_mutex);
-	      return s;
+	      if (returnValue == NULL)
+		{
+		  /* First typed selector that we find.  Keep it in
+		     returnValue, but keep checking as we want to
+		     detect conflicts.  */
+		  returnValue = s;
+		}
+	      else
+		{
+		  /* We had already found a typed selectors, so we
+		     have multiple ones.  Double-check that they have
+		     different types, just in case for some reason we
+		     got duplicates with the same types.  If so, it's
+		     OK, we'll ignore the duplicate.  */
+		  if (returnValue->sel_types == s->sel_types)
+		    continue;
+		  else if (sel_types_match (returnValue->sel_types, s->sel_types))
+		    continue;
+		  else
+		    {
+		      /* The types of the two selectors are different;
+			 it's a conflict.  Too bad.  Return NULL.  */
+		      objc_mutex_unlock (__objc_runtime_mutex);
+		      return NULL;
+		    }
+		}
 	    }
 	}
+
+      if (returnValue != NULL)
+	{
+	  objc_mutex_unlock (__objc_runtime_mutex);
+	  return returnValue;
+	}
     }
 
   /* No typed selector found.  Return NULL.  */