diff mbox

[C++] Avoid UB in cp_lexer_previous_token (PR c++/71182)

Message ID 20170103224255.GB21933@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Jan. 3, 2017, 10:42 p.m. UTC
Hi!

cp_lexer_new_from_tokens creates lexer that has NULL lexer->buffer,
calling lexer->buffer->address () therefore is UB (diagnosed by
--with-boot-config=bootstrap-ubsan).

The following patch fixes this, or Markus offered
      gcc_assert (!lexer->buffer || tp != lexer->buffer->address ());
instead.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk (or do you prefer Markus' version)?

2017-01-03  Jakub Jelinek  <jakub@redhat.com>

	PR c++/71182
	* parser.c (cp_lexer_previous_token): Use vec_safe_address in the
	assertion, as lexer->buffer may be NULL.

	* g++.dg/cpp0x/pr71182.C: New test.


	Jakub

Comments

Jason Merrill Jan. 4, 2017, 7:48 p.m. UTC | #1
OK.

On Tue, Jan 3, 2017 at 5:42 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> cp_lexer_new_from_tokens creates lexer that has NULL lexer->buffer,
> calling lexer->buffer->address () therefore is UB (diagnosed by
> --with-boot-config=bootstrap-ubsan).
>
> The following patch fixes this, or Markus offered
>       gcc_assert (!lexer->buffer || tp != lexer->buffer->address ());
> instead.  Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk (or do you prefer Markus' version)?
>
> 2017-01-03  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/71182
>         * parser.c (cp_lexer_previous_token): Use vec_safe_address in the
>         assertion, as lexer->buffer may be NULL.
>
>         * g++.dg/cpp0x/pr71182.C: New test.
>
> --- gcc/cp/parser.c.jj  2017-01-03 09:58:13.000000000 +0100
> +++ gcc/cp/parser.c     2017-01-03 11:39:56.940595981 +0100
> @@ -766,7 +766,7 @@ cp_lexer_previous_token (cp_lexer *lexer
>    /* Skip past purged tokens.  */
>    while (tp->purged_p)
>      {
> -      gcc_assert (tp != lexer->buffer->address ());
> +      gcc_assert (tp != vec_safe_address (lexer->buffer));
>        tp--;
>      }
>
> --- gcc/testsuite/g++.dg/cpp0x/pr71182.C.jj     2017-01-03 11:44:19.400246340 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/pr71182.C        2017-01-03 11:44:04.795432815 +0100
> @@ -0,0 +1,12 @@
> +// PR c++/71182
> +// { dg-do compile { target c++11 } }
> +
> +class A {
> +  template <typename> void As();
> +};
> +template <typename T> class B : A {
> +  void f() {
> +    A *g ;
> +    g ? g->As<T>() : nullptr;
> +  }
> +};
>
>         Jakub
diff mbox

Patch

--- gcc/cp/parser.c.jj	2017-01-03 09:58:13.000000000 +0100
+++ gcc/cp/parser.c	2017-01-03 11:39:56.940595981 +0100
@@ -766,7 +766,7 @@  cp_lexer_previous_token (cp_lexer *lexer
   /* Skip past purged tokens.  */
   while (tp->purged_p)
     {
-      gcc_assert (tp != lexer->buffer->address ());
+      gcc_assert (tp != vec_safe_address (lexer->buffer));
       tp--;
     }
 
--- gcc/testsuite/g++.dg/cpp0x/pr71182.C.jj	2017-01-03 11:44:19.400246340 +0100
+++ gcc/testsuite/g++.dg/cpp0x/pr71182.C	2017-01-03 11:44:04.795432815 +0100
@@ -0,0 +1,12 @@ 
+// PR c++/71182
+// { dg-do compile { target c++11 } }
+
+class A {
+  template <typename> void As();
+};
+template <typename T> class B : A {
+  void f() {
+    A *g ;
+    g ? g->As<T>() : nullptr;
+  }
+};