https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86289

            Bug ID: 86289
           Summary: Cgo integer constant overflow for 64 bits (unsigned)
                    int
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: go
          Assignee: ian at airs dot com
          Reporter: stephen.kim at oracle dot com
                CC: cmang at google dot com
  Target Milestone: ---

I think the bug report is not the best format for this issue but that's the
only I have. Let me start with the bug. The bug seems a regression that I have
found in building docker with gccgo for aarch64. Here is, however, the reduced
test case:

$ cat ~/ce.go
package main

import "fmt"

/*
const unsigned long long int neg = (const unsigned long long) -1;
*/
import "C"

func main() {
        var i int64     
        i = int64(C.neg)
        fmt.Println(C.neg)      
        fmt.Println(i)
}

$ go build -x ~/ce.go
(omitted some logs)
../../../ce.go:14:6: error: integer constant overflow
  i = int64(C.neg)
      ^
The problem is, cgo invokes gcc as just "gcc." Gcc 8.x started to accept the
following C code:
const unsigned long long int neg = (const unsigned long long) -1;

#line 1 "not-num-const"
void __cgo_f_1_4(void) { static const double __cgo_undefined__4 = (neg); }

The code above is generated by cgo; cgo tries to understand "neg" by generating
the code and giving it to gcc. Gcc 7.3 said "That's a compile error." while gcc
8.x and 9.0 silently accept it. 

Once the code is accepted by, say, gcc 9, cgo type-casts the value as double.
It is very clear that a 64 bit double cannot accommodate all 64 bits integer
values. -1 is one of the corner cases. 

As "neg" is "not-int-const," if gcc says it does not fall into "not-num-const,"
cgo thinks "neg" is an fconst. That is destined to be type-casted to a double:

#line 1 "cgo-generated-wrapper"
#line 1 "cgo-dwarf-inference"
__typeof__(neg) *__cgo__0;
long long __cgodebug_ints[] = {
        0,
        1
};
double __cgodebug_floats[] = {
        neg,
        1
};

Cgo generates the code above to get some debugging information gcc generated,
and use the value there to initialize C.neg in the Go code. 

I believe that is not correct. 

Firstly, this bug would be a regression as gcc 7.3 did say the following is a
compile error:
const unsigned long long int neg = (const unsigned long long) -1;

#line 1 "not-num-const"
void __cgo_f_1_4(void) { static const double __cgo_undefined__4 = (neg); }


Then, should the bug be filed against gcc? 

However, I am also wondering. Even if everything were fine, I still think that
my "neg" variable perhaps should not fall into "not-int-const." It should be
int-const. 

Personally, regarding my work with my employer, I have worked on this issue. I
would like to proceed to provide a fix for the issue if someone confirms I am
on the right track.

Thank you!

Reply via email to