Message ID | 2222c8ff04699ae5671e1b654aafe5502259feaa.1667514153.git.lhyatt@gmail.com |
---|---|
State | New |
Headers | show |
Series | diagnostics: libcpp: Overhaul locations for _Pragma tokens | expand |
On 11/4/22 07:44, Lewis Hyatt via Gcc-patches wrote: > In directives.cc, do_pragma() contains logic to handle a case such as the new > testcase pragma-omp-unknown.c, where an unknown pragma was the result of macro > expansion (for pragma namespaces that permit expansion). This no longer works > correctly as shown by the testcase, fixed by adding PREV_WHITE to the flags on > the second token to prevent an unwanted paste. Also fixed the memory leak, > since the temporary tokens are pushed on their own context, nothing prevents > freeing of the buffer that holds them when the context is eventually popped. > > libcpp/ChangeLog: > > * directives.cc (do_pragma): Fix memory leak in token buffer. Fix > unwanted paste between two tokens. > > gcc/testsuite/ChangeLog: > > * c-c++-common/gomp/pragma-omp-unknown.c: New test. OK jeff
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 00000000000..04881f786ab --- /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 918752f6b1f..9dc4363c65a 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); }