diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1748afdbfe0a..0c4d27bd0241 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5712,8 +5712,7 @@ where the JSON is emitted to - with the former, the JSON is emitted to stderr,
 whereas with @samp{json-file} it is written to @file{@var{source}.gcc.json}.
 
 The emitted JSON consists of a top-level JSON array containing JSON objects
-representing the diagnostics.  The JSON is emitted as one line, without
-formatting; the examples below have been formatted for clarity.
+representing the diagnostics.
 
 Diagnostics can have child diagnostics.  For example, this error and note:
 
diff --git a/gcc/json.cc b/gcc/json.cc
index d0f157f0dfe7..d5a38c773f4d 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -66,6 +66,7 @@ void
 object::print (pretty_printer *pp) const
 {
   pp_character (pp, '{');
+  pp_indentation (pp) += 1;
 
   /* Iterate in the order that the keys were inserted.  */
   unsigned i;
@@ -73,15 +74,23 @@ object::print (pretty_printer *pp) const
   FOR_EACH_VEC_ELT (m_keys, i, key)
     {
       if (i > 0)
-	pp_string (pp, ", ");
+	{
+	  pp_string (pp, ",");
+	  pp_newline (pp);
+	  pp_indent (pp);
+	}
       map_t &mut_map = const_cast<map_t &> (m_map);
       value *value = *mut_map.get (key);
       pp_doublequote (pp);
       pp_string (pp, key); // FIXME: escaping?
       pp_doublequote (pp);
       pp_string (pp, ": ");
+      const int indent = strlen (key) + 4;
+      pp_indentation (pp) += indent;
       value->print (pp);
+      pp_indentation (pp) -= indent;
     }
+  pp_indentation (pp) -= 1;
   pp_character (pp, '}');
 }
 
@@ -183,14 +192,20 @@ void
 array::print (pretty_printer *pp) const
 {
   pp_character (pp, '[');
+  pp_indentation (pp) += 1;
   unsigned i;
   value *v;
   FOR_EACH_VEC_ELT (m_elements, i, v)
     {
       if (i)
-	pp_string (pp, ", ");
+	{
+	  pp_string (pp, ",");
+	  pp_newline (pp);
+	  pp_indent (pp);
+	}
       v->print (pp);
     }
+  pp_indentation (pp) -= 1;
   pp_character (pp, ']');
 }
 
@@ -354,7 +369,9 @@ test_writing_objects ()
   obj.set_string ("baz", "quux");
   /* This test relies on json::object writing out key/value pairs
      in key-insertion order.  */
-  ASSERT_PRINT_EQ (obj, "{\"foo\": \"bar\", \"baz\": \"quux\"}");
+  ASSERT_PRINT_EQ (obj,
+		   "{\"foo\": \"bar\",\n"
+		   " \"baz\": \"quux\"}");
 }
 
 /* Verify that JSON arrays are written correctly.  */
@@ -369,7 +386,9 @@ test_writing_arrays ()
   ASSERT_PRINT_EQ (arr, "[\"foo\"]");
 
   arr.append (new json::string ("bar"));
-  ASSERT_PRINT_EQ (arr, "[\"foo\", \"bar\"]");
+  ASSERT_PRINT_EQ (arr,
+		   "[\"foo\",\n"
+		   " \"bar\"]");
 }
 
 /* Verify that JSON numbers are written correctly.  */
@@ -424,6 +443,40 @@ test_writing_literals ()
   ASSERT_PRINT_EQ (literal (false), "false");
 }
 
+/* Verify that nested values are formatted correctly when written.  */
+
+static void
+test_formatting ()
+{
+  object obj;
+  object *child = new object;
+  object *grandchild = new object;
+
+  obj.set_string ("str", "bar");
+  obj.set ("child", child);
+  obj.set_integer ("int", 42);
+
+  child->set ("grandchild", grandchild);
+  child->set_integer ("int", 1776);
+
+  array *arr = new array;
+  for (int i = 0; i < 3; i++)
+    arr->append (new integer_number (i));
+  grandchild->set ("arr", arr);
+  grandchild->set_integer ("int", 1066);
+
+  /* This test relies on json::object writing out key/value pairs
+     in key-insertion order.  */
+  ASSERT_PRINT_EQ (obj,
+		   ("{\"str\": \"bar\",\n"
+		    " \"child\": {\"grandchild\": {\"arr\": [0,\n"
+		    "                                  1,\n"
+		    "                                  2],\n"
+		    "                          \"int\": 1066},\n"
+		    "           \"int\": 1776},\n"
+		    " \"int\": 42}"));
+}
+
 /* Run all of the selftests within this file.  */
 
 void
@@ -436,6 +489,7 @@ json_cc_tests ()
   test_writing_integer_numbers ();
   test_writing_strings ();
   test_writing_literals ();
+  test_formatting ();
 }
 
 } // namespace selftest
diff --git a/gcc/optinfo-emit-json.cc b/gcc/optinfo-emit-json.cc
index 11cad42a4330..1f8cb9b04e8e 100644
--- a/gcc/optinfo-emit-json.cc
+++ b/gcc/optinfo-emit-json.cc
@@ -471,7 +471,8 @@ test_building_json_from_dump_calls ()
   ASSERT_STR_CONTAINS (json_str, "impl_location");
   ASSERT_STR_CONTAINS (json_str, "\"kind\": \"note\"");
   ASSERT_STR_CONTAINS (json_str,
-		       "\"message\": [\"test of tree: \", {\"expr\": \"0\"}]");
+		       " \"message\": [\"test of tree: \",\n"
+		       "             {\"expr\": \"0\"}]");
   delete json_obj;
 }
 
