diff --git a/includes/form.inc b/includes/form.inc
index e0bc9cb..4dc1c99 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -2716,8 +2716,18 @@ function theme_radio($variables) {
   $element['#attributes']['type'] = 'radio';
   element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
 
-  if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
-    $element['#attributes']['checked'] = 'checked';
+  // Because of PHP's type juggling, 0 == 'foo' and 1 == '1foo'.  To avoid this
+  // we cast to strings so that 0 and '0' are equal, 0 and 'foo' are not equal,
+  // and 1 and '1foo' are not equal. Note: this means TRUE, 1, and '1' are
+  // equal, as are FALSE, 0, and '0'. We special case FALSE and '' to avoid
+  // confusion as an empty string is a valid return value.
+  if (isset($element['#return_value']) && $element['#value'] !== FALSE) {
+    if ($element['#return_value'] === FALSE && $element['#value'] === '') {
+      // Do nothing
+    }
+    else if ((string)$element['#value'] == (string)$element['#return_value']) {
+      $element['#attributes']['checked'] = 'checked';
+    }
   }
   _form_set_class($element, array('form-radio'));
 
diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test
index fe2c1bb..5b49d8e 100644
--- a/modules/simpletest/tests/form.test
+++ b/modules/simpletest/tests/form.test
@@ -521,7 +521,7 @@ class FormValidationTestCase extends DrupalWebTestCase {
    */
   function testValidateLimitErrors() {
     $edit = array(
-      'test' => 'invalid', 
+      'test' => 'invalid',
       'test_numeric_index[0]' => 'invalid',
       'test_substring[foo]' => 'invalid',
     );
@@ -1548,3 +1548,56 @@ class FormCheckboxTestCase extends DrupalWebTestCase {
     }
   }
 }
+
+/**
+ * Tests radio button element.
+ */
+class FormRadioTestCase extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Form API radio buttons',
+      'description' => 'Tests form API radio button handling of various combinations of #return_value and #value.',
+      'group' => 'Form API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('form_test');
+  }
+
+  function testFormRadio() {
+    // Ensure that the checked state is determined and rendered correctly for
+    // tricky combinations of return and current values.
+    foreach (array(FALSE, TRUE, '', 0, '0', 1, '1', 'foobar', '1foobar') as $value) {
+      foreach (array(FALSE, TRUE, '', 0, '0', 1, '1', 'foobar', '1foobar') as $return_value) {
+        $form_array = drupal_get_form('form_test_radio_type_juggling', $return_value, $value);
+        $form = drupal_render($form_array);
+        if ($value === FALSE) {
+          $checked = FALSE;
+        }
+        else {
+          // Because of PHP's type juggling, 0 == 'foo' and 1 == '1foo'.  To
+          // avoid this, we cast to strings so that 0 and '0' are equal,
+          // 0 and 'foo' are not equal, and 1 and '1foo' are not equal. However
+          // we special case (string)FALSE == (string)''.
+          if ($return_value === FALSE && $value === '') {
+            $checked = FALSE;
+          }
+          else {
+            $checked = (string)$value === (string)$return_value;
+          }
+        }
+        $checked_in_html = strpos($form, 'checked') !== FALSE;
+        $message = t(
+          '#return_value is %return_value and #value is %value so this element should be %checked.',
+          array(
+            '%return_value' => var_export($return_value, TRUE),
+            '%value' => var_export($value, TRUE),
+            '%checked' => $checked ? 'checked' : 'not checked'
+        ));
+        $this->assertIdentical($checked, $checked_in_html, $message);
+      }
+    }
+  }
+}
diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module
index 23aca24..689b3b5 100644
--- a/modules/simpletest/tests/form_test.module
+++ b/modules/simpletest/tests/form_test.module
@@ -1594,6 +1594,15 @@ function form_test_checkbox_type_juggling($form, $form_state, $default_value, $r
   return $form;
 }
 
+function form_test_radio_type_juggling($form, $form_state, $return_value, $value) {
+  $form['checkbox'] = array(
+    '#type' => 'radio',
+    '#return_value' => $return_value,
+    '#value' => $value,
+  );
+  return $form;
+}
+
 function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) {
   $form['checkbox_off'] = array(
     '#type' => 'checkboxes',
