diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c b/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c
new file mode 100644
index 0000000000000000000000000000000000000000..04881f786ab84eea9e9a6ce51b63fc4cd65b3fd9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-omp-unknown.c
@@ -0,0 +1,10 @@
+/* { dg-do preprocess } */
+/* { dg-options "-fopenmp" } */
+
+#define X UNKNOWN1
+#pragma omp X
+/* { dg-final { scan-file pragma-omp-unknown.i "#pragma omp UNKNOWN1" } } */
+
+#define Y UNKNOWN2
+_Pragma("omp Y")
+/* { dg-final { scan-file pragma-omp-unknown.i "#pragma omp UNKNOWN2" } } */
diff --git a/libcpp/directives.cc b/libcpp/directives.cc
index 918752f6b1f0f51a24df6ed246d01f90c6187880..9dc4363c65aecf8ee8b64c7b670afaeac4a0e79d 100644
--- a/libcpp/directives.cc
+++ b/libcpp/directives.cc
@@ -1565,15 +1565,15 @@ do_pragma (cpp_reader *pfile)
 	{
 	  /* Invalid name comes from macro expansion, _cpp_backup_tokens
 	     won't allow backing 2 tokens.  */
-	  /* ??? The token buffer is leaked.  Perhaps if def_pragma hook
-	     reads both tokens, we could perhaps free it, but if it doesn't,
-	     we don't know the exact lifespan.  */
-	  cpp_token *toks = XNEWVEC (cpp_token, 2);
+	  const auto tok_buff = _cpp_get_buff (pfile, 2 * sizeof (cpp_token));
+	  const auto toks = (cpp_token *)tok_buff->base;
 	  toks[0] = ns_token;
 	  toks[0].flags |= NO_EXPAND;
 	  toks[1] = *token;
-	  toks[1].flags |= NO_EXPAND;
+	  toks[1].flags |= NO_EXPAND | PREV_WHITE;
 	  _cpp_push_token_context (pfile, NULL, toks, 2);
+	  /* Arrange to free this buffer when no longer needed.  */
+	  pfile->context->buff = tok_buff;
 	}
       pfile->cb.def_pragma (pfile, pfile->directive_line);
     }