Message ID | 55A39AD5.1020006@mentor.com |
---|---|
State | New |
Headers | show |
On 13/07/15 13:02, Tom de Vries wrote: > Hi, > > this patch fixes PR46193. > > It handles min and max reductions of pointer type in parloops. > > Bootstrapped and reg-tested on x86_64. > > OK for trunk? > Ping. Thanks, - Tom > 0001-Handle-mix-max-pointer-reductions-in-parloops.patch > > > Handle mix/max pointer reductions in parloops > > 2015-07-13 Tom de Vries<tom@codesourcery.com> > > PR tree-optimization/46193 > * omp-low.c (omp_reduction_init): Handle pointer type for min or max > clause. > > * gcc.dg/autopar/pr46193.c: New test. > > * testsuite/libgomp.c/pr46193.c: New test. > --- > gcc/omp-low.c | 4 ++ > gcc/testsuite/gcc.dg/autopar/pr46193.c | 38 +++++++++++++++++++ > libgomp/testsuite/libgomp.c/pr46193.c | 67 ++++++++++++++++++++++++++++++++++ > 3 files changed, 109 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/autopar/pr46193.c > create mode 100644 libgomp/testsuite/libgomp.c/pr46193.c > > diff --git a/gcc/omp-low.c b/gcc/omp-low.c > index 2e2070a..20d0010 100644 > --- a/gcc/omp-low.c > +++ b/gcc/omp-low.c > @@ -3423,6 +3423,8 @@ omp_reduction_init (tree clause, tree type) > real_maxval (&min, 1, TYPE_MODE (type)); > return build_real (type, min); > } > + else if (POINTER_TYPE_P (type)) > + return lower_bound_in_type (type, type); > else > { > gcc_assert (INTEGRAL_TYPE_P (type)); > @@ -3439,6 +3441,8 @@ omp_reduction_init (tree clause, tree type) > real_maxval (&max, 0, TYPE_MODE (type)); > return build_real (type, max); > } > + else if (POINTER_TYPE_P (type)) > + return upper_bound_in_type (type, type); > else > { > gcc_assert (INTEGRAL_TYPE_P (type)); > diff --git a/gcc/testsuite/gcc.dg/autopar/pr46193.c b/gcc/testsuite/gcc.dg/autopar/pr46193.c > new file mode 100644 > index 0000000..544a5da > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/autopar/pr46193.c > @@ -0,0 +1,38 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops-details" } */ > + > +extern void abort (void); > + > +char * > +foo (int count, char **list) > +{ > + char *minaddr = list[0]; > + int i; > + > + for (i = 0; i < count; i++) > + { > + char *addr = list[i]; > + if (addr < minaddr) > + minaddr = addr; > + } > + > + return minaddr; > +} > + > +char * > +foo2 (int count, char **list) > +{ > + char *maxaddr = list[0]; > + int i; > + > + for (i = 0; i < count; i++) > + { > + char *addr = list[i]; > + if (addr > maxaddr) > + maxaddr = addr; > + } > + > + return maxaddr; > +} > + > +/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 2 "parloops" } } */ > diff --git a/libgomp/testsuite/libgomp.c/pr46193.c b/libgomp/testsuite/libgomp.c/pr46193.c > new file mode 100644 > index 0000000..1e27faf > --- /dev/null > +++ b/libgomp/testsuite/libgomp.c/pr46193.c > @@ -0,0 +1,67 @@ > +/* { dg-do run } */ > +/* { dg-additional-options "-ftree-parallelize-loops=2" } */ > + > +extern void abort (void); > + > +char * > +foo (int count, char **list) > +{ > + char *minaddr = list[0]; > + int i; > + > + for (i = 0; i < count; i++) > + { > + char *addr = list[i]; > + if (addr < minaddr) > + minaddr = addr; > + } > + > + return minaddr; > +} > + > +char * > +foo2 (int count, char **list) > +{ > + char *maxaddr = list[0]; > + int i; > + > + for (i = 0; i < count; i++) > + { > + char *addr = list[i]; > + if (addr > maxaddr) > + maxaddr = addr; > + } > + > + return maxaddr; > +} > + > +#define N 5 > + > +static void > +init (char **list) > +{ > + int i; > + for (i = 0; i < N; ++i) > + list[i] = (char *)&list[i]; > +} > + > +int > +main (void) > +{ > + char *list[N]; > + char * res; > + > + init (list); > + > + res = foo (N, list); > + > + if (res != (char *)&list[0]) > + abort (); > + > + res = foo2 (N, list); > + > + if (res != (char *)&list[N-1]) > + abort (); > + > + return 0; > +} > -- 1.9.1 >
On 22/07/15 20:15, Tom de Vries wrote: > On 13/07/15 13:02, Tom de Vries wrote: >> Hi, >> >> this patch fixes PR46193. >> >> It handles min and max reductions of pointer type in parloops. >> >> Bootstrapped and reg-tested on x86_64. >> >> OK for trunk? >> > > Ping. > Committed to gomp-4_0-branch. Thanks, - Tom >> 0001-Handle-mix-max-pointer-reductions-in-parloops.patch >> >> >> Handle mix/max pointer reductions in parloops >> >> 2015-07-13 Tom de Vries<tom@codesourcery.com> >> >> PR tree-optimization/46193 >> * omp-low.c (omp_reduction_init): Handle pointer type for min or max >> clause. >> >> * gcc.dg/autopar/pr46193.c: New test. >> >> * testsuite/libgomp.c/pr46193.c: New test. >> --- >> gcc/omp-low.c | 4 ++ >> gcc/testsuite/gcc.dg/autopar/pr46193.c | 38 +++++++++++++++++++ >> libgomp/testsuite/libgomp.c/pr46193.c | 67 >> ++++++++++++++++++++++++++++++++++ >> 3 files changed, 109 insertions(+) >> create mode 100644 gcc/testsuite/gcc.dg/autopar/pr46193.c >> create mode 100644 libgomp/testsuite/libgomp.c/pr46193.c >> >> diff --git a/gcc/omp-low.c b/gcc/omp-low.c >> index 2e2070a..20d0010 100644 >> --- a/gcc/omp-low.c >> +++ b/gcc/omp-low.c >> @@ -3423,6 +3423,8 @@ omp_reduction_init (tree clause, tree type) >> real_maxval (&min, 1, TYPE_MODE (type)); >> return build_real (type, min); >> } >> + else if (POINTER_TYPE_P (type)) >> + return lower_bound_in_type (type, type); >> else >> { >> gcc_assert (INTEGRAL_TYPE_P (type)); >> @@ -3439,6 +3441,8 @@ omp_reduction_init (tree clause, tree type) >> real_maxval (&max, 0, TYPE_MODE (type)); >> return build_real (type, max); >> } >> + else if (POINTER_TYPE_P (type)) >> + return upper_bound_in_type (type, type); >> else >> { >> gcc_assert (INTEGRAL_TYPE_P (type)); >> diff --git a/gcc/testsuite/gcc.dg/autopar/pr46193.c >> b/gcc/testsuite/gcc.dg/autopar/pr46193.c >> new file mode 100644 >> index 0000000..544a5da >> --- /dev/null >> +++ b/gcc/testsuite/gcc.dg/autopar/pr46193.c >> @@ -0,0 +1,38 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -ftree-parallelize-loops=2 >> -fdump-tree-parloops-details" } */ >> + >> +extern void abort (void); >> + >> +char * >> +foo (int count, char **list) >> +{ >> + char *minaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr < minaddr) >> + minaddr = addr; >> + } >> + >> + return minaddr; >> +} >> + >> +char * >> +foo2 (int count, char **list) >> +{ >> + char *maxaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr > maxaddr) >> + maxaddr = addr; >> + } >> + >> + return maxaddr; >> +} >> + >> +/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 2 >> "parloops" } } */ >> diff --git a/libgomp/testsuite/libgomp.c/pr46193.c >> b/libgomp/testsuite/libgomp.c/pr46193.c >> new file mode 100644 >> index 0000000..1e27faf >> --- /dev/null >> +++ b/libgomp/testsuite/libgomp.c/pr46193.c >> @@ -0,0 +1,67 @@ >> +/* { dg-do run } */ >> +/* { dg-additional-options "-ftree-parallelize-loops=2" } */ >> + >> +extern void abort (void); >> + >> +char * >> +foo (int count, char **list) >> +{ >> + char *minaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr < minaddr) >> + minaddr = addr; >> + } >> + >> + return minaddr; >> +} >> + >> +char * >> +foo2 (int count, char **list) >> +{ >> + char *maxaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr > maxaddr) >> + maxaddr = addr; >> + } >> + >> + return maxaddr; >> +} >> + >> +#define N 5 >> + >> +static void >> +init (char **list) >> +{ >> + int i; >> + for (i = 0; i < N; ++i) >> + list[i] = (char *)&list[i]; >> +} >> + >> +int >> +main (void) >> +{ >> + char *list[N]; >> + char * res; >> + >> + init (list); >> + >> + res = foo (N, list); >> + >> + if (res != (char *)&list[0]) >> + abort (); >> + >> + res = foo2 (N, list); >> + >> + if (res != (char *)&list[N-1]) >> + abort (); >> + >> + return 0; >> +} >> -- 1.9.1 >> >
On 22-07-15 20:15, Tom de Vries wrote: > On 13/07/15 13:02, Tom de Vries wrote: >> Hi, >> >> this patch fixes PR46193. >> >> It handles min and max reductions of pointer type in parloops. >> >> Bootstrapped and reg-tested on x86_64. >> >> OK for trunk? >> > Ping^2. Original submission at https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01018.html . Thanks, - Tom > >> 0001-Handle-mix-max-pointer-reductions-in-parloops.patch >> >> >> Handle mix/max pointer reductions in parloops >> >> 2015-07-13 Tom de Vries<tom@codesourcery.com> >> >> PR tree-optimization/46193 >> * omp-low.c (omp_reduction_init): Handle pointer type for min or max >> clause. >> >> * gcc.dg/autopar/pr46193.c: New test. >> >> * testsuite/libgomp.c/pr46193.c: New test. >> --- >> gcc/omp-low.c | 4 ++ >> gcc/testsuite/gcc.dg/autopar/pr46193.c | 38 +++++++++++++++++++ >> libgomp/testsuite/libgomp.c/pr46193.c | 67 ++++++++++++++++++++++++++++++++++ >> 3 files changed, 109 insertions(+) >> create mode 100644 gcc/testsuite/gcc.dg/autopar/pr46193.c >> create mode 100644 libgomp/testsuite/libgomp.c/pr46193.c >> >> diff --git a/gcc/omp-low.c b/gcc/omp-low.c >> index 2e2070a..20d0010 100644 >> --- a/gcc/omp-low.c >> +++ b/gcc/omp-low.c >> @@ -3423,6 +3423,8 @@ omp_reduction_init (tree clause, tree type) >> real_maxval (&min, 1, TYPE_MODE (type)); >> return build_real (type, min); >> } >> + else if (POINTER_TYPE_P (type)) >> + return lower_bound_in_type (type, type); >> else >> { >> gcc_assert (INTEGRAL_TYPE_P (type)); >> @@ -3439,6 +3441,8 @@ omp_reduction_init (tree clause, tree type) >> real_maxval (&max, 0, TYPE_MODE (type)); >> return build_real (type, max); >> } >> + else if (POINTER_TYPE_P (type)) >> + return upper_bound_in_type (type, type); >> else >> { >> gcc_assert (INTEGRAL_TYPE_P (type)); >> diff --git a/gcc/testsuite/gcc.dg/autopar/pr46193.c >> b/gcc/testsuite/gcc.dg/autopar/pr46193.c >> new file mode 100644 >> index 0000000..544a5da >> --- /dev/null >> +++ b/gcc/testsuite/gcc.dg/autopar/pr46193.c >> @@ -0,0 +1,38 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops-details" >> } */ >> + >> +extern void abort (void); >> + >> +char * >> +foo (int count, char **list) >> +{ >> + char *minaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr < minaddr) >> + minaddr = addr; >> + } >> + >> + return minaddr; >> +} >> + >> +char * >> +foo2 (int count, char **list) >> +{ >> + char *maxaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr > maxaddr) >> + maxaddr = addr; >> + } >> + >> + return maxaddr; >> +} >> + >> +/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 2 "parloops" >> } } */ >> diff --git a/libgomp/testsuite/libgomp.c/pr46193.c >> b/libgomp/testsuite/libgomp.c/pr46193.c >> new file mode 100644 >> index 0000000..1e27faf >> --- /dev/null >> +++ b/libgomp/testsuite/libgomp.c/pr46193.c >> @@ -0,0 +1,67 @@ >> +/* { dg-do run } */ >> +/* { dg-additional-options "-ftree-parallelize-loops=2" } */ >> + >> +extern void abort (void); >> + >> +char * >> +foo (int count, char **list) >> +{ >> + char *minaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr < minaddr) >> + minaddr = addr; >> + } >> + >> + return minaddr; >> +} >> + >> +char * >> +foo2 (int count, char **list) >> +{ >> + char *maxaddr = list[0]; >> + int i; >> + >> + for (i = 0; i < count; i++) >> + { >> + char *addr = list[i]; >> + if (addr > maxaddr) >> + maxaddr = addr; >> + } >> + >> + return maxaddr; >> +} >> + >> +#define N 5 >> + >> +static void >> +init (char **list) >> +{ >> + int i; >> + for (i = 0; i < N; ++i) >> + list[i] = (char *)&list[i]; >> +} >> + >> +int >> +main (void) >> +{ >> + char *list[N]; >> + char * res; >> + >> + init (list); >> + >> + res = foo (N, list); >> + >> + if (res != (char *)&list[0]) >> + abort (); >> + >> + res = foo2 (N, list); >> + >> + if (res != (char *)&list[N-1]) >> + abort (); >> + >> + return 0; >> +} >> -- 1.9.1 >> >
On Mon, Aug 24, 2015 at 5:10 PM, Tom de Vries <Tom_deVries@mentor.com> wrote: > On 22-07-15 20:15, Tom de Vries wrote: >> >> On 13/07/15 13:02, Tom de Vries wrote: >>> >>> Hi, >>> >>> this patch fixes PR46193. >>> >>> It handles min and max reductions of pointer type in parloops. >>> >>> Bootstrapped and reg-tested on x86_64. >>> >>> OK for trunk? >>> >> > > Ping^2. > > Original submission at > https://gcc.gnu.org/ml/gcc-patches/2015-07/msg01018.html . Please don't use lower_bound_in_type with two identical types. Instead use wi::max_value and wide_int_to_tree. Ok with that change. Thanks, Richard. > > Thanks, > - Tom > >> >>> 0001-Handle-mix-max-pointer-reductions-in-parloops.patch >>> >>> >>> Handle mix/max pointer reductions in parloops >>> >>> 2015-07-13 Tom de Vries<tom@codesourcery.com> >>> >>> PR tree-optimization/46193 >>> * omp-low.c (omp_reduction_init): Handle pointer type for min or max >>> clause. >>> >>> * gcc.dg/autopar/pr46193.c: New test. >>> >>> * testsuite/libgomp.c/pr46193.c: New test. >>> --- >>> gcc/omp-low.c | 4 ++ >>> gcc/testsuite/gcc.dg/autopar/pr46193.c | 38 +++++++++++++++++++ >>> libgomp/testsuite/libgomp.c/pr46193.c | 67 >>> ++++++++++++++++++++++++++++++++++ >>> 3 files changed, 109 insertions(+) >>> create mode 100644 gcc/testsuite/gcc.dg/autopar/pr46193.c >>> create mode 100644 libgomp/testsuite/libgomp.c/pr46193.c >>> >>> diff --git a/gcc/omp-low.c b/gcc/omp-low.c >>> index 2e2070a..20d0010 100644 >>> --- a/gcc/omp-low.c >>> +++ b/gcc/omp-low.c >>> @@ -3423,6 +3423,8 @@ omp_reduction_init (tree clause, tree type) >>> real_maxval (&min, 1, TYPE_MODE (type)); >>> return build_real (type, min); >>> } >>> + else if (POINTER_TYPE_P (type)) >>> + return lower_bound_in_type (type, type); >>> else >>> { >>> gcc_assert (INTEGRAL_TYPE_P (type)); >>> @@ -3439,6 +3441,8 @@ omp_reduction_init (tree clause, tree type) >>> real_maxval (&max, 0, TYPE_MODE (type)); >>> return build_real (type, max); >>> } >>> + else if (POINTER_TYPE_P (type)) >>> + return upper_bound_in_type (type, type); >>> else >>> { >>> gcc_assert (INTEGRAL_TYPE_P (type)); >>> diff --git a/gcc/testsuite/gcc.dg/autopar/pr46193.c >>> b/gcc/testsuite/gcc.dg/autopar/pr46193.c >>> new file mode 100644 >>> index 0000000..544a5da >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.dg/autopar/pr46193.c >>> @@ -0,0 +1,38 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-O2 -ftree-parallelize-loops=2 >>> -fdump-tree-parloops-details" >>> } */ >>> + >>> +extern void abort (void); >>> + >>> +char * >>> +foo (int count, char **list) >>> +{ >>> + char *minaddr = list[0]; >>> + int i; >>> + >>> + for (i = 0; i < count; i++) >>> + { >>> + char *addr = list[i]; >>> + if (addr < minaddr) >>> + minaddr = addr; >>> + } >>> + >>> + return minaddr; >>> +} >>> + >>> +char * >>> +foo2 (int count, char **list) >>> +{ >>> + char *maxaddr = list[0]; >>> + int i; >>> + >>> + for (i = 0; i < count; i++) >>> + { >>> + char *addr = list[i]; >>> + if (addr > maxaddr) >>> + maxaddr = addr; >>> + } >>> + >>> + return maxaddr; >>> +} >>> + >>> +/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 2 >>> "parloops" >>> } } */ >>> diff --git a/libgomp/testsuite/libgomp.c/pr46193.c >>> b/libgomp/testsuite/libgomp.c/pr46193.c >>> new file mode 100644 >>> index 0000000..1e27faf >>> --- /dev/null >>> +++ b/libgomp/testsuite/libgomp.c/pr46193.c >>> @@ -0,0 +1,67 @@ >>> +/* { dg-do run } */ >>> +/* { dg-additional-options "-ftree-parallelize-loops=2" } */ >>> + >>> +extern void abort (void); >>> + >>> +char * >>> +foo (int count, char **list) >>> +{ >>> + char *minaddr = list[0]; >>> + int i; >>> + >>> + for (i = 0; i < count; i++) >>> + { >>> + char *addr = list[i]; >>> + if (addr < minaddr) >>> + minaddr = addr; >>> + } >>> + >>> + return minaddr; >>> +} >>> + >>> +char * >>> +foo2 (int count, char **list) >>> +{ >>> + char *maxaddr = list[0]; >>> + int i; >>> + >>> + for (i = 0; i < count; i++) >>> + { >>> + char *addr = list[i]; >>> + if (addr > maxaddr) >>> + maxaddr = addr; >>> + } >>> + >>> + return maxaddr; >>> +} >>> + >>> +#define N 5 >>> + >>> +static void >>> +init (char **list) >>> +{ >>> + int i; >>> + for (i = 0; i < N; ++i) >>> + list[i] = (char *)&list[i]; >>> +} >>> + >>> +int >>> +main (void) >>> +{ >>> + char *list[N]; >>> + char * res; >>> + >>> + init (list); >>> + >>> + res = foo (N, list); >>> + >>> + if (res != (char *)&list[0]) >>> + abort (); >>> + >>> + res = foo2 (N, list); >>> + >>> + if (res != (char *)&list[N-1]) >>> + abort (); >>> + >>> + return 0; >>> +} >>> -- 1.9.1 >>> >> >
Handle mix/max pointer reductions in parloops 2015-07-13 Tom de Vries <tom@codesourcery.com> PR tree-optimization/46193 * omp-low.c (omp_reduction_init): Handle pointer type for min or max clause. * gcc.dg/autopar/pr46193.c: New test. * testsuite/libgomp.c/pr46193.c: New test. --- gcc/omp-low.c | 4 ++ gcc/testsuite/gcc.dg/autopar/pr46193.c | 38 +++++++++++++++++++ libgomp/testsuite/libgomp.c/pr46193.c | 67 ++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/autopar/pr46193.c create mode 100644 libgomp/testsuite/libgomp.c/pr46193.c diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 2e2070a..20d0010 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3423,6 +3423,8 @@ omp_reduction_init (tree clause, tree type) real_maxval (&min, 1, TYPE_MODE (type)); return build_real (type, min); } + else if (POINTER_TYPE_P (type)) + return lower_bound_in_type (type, type); else { gcc_assert (INTEGRAL_TYPE_P (type)); @@ -3439,6 +3441,8 @@ omp_reduction_init (tree clause, tree type) real_maxval (&max, 0, TYPE_MODE (type)); return build_real (type, max); } + else if (POINTER_TYPE_P (type)) + return upper_bound_in_type (type, type); else { gcc_assert (INTEGRAL_TYPE_P (type)); diff --git a/gcc/testsuite/gcc.dg/autopar/pr46193.c b/gcc/testsuite/gcc.dg/autopar/pr46193.c new file mode 100644 index 0000000..544a5da --- /dev/null +++ b/gcc/testsuite/gcc.dg/autopar/pr46193.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fdump-tree-parloops-details" } */ + +extern void abort (void); + +char * +foo (int count, char **list) +{ + char *minaddr = list[0]; + int i; + + for (i = 0; i < count; i++) + { + char *addr = list[i]; + if (addr < minaddr) + minaddr = addr; + } + + return minaddr; +} + +char * +foo2 (int count, char **list) +{ + char *maxaddr = list[0]; + int i; + + for (i = 0; i < count; i++) + { + char *addr = list[i]; + if (addr > maxaddr) + maxaddr = addr; + } + + return maxaddr; +} + +/* { dg-final { scan-tree-dump-times "parallelizing inner loop" 2 "parloops" } } */ diff --git a/libgomp/testsuite/libgomp.c/pr46193.c b/libgomp/testsuite/libgomp.c/pr46193.c new file mode 100644 index 0000000..1e27faf --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr46193.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-parallelize-loops=2" } */ + +extern void abort (void); + +char * +foo (int count, char **list) +{ + char *minaddr = list[0]; + int i; + + for (i = 0; i < count; i++) + { + char *addr = list[i]; + if (addr < minaddr) + minaddr = addr; + } + + return minaddr; +} + +char * +foo2 (int count, char **list) +{ + char *maxaddr = list[0]; + int i; + + for (i = 0; i < count; i++) + { + char *addr = list[i]; + if (addr > maxaddr) + maxaddr = addr; + } + + return maxaddr; +} + +#define N 5 + +static void +init (char **list) +{ + int i; + for (i = 0; i < N; ++i) + list[i] = (char *)&list[i]; +} + +int +main (void) +{ + char *list[N]; + char * res; + + init (list); + + res = foo (N, list); + + if (res != (char *)&list[0]) + abort (); + + res = foo2 (N, list); + + if (res != (char *)&list[N-1]) + abort (); + + return 0; +} -- 1.9.1