[Muq-bugs] gcc 2.95.2 -O9 int <--> long long bug?

Scott A Crosby crosby@qwes.math.cmu.edu
Sun Sep 10 19:55:00 GMT 2000


On Sun, 10 Sep 2000, Cynbe ru Taren wrote:

> 
> Dunno if this is a known issue or what, but there appears to be
> a gcc 2.95.2 issue with implicit long long <--> int conversions
> at optimization level -O9.
> 
> Here is a sample program for reproducing the problem:
> 
>     #include <stdio.h>
>     #include <sys/types.h>
>     #include <sys/stat.h>
>     #include <fcntl.h>
> 
>     int  vopen(const unsigned char* file,int line,const unsigned char* name,int mode );
> 
>     #define vmopen(x,y) vopen(__FILE__,__LINE__,x,y)
> 
>     int
>     vopen(
> 	const unsigned char* file,
> 	      int     line,
> 	const unsigned char* name,
> 	      int     mode
>     ){
> 	int fd = open(name,mode);
> 	/* This wrapper gives us a central place */
> 	/* to add debugging logic or such.       */
> 	printf("%s.%d: vopen(%s,%d) = %d...\n",file,line,name,mode,fd);
> 	return fd;
>     }
> 
>     void
>     dbDuplicate(
> 	void
>     ) {
> 	long long   fd;
> 	unsigned char  buf[ 256 ];
> 
> 	strcpy( buf, "touch mytest.tmp" );
> 	system(buf);
> 	strcpy( buf, "mytest.tmp" );
> 


> 	if ((fd = vmopen( buf, O_RDONLY)) >= 0) {
> 
> 	    close( fd );
> 	    printf("mytest.tmp FOUND\n");
> 	} else {
> 	    printf("mytest.tmp LOST\n");
> 	}
>     }


I think that this conditional is where the problem is..

I ran both of the programs under an strace (out1/out2 are with and without
-O9 optimization):


>>>
strace -F -f -o out1.log ./out1
strace -F -f -o out2.log ./out2 

cat out1.log | sed -es/3074/3071/g | sed -es/3075/3072/g | diff - out2.log 
<<<

THe 'seds' are to make the process numbers congruent so that I don't get
superflouis lines in the diff. The diff reports the two programs as being
essentially identical when running. (AT least in terms of system call
trace.) There are no differences in terms of files created, opened,
mmapped, stat'ed.

Therefore it must be the result of the 'if'. The cast from 'long long' in
return values down to 'int' for storing in 'fd'. Changing the declaration
of 'fd' to an int fixes the problem.

> 
>     int
>     main( int argc, char** argv ) {
>       dbDuplicate();
>     }
> 
> 

As such, I submit a reduced and standalone testcase that does not create
extra files:

    #include <unistd.h>
    #include <stdio.h>

    int
    vopen(
    ){
          /* We need a system call or another function that returns a
pid_t, so we use 'fork'. */
        int pid;
        if ((pid = fork())) {
          printf("pid output: %d\n",pid);
          return pid;
        } else {
          /* If it's the child, just exit */
          exit(0);
          }
    }

    void
    dbDuplicate(
        void
    ) {
        long long   pid;

        if ((pid = vopen()) >= 0) {
            printf("pid is >= 0\n");
        } else {
            printf("pid is not >= 0\n");
        }
    }

    int
    main( int argc, char** argv ) {
      dbDuplicate();
    }



--- With this output ---

crosby@dragonlight:/tmp$ gcc -o out3 -O2 bugtest.c ; ./out3
pid output: 3675
pid is >= 0
crosby@dragonlight:/tmp$ gcc -o out3 -O9 bugtest.c ; ./out3
pid output: 3683
pid is not >= 0


--


Scott


--
No DVD movie will ever enter the public domain, nor will any CD. The last CD 
and the last DVD will have moldered away decades before they leave copyright. 
This is not encouraging the creation of knowledge in the public domain.



More information about the Gcc-bugs mailing list