[Bug c++/38990] New: preprocessing different in g++ -E and regular compiling.

2009-01-27 Thread kkylheku at gmail dot com
(This might affect the C front end also, I have not tried).

Basically, there are situations where g++ -E accepts multi-line string literals
and glues them together into a proper string literal token. If the resulting
preprocessor output is compiled, there are no diagnostics. But if the compiler
is run on the original code, there are diagnostics. Test case:

#include 

#define pf(FMT, ARGS ...) printf(FMT, ## ARGS)

int main()
{
  pf("Hello,
 %s!",
 "world");
}

If this is passed through g++ (4.3.2) there are warnings from the preprocessor
about unmatched " characters. But the problem is repaired in the output, where
the pf expression turns to:

  printf("Hello, %s", "world");

The preprocessor output, if captured, can be compiled without diagnostics,
because it no longer contains a multi-line string literal. If the program is
compiled directly, there are syntax errors from the compiler, in addition to
the warnings from the preprocessor. The behavior of the preprocessor, when
integrated into the compiler, is different; it does not repair the broken
string literal.

In g++ 4.1.1, the behavior is similar, except that preprocessing does not emit
any diagnostics at all in either situation, so if the compilation is broken
into two steps (preprocess with g++ -E and then compile), then it's completely
silent.

To answer the question, why would anyone preprocess and then compile: there are
tools which do this, like ccache. The ccache program preprocesses a translation
unit, and digests it to a hash. Using the hash, it can decide to retrieve a
cached object file, or to pass the preprocessed output to the compiler
(avoiding double preprocessing). Other tools like distmake and distcc works
similarly.

So when ccache is used with g++, in effect the combo turns into a C++
implementation that accepts broken string literals when they are macro
arguments. If developer accidentally write such string literals, then the build
breaks for anyone who runs it without ccache.

(If there is a way for to run g++ or gcc as a preprocessor in such a way that
it does not accept multi-line string literals as macro arguments, please
advise; I can hack it into ccache as a workaround).


-- 
   Summary: preprocessing different in g++ -E and regular compiling.
   Product: gcc
   Version: 4.3.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: kkylheku at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38990



[Bug preprocessor/38990] preprocessing different in g++ -E and regular compiling.

2009-01-28 Thread kkylheku at gmail dot com


--- Comment #2 from kkylheku at gmail dot com  2009-01-28 16:30 ---
(In reply to comment #1)
> Confirmed.

Thanks. By the way, I started looking at patching this. My suspicions were
confirmed that this is a case of pasting together invalid tokens. The compiler
sees the tokens individually, because it's closely integrated with the
preprocessor. But when the tokens are converted to text, they resemble a valid
string literal. The embedded newlines are gone.

What's happening is that the input:

"Hello,\n  %s!",\n  "world");

is being tokenized like this:

{"Hello,}{%}{s}{",}{"world"}{)}

The "Hello, and ", are assigned the special lexical category CPP_OTHER, because
they are improper tokens. Of course % is an operator and s is a CPP_NAME
identifier.  Also note how everything becomes one argument to the macro, since
the comma is never seen as a independent token.

A possible way to fix this bug would be in the function lex_string to not back
up over the \n that is found in the middle of a string literal, so that the
newline becomes part of the CPP_OTHER token.  This behavior might have to be
language-dependent, though. It looks like assembly language programs may be
depending on the current behavior, hence this test in lex_string:

  if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM)
cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character",
   (int) terminator);

Or maybe CPP_OTHER tokens should never be pasted together with anything that
follows them because even inserting a space is not good enough; maybe a newline
should be emitted between CPP_OTHER and the next token instead of a space, if
the language is other than CLK_ASM.

Will experiment.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38990



[Bug driver/35300] New: References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com
I am seeing the following two problems problem in gcc 4.1.1.

The front-end driver contains paths from the --prefix where the toolchain was
built, when it is installed at a different location. It was built using
--with-sysroot.

I am aware of bug 17621, and have applied all of Carlos's patches to gcc 4.1.1.
They do not fix the behavior that I am seeing.

Secondly, some of the search paths are /usr/lib/.. and /lib/... which is
inappropriate for a cross compiler.

I have not tried a newer compiler, but I fixed these issues for myself in
4.1.1.  (Which I have to do, since upgrading our toolchain is not in my
organization's near-term schedule, and fixing problems in our current toolchain
falls on me!)

Patches and discussion follow.


-- 
   Summary: References to original ${prefix} paths in relocated
toolchain and /lib and /usr/lib search paths appear in
cross toolchain.
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: driver
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: kkylheku at gmail dot com
 GCC build triplet: i686-linux
  GCC host triplet: i686-linux
GCC target triplet: mips64-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com


--- Comment #1 from kkylheku at gmail dot com  2008-02-23 01:35 ---
Created an attachment (id=15210)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15210&action=view)
Patch to gcc/prefix.c for path relocation.

At some point gcc/gcc.c calls the function set_std_prefix in gcc/prefix.c to
install a different prefix, overriding the original one which comes from the
PREFIX variable at compile time (passed in via -DPREFIX when the file is
compiled).

The problem is that there is only one variable! The std_prefix variable is used
to determine whether the path is inside the toolchain. However, the default
substitution logic is that the key lookup for @GCC, @BINUTILS, et cetera will
produce that same path.  I.e. std_prefix is both the match and the default
substitution, if the key doesn't resolve. And so the update_path function
doesn't translate the path from the prefix to the relocated location. 

