Discussion:
Clang-6 and GNUisms.
(too old to reply)
Ian FREISLICH
2018-03-11 23:56:35 UTC
Permalink
Hi

There's been some fallout in ports land since clang-6 around null
pointer arithmetic and casts.  I cannot think of a good reason for doing
the following but then I've not dabbled in the arcane much:

# define __INT_TO_PTR(P) ((P) + (char *) 0)

So far I've encountered these in lang/v8 and devel/avr-gcc.  I know it
just generates warnings, but GNUisms and -Werror abound.  Adding
-Wno-null-pointer-arithmetic and -Wno-vexing-parse to CFLAGS/CXXFLAGS
provides some relief but V8 still fails:

/usr/ports/lang/v8/work/v8-3.18.5/out/native/obj.target/v8_base.x64/src/type-info.o../src/stub-cache.cc:1477:33:
error: reinterpret_cast from 'nullptr_t' to 'char *' is not allowed
      : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));

                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I haven't got avr-gcc to compile yet.

Ian
--
Ian Freislich


--
Mark Linimon
2018-03-12 02:37:14 UTC
Permalink
The problem is even worse on armv6/armv7/aarch64, and much worse on
powerpc64/sparc64, which still have gcc in base.

I have not been saving up the emails where ports committers have been
fixing various failure modes. I hesitate to start making harmless-
seeming patches myself for fear of my non-existant C++ skills.

I would be glad to help someone write up some documentation. This
affects hundreds of port builds right now -- I have not even caught
up yet on tracking them all.

mcl
Jan Beich
2018-03-12 08:24:57 UTC
Permalink
Post by Ian FREISLICH
error: reinterpret_cast from 'nullptr_t' to 'char *' is not allowed
: GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Try using static_cast instead e.g.,
https://freshbsd.org/search?q=reinterpret_cast+from+%27nullptr_t%27+to

Which is caused by
https://svnweb.freebsd.org/changeset/base/228918
Dimitry Andric
2018-03-12 15:03:44 UTC
Permalink
Post by Ian FREISLICH
There's been some fallout in ports land since clang-6 around null
pointer arithmetic and casts. I cannot think of a good reason for doing
# define __INT_TO_PTR(P) ((P) + (char *) 0)
The idea of this construct is to store integers in pointers, and vice
versa. This could also be done with unions, but those have their own
portability issues.

However, arithmetic on a null pointer is undefined according to the C
and C++ standards, though this particular use case is a GNU extension.

It would be safer and more portable to use intptr_t (or a custom integer
type that is exactly as large as a pointer), then cast the pointer to
that type, and vice versa.

E.g.:

#define __INT_TO_PTR(i) ((char *)(intptr_t)(i))
#define __PTR_TO_INT(p) ((intptr_t)(char *)(p))

That said, -Wno-null-pointer-arithmetic can of course be used to
suppress the warnings, but unfortunately this not only applies to the
GNU extension, but also to real undefined behavior.
Post by Ian FREISLICH
So far I've encountered these in lang/v8 and devel/avr-gcc. I know it
just generates warnings, but GNUisms and -Werror abound. Adding
-Wno-null-pointer-arithmetic and -Wno-vexing-parse to CFLAGS/CXXFLAGS
error: reinterpret_cast from 'nullptr_t' to 'char *' is not allowed
: GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In this case, the casting is unnecessary, and can simply be removed.

The "vexing parse" warning is caused by unnecessary (and confusing)
parentheses, which can also be removed.

See the attached patch, which fixes both issues, and suppresses the
null pointer arithmetic warnings.
Post by Ian FREISLICH
I haven't got avr-gcc to compile yet.
No idea about this, is it very different from regular gcc's? As those
all compile fine now.

-Dimitry
Brooks Davis
2018-03-12 16:21:43 UTC
Permalink
Post by Dimitry Andric
Post by Ian FREISLICH
There's been some fallout in ports land since clang-6 around null
pointer arithmetic and casts. I cannot think of a good reason for doing
# define __INT_TO_PTR(P) ((P) + (char *) 0)
The idea of this construct is to store integers in pointers, and vice
versa. This could also be done with unions, but those have their own
portability issues.
However, arithmetic on a null pointer is undefined according to the C
and C++ standards, though this particular use case is a GNU extension.
It would be safer and more portable to use intptr_t (or a custom integer
type that is exactly as large as a pointer), then cast the pointer to
that type, and vice versa.
#define __INT_TO_PTR(i) ((char *)(intptr_t)(i))
#define __PTR_TO_INT(p) ((intptr_t)(char *)(p))
This is the only correct way to do this. Please don't a type other than
(__|)(u|)intptr_t for this purpose.

-- Brooks
Dimitry Andric
2018-03-12 17:54:28 UTC
Permalink
...
Post by Dimitry Andric
Post by Ian FREISLICH
I haven't got avr-gcc to compile yet.
No idea about this, is it very different from regular gcc's? As those
all compile fine now.
For avr-gcc, which is an older version of gcc with some customizations,
a fix similar to https://svnweb.freebsd.org/changeset/ports/458581 is
needed, such as the attached patch.

-Dimitry
Ian FREISLICH
2018-03-16 01:35:22 UTC
Permalink
Post by Dimitry Andric
...
Post by Dimitry Andric
Post by Ian FREISLICH
I haven't got avr-gcc to compile yet.
No idea about this, is it very different from regular gcc's? As those
all compile fine now.
For avr-gcc, which is an older version of gcc with some customizations,
a fix similar to https://svnweb.freebsd.org/changeset/ports/458581 is
needed, such as the attached patch
This works,  thanks.  Can you commit to the port, the maintainer hasn't
responded to me.

Ian

--

Loading...