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

            Bug ID: 92693
           Summary: Inconsistency between __UINTPTR_TYPE__ and
                    __UINT32_TYPE__ on ARM
           Product: gcc
           Version: 7.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: matthijs at stdin dot nl
  Target Milestone: ---

Gcc defines a number of macros for types, which are used by stdint.h to define
the corresponding typedefs. In particular, I'm looking at uintptr_t. On ARM,
this is 32-bits and equals unsigned int:

#define __UINTPTR_TYPE__ unsigned int

In my code, I was running into problems trying to pass a uintptr_t to a
function that has overloads for uint8_t, uint16_t and uint32_t (ambigious
function call). Investigating, it turns out that uint32_t is defined as long
unsigned int:

#define __UINT32_TYPE__ long unsigned int

I would expect that, since both types are 32-bit long, they would actually
resolve to the same type. This would also make overload resolution work as
expected. Is there any reason for this inconsistency, or could it be fixed?

To test this, I installed the gcc-arm-none-eabi, version 15:7-2018-q2-6 from
Ubuntu Disco (same version should be in Debian testing):

$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:7-2018-q2-6) 7.3.1 20180622 (release)
[ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-none-eabi-gcc -dM -E -x c++ /dev/null |egrep '(UINTPTR_TYPE|UINT32_TYPE)'
#define __UINT32_TYPE__ long unsigned int
#define __UINTPTR_TYPE__ unsigned int

I see the same problem using gcc 8.2.1 shipped with the STM32 arduino core
(https://github.com/stm32duino/Arduino_Core_STM32).

To illustrate the original problem I was seeing, here's a small testcase:

$ cat foo.cpp
#include <stdint.h>

void func(uint16_t);
void func(uint32_t);

int main() {
        func((uintptr_t)nullptr);
        static_assert(sizeof(uintptr_t) == sizeof(uint32_t), "Sizes not
equal");
}

$ arm-none-eabi-gcc -c foo.cpp 
foo.cpp: In function 'int main()':
foo.cpp:7:25: error: call of overloaded 'func(uintptr_t)' is ambiguous
  func((uintptr_t)nullptr);
                         ^
foo.cpp:3:6: note: candidate: void func(uint16_t)
 void func(uint16_t);
      ^~~~
foo.cpp:4:6: note: candidate: void func(uint32_t)
 void func(uint32_t);
      ^~~~

Reply via email to