When the add_prefix function is called in various places in gcc.c to install
search paths, in sometimes passes down paths from the original $prefix, which
are recorded as string literals during compilation of gcc. These paths don't
match the new prefix set up by the call to set_std_prefix, and so are entered
into the list untranslated.

The update_path function should use the original prefix to match against input
paths, but then substitute the new path (if the @ translation doesn't produce
any match).

E.g. the path /original/libexec/bin should become (for example, if the key is
"GCC") @GCC/libexec/bin. Then the @GCC substituion finds that the environment
variable GCC_ROOT is not defined, and so substitutes /new to make
/new/libexec/bin.

Don't know if the current GCC has the problem, but a superficial skim through
gcc/prefix.c tells me that nothing has changed there. So either the problem is
not solved, or it's addressed by other logic elsewhere.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com


--- Comment #2 from kkylheku at gmail dot com  2008-02-23 01:40 ---
Created an attachment (id=15211)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15211&action=view)
Hack to not have /lib and /usr/ paths in cross-compiler.

I don't know whether this path is right in general, but it gets rid of
questionable search paths in my cross toolchain. 

Should gcc ever (i.e. in any configuration) be unconditionally be looking in
/usr/libexec/gcc and /usr/lib/gcc for executables and libraries? It doesn't
seem right.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com


--- Comment #3 from kkylheku at gmail dot com  2008-02-23 02:18 ---
Oops, I spoke to soon. The no-prefix-search path breaks my final gcc build,
with shared libraries and glibc. When making libgcc_s.so, it can't find the
crti.o module.

What's happening is two problems.

Firstly, it appears as if xgcc thinks it's already sysrooted; like it has
already been installed and must look for the target libraries relative to
itself as if its build directory was the sysroot.  But of course, the real
sysroot with glibc material is somewhere else entirely, and during this stage
of the build, it must be referenced absolutely.

Secondly, the crti.o module is actually in a /lib32 directory, because
I'm building for the n32 ABI. xgcc has nothing ending in /lib32 in any of its
search paths.

*Head scratch*. How did this link step ever find crti.o before?


-- 

kkylheku at gmail dot com changed:

   What|Removed |Added

 CC|        |kkylheku at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com


