Bug 40411 - -std=c99 does not enable c99 mode in Solaris C library
Summary: -std=c99 does not enable c99 mode in Solaris C library
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.3.3
: P3 normal
Target Milestone: 8.0
Assignee: Rainer Orth
URL: https://gcc.gnu.org/ml/gcc-patches/20...
Keywords:
Depends on:
Blocks: 64054
  Show dependency treegraph
 
Reported: 2009-06-10 22:44 UTC by Jeff Downs
Modified: 2018-03-26 08:59 UTC (History)
9 users (show)

See Also:
Host: *-solaris2.10
Target: *-solaris2.10
Build: *-solaris2.10
Known to work:
Known to fail:
Last reconfirmed: 2009-11-20 17:53:02


Attachments
Proposed fix: Changes linking on solaris based on std=X and implements escapes in braced specs (1.63 KB, patch)
2009-07-02 14:46 UTC, Jeff Downs
Details | Diff
Fix updated for gcc 4.4.0, link xpg6 for c++, and link xpg4 for gnu* (1.55 KB, patch)
2009-07-16 21:11 UTC, Jeff Downs
Details | Diff
proposed fix to link values-*.o (963 bytes, patch)
2016-07-22 03:40 UTC, Norm Jacobs
Details | Diff
combined proposed patch (1.96 KB, patch)
2017-01-12 10:06 UTC, Rainer Orth
Details | Diff
gcc-5 backport patch (3.64 KB, patch)
2018-03-26 08:58 UTC, Rainer Orth
Details | Diff
gcc-7 backport patch (3.76 KB, patch)
2018-03-26 08:59 UTC, Rainer Orth
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Downs 2009-06-10 22:44:09 UTC
On Solaris, the C library does not operate in c99 compliant mode by default.  If c99 compliant operation is desired, the object file /usr/lib/{32,64}/values-xpg6.o needs to be linked.  The details are in the Solaris standards(5) manpage.

When linking using "gcc -std=c99", gcc does not instruct the linker to include this object file.
Comment 1 Jeff Downs 2009-06-17 15:13:06 UTC
This also applies to Solaris x86.

Additionally, this only applies to Solaris 10 and later. Earlier versions of Solaris did not ship c99-compliant C library and thus do not have the values-xpg6.o object file for enabling c99-compliance.
Comment 2 Richard Biener 2009-06-17 15:24:13 UTC
GCC 3.4.x is no longer maintained, please check GCC 4.3.x or newer.
Comment 3 joseph@codesourcery.com 2009-06-17 15:34:18 UTC
Subject: Re:  -std=c99 does not enable c99 mode in Solaris
 C library

On Wed, 17 Jun 2009, rguenth at gcc dot gnu dot org wrote:

> GCC 3.4.x is no longer maintained, please check GCC 4.3.x or newer.

It is a matter of straightforward observation of the config/*.h and 
config/*/*.h files that these files are not linked in.  (That they should 
be linked in was noted on the Austin Group mailing list on 19 March 2005.)  
sol2.h links in values-Xc.o or values-Xa.o depending on -ansi, which 
itself is wrong because it doesn't allow for the other spellings of that 
option (-std=c89, -std=iso9899:1990, or -std=iso9899:199409 for C90 AMD1).

Comment 4 Jeff Downs 2009-06-17 16:39:54 UTC
Also observed on gcc 4.3.3
Comment 5 Jeff Downs 2009-06-18 21:26:37 UTC
Was looking at modifying the spec to produce the desired results and contribute patch, however ran into trouble trying to match options containing literal colons (-std=iso9899:199409) in %{S:X} style spec.

Is there a way in the spec language to escape colons?  I briefly scanned the spec parsing code and nothing jumped out.

If not, is there some other way to match options containing colons (without using greedy * matches, since the part after the colon is significant here...)
Comment 6 joseph@codesourcery.com 2009-06-18 21:49:11 UTC
Subject: Re:  -std=c99 does not enable c99 mode in Solaris
 C library

On Thu, 18 Jun 2009, heydowns at borg dot com wrote:

