Bug with AC_C_RESTRICT on non-GNU-C compiler when using GLIBC

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Bug with AC_C_RESTRICT on non-GNU-C compiler when using GLIBC

Dwight Guth
Currently there is a problem with the way the AC_C_RESTRICT macro behaves
if you are using GLIBC with a C99-compliant compiler that does not define
the __GNUC__ macro, but does define __restrict. You can see this for
yourself by passing `CFLAGS="-U __GNUC__"` to a configure script that uses
it. Autoconf defines the restrict keyword to __restrict, because it detects
that this keyword exists. However, glibc defines away the __restrict
keyword to empty in this case. This leads the restrict keyword being
removed in all cases even though the compiler treats it as a valid keyword.
Attached is my testsuite.log file for information about my environment. I
believe that glibc's behavior is also wrong in this case, but even if glibc
were to do the correct thing and define __restrict to the keyword, you
would still have a bug in autoconf caused by a circular define. You can't
see this in the case with gcc, but if another compiler were to define
__restrict as a macro but not a keyword, this would then cause compilation
to crash whenever the __restrict keyword is used, because the circular
define would prevent macro replacement, __restrict would not be a keyword.

I'm pretty sure that the way you want to handle this is that if __restrict
is preprocessed into "foo", then config.h should define "restrict" as "foo"
instead of as "__restrict".

testsuite.log (55K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Bug with AC_C_RESTRICT on non-GNU-C compiler when using GLIBC

Paul Eggert
On 02/22/2016 01:46 PM, Dwight Guth wrote:
> Currently there is a problem with the way the AC_C_RESTRICT macro behaves
> if you are using GLIBC with a C99-compliant compiler that does not define
> the __GNUC__ macro, but does define __restrict.

Which compiler is this, exactly? What does it define __restrict to?

> I believe that glibc's behavior is also wrong in this case, but even if glibc
> were to do the correct thing and define __restrict to the keyword, you
> would still have a bug in autoconf caused by a circular define. You can't
> see this in the case with gcc, but if another compiler were to define
> __restrict as a macro but not a keyword, this would then cause compilation
> to crash whenever the __restrict keyword is used, because the circular
> define would prevent macro replacement, __restrict would not be a keyword.

Sorry, I'm not getting the scenario. Another compiler would define a
macro for __restrict? Why would it bother? It can implement __restrict
directly.

> I'm pretty sure that the way you want to handle this is that if __restrict
> is preprocessed into "foo", then config.h should define "restrict" as "foo"
> instead of as "__restrict".

We have no portable way to deduce what a macro expands to, for arbitrary
compilers.

Perhaps we can do something for your particular case, but we'd need to
know more about it.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Bug with AC_C_RESTRICT on non-GNU-C compiler when using GLIBC

Dwight Guth
The compiler I am working with is a compiler I am developing designed to
dynamically analyze C code (you can read more about it at
http://runtimeverification.com/match if you are interested, although it's
not 100% relevant to this discussion). We use GLIBC's header files, but we
do not define the __GNUC__ macro. This causes <sys/cdefs.h> to include the
following line:

# define __restrict     /* Ignore */

I am working separately with the glibc people to try to get a patch
submitted that allows __restrict to be defined as restrict if
__STDC_VERSION__ is at least 199901. This seems like a reasonable solution
to me, however, when combined with the behavior of AC_C_RESTRICT, this
leads to a circular definition that causes both of these macro replacements
to be cancelled. Since our compiler does not actually support the
__restrict keyword (it's merely defined as a macro by glibc), this causes a
syntax error to occur. Technically speaking, this is a valid C99
implementation and the C program was valid C99 until autoconf came along
and tried to make it more portable.

You are I suppose correct insofar as we could define __restrict as a
keyword equivalent to restrict. In fact that is probably what I am going to
have to do if we can't come to some kind of consensus here. But it seems to
me like it makes more sense for autoconf not to interfere with programs
written in pure C99 in ways that make them not portable anymore. This is
also consistent with the fact that the documentation generated in config.h
for AC_C_RESTRICT says "Do not define if restrict is supported directly."
(although this documentation seems inconsistent with the online
documentation, which correctly explains the current behavior). I found an
old thread online talking about exactly this issue, but the people
discussing it didn't have a concrete example where this behavior fell
apart. I just wanted to bring this up again because it fell apart for us.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Bug with AC_C_RESTRICT on non-GNU-C compiler when using GLIBC

Paul Eggert
Dwight Guth wrote:
> We use GLIBC's header files, but we
> do not define the __GNUC__ macro.

Ah, in that case there's a simple solution: your compiler should define
__GNUC__. That's what Clang does.

> we could define __restrict as a
> keyword equivalent to restrict. In fact that is probably what I am going to
> have to do if we can't come to some kind of consensus here.

Even if we came to a consensus, it would take years for the fixes to propagate
everywhere and in the meantime your compiler's users would have problems. So
really, it needs to support __restrict and define __GNUC__, like Clang does.

> This is
> also consistent with the fact that the documentation generated in config.h
> for AC_C_RESTRICT says "Do not define if restrict is supported directly."
> (although this documentation seems inconsistent with the online
> documentation, which correctly explains the current behavior).

Yes, that's a typo in that comment. It should say "supported only directly".

Anyway, does the attached hacky patch fix the problem?



0001-AC_C_RESTRICT-port-better-to-non-GCC-glibc.patch (2K) Download Attachment
Loading...