--- Comment #5 from kkylheku at gmail dot com  2008-02-23 04:58 ---
(In reply to comment #4)
> [crti.o is] found through multilib os-directory suffixes.

Actually, I'm even more confused, because the breakage I'm seeing is simply
arising from mips64-linux-ld being called on a bunch of object files, one of
which is crti.o. It's specified just like that. The linker won't search for it;
it's expected to just be there. I will pop off these patches and see how the
link job was being done before.

> How did you configure GCC?

Binutils:

$SRC_ROOT/packages/unpacked/binutils-2.17/configure \
--target=$TARGET_ARCH \
--prefix=$CROSS_ROOT \
--disable-nls \
${TARGET_ABI:+--with-abi=$TARGET_ABI} \
${BUILD64+--enable-64-bit-bfd} \
--with-sysroot=$TARGET_ROOT

TARGET_ARCH is, e.g. mips64-linux. CROSS_ROOT is the root of a cross toolchain
and TARGET_ROOT is derived from that elsewhere (a subdirectory thereof).
TARGET_ABI is like "n32" for MIPS, for instance. Or unset for i686, in which
case the option isn't passed.

Final shared library GCC:

$SRC_ROOT/packages/unpacked/gcc-$VERSION/configure \
--host=$BUILD_ARCH-none-linux \
--build=$BUILD_ARCH-none-linux \
--target=$TARGET_ARCH \
--prefix=$CROSS_ROOT \
--with-sysroot=$TARGET_ROOT \
--with-gnu-ld \
--with-gnu-as \
--disable-libmudflap \
--disable-libada \
--disable-libssp \
--disable-multilib \
--enable-__cxa_atexit \
--enable-c99 \
--enable-long-long \
${TARGET_ABI:+--with-abi=$TARGET_ABI} \
--enable-languages=c,c++ \
--enable-threads=posix

> The standard_exec_prefix_1, et cetera patch is not necessary on HEAD and will
> conflict.  In fact that's another of Carlos's patches.

I should pop those patches off and rework my stuff.

> I don't know about the
> update_path patch, but CodeSourcery's been building relocatable sysrooted
> compilers since before 4.1.1 and never encountered this problem.  I think we
> avoid the code in prefix.c entirely.

In 4.1.1, update_path is called many tiems, since it's used by add_prefix. If
you load gcc under gdb and put a breakpoint on update_path, and then just run
even with no arguments you can see.

I've been building and relocating this toolchain also, apparently successfully.
It was the users who discovered these bad paths. They were looking at running
compiles with "ps" and noticed that collect2 was being called with -L options
specifying paths on the machine where the toolchain (and Linux distro) is
built. Our configuration manager is concerned that this may create problems. We
produce versioned, binary builds of the toolchain, and have Makefiles
referencing specific versions of a toolchain by pathname. If you check out last
week's build of some software, you get last week's Makefile which points to the
toolchain which was current then. If that toolchain uses some bad paths to pick
up executables or libraries outside of itself, this nice little scheme might in
fact not be so bullet-proof.

Thanks for any discussion. I will continue with this until it's solved. Sorry
about opening a bug, I just thought I had something, but it's a little bit more
elusive than I thought.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-22 Thread kkylheku at gmail dot com


--- Comment #6 from kkylheku at gmail dot com  2008-02-23 05:06 ---
(In reply to comment #5)
> (In reply to comment #4)
> > [crti.o is] found through multilib os-directory suffixes.
> Actually, I'm even more confused, because the breakage I'm seeing is simply
> arising from mips64-linux-ld being called on a bunch of object files, one of
> which is crti.o. It's specified just like that. The linker won't search for 
> it;
> it's expected to just be there. 

In fact if you run an strace -f job on the whole thing, you can see that the
linker just tries to open "crti.o", gets an error and that's that.

> --disable-multilib \

Oops, just noticed that. I don't think we want to be disabling multilib. I
can't remember why that option was put in there. It hasn't caused any problems,
though. The toolchain targets only one ABI, when we build it for MIPS.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-23 Thread kkylheku at gmail dot com


--- Comment #7 from kkylheku at gmail dot com  2008-02-23 08:03 ---
Both my patches apply even if Carlos' patches are removed. The crti.o problem
remains.

What's happening is that xgcc actually searches for the crti.o module, and then
passes the full path to crti.o down to collect2 if it finds it.

It looks like in the case when crti.o is not found, it simply passes the
unprefixed name "crti.o" down to collect2, which bounces the arguments down to
the linker and so it fails there.

I made the compiler too smart :) so that even the intermediate stage xgcc
restricts its search paths to its own installation. It thinks that its own
temporary installation contains the sysroot, when in fact it should be
``breaking the rules'' and using the absolute path to the sysroot.

I think that I'm hacking in the right direction here; there just has to be
logic to have no path translation during staging.

I have an idea, which I think is the cleanest solution for me. During the
building of a shared gcc, quite simply, you have to fake out a miniature
sysroot within gcc's own build directory. This is done by copyinig some files
from the real sysroot (like crti.o, and some others) into the location where
xgcc will expect them. 

This way there are no hacks in gcc itself to have a different search strategy
during staging.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug driver/35300] References to original ${prefix} paths in relocated toolchain and /lib and /usr/lib search paths appear in cross toolchain.

2008-02-23 Thread kkylheku at gmail dot com


--- Comment #8 from kkylheku at gmail dot com  2008-02-23 08:54 ---
I ended up doing the symlink trick because quite a bit of the sysroot material
is needed to build everything, like libstdc++. It worked like a charm. And so
now I have a compiler with search paths only in its own tree. Check this out:

$ toolchain2/mips64-linux/bin/mips64-linux-gcc -print-search-dirs

install:
/data/work/main-trunk/ZeugmaLinux/toolchain/mips64-linux/lib/gcc/mips64-linux/4.1.1/
programs:
=/toolchain2/mips64-linux/bin/../libexec/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../libexec/gcc/:/toolchain2/mips64-linux/bin/../libexec/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../libexec/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../libexec/gcc/mips64-linux/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/bin/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/bin/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/bin/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/bin/
libraries:
=/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/lib/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/lib/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/lib/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../lib/gcc/mips64-linux/4.1.1/../../../../mips64-linux/lib/:/toolchain2/mips64-linux/bin/../mips64-linux/root/lib/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../mips64-linux/root/lib/:/toolchain2/mips64-linux/bin/../mips64-linux/root/usr/lib/mips64-linux/4.1.1/:/toolchain2/mips64-linux/bin/../mips64-linux/root/usr/lib/

The install: line reveals where I built the compiler: in the directory
/data/work/main-trunk/...

All other paths nicely begin with /toolchain2 where I copied the whole
toolchain. (Actually I cheated; /toolchain2 it's a loopback NFS mount that
points under /data/work, but that's beside the point).

Before building GCC, I created a symlink: $GCC_BUILD_DIR/mips64-linux/root

The "mips64-linux/root" is my relative path to the sysroot within a toolchain.
So I just made this relative path work relative to the build directory, as a
symlink to the real sysroot. Presto; xgcc nicely accepted this, and everything
built. libgcc_s.so, libstdc++.

What to do to close this bug? Someone should investigate the behavior of
current gcc maybe. If you build a cross toolchain and relocate it, what is the
output of -print-search-dirs? Are all the paths under the toolchain, or do some
point back to the original build or install directory? Does a cross-compiling
toolchain refer to build machine material in /usr/lib/gcc or /usr/libexec/gcc?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35300



[Bug inline-asm/87733] local register variable not honored with earlyclobber

2019-03-15 Thread kkylheku at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87733

Kaz Kylheku  changed:

   What|Removed |Added

 CC||kkylheku at gmail dot com

--- Comment #9 from Kaz Kylheku  ---
Can someone kindly point out where this is fixed? What commit(s)?

[Bug fortran/90329] Incompatibility between gfortran and C lapack calls

2019-06-21 Thread kkylheku at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90329

Kaz Kylheku  changed:

   What|Removed |Added

 CC||kkylheku at gmail dot com

--- Comment #45 from Kaz Kylheku  ---
Hi everyone.

Pardon my ignorance of C-Fortran bridging matters, but does any of the
following make sense?

The Fortran subroutine has no idea whether the word where the argument is
supposed to be is really the argument, or just some unrelated part of the stack
(because the caller didn't pass the argument).

Can't the Fortran routine check whether that word has the expected value 1?
Then in that case, just pretend it's the argument (whether that is the case, or
whether that 1 is just a spurious value that looks like the right argument). In
this case, just do all the tail calling to sibling routines happily, who will
get the right string length.

If the word does not have value 1, then, uh oh: treat it suspiciously! The
function can then *call itself* with with a *copy* of the arguments, including
the correct length 1. When that call returns, it returns.   The recursively
invoked activation will of course the value of 1, and then act cool.

The downside is that there is a performance penalty with this check and extra
recursive call. When the callers are fixed to pass the argument, the penalty is
reduced, but the check is still being made.

[Bug fortran/90329] Incompatibility between gfortran and C lapack calls

2019-06-21 Thread kkylheku at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90329

--- Comment #46 from Kaz Kylheku  ---
C pseudocode in light of previous comment:

   double abused_fortran_fn(double x, double y, char str[1], int len)
   {
  if (len != 1)
return abused_fortran_fn(x, y, str, 1); /* full call, not tail! */

  return tail_call_sibling(x, y, str, len);  
   }

[Bug fortran/90329] Incompatibility between gfortran and C lapack calls

2019-06-22 Thread kkylheku at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90329

--- Comment #48 from Kaz Kylheku  ---
(In reply to Thomas Koenig from comment #47)
> I see two problems with this suggestion, one minor and one major.
> 
> First, there may well be a value > 1 on the stack for a regular
> call, see comment #15.

Thus it adds overhead to cases like when "ab" is passed, where the callee
treats that as a length 1 string. It has to be suspicious of the value 2 and go
through the self-calling hoop.

(Oh well; obviously this is a workaround that would have to go through
deprecation and removal.)

> Second, the value 1 may end up being there by accident, then this

That I clearly understand: a value 1 may be there spuriously even if no
argument was passed.

> method would cause a crash, and this would be even harder to debug
> than the original case.

That's the thing I'm keenly curious about: if that value is fortuitously the
right one, in the right place on the stack, where is the crash?

(Of course, we must not mutate that word; it belongs to the C caller's frame.)

[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2015-07-24 Thread kkylheku at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587

--- Comment #11 from Kaz Kylheku  ---
(In reply to Manuel López-Ibáñez from comment #10)
> (In reply to Kaz Kylheku from comment #1)
> > Created attachment 15798 [details]
> > Implements -Wunused-objects warning for C++.
> 
> Patches need to be properly tested and submitted. See
> https://gcc.gnu.org/wiki/GettingStarted#Basics:
> _Contributing_to_GCC_in_10_easy_steps
> 
> The few people that have the power to approve patches are very busy and they
> very rarely read bugzilla.

The bug database has an "enhancement" type, so obviously, it is to be used for
submitting enhancements. Why would you duplicate effort by implementing a
different process for tracking submissions?

In June 2008, when I submitted this, here is how the above Wiki page looked:

https://gcc.gnu.org/wiki/GettingStarted?action=recall&rev=19

There is no mention of any special process at that time.

Please "grandfather" old submissions that were posted to Bugzilla before the
special submission process was described in the Wiki.

>Patches attached to bugzilla are usually understood as proof-of-concept or 
>work-in-progress, not actual submissions.

I deployed that change to large team of developers, and the toolchain with that
change went to customers also. The warning caught problems that were fixed and
didn't appear to break anything.

So yes, actual submission.

Today, I no longer care about upstreaming code to OSS projects because of prima
donna attitudes like this. It's just too much effort dealing with the barriers.

In my own projects, I accept good patches, even if they are written on a
grease-stained napkin.

If I lead by example, maybe others will follow.

[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2009-12-10 Thread kkylheku at gmail dot com


--- Comment #4 from kkylheku at gmail dot com  2009-12-11 02:34 ---
(In reply to comment #3)
> This would have prevented bugs I've dealt with where critical sections where
> not protected:
> {
>   lock_guard (mutex);
>   // mutex NOT locked here!
> }
> But I'm not convinced that doing this is always a mistake.

Since we don't care about the object, we must care about the constructor side
effect. I seem to be under the impression that ISO C++ allows the construction
of temporary objects to be optimized away---even if there are side effects in
the constructor or destructor! Therefore, it's hard to see a valid use case for
this.

 Would the warning be
> suppressed by casting to void?
>   (void) TypeWithSideEffectsInCtor(x);

Not as implemented, I am afraid. The diagnostic is still produced that the
object is discarded. This is can be regarded as a flaw; something explicitly
requested by a cast should not be diagnosed.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587



[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2009-12-11 Thread kkylheku at gmail dot com


--- Comment #6 from kkylheku at gmail dot com  2009-12-11 11:57 ---
(In reply to comment #5)
> (In reply to comment #4)
> > > But I'm not convinced that doing this is always a mistake.
> > 
> > Since we don't care about the object, we must care about the constructor 
> > side
> > effect. I seem to be under the impression that ISO C++ allows the 
> > construction
> > of temporary objects to be optimized away---even if there are side effects 
> > in
> > the constructor or destructor! Therefore, it's hard to see a valid use case 
> > for
> > this.
> Certain temporaries (such as those created during copying or reference 
> binding)
> can be optimised away, I don't think it's true of temporaries created
> explicitly like this.

I've gone over the relevant 14882:2003 sections and have come to the same
conclusion.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587



[Bug rtl-optimization/34456] Flaw in branch delay optimization (patch included).

2007-12-13 Thread kkylheku at gmail dot com


--- Comment #1 from kkylheku at gmail dot com  2007-12-14 02:51 ---
Created an attachment (id=14749)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14749&action=view)
Patch for caller used registers in mark_set_resources.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34456



[Bug rtl-optimization/34456] New: Flaw in branch delay optimization (patch included).

2007-12-13 Thread kkylheku at gmail dot com
This was discovered in GCC 4.1.1 on MIPS, but the problem is in the current SVN
head.

The mark_set_resources function incorrectly calculates the potentially
clobbered registers for a CALL_INSN, using an obsolete approach relying on the
call_used_regs array.

A potential consequence of this is that a register which should be live is
marked dead during the liveness analysis which is done in order to determine
whether an instruction move into a delay slot is free of resource conflicts.

Thus, it's possible that an instruction which clobbers a register that is live
in the fall-through path is moved into a non-annulled delay slot of a branch
instruction. This behavior in fact happened when compiling a C++ application
for MIPS (n32). The MIPS GP register ($28) is in call_used_regs, but not in
call_really_used_regs. 

The hard reg set regs_invalidated_by_call should be used; it contains the right
information compiled from global_regs and call_really_used_regs.

The target of the branch instruction in the failed program is an epilogue which
restores registers, the first being the GP. This GP-restoring instruction is
moved into the branch delay slot, because in the fall-through-code
mark_target_live_regs finds a call instruction ahead of anything which uses the
GP, and concludes that GP is a dead register.

The result is that a GOT-based indirect function call is made using the
caller's GP, which is different from the caller's.

After this patch, nearly the same code is generated, except that the branch is
correctly changed to an annulling one (MIPS ``branch likely'').

--- gcc-4.1.1.orig/gcc/resource.c   2007-12-16 11:59:18.0 -0800
+++ gcc-4.1.1/gcc/resource.c2007-12-19 20:59:02.724735120 -0800
@@ -664,9 +664,8 @@
  rtx link;

  res->cc = res->memory = 1;
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
-   if (call_used_regs[r] || global_regs[r])
- SET_HARD_REG_BIT (res->regs, r);
+
+ IOR_HARD_REG_SET (res->regs, regs_invalidated_by_call);

  for (link = CALL_INSN_FUNCTION_USAGE (x);
   link; link = XEXP (link, 1))


-- 
   Summary: Flaw in branch delay optimization (patch included).
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: rtl-optimization
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kkylheku at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34456



[Bug c++/36587] New: Feature: add warning for constructor call with discarded return.

2008-06-20 Thread kkylheku at gmail dot com
This patch implements a ``-Wunused-objects'' warning which is triggered if a
constructor is called, and the returned object is thrown away.

This can happen by accident when a declaration for an object accidentally omits
a name. For instance:

  {
trace_class ("foo", ...);
// ^ missing name
  }

Whereas it is common for C++ function calls to discard returned objects,
discarding the result of an explicit constructor call is most likely a mistake.

I developed a patch against GCC 4.1.1 for this (because that's the compiler
currently used by my organization). The patch doesn't include a documentation
update, just code.


-- 
   Summary: Feature: add warning for constructor call with discarded
return.
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
    ReportedBy: kkylheku at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587



[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2008-06-20 Thread kkylheku at gmail dot com


--- Comment #1 from kkylheku at gmail dot com  2008-06-20 19:23 ---
Created an attachment (id=15798)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15798&action=view)
Implements -Wunused-objects warning for C++.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587



[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2008-06-20 Thread kkylheku at gmail dot com


--- Comment #2 from kkylheku at gmail dot com  2008-06-20 20:26 ---
I should add that this is different from -Wunused-value, because I want this
warning emitted even if the constructor (or its corresponding destructor) have
side effects.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587



[Bug preprocessor/44317] ,##__VA_ARGS__ comma not eaten with -std=c++0x

2022-04-21 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44317

Kaz Kylheku  changed:

   What|Removed |Added

 CC||kkylheku at gmail dot com

--- Comment #12 from Kaz Kylheku  ---
(In reply to Harald van Dijk from comment #9)
> The comma should not be eaten, as the invocation of FAIL() is valid in
> standard C++. The rules of concatenation of empty pp-token sequences are
> well-defined: the empty sequences are replaced by placemarker preprocessor
> tokens, and concatenating any non-placeholder token with a placemarker
> preprocessor token produces the former, see [cpp.concat]. 

And thus, more directly to the point, here is the fix:

cpp -std=gnu++0x test.cpp

The behavior does not reproduce then; the comma eating works.

If you want GNU extensions, request the GNU dialect which most closely
corresponds to the ISO dialect you want.

The issue here is that ## __VA_ARGS__ is a conforming extension in C,
and so it can work even when an ISO dialect is selected.
The documentation does not mention that ## __VA_ARGS__ might be
valid in some dialects of C++ and so has to be enabled as a nonconforming
extension.

Also this is an opton. The following workaround also works for me,
on gcc 10.x on Debian 11:

#define ASSERT( cnd, ... ) SomeClass() __VA_OPT__(,) __VA_ARGS__
#define FAIL( ... )SomeClass() __VA_OPT__(,) __VA_ARGS__

This works with "cpp" with no options, with "-std=gnu++0x",
and with "-std=c++0x".

This may be a better workaround for someone who doesn't want to broadly
switch to the GNU dialect. __VA_OPT__ didn't exist when this bug was opened.

[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2024-03-17 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587

--- Comment #15 from Kaz Kylheku  ---
(In reply to Manuel López-Ibáñez from comment #13)
> (In reply to Kaz Kylheku from comment #11)
> > I deployed that change to large team of developers, and the toolchain with
> > that change went to customers also. The warning caught problems that were
> > fixed and didn't appear to break anything.
> 
> If the patch were to be upstreamed, it will be reviewed, regression tests
> would be added to make sure it doesn't silently break, and your customers
> could update to newer versions of GCC without losing the warning.

In April 2020 I created a patch for the GNU C Preprocessor, with documentation,
test cases and everything. I submitted it to the GCC Patches mailing list,
exactly as comments in this ticket from 2015 advised me I should have done for
this item back in 2008.

I received absolutely no replies; not even to reject the submission.

I "pinged" it a number of times, to no avail.

The four year anniversary is coming up; I'm going to ping again. Then if I'm
still ignored, one last time in April 2025.

[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2024-03-17 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587

--- Comment #16 from Kaz Kylheku  ---
(In reply to Andrew Pinski from comment #14)
> C++17 adds nodiscard attribute which can be placed on class/struct types,
> functions, constructors and others and then you get a warning if you ignore
> the value. In the case of struct/class types and constructors that will warn
> when a temporary value is ignored. Exactly in the case you were asking for a
> warning.
> 
> Which was added to GCC by r7-377-gb632761d2c6a65 (and fixes afterwards).
> 
> So closing as fixed.

I'm afraid that this doesn't seem like a good resolution. The feature you are
referring to is opt-in, per class, whereas the proposed warning imposes the
behavior for every class.

This is a big difference.

The number of situations in which "classname(arg);" as an expression statement
with a discarded value is correct is pretty small. This is almost always going
to be a coding mistake. Where it isn't a coding mistake, the intent can be
indicated using "(void) classname(arg);".

The good news is that, at least it would seem that the implementation of the
warning can be piggybacked on the nodiscard attribute implementation. The
simplest possible requirement is that the option makes the compiler pretend
that the attribute has been asserted for every class. (I say tentatively,
without having studied the attribute's semantics in detail.)

nodiscard could be "stronger" in that if it is asserted, then even the cast to
(void) won't silence the diagnostic, so that it's still meaningful to use in
spite of the warning option.

[Bug c++/36587] Feature: add warning for constructor call with discarded return.

2024-03-18 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587

--- Comment #19 from Kaz Kylheku  ---
(In reply to Jonathan Wakely from comment #18)
> Was there an earlier submission?

No there wasn't; that's my mistake in my comment.

[Bug c/114526] New: ISO C does not prohibit extensions: fix misconception.

2024-03-28 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

Bug ID: 114526
   Summary: ISO C does not prohibit extensions: fix misconception.
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: kkylheku at gmail dot com
  Target Milestone: ---

There seems to be a historic misconception in the development of GCC that the C
standard prohibits extensions. The -Wpedantic/-pedantic options are
unfortunately organized around this false idea.

Firstly, for a bit of background, in the GNU Coding Standards document we have
this:

> But we do not follow either of these specifications rigidly,
> and there are specific points on which we decided not to
> follow them, so as to make the GNU system better for users.
>
> For instance, Standard C says that nearly all extensions to C
> are prohibited. How silly! GCC implements many extensions,
> some of which were later adopted as part of the standard.
> If you want these constructs to give an error message as
> “required” by the standard, you must specify ‘--pedantic’,
> which was implemented only so that we can say “GCC is a 100%
> implementation of the standard”, not because there is any
> reason to actually use it. 

[https://www.gnu.org/prep/standards/standards.html]

I suspect this might have been written, at some point, by someone actually
working on the design of GCC. Or at least believing the GCC documentation.

The GCC man page contains text which propagates the same falsehood, claiming
that the -Wpedantic/-pedantic options "[i]ssue all the warnings demanded by
strict ISO C and ISO C++; reject all programs that use forbidden extensions,
and some other programs that do not follow ISO C and ISO C++." The same text
appears in the main documentation.

This is false; there are no forbidden extensions. There are conforming
extensions and nonconforming extensions. Nonconforming extensions are those
that require a diagnostic if interpreted as ISO C, due to using new syntax or
anything else diagnosable.

Probably, -pedantic mode should only stick to emitting required diagnostics.
For instance if program uses a nonconforming extension then -pedantic should
cause that to be diagnosed (while continuing to accept the GNU extension, if
it's just a warning).

The following diagnostics have a wording which perpetrates the falsehood that
extensions are forbidden:

> warning: ISO C forbids conversion of function pointer to object pointer type 
> [-Wpedantic]
> warning: ISO C forbids conversion of object pointer to function pointer type 
> [-Wpedantic]

ISO C forbids no not such thing, and requires no diagnostic. 

It is a conforming extension in GCC, allowed by the standard, and even required
by POSIX (so that the result of dlsym can be usefully converted to a function
pointer).

Diagnostics which warn about conforming extensions (and reject programs when
warnings are treated as errors) arguably have no place in -pedantic mode. (They
can stand on their own, or be put into some other special category.)

The incorrect claims in the documentation should be removed, and pedantic
mode's focus should be diagnosing situations where ISO C requires a diagnostic
but GCC doesn't emit one by default.

Wording in diagnostics which claims that ISO C forbids something should
likewise be revised; people read these statements and take them to be true!

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-03-28 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #3 from Kaz Kylheku  ---
(In reply to Andrew Pinski from comment #2)
> Actually it is a required diagnostic. See PR 11234 for explanation on how.
> This was changed a little over 20 years ago explictly to reject this because
> it is invalid C.
> 
> *** This bug has been marked as a duplicate of bug 11234 ***

This bug report is more than about the specific warning about conversion of
function and object pointers.

It's about all/any options that don't belong in -pedantic; and about false
sentences in diagnostics and documentation.

Now, a conversion between a function and object pointer requires no diagnostic
if the required cast is present. Either way, it is undefined behavior.

I'm referencing the N3220 draft.

The 6.3 Conversions sections lists, in 6.3.2.3 Pointers, various possible
conversions among pointers. Conversions between pointers to object types and to
function types are not mentioned.

It has always been like that going back to ISO C 90 and ANSI C.

As an extension, not only is it not forbidden, but it is listed in an Appendix
as a common extension. In the N3220 draft we have:

  J.5.8 Function pointer casts

  A pointer to an object or to void may be cast to a pointer to a function,
  allowing data to be invoked as a function (6.5.5).

A diagnostic is required if a pointer to function is converted to an object
pointer, without a cast.

  6.5.5 Cast Operators

  Constraints

  ...

  Conversions that involve pointers, other than where permitted by the
  constraints of 6.5.17.2, shall be specified by means of an explicit cast.  

If a cast is present, the constraint is satisfied; the conversion is no longer
implicit but explicit. No other constraints apply to the conversion. In fact no
other requirements at all, since it is not defined.

GCC provides the common extension described in J.5.8. It is conforming; nothing
needs to be diagnosed about a program which uses it. It, and other extensions,
must not be called "forbidden".

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2024-03-28 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

Kaz Kylheku  changed:

   What|Removed |Added

 CC||kkylheku at gmail dot com

--- Comment #22 from Kaz Kylheku  ---
(In reply to Pavel M from comment #21)
> FYI: Rationale for C, Revision 5.10, April-2003:
> > Even with an explicit cast, it is invalid to convert a function pointer to 
> > an object pointer or a pointer to void, or vice versa.

That means nothing; it's not even part of the standard document. In the
document itself, there are texts which are part of it, yet not "normative",
such as examples and footnotes.

The standard itself mentions the conversion as a common extension (not in a
normative way though, but at least in the document!)

Now the absence of a documented extension, it certainly isn't correct; it's
undefined behavior.

But it's not incorrect in a way that requires a diagnostic (when the required
cast is present).

The only diagnostic ever required when a pointer conversion is requested is
when the conversion isn't one of the ones allowed implicitly, and a correct
cast is missing.

The "absence of a documented extension" is irrelevant in the context of GCC,
which has the extension. That extension is at the cornerstone of the tech
stacks built on GCC, and required by POSIX.

It is not useful for the -pedantic option to pretend that GCC is some other
compiler which doesn't have any of its conforming extensions. 

Diagnostics like that could be useful to someone, but deserve their own
category, like -Wutmost-portability or something.

Someone who just wants the ISO-C-required situations diagnosed shouldn't have
to have these other diagnostics foisted on them.

You can always pick and choose diagnostics individually, but the categories are
useful, which is why they are there.

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-03-28 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #7 from Kaz Kylheku  ---
Also, it would be useful for the documentation to list all the -W-* options
that are implied by -Wpedantic.

The function/object pointer conversion diagnostics, unfortunately, are tied to
-Wpedantic itself, which is unhelpful.

-Wpedantic serves both as a diagnostic option, and a container for diagnostic
options. E.g if you don't want the extension of void * pointer arithmetic, you
can use -Wpointer-arith to diagnose it; that is turned on by -Wpedantic.

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-04-02 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #12 from Kaz Kylheku  ---
(In reply to Harald van Dijk from comment #10)
> Sorry, sent my earlier comment too soon.
> 
> (In reply to Joseph S. Myers from comment #8)
> > I believe conversions between function and object pointers are undefined as
> > a property of the translation unit - not of a particular execution.
> 
> But there is nothing in the standard to support this. The standard fully
> defines the behaviour of the program I posted, which is just to return 0.

It does not. You're relying on the implementation (1) glossing over the
undefined conversion at translation time (or supporting it as an extension) and
then (2) optimization removing whatever code was generated for it since the
value is unused.

The standard does not define the conversion, by omission of defined behavior.

Moreover, the omission isn't absolute. There is a non-normative mention of this
conversion in an informative Annex which acknowledges the conversion as a
common extension. That tells us that the omission of a definition of behavior
from the normative text is known, and deliberate.

Undefined behavior means that the implementation is permitted to stop, at
translation or execution time, with or without the issuance of a diagnostic
message.

Moreover, implementations are not required to optimize. If the abstract
semantics of your program is executed literally, then there will be an
undefined conversion performed, whose value is then discarded in the
expression-statement.

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-04-02 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #13 from Kaz Kylheku  ---
(In reply to Joseph S. Myers from comment #11)
> I think that simply failing to say whether a value of type X may be
> converted to type Y is clearly enough for it at least to be unspecified
> whether or when such conversions are possible in a cast at all (which is
> enough for rejecting the translation unit).

"Unspecified (Behavior)" is a normative term though. Unspecified situations
occur when the standard gives the implementation a choice from among a finite
number of behaviors (none of those being anything like "stop the program", or
"behave unpredictably"), but the implementation is not required to document
which behavior is selected.

The difference between "unspecified" and "implementation-defined" is that under
the latter, the choice must be documented.

E.g. order of evaluation of function argument expressions is unspecified,
therefore we don't know whether G or H is called first in F(G(), H()), and the
implementation doesn't have to provide any documented requirements about it.

When the standard doesn't define a behavior, not mentioning any possible
choices or anything of the sort, it is undefined. "behave unpredictably" or
"stop the program" are possible behaviors then.

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-04-02 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #17 from Kaz Kylheku  ---
(In reply to Harald van Dijk from comment #14)
> (In reply to Joseph S. Myers from comment #11)
> > I think that simply failing to say whether a value of type X may be
> > converted to type Y is clearly enough for it at least to be unspecified
> > whether or when such conversions are possible in a cast at all (which is
> > enough for rejecting the translation unit).
> 
> I disagree. You're reading something into the standard that it does not say
> anywhere. It would make sense if it did say that, but it doesn't.

The standrad does not define the conversion at the *type* level.

> 
> > And since no requirements are
> > imposed relating to such conversions at either translation time or runtime,
> > the definition of undefined behavior is met.
> 
> The behaviour at runtime is implicitly unspecified. The behaviour at
> translation time is not, as my program does not attempt to convert between
> any function and object pointer. Performing that conversion is undefined by
> omission. Writing code that *would* perform that conversion, if executed, is
> not undefined, because the standard defines the behaviour of code that is
> not executed: it does nothing.
> 
> I am assuming, at least, that there is no dispute that
> 
>   #include 
>   int main(void) {
> if (0) puts("Hello, world!");
> return 0;
>   }
> 
> has never been permitted to print "Hello, world!".
> 
> (In reply to Kaz Kylheku from comment #12)
> > It does not. You're relying on the implementation (1) glossing over the
> > undefined conversion at translation time (or supporting it as an extension)
> 
> I'm not.
> 
> > Undefined behavior means that the implementation is permitted to stop, at
> > translation or execution time, with or without the issuance of a diagnostic
> > message.
> 
> My program has no undefined behaviour. It is in the same category as
> 
>   void f(void) { 1/0; }
>   int main(void) { return 0; }
> 
> which is strictly confirming despite the division by zero in an uncalled
> function, despite division taking constant operands.

The program is strictly conforming because it has no problem with type. The
language defines a division operator for the types int x int -> int. There can
be divisions written x / y where we don't know that y is zero until a run-time
input is supplied.

The expression 1/0 has a meaning and is translatable; just the operand values
are bad.

Compilers have to be careful when doing constant folding not to blow up on bad
expressions that are not actually called.
Something like this could occur:

   switch (sizeof (T)) {
   case 4:
  ...  1 / (8 - sizeof (T));
   case 8
  ...  1 / (16 - sizeof (T));

   }

where if the size is 8, then case 4: never taken in that case, has a constant
division by zero.  Evaluation of constants is required for dead-code
elimination, so dead code elimination cannot be counted on to remove bad
expressions.

But:

  (void *) &function

has no meaning at all due to a type problem. Because it's a type problem, it is
a static problem which speaks to the ability to translate the expression. That
ability is not required.

The standard is mum about converting a function pointer type to void * type,
regardless of the specific run-time values involved.

We wouldn't say that

  void f(void) { "abc" / "def"; }

is strictly conforming because f is not called in the program. There is a type
problem. Now in this case there is a constraint violation: it requires a
diagnostic.

(void *) &function has a problem in the same category: operator not defined for
the given types. The only difference is that there is no requirement for a
diagnostic.

The implementation is justified in aborting the translation. Possibly with a
diagnostic (which could say "conversion of function pointers to data pointers
is not supported, goodbye!").

In summary,   (void *) &function  is a type mismatch error, which is not caught
by the C type system due to there being no constraint violation. It's a hole in
the type system.

When an implementation hits a situation that triggers a hole in the type
system, it is allowed to diagnose it and reject the program.

Anyway, this is all moot because this bugzilla is about GNU C, which has the
extension. The behavior is locally defined.

We would like NOT to have a diagnostic under -Wpedantic, so we are on the same
page.

Whether your program is strictly conforming or not, we would like not to have
it diagnosed under the -Wpedantic umbrella, and even if it is changed to a
program which calls f.

There is nothing wrong with the diagnostic, but it should be uncoupled from
-Wpedantic and available under its own option.   Possibly, an umbrella option
could exist for this kind of "super pedantic" errors, like
-Wconforming-extensions (warn about the use of GNU extensions that are
conforming, and thus require no diagnostic by ISO C).

[Bug c/114526] ISO C does not prohibit extensions: fix misconception.

2024-04-02 Thread kkylheku at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114526

--- Comment #19 from Kaz Kylheku  ---
(In reply to Harald van Dijk from comment #18)
> (In reply to Kaz Kylheku from comment #17)
> > The standrad does not define the conversion at the *type* level.
> > ...
> > The program is strictly conforming because it has no problem with type.
> 
> The DRs I referenced include ones where type errors have explicitly been
> stated not to render behaviour undefined.
> 
> DR 132 (C90):
> 
>   /* No headers included */
>   int checkup()
>   {
>   /* Case 1 */
>   if (0)
>   printf("Printing.\n");
>   /* Case 2 */
>   return 2 || 1 / 0;
>   } 
> 
>   Response: "The Response to Defect Report #109 addresses this issue. The
> translation unit must be successfully translated."

Note that this report response does not say that the translation
unit must also be successfully linked, in a hosted implementation, to
produce a program.

> This, despite the fact that it implicitly declares as int(*)(), which is
> incompatible with the type it is meant to be declared as.

A mismatch, in linkage, can only occur when a reference is of a
different type from the definition.

In this translation unit alone, there is no type mismatch, because
the unit contains only a reference to printf, and no definition.

The translation unit can be part of a program where it makes sense.
E.g. in a freestanding implementation, where there isn't a library
with a printf, another translation unit can supply a compatible
definition of printf. Then, if (0) can be flipped to if (1) and
checkup() can be called, even.

There is no type problem here whatsoever that is comparable to
an operator being given operands whose type combination is not
defined for the operator. That's a problem entirely confined in
translation phase 7; it cannot be rescued by adding a suitable
secondary translation unit.

A call to an implicitly declared printf is translatable. There are
requirements about every aspect of it. There are no requiremnts
about how to translate (void *) &fn.