From: Andris K, on
Hello. I found a problem in the way that some C compilers handle
the case where a function modifies a global pointer and returns
an address which is assigned to that same global pointer.
A test program appears below. The following compilers are able
to generate a code which can take branch #1 of the test program
without any problems:

HP-UX bundled C (K&R) \
HP-UX ANSI-C > all 11.x releases on all platforms
HP-UX aCC (C++) /
Microsoft C (Visual Studio 2008)
gcc-2.95

The compilers that fail the branch #1 test are:

gcc 3.x
gcc 4.x
Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)

Could any of you who have access to Sun's Studio C compiler
please compile the test program and post the results?

Thanks,
Andris

....................................................................

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define PC struct pc
typedef unsigned short word;

PC { /* typical linked list structure */
word op;
PC *code;
};

PC *pcptr; /* global structures */
PC *pcptr_copy;

#ifdef __STDC__
int get_data(char *prompt)
#else
int get_data(prompt)
char *prompt;
#endif
{
char buf[40];
int result, *result_ptr;

result_ptr = &result;
do {
fputs(prompt, stdout);
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%i", result_ptr);
} while (result != 1 && result != 2);
return(result);
}

#ifdef __STDC__
PC *fnc_A(void)
#else
PC *fnc_A()
#endif
{
if ((pcptr = pcptr_copy = (PC *)malloc(sizeof(PC))) == NULL) {
perror("malloc(3) failed");
exit(1);
}
pcptr->code = NULL;
printf("fnc_A: \tpcptr = %p\n", (void *)pcptr);
printf(" \tpcptr->code = %p\n", (void *)pcptr->code);
return(pcptr);
}

#ifdef __STDC__
int main(void)
#else
int main()
#endif
{
int init_choice, branch;

branch = get_data("Take the suspect branch [1] or stay
`safe' [2]? ");
init_choice = get_data("Initialize `pcptr' with NULL [1] or malloc
[2]? ");
puts("");

if (init_choice == 1)
pcptr = NULL;
else {
if ((pcptr = (PC *)malloc(sizeof(PC))) == NULL) {
perror("malloc(3) failed");
exit(1);
}
}
printf("main: [init] pcptr = %p\n\n", (void *)pcptr);

printf("Taking branch %i.\n", branch);
if (branch == 1)
/*
* This branch works fine with the gcc-2.95 and HP-UX
compilers.
* If compiled with gcc {3,4}.X, however, the results are:
*
* > SEGFAULT if `pcptr' is initialized to NULL
* or
* > Corrupted value of `pcptr->code' if `pcptr'
* is initialized to a non-NULL address.
*
* The newer compilers appear to incorrectly handle the case
* where the assignment target is a global pointer reference
* (pcptr->code) and the value being assigned is returned by
* a function which can modify the global pointer itself.
*/
pcptr->code = fnc_A();
else {
/*
* All compilers can handle this branch correctly
* regardless of how `pcptr' is initialized.
*/
PC *tmp_ptr;
tmp_ptr = fnc_A();
pcptr->code = tmp_ptr;
}
printf("main: \tpcptr = %p", (void *)pcptr);
printf("\t(%p <- should be this)\n", (void *)pcptr_copy);
printf(" \tpcptr->code = %p", (void *)pcptr->code);
printf("\t(%p <- should be this)\n", (void *)pcptr_copy);
return(0);
}
From: Ian Collins on
Andris K, wrote:
> Hello. I found a problem in the way that some C compilers handle
> the case where a function modifies a global pointer and returns
> an address which is assigned to that same global pointer.
> A test program appears below. The following compilers are able
> to generate a code which can take branch #1 of the test program
> without any problems:
>
> HP-UX bundled C (K&R) \
> HP-UX ANSI-C > all 11.x releases on all platforms
> HP-UX aCC (C++) /
> Microsoft C (Visual Studio 2008)
> gcc-2.95
>
> The compilers that fail the branch #1 test are:
>
> gcc 3.x
> gcc 4.x
> Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)
>
> Could any of you who have access to Sun's Studio C compiler
> please compile the test program and post the results?
>
I don't think much of the code, but it runs fin when compiled with cc:

> c99 /tmp/x.c
> ./a.out
Take the suspect branch [1] or stay`safe' [2]? 1
Initialize `pcptr' with NULL [1] or malloc[2]? 1

main: [init] pcptr = 0

Taking branch 1.
fnc_A: pcptr = 8061638
pcptr->code = 0
main: pcptr = 8061638 (8061638 <- should be this)
pcptr->code = 8061638 (8061638 <- should be this)

--
Ian Collins
From: Andris K, on
On Jan 10, 8:23 pm, Ian Collins <ian-n...(a)hotmail.com> wrote:
> Andris K, wrote:
> > Hello.  I found a problem in the way that some C compilers handle
> > the case where a function modifies a global pointer and returns
> > an address which is assigned to that same global pointer.
> > A test program appears below.  The following compilers are able
> > to generate a code which can take branch #1 of the test program
> > without any problems:
>
> >   HP-UX bundled C (K&R)  \
> >   HP-UX ANSI-C            > all 11.x releases on all platforms
> >   HP-UX aCC (C++)        /
> >   Microsoft C (Visual Studio 2008)
> >   gcc-2.95
>
> > The compilers that fail the branch #1 test are:
>
> >   gcc 3.x
> >   gcc 4.x
> >   Compaq C V6.5-011 on HP Tru64 UNIX V5.1B (Rev. 2650)
>
> > Could any of you who have access to Sun's Studio C compiler
> > please compile the test program and post the results?
>
> I don't think much of the code, but it runs fin when compiled with cc:
>
>  > c99 /tmp/x.c
>  > ./a.out
> Take the suspect branch [1] or stay`safe' [2]? 1
> Initialize `pcptr' with NULL [1] or malloc[2]? 1
>
> main:    [init] pcptr       = 0
>
> Taking branch 1.
> fnc_A:        pcptr       = 8061638
>                  pcptr->code = 0
> main:         pcptr       = 8061638   (8061638 <- should be this)
>                  pcptr->code = 8061638   (8061638 <- should be this)

Thanks, Ian. The legacy code (early 90's) from which this test was
derived is, unfortunately, what it is. I'm glad to see that Sun's
compiler
could handle this particular situation.

------
Andris

From: Ian Collins on
Andris K, wrote:
>
> Thanks, Ian. The legacy code (early 90's) from which this test was
> derived is, unfortunately, what it is. I'm glad to see that Sun's
> compiler
> could handle this particular situation.

I think the line

pcptr->code = fnc_A();

exhibits undefined behaviour. Try posting the code to comp.lang.c and
see what they have to say.

--
Ian Collins
From: Andris K, on
On Jan 10, 10:27 pm, Ian Collins <ian-n...(a)hotmail.com> wrote:
> Andris K, wrote:
>
> > Thanks, Ian.  The legacy code (early 90's) from which this test was
> > derived is, unfortunately, what it is.  I'm glad to see that Sun's
> > compiler
> > could handle this particular situation.
>
> I think the line
>
> pcptr->code = fnc_A();
>
> exhibits undefined behaviour.  Try posting the code to comp.lang.c and
> see what they have to say.
>
> --
> Ian Collins

Will do. I'm in the midst of trying to convince the gcc folks that
their
failure to handle this situation is a defect. I've made a similar
test
request to comp.unix.aix to see if the IBM compilers behave like the
Sun, HP-UX, and Microsoft compilers. I'll certainly consider the
advice
of the experts in comp.lang.c.

------
Andris
community