On Tue, 31 Jan 2023, Qing Zhao wrote:

> GCC extension accepts the case when a struct with a flexible array member
> is embedded into another struct (possibly recursively).
> __builtin_object_size should treat such struct as flexible size per
> -fstrict-flex-arrays.
> 
>       PR tree-optimization/101832
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/101832
>       * tree-object-size.cc (flexible_size_type_p): New function.
>       (addr_object_size): Handle structure/union type when it has
>       flexible size.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR tree-optimization/101832
>       * gcc.dg/builtin-object-size-pr101832-2.c: New test.
>       * gcc.dg/builtin-object-size-pr101832-3.c: New test.
>       * gcc.dg/builtin-object-size-pr101832-4.c: New test.
>       * gcc.dg/builtin-object-size-pr101832.c: New test.
> ---
>  .../gcc.dg/builtin-object-size-pr101832-2.c   | 135 ++++++++++++++++++
>  .../gcc.dg/builtin-object-size-pr101832-3.c   | 135 ++++++++++++++++++
>  .../gcc.dg/builtin-object-size-pr101832-4.c   | 135 ++++++++++++++++++
>  .../gcc.dg/builtin-object-size-pr101832.c     | 119 +++++++++++++++
>  gcc/tree-object-size.cc                       | 115 +++++++++++----
>  5 files changed, 611 insertions(+), 28 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> 
> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-2.c 
> b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-2.c
> new file mode 100644
> index 00000000000..f38babc5415
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-2.c
> @@ -0,0 +1,135 @@
> +/* PR 101832: 
> +   GCC extension accepts the case when a struct with a flexible array member
> +   is embedded into another struct (possibly recursively).
> +   __builtin_object_size will treat such struct as flexible size per
> +   -fstrict-flex-arrays.  */ 
> +/* { dg-do run } */
> +/* { dg-options "-O2 -fstrict-flex-arrays=1" } */
> +
> +#include <stdio.h>
> +
> +unsigned n_fails = 0;
> +
> +#define expect(p, _v) do { \
> +  size_t v = _v; \
> +  if (p == v) \
> +    printf("ok:  %s == %zd\n", #p, p); \
> +  else {\
> +    printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
> +    n_fails++; \
> +  } \
> +} while (0);
> +
> +struct A {
> +  int n;
> +  char data[];/* Content following header */
> +};
> +
> +struct B {
> +  int m;
> +  struct A a;
> +};
> +
> +struct C {
> +  int q;
> +  struct B b;
> +};
> +
> +struct A0 {
> +  int n;
> +  char data[0];/* Content following header */
> +};
> +
> +struct B0 {
> +  int m;
> +  struct A0 a;
> +};
> +
> +struct C0 {
> +  int q;
> +  struct B0 b;
> +};
> +
> +struct A1 {
> +  int n;
> +  char data[1];/* Content following header */
> +};
> +
> +struct B1 {
> +  int m;
> +  struct A1 a;
> +};
> +
> +struct C1 {
> +  int q;
> +  struct B1 b;
> +};
> +
> +struct An {
> +  int n;
> +  char data[8];/* Content following header */
> +};
> +
> +struct Bn {
> +  int m;
> +  struct An a;
> +};
> +
> +struct Cn {
> +  int q;
> +  struct Bn b;
> +};
> +
> +volatile void *magic1, *magic2;
> +
> +int main(int argc, char *argv[])
> +{
> +    struct B *outer;
> +    struct C *outest;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer = (void *)magic1;
> +    outest = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer->a, 1), -1);
> +    expect(__builtin_object_size(&outest->b, 1), -1);
> +    expect(__builtin_object_size(&outest->b.a, 1), -1);
> +
> +    struct B0 *outer0;
> +    struct C0 *outest0;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer0 = (void *)magic1;
> +    outest0 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer0->a, 1), -1);
> +    expect(__builtin_object_size(&outest0->b, 1), -1);
> +    expect(__builtin_object_size(&outest0->b.a, 1), -1);
> +
> +    struct B1 *outer1;
> +    struct C1 *outest1;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer1 = (void *)magic1;
> +    outest1 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer1->a, 1), -1);
> +    expect(__builtin_object_size(&outest1->b, 1), -1);
> +    expect(__builtin_object_size(&outest1->b.a, 1), -1);
> +
> +    struct Bn *outern;
> +    struct Cn *outestn;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outern = (void *)magic1;
> +    outestn = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outern->a, 1), sizeof(outern->a));
> +    expect(__builtin_object_size(&outestn->b, 1), sizeof(outestn->b));
> +    expect(__builtin_object_size(&outestn->b.a, 1), sizeof(outestn->b.a));
> +
> +    if (n_fails > 0)
> +      __builtin_abort ();
> +
> +    return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-3.c 
> b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-3.c
> new file mode 100644
> index 00000000000..aaae99b8d67
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-3.c
> @@ -0,0 +1,135 @@
> +/* PR 101832: 
> +   GCC extension accepts the case when a struct with a flexible array member
> +   is embedded into another struct (possibly recursively).
> +   __builtin_object_size will treat such struct as flexible size per
> +   -fstrict-flex-arrays.  */
> +/* { dg-do run } */
> +/* { dg-options "-O2 -fstrict-flex-arrays=2" } */
> +
> +#include <stdio.h>
> +
> +unsigned n_fails = 0;
> +
> +#define expect(p, _v) do { \
> +  size_t v = _v; \
> +  if (p == v) \
> +    printf("ok:  %s == %zd\n", #p, p); \
> +  else {\
> +    printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
> +    n_fails++; \
> +  } \
> +} while (0);
> +
> +struct A {
> +  int n;
> +  char data[];/* Content following header */
> +};
> +
> +struct B {
> +  int m;
> +  struct A a;
> +};
> +
> +struct C {
> +  int q;
> +  struct B b;
> +};
> +
> +struct A0 {
> +  int n;
> +  char data[0];/* Content following header */
> +};
> +
> +struct B0 {
> +  int m;
> +  struct A0 a;
> +};
> +
> +struct C0 {
> +  int q;
> +  struct B0 b;
> +};
> +
> +struct A1 {
> +  int n;
> +  char data[1];/* Content following header */
> +};
> +
> +struct B1 {
> +  int m;
> +  struct A1 a;
> +};
> +
> +struct C1 {
> +  int q;
> +  struct B1 b;
> +};
> +
> +struct An {
> +  int n;
> +  char data[8];/* Content following header */
> +};
> +
> +struct Bn {
> +  int m;
> +  struct An a;
> +};
> +
> +struct Cn {
> +  int q;
> +  struct Bn b;
> +};
> +
> +volatile void *magic1, *magic2;
> +
> +int main(int argc, char *argv[])
> +{
> +    struct B *outer;
> +    struct C *outest;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer = (void *)magic1;
> +    outest = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer->a, 1), -1);
> +    expect(__builtin_object_size(&outest->b, 1), -1);
> +    expect(__builtin_object_size(&outest->b.a, 1), -1);
> +
> +    struct B0 *outer0;
> +    struct C0 *outest0;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer0 = (void *)magic1;
> +    outest0 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer0->a, 1), -1);
> +    expect(__builtin_object_size(&outest0->b, 1), -1);
> +    expect(__builtin_object_size(&outest0->b.a, 1), -1);
> +
> +    struct B1 *outer1;
> +    struct C1 *outest1;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer1 = (void *)magic1;
> +    outest1 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer1->a, 1), sizeof(outer1->a));
> +    expect(__builtin_object_size(&outest1->b, 1), sizeof(outest1->b));
> +    expect(__builtin_object_size(&outest1->b.a, 1), sizeof(outest1->b.a));
> +
> +    struct Bn *outern;
> +    struct Cn *outestn;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outern = (void *)magic1;
> +    outestn = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outern->a, 1), sizeof(outern->a));
> +    expect(__builtin_object_size(&outestn->b, 1), sizeof(outestn->b));
> +    expect(__builtin_object_size(&outestn->b.a, 1), sizeof(outestn->b.a));
> +
> +    if (n_fails > 0)
> +      __builtin_abort ();
> +
> +    return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-4.c 
> b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-4.c
> new file mode 100644
> index 00000000000..424264e2acd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832-4.c
> @@ -0,0 +1,135 @@
> +/* PR 101832: 
> +   GCC extension accepts the case when a struct with a flexible array member
> +   is embedded into another struct (possibly recursively).
> +   __builtin_object_size will treat such struct as flexible size per
> +   -fstrict-flex-arrays.  */
> +/* { dg-do run } */
> +/* { dg-options "-O2 -fstrict-flex-arrays=3" } */
> +
> +#include <stdio.h>
> +
> +unsigned n_fails = 0;
> +
> +#define expect(p, _v) do { \
> +  size_t v = _v; \
> +  if (p == v) \
> +    printf("ok:  %s == %zd\n", #p, p); \
> +  else {\
> +    printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
> +    n_fails++; \
> +  } \
> +} while (0);
> +
> +struct A {
> +  int n;
> +  char data[];/* Content following header */
> +};
> +
> +struct B {
> +  int m;
> +  struct A a;
> +};
> +
> +struct C {
> +  int q;
> +  struct B b;
> +};
> +
> +struct A0 {
> +  int n;
> +  char data[0];/* Content following header */
> +};
> +
> +struct B0 {
> +  int m;
> +  struct A0 a;
> +};
> +
> +struct C0 {
> +  int q;
> +  struct B0 b;
> +};
> +
> +struct A1 {
> +  int n;
> +  char data[1];/* Content following header */
> +};
> +
> +struct B1 {
> +  int m;
> +  struct A1 a;
> +};
> +
> +struct C1 {
> +  int q;
> +  struct B1 b;
> +};
> +
> +struct An {
> +  int n;
> +  char data[8];/* Content following header */
> +};
> +
> +struct Bn {
> +  int m;
> +  struct An a;
> +};
> +
> +struct Cn {
> +  int q;
> +  struct Bn b;
> +};
> +
> +volatile void *magic1, *magic2;
> +
> +int main(int argc, char *argv[])
> +{
> +    struct B *outer;
> +    struct C *outest;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer = (void *)magic1;
> +    outest = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer->a, 1), -1);
> +    expect(__builtin_object_size(&outest->b, 1), -1);
> +    expect(__builtin_object_size(&outest->b.a, 1), -1);
> +
> +    struct B0 *outer0;
> +    struct C0 *outest0;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer0 = (void *)magic1;
> +    outest0 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer0->a, 1), sizeof(outer0->a));
> +    expect(__builtin_object_size(&outest0->b, 1), sizeof(outest0->b));
> +    expect(__builtin_object_size(&outest0->b.a, 1), sizeof(outest0->b.a));
> +
> +    struct B1 *outer1;
> +    struct C1 *outest1;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outer1 = (void *)magic1;
> +    outest1 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer1->a, 1), sizeof(outer1->a));
> +    expect(__builtin_object_size(&outest1->b, 1), sizeof(outest1->b));
> +    expect(__builtin_object_size(&outest1->b.a, 1), sizeof(outest1->b.a));
> +
> +    struct Bn *outern;
> +    struct Cn *outestn;
> +
> +    /* Make sure optimization can't find some other object size. */
> +    outern = (void *)magic1;
> +    outestn = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outern->a, 1), sizeof(outern->a));
> +    expect(__builtin_object_size(&outestn->b, 1), sizeof(outestn->b));
> +    expect(__builtin_object_size(&outestn->b.a, 1), sizeof(outestn->b.a));
> +
> +    if (n_fails > 0)
> +      __builtin_abort ();
> +
> +    return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c 
> b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> new file mode 100644
> index 00000000000..8ed6980edf0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> @@ -0,0 +1,119 @@
> +/* PR 101832: 
> +   GCC extension accepts the case when a struct with a flexible array member
> +   is embedded into another struct (possibly recursively).
> +   __builtin_object_size will treat such struct as flexible size per
> +   -fstrict-flex-arrays.  */
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +#include <stdio.h>
> +
> +unsigned n_fails = 0;
> +
> +#define expect(p, _v) do { \
> +  size_t v = _v; \
> +  if (p == v) \
> +    printf("ok:  %s == %zd\n", #p, p); \
> +  else {\
> +    printf("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
> +    n_fails++; \
> +  } \
> +} while (0);
> +
> +struct A {
> +  int n;
> +  char data[];/* Content following header */
> +};
> +
> +struct B {
> +  int m;
> +  struct A a;
> +};
> +
> +struct C {
> +  int q;
> +  struct B b;
> +};
> +
> +struct A0 {
> +  int n;
> +  char data[0];/* Content following header */
> +};
> +
> +struct B0 {
> +  int m;
> +  struct A0 a;
> +};
> +
> +struct C0 {
> +  int q;
> +  struct B0 b;
> +};
> +
> +struct A1 {
> +  int n;
> +  char data[1];/* Content following header */
> +};
> +
> +struct B1 {
> +  int m;
> +  struct A1 a;
> +};
> +
> +struct C1 {
> +  int q;
> +  struct B1 b;
> +};
> +
> +struct An {
> +  int n;
> +  char data[8];/* Content following header */
> +};
> +
> +struct Bn {
> +  int m;
> +  struct An a;
> +};
> +
> +struct Cn {
> +  int q;
> +  struct Bn b;
> +};
> +
> +volatile void *magic1, *magic2;
> +
> +int main(int argc, char *argv[])
> +{
> +    struct B *outer = (void *)magic1;
> +    struct C *outest = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer->a, 1), -1);
> +    expect(__builtin_object_size(&outest->b, 1), -1);
> +    expect(__builtin_object_size(&outest->b.a, 1), -1);
> +
> +    struct B0 *outer0 = (void *)magic1;
> +    struct C0 *outest0 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer0->a, 1), -1);
> +    expect(__builtin_object_size(&outest0->b, 1), -1);
> +    expect(__builtin_object_size(&outest0->b.a, 1), -1);
> +
> +    struct B1 *outer1 = (void *)magic1;
> +    struct C1 *outest1 = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outer1->a, 1), -1);
> +    expect(__builtin_object_size(&outest1->b, 1), -1);
> +    expect(__builtin_object_size(&outest1->b.a, 1), -1);
> +
> +    struct Bn *outern = (void *)magic1;
> +    struct Cn *outestn = (void *)magic2;
> +
> +    expect(__builtin_object_size(&outern->a, 1), -1);
> +    expect(__builtin_object_size(&outestn->b, 1), -1);
> +    expect(__builtin_object_size(&outestn->b.a, 1), -1);
> +
> +    if (n_fails > 0)
> +      __builtin_abort ();
> +
> +    return 0;
> +}
> diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
> index 9a936a91983..56b78ca2a8c 100644
> --- a/gcc/tree-object-size.cc
> +++ b/gcc/tree-object-size.cc
> @@ -500,6 +500,42 @@ decl_init_size (tree decl, bool min)
>    return size;
>  }
>  
> +/* Determine whether TYPE is a structure with a flexible array member
> +   per -fstrict-flex-array or a union containing such a structure
> +   (possibly recursively).  */
> +static bool
> +flexible_size_type_p (const_tree type)
> +{
> +  tree x = NULL_TREE;
> +  tree last = NULL_TREE;
> +  switch (TREE_CODE (type))
> +    {
> +    case RECORD_TYPE:
> +      for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
> +     if (TREE_CODE (x) == FIELD_DECL)
> +       last = x;
> +      if (last == NULL_TREE)
> +     return false;
> +      if (TREE_CODE (TREE_TYPE (last)) == ARRAY_TYPE
> +       && !DECL_NOT_FLEXARRAY (last))
> +     return true;
> +      else if (TREE_CODE (TREE_TYPE (last)) == RECORD_TYPE
> +            || TREE_CODE (TREE_TYPE (last)) == UNION_TYPE)
> +     return flexible_size_type_p (TREE_TYPE (last));

For types with many members this can become quite slow (IIRC we had
bugs about similar walks of all fields in types), and this function
looks like it's invoked multiple times on the same type per TU.

In principle the property is fixed at the time we lay out a record
type, so we might want to compute it at that time and record the
result.

> +      return false;
> +    case UNION_TYPE:
> +      for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x))
> +     {
> +       if (TREE_CODE (x) == FIELD_DECL
> +           && flexible_array_type_p (TREE_TYPE (x)))
> +         return true;
> +     }
> +      return false;
> +    default:
> +      return false;
> +  }
> +}
> +
>  /* Compute __builtin_object_size for PTR, which is a ADDR_EXPR.
>     OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
>     If unknown, return size_unknown (object_size_type).  */
> @@ -633,45 +669,68 @@ addr_object_size (struct object_size_info *osi, 
> const_tree ptr,
>                   v = NULL_TREE;
>                   break;
>                 case COMPONENT_REF:
> -                 if (TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
> +                 /* When the ref is not to an array, a record or a union, it
> +                    will not have flexible size, compute the object size
> +                    directly.  */
> +                 if ((TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
> +                     && (TREE_CODE (TREE_TYPE (v)) != RECORD_TYPE)
> +                     && (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE))
>                     {
>                       v = NULL_TREE;
>                       break;
>                     }
> -                 is_flexible_array_mem_ref = array_ref_flexible_size_p (v);
> -                 while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
> -                   if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> -                       != UNION_TYPE
> -                       && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> -                       != QUAL_UNION_TYPE)
> -                     break;
> -                   else
> -                     v = TREE_OPERAND (v, 0);
> -                 if (TREE_CODE (v) == COMPONENT_REF
> -                     && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> -                        == RECORD_TYPE)
> +                 /* if the record or union does not have flexible size
> +                    compute the object size directly.  */
> +                 if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE
> +                     || TREE_CODE (TREE_TYPE (v)) == UNION_TYPE)
>                     {
> -                     /* compute object size only if v is not a
> -                        flexible array member.  */
> -                     if (!is_flexible_array_mem_ref)
> +                     if (!flexible_size_type_p (TREE_TYPE (v)))
>                         {
>                           v = NULL_TREE;
>                           break;
>                         }
> -                     v = TREE_OPERAND (v, 0);
> +                     else
> +                       v = TREE_OPERAND (v, 0);
>                     }
> -                 while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
> -                   if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> -                       != UNION_TYPE
> -                       && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> -                       != QUAL_UNION_TYPE)
> -                     break;
> -                   else
> -                     v = TREE_OPERAND (v, 0);
> -                 if (v != pt_var)
> -                   v = NULL_TREE;
>                   else
> -                   v = pt_var;
> +                   {
> +                     /* Now the ref is to an array type.  */
> +                     is_flexible_array_mem_ref
> +                       = array_ref_flexible_size_p (v);
> +                     while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
> +                     if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> +                           != UNION_TYPE
> +                         && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> +                              != QUAL_UNION_TYPE)
> +                       break;
> +                     else
> +                       v = TREE_OPERAND (v, 0);
> +                     if (TREE_CODE (v) == COMPONENT_REF
> +                         && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> +                              == RECORD_TYPE)
> +                       {
> +                         /* compute object size only if v is not a
> +                            flexible array member.  */
> +                         if (!is_flexible_array_mem_ref)
> +                           {
> +                             v = NULL_TREE;
> +                             break;
> +                           }
> +                         v = TREE_OPERAND (v, 0);
> +                       }
> +                     while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
> +                       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> +                             != UNION_TYPE
> +                           && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> +                                != QUAL_UNION_TYPE)
> +                         break;
> +                       else
> +                         v = TREE_OPERAND (v, 0);
> +                     if (v != pt_var)
> +                       v = NULL_TREE;
> +                     else
> +                       v = pt_var;
> +                   }
>                   break;
>                 default:
>                   v = pt_var;
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

Reply via email to