> Was looking at modifying the spec to produce the desired results and contribute
> patch, however ran into trouble trying to match options containing literal
> colons (-std=iso9899:199409) in %{S:X} style spec.
> 
> Is there a way in the spec language to escape colons?  I briefly scanned the
> spec parsing code and nothing jumped out.
> 
> If not, is there some other way to match options containing colons (without
> using greedy * matches, since the part after the colon is significant here...)

You may well need to add a new feature to the specs parsing code to deal 
with this.

I have some ideas about how option handling, multilib handling and some 
aspects of specs should be redesigned, but this issue should not need any 
redesign.

Comment 7 Jeff Downs 2009-07-02 14:46:06 UTC
Created attachment 18121 [details]
Proposed fix: Changes linking on solaris based on std=X and implements escapes in braced specs

Attaching a fix that works here for Solaris 10 and I think would work for other Solaris versions.
It changes the spec to account for the other options mentioned in comment 3, to handle the main issue of the bug (link values-xpg6.o in c99 mode), and also adds linking of values-xpg4.o as the Solaris manual suggests should be done.
I wasn't sure exactly how to handle the various -std=gnu* modes, so I left those as they were. 

To enable matching on ':' in std=iso9899:xxxx, I had to augment the spec language, as suggested in comment 6.  I realize you might want to treat this as a separate issue -- I can open a separate issue for this if you want.
Comment 8 Eric Botcazou 2009-07-04 07:57:23 UTC
> Attaching a fix that works here for Solaris 10 and I think would work for
> other Solaris versions.

Thanks.

> It changes the spec to account for the other options mentioned in comment 3,
> to handle the main issue of the bug (link values-xpg6.o in c99 mode), and
> also adds linking of values-xpg4.o as the Solaris manual suggests should be 
> done.

sol2-6.h doesn't exist anymore in GCC 4.4 and later.  Since the patch won't be applied to GCC 4.3.x, it must be adjusted.  Why was values-xpg4 only added to sol2-6.h and not to sol2.h?

> I wasn't sure exactly how to handle the various -std=gnu* modes, so I left
> those as they were. 

Joseph, any recommendations about that?

> To enable matching on ':' in std=iso9899:xxxx, I had to augment the spec
> language, as suggested in comment 6.  I realize you might want to treat this
> as a separate issue -- I can open a separate issue for this if you want.

The combined patch is fine I think.
Comment 9 joseph@codesourcery.com 2009-07-04 11:49:22 UTC
Subject: Re:  -std=c99 does not enable c99 mode in Solaris
 C library

On Sat, 4 Jul 2009, ebotcazou at gcc dot gnu dot org wrote:

> > I wasn't sure exactly how to handle the various -std=gnu* modes, so I left
> > those as they were. 
> 
> Joseph, any recommendations about that?

I don't know what the exact effects of linking in these various objects 
are; whether they select between C90 and C99 behavior where those 
standards specify conflicting semantics for the same function, or disable 
Solaris extensions that conflict with the standards, or something else.  
If it's only selecting between the standards where they conflict, then 
gnu99/gnu9x should select C99, but gnu99/gnu9x should not generally 
disable extensions.

C++ options for C++0x / GNU-extended C++0x (-std=c++0x, -std=gnu++0x) 
should probably be treated like those for c99/gnu99, since C++0x uses the 
C99 library (whereas C++98/C++03 uses the C90+AMD1 library).

Comment 10 Jeff Downs 2009-07-04 15:03:45 UTC
"sol2-6.h doesn't exist anymore in GCC 4.4 and later.  Since the patch won't be
applied to GCC 4.3.x, it must be adjusted.  Why was values-xpg4 only added to
sol2-6.h and not to sol2.h?"

As far as I could tell from the documentation available to me, values-xpg4 didn't exist until Solaris 2.6.  Based on the file names I was thinking sol2-6.h was for 2.6 and above, where sol2.h had to work for 2.5, etc.

I can adjust it and try it with 4.4, but do we need to be concerned with Solaris < 2.6?

