[Bug c++/38990] New: preprocessing different in g++ -E and regular compiling.
(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.
--- 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.
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.
--- 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.
--- 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.
--- 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.
--- 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.
--- 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.
--- 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.
--- 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
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
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
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
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.
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.
--- 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.
--- 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).
--- 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).
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.
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.
--- 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.
--- 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
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.