diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index feb0904..30b0603 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5949,12 +5949,13 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
   return result;
 }
 
-/* Issue the error given by GMSGID, indicating that it occurred before
-   TOKEN, which had the associated VALUE.  */
+/* Issue the error given by GMSGID at RICHLOC, indicating that it occurred
+   before TOKEN, which had the associated VALUE.  */
 
 void
 c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
-	       tree value, unsigned char token_flags)
+	       tree value, unsigned char token_flags,
+	       rich_location *richloc)
 {
 #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
 
@@ -5995,7 +5996,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
       else
 	message = catenate_messages (gmsgid, " before %s'\\x%x'");
 
-      error (message, prefix, val);
+      error_at_rich_loc (richloc, message, prefix, val);
       free (message);
       message = NULL;
     }
@@ -6023,7 +6024,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
   else if (token_type == CPP_NAME)
     {
       message = catenate_messages (gmsgid, " before %qE");
-      error (message, value);
+      error_at_rich_loc (richloc, message, value);
       free (message);
       message = NULL;
     }
@@ -6036,16 +6037,16 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
   else if (token_type < N_TTYPES)
     {
       message = catenate_messages (gmsgid, " before %qs token");
-      error (message, cpp_type2name (token_type, token_flags));
+      error_at_rich_loc (richloc, message, cpp_type2name (token_type, token_flags));
       free (message);
       message = NULL;
     }
   else
-    error (gmsgid);
+    error_at_rich_loc (richloc, gmsgid);
 
   if (message)
     {
-      error (message);
+      error_at_rich_loc (richloc, message);
       free (message);
     }
 #undef catenate_messages
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index a29f1ad..63fe845 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1124,7 +1124,8 @@ extern void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
 extern void builtin_define_type_sizeof (const char *, tree);
 extern void c_stddef_cpp_builtins (void);
 extern void fe_file_change (const line_map_ordinary *);
-extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char);
+extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char,
+			   rich_location *richloc);
 
 /* In c-ppoutput.c  */
 extern void init_pp_output (FILE *);
diff --git a/gcc/testsuite/c-c++-common/missing-close-symbol.c b/gcc/testsuite/c-c++-common/missing-close-symbol.c
new file mode 100644
index 0000000..85b96f28
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/missing-close-symbol.c
@@ -0,0 +1,33 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+/* Verify that the C/C++ frontends show the pertinent opening symbol when
+   a closing symbol is missing.  */
+
+/* Verify that, when they are on the same line, that the opening symbol is
+   shown as a secondary range within the main diagnostic.  */
+
+void test_static_assert_same_line (void)
+{
+  _Static_assert(sizeof(int) >= sizeof(char), "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+  /* { dg-begin-multiline-output "" }
+   _Static_assert(sizeof(int) >= sizeof(char), "msg";
+                 ~                                  ^
+     { dg-end-multiline-output "" } */
+}
+
+/* Verify that, when they are on different lines, that the opening symbol is
+   shown via a secondary diagnostic.  */
+
+void test_static_assert_different_line (void)
+{
+  _Static_assert(sizeof(int) >= sizeof(char), /* { dg-message "to match this '\\('" } */
+		 "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+  /* { dg-begin-multiline-output "" }
+    "msg";
+         ^
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+   _Static_assert(sizeof(int) >= sizeof(char),
+                 ^
+     { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/c-c++-common/missing-symbol.c b/gcc/testsuite/c-c++-common/missing-symbol.c
new file mode 100644
index 0000000..33a501b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/missing-symbol.c
@@ -0,0 +1,50 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+extern int foo (void);
+extern int bar (void);
+
+int missing_close_paren_in_switch (int i)
+{
+  switch (i /* { dg-message "10: to match this '\\('" } */
+    { /* { dg-error "5: expected '\\)' before '.' token" } */
+  /* { dg-begin-multiline-output "" }
+     {
+     ^
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+   switch (i
+          ^
+     { dg-end-multiline-output "" } */
+
+    case 0:
+      return 5;
+    default:
+      return i;
+    }
+} /* { dg-error "1: expected" } */
+  /* { dg-begin-multiline-output "" }
+ }
+ ^
+     { dg-end-multiline-output "" } */
+
+void missing_close_paren_in_if (void)
+{
+  if (foo () /* { dg-line start_of_if } */
+      && bar () 
+    { /* { dg-error "5: expected '\\)' before '.' token" } */
+      /* { dg-begin-multiline-output "" }
+     {
+     ^
+         { dg-end-multiline-output "" } */
+      /* { dg-message "6: to match this '\\('" "" { target *-*-* } start_of_if } */
+      /* { dg-begin-multiline-output "" }
+   if (foo ()
+      ^
+      { dg-end-multiline-output "" } */
+    }
+
+} /* { dg-error "1: expected" } */
+  /* { dg-begin-multiline-output "" }
+ }
+ ^
+     { dg-end-multiline-output "" } */