I will also try to research and adjust for Joseph's questions/comments on std=gnu* and c++.
Comment 11 Eric Botcazou 2009-07-04 16:46:36 UTC
> As far as I could tell from the documentation available to me, values-xpg4
> didn't exist until Solaris 2.6.  Based on the file names I was thinking
> sol2-6.h was for 2.6 and above, where sol2.h had to work for 2.5, etc.

sol2.h is for all versions of Solaris, sol2-6.h was for 2.6 and below.

> I can adjust it and try it with 4.4, but do we need to be concerned with
> Solaris < 2.6?

Support for 2.6 and below was removed in GCC 4.4 so we indeed don't care, you only need to patch sol2.h and sol2-10.h.

> I will also try to research and adjust for Joseph's questions/comments on
> std=gnu* and c++.

Thanks in advance.
Comment 12 Jeff Downs 2009-07-10 14:41:01 UTC
Trying to give some answers to Joseph's questions in comment 9.

The best documentation I found on what, exactly, the various object files do is actually the man pages for the Sun Studio compilers and the OpenSolaris source code for values-*.c

Choice of values-xpg*.o and values-X*.o are someone independent, so I'm splitting up the explanation.


First, values-xpg*.o:

Link Tool & Flags          Link Result            Comment
c89                        values-xpg4.o
c99                        values-xpg6.o
cc -xc99=all,no_lib        Neither                Default -xc99 option
                                                  c99 language features, 
                                                  no c99 library support
cc -xc99=all               values-xpg6.o          c99 lang feat. & lib support
cc -xc99=none              Neither                No c99 at all

So, values-xpg6.o clearly enables c99 behavior of system libraries where there is a runtime difference.  It also enables the preference of XPG4 behavior over XPG3 behavior (as below).

From looking at the OpenSolaris source code for values-xpg4.o, it is stated that linking in that object file enables "xpg4 mode for APIs which have differing runtime behavior from xpg3 to xpg4".

Lastly, from man page 'standards', the only time "cc" is recommended as a compiler (instead of c89 or c99, and thus not linking any of values-xpg*.o) is when you want to conform to SVID3 or CAE XPG3. 

What is the runtime difference of xpg3 versus xpg4?  I really don't know - maybe someone can help here.

But, back to Joseph's question, the inclusion values-xpg*.o does not seem to deal with extensions to standard behavior; rather it does sound like it controls the standard to which functions should conform. Based on this I am leaning towards saying values-xpg4.o should be enabled for -std=gnu89.  I'd appreciate comments in light of the above.  (please note that this would make it non-trivial to link for xpg3 behavior).


values-X{c,a,t,s}.o are what seem to control how strict the implementation follows the standard.  Currently gcc only ever uses values-X{a,c}.o which is probably sufficient, and I don't think that this needs to change at all:

-std=gnu*   -> values-Xa.o
otherwise   -> values-Xc.o

values-Xa is described as "ANSI conforming mode" whereas -Xc is "Strict ANSI mode" in the Open Solaris sources. 

The 'cc' man page documents -Xa as ISO C plus K&R C compatibility extensions, plus semantic changes required by ISO C, preferring ISO C semantics where there is conflict.
-Xc is documented as "Strictly conforming" ISO C, no K&R extensions.

Comment 13 Jeff Downs 2009-07-16 21:11:35 UTC
Created attachment 18210 [details]
Fix updated for gcc 4.4.0, link xpg6 for c++, and link xpg4 for gnu*

Updated patch against gcc 4.4.0.
Also add xpg6 for c++ and xpg4 for gnu* as discussed above (this is now easily modified by changing the spec if someone who knows better can say what gnu* should do).
Comment 14 Jeff Downs 2009-10-09 19:38:35 UTC
Ping - anyone able to comment on or integrate this patch please?
Thank you!
Comment 15 Richard Biener 2009-10-09 19:42:44 UTC
Patches should be sent to gcc-patches@gcc.gnu.org with a changelog entry and
a note on how you tested the patch.
Comment 16 Rainer Orth 2009-11-20 17:53:02 UTC
Mine.
Comment 17 Bruno Haible 2010-12-26 18:06:15 UTC
Note that the use of values-xpg6.o leads to unexpected behaviour when
considering shared libraries:

1) The behaviour of a shared library also depends on whether the executable
is linked with or without values-xpg6.o. The author of the shared library
may not expect this and may not have tested in this situation.

2) The behaviour of an executable also depends on whether some of the shared
libraries was built with values-xpg6.o. The author of the program may not
expect this. This leads to real bugs:
<http://lists.gnu.org/archive/html/autoconf/2010-02/msg00013.html>

More details in
<http://lists.gnu.org/archive/html/autoconf/2010-12/msg00059.html>

For this reason, I would find it bad if "gcc -std=c99" or "gcc -std=gnu99"
would cause values-xpg6.o to be included in the link. Please close this
issue as "Won't fix". Programs which wish to have POSIX compliant behaviour
of system functions can use GNU gnulib; it doesn't rely on values-xpg6.o.
Comment 18 Paolo Carlini 2010-12-26 18:35:49 UTC
Rainer, can you have another look to this issue and possibly actually close it?
Comment 19 Jonathan Wakely 2010-12-26 21:52:07 UTC
(In reply to comment #17)
> For this reason, I would find it bad if "gcc -std=c99" or "gcc -std=gnu99"
> would cause values-xpg6.o to be included in the link. Please close this
> issue as "Won't fix". Programs which wish to have POSIX compliant behaviour
> of system functions can use GNU gnulib; it doesn't rely on values-xpg6.o.

I don't entirely agree with this line of reasoning. If the system provides a POSIX compliant C library it's reasonable to want to use it and users will want some way to tel the compiler to do so. Whether using it is enabled via -std or not, linking to values-xpg6.o can cause unexpected behaviour for applications or shared objects.

It does seem reasonable to expect -std=c99 to enable C99 features if the system supports them, and similarly for -std=c++0x
Comment 20 Peter O'Gorman 2010-12-27 19:17:18 UTC
(In reply to comment #19)
> Whether using it is enabled via -std or
> not, linking to values-xpg6.o can cause unexpected behaviour for applications
> or shared objects.

Yes, it can, and that behaviour change is surprising, especially if relinking a library with a newer gcc (using the same flags as it was linked with using an older version of the compiler) can cause clients of that library to stop working or to behave in a different manner.

If a user really wants the xpg6 behaviour from libc they can simply add the relevant object file to their output or even just define the __xpg4 and __xpg6 symbols in their application, or, as Bruno suggests - use gnulib.
Comment 21 Sean McGovern 2011-01-04 18:11:09 UTC
Why not introduce a warning for 4.6 that it is linking against this object file and that any other libraries alongside that are not tested against C99 may experience side effects, with eventual deprecation (of the warning) later on in 4.7 or 4.8?

Is this appropriate to do inside collect2?
Comment 22 Sean McGovern 2011-01-05 19:50:09 UTC
Sorry, still learning -- collect2 is definitely not the place for this.

Target-specific plugin maybe?
Comment 23 Sean McGovern 2011-03-07 20:16:09 UTC
Ping.
Comment 24 Sean McGovern 2011-11-25 16:25:02 UTC
Ping^2.
Comment 25 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 16:34:03 UTC
No progress yet: an attempt to handle this via specs some time ago
failed since there was some of Joseph's option work missing.

	Rainer
Comment 26 joseph@codesourcery.com 2011-11-25 17:15:31 UTC
All the various options equivalent to -std=c99 now map to -std=c99 using 
Alias in the .opt file, so specs only need to handle that one spelling.  
The same applies with -std=gnu99.

Note that -ansi and -std=c90 are not marked as Aliases for each other 
because the meaning of -ansi depends on whether C or C++ is being built.
Comment 27 Sean McGovern 2012-06-01 14:23:21 UTC
I just found out how ugly this can get.

freopen(3C) has different behaviour in the case where the first argument is NULL depending on if SUSv3 behaviour has been enabled by including values-xpg6.o and defining _XOPEN_SOURCE = 600.

Here's the prototype from Solaris 10 8/11:
FILE *freopen(const char *filename, const char *mode, FILE *stream);

From the freopen(3C) manpage:
If filename is a null pointer and the application comforms to SUSv3 (see standards(5)), the freopen() function attempts to change the mode of the stream to that specified by mode, as though the name of the file currently associated with the stream had been used.

<...>

If the filename is a null pointer and the application does not comform to SUSv3, freopen() returns a null pointer.
Comment 28 Lionel Cons 2013-08-06 00:21:12 UTC
Any progress on this bug?
Comment 29 Norm Jacobs 2016-07-22 03:40:31 UTC
Created attachment 38948 [details]
proposed fix to link values-*.o

Unfortunately, due to the way support for behavioral differences in conflicting standards interfaces is implemented in Solaris libc and libm, there really isn't a perfect answer here.  An offline discussion of this led to the conclusion that "the application dictates the xpg'ness and any library that thinks it has control from the compilation options it uses, is fooling itself."

The current builds of GCC that are delivered with Solaris 11 and later include a patch very similar to the one that I have attached.  The one that I have attached should only link in appropriate values-*.o files when GCC calls the linker to generate an executable program.  This seems consistent with what the Studio compilers do.
Comment 30 Rainer Orth 2017-01-12 10:06:12 UTC
Created attachment 40507 [details]
combined proposed patch
Comment 31 ro@CeBiTec.Uni-Bielefeld.DE 2017-01-12 10:20:33 UTC
I've started looking at this again.

Norm's patch has a few problems:

* For one, it matches a couple of alias names for -std values, which
  will never hit the specs machinery.

* Worse, though: since gcc 5 changed its default to -std=gnu11 it
  doesn't work without an explicit -std=* option given.  Instead, one
  has to handle it the other way round: use values-xpg4.o only with an
  explicit -std=c90 or -std=gnu90, and values-xpg6.o otherwise.

  That default is also necessary because many runtime libraries
  (libstdc++, libgfortran, libgo, probably others) depend on C99
  semantics by default, and there's no way of determining in specs which
  language is being linked for.

The attached patch does this, and includes a forward port of Jeff's
patch to escape special characters like `:' in %{S:X} expressions.

It also removes the xfail from the libstdc++ test that requires C99
semantics from libc to work.

There's still more investigation to be done on my part, like

* when exactly values-X[ac].o are appropriate,

* what Studio 15.c cc/c89/c99, CC, f77/f90/f95 do in this space

Also, there's the issue of copyright: I suspect Jeff's patch is large
enough to require an assignment (which may be hard to get after 8 years,
unless he has one in place already ;-).  If this proves impossible, one
could omit the handling for -std=iso9899:199409 for now, which is only a
niche case (or introduce -std=c94 and make -std=iso9899:199409 an alias
for that, but that would be an ugly hack).

The same might be true for Norm's comment in his patch, though I suspect
Oracle has a corporate assignment on file.

Given how late in the GCC 7 cycle we are, I fear it's becoming too late
to get this in; however I still wanted to keep the ball rolling.

	Rainer
Comment 32 Jeff Downs 2017-01-12 20:26:20 UTC
(In reply to ro@CeBiTec.Uni-Bielefeld.DE from comment #31)
> The attached patch does this, and includes a forward port of Jeff's
> patch to escape special characters like `:' in %{S:X} expressions.

[...]

> Also, there's the issue of copyright: I suspect Jeff's patch is large
> enough to require an assignment (which may be hard to get after 8 years,
> unless he has one in place already ;-).  If this proves impossible, one
> could omit the handling for -std=iso9899:199409 for now, which is only a
> niche case (or introduce -std=c94 and make -std=iso9899:199409 an alias
> for that, but that would be an ugly hack).

Rainer,
Still here and following from afar; I'm not using solaris much these days, but it always brightens my day when I get an email re this bug and some level of progress is made on this given the work I put into it so long ago  :)

Regarding copyright I'm happy to work with you/whomever on this. Just point me at what you need (feel free to email to address on my bzilla account).

Regards,
Jeff
Comment 33 ro@CeBiTec.Uni-Bielefeld.DE 2017-01-13 13:09:30 UTC
Jeff,

> Still here and following from afar; I'm not using solaris much these days, but
> it always brightens my day when I get an email re this bug and some level of
> progress is made on this given the work I put into it so long ago  :)

very true, unfortunately.  I'm sorry for dropping the ball on this for
so long.

> Regarding copyright I'm happy to work with you/whomever on this. Just point me
> at what you need (feel free to email to address on my bzilla account).

I've just submitted the specs escaping part of the patch, both to check
if it needs a copyright assignment (seems to be a border case AFAICT)
and if it's acceptable for gcc 7.  If it turns out an assignment is
needed, I'll check with one of the maintainers who has done this before.

There's some info on

	https://gcc.gnu.org/contribute.html#legal

now, together with a pointer to the various forms.

	Rainer
Comment 34 Rainer Orth 2018-01-12 09:53:29 UTC
Author: ro
Date: Fri Jan 12 09:52:53 2018
New Revision: 256568

URL: https://gcc.gnu.org/viewcvs?rev=256568&root=gcc&view=rev
Log:
Link with correct values-*.o files on Solaris (PR target/40411)

	gcc/testsuite:
	PR libfortran/67412
	* gfortran.dg/execute_command_line_2.f90: Remove dg-xfail-run-if
	on *-*-solaris2.10.

	libstdc++-v3:
	PR libstdc++/64054
	* testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc:
	Remove dg-xfail-run-if.

	gcc:
	PR target/40411
	* config/sol2.h (STARTFILE_ARCH_SPEC): Don't use with -shared or
	-symbolic.
	Use values-Xc.o for -pedantic.
	Link with values-xpg4.o for C90, values-xpg6.o otherwise.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sol2.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/execute_command_line_2.f90
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc
Comment 35 Rainer Orth 2018-01-12 10:01:48 UTC
Fixed for GCC 8.1.
Comment 36 Rainer Orth 2018-01-12 10:03:40 UTC
Meant to mark fixed.
Comment 37 Bruno Haible 2018-01-12 10:46:18 UTC
(In reply to Rainer Orth from comment #35)
> Fixed for GCC 8.1.

Please consider comment 17:
The behaviour of a shared library also depends on whether the executable
is linked with or without values-xpg6.o. The author of the shared library
may not expect this and may not have tested in this situation.

Can you please address this through documentation? As a shared library
author, I find it extremely nasty to become aware of this tricky issue
only after the fact.

It could be some text such as
"Note about Solaris: If you develop a shared library that makes use of
functionality that is specified differently in C99 than in C90, you need
to make sure that the library works fine either way. Whether C99 compliant
definitions or C90 compliant definitions are in effect, depends whether the
executable(!) is created with "gcc -std=c99" versus "gcc -std=c90"."
Comment 38 Rainer Orth 2018-01-30 21:19:12 UTC
Author: ro
Date: Tue Jan 30 21:18:40 2018
New Revision: 257209

URL: https://gcc.gnu.org/viewcvs?rev=257209&root=gcc&view=rev
Log:
Fix use of Solaris values-Xc.o (PR target/40411)

	PR target/40411
	* config/sol2.h (STARTFILE_ARCH_SPEC): Use -std=c*,
	-std=iso9899:199409 instead of -pedantic to select values-Xc.o.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sol2.h
Comment 39 Rainer Orth 2018-03-26 08:58:08 UTC
Created attachment 43753 [details]
gcc-5 backport patch

There's been some interest in a backport of the patch to gcc-5 and gcc-7 branches.
Since I've currently no intention of applying them (and the gcc-5 branch is closed
anyway), I'm attaching them here for reference.
Comment 40 Rainer Orth 2018-03-26 08:59:05 UTC
Created attachment 43755 [details]
gcc-7 backport patch