[Bug c++/106159] New: Have -Woverloaded-virtual not warn about virtual destructors?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106159 Bug ID: 106159 Summary: Have -Woverloaded-virtual not warn about virtual destructors? Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- The new version of -Woverloaded-virtual recently introduced seems to warn about virtual destructors in case of multiple inheritance. Is this really intended? Could destructors be ignored from this warning? Also note that the diagnostic is output three times. $ cat > vee.cc
[Bug preprocessor/103488] New: cpp --help lists some options that are silently ignored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103488 Bug ID: 103488 Summary: cpp --help lists some options that are silently ignored Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- Hi! Sorry for this trivialish issue, but that puzzled me for 10 minutes this morning while I was looking whether cpp had some option I needed. The help text of cpp suggests that `cpp --help=common' will work, but that option seems to be silently ignored. % cpp --version | sed 1q cpp (Debian 11.2.0-12) 11.2.0 % cpp --help | sed 7q Usage: cpp [options] file... Options: -pass-exit-codes Exit with highest error code from a phase. --help Display this information. --target-helpDisplay target specific command line options. --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]. Display specific types of command line options. % cpp --help=common " # 0 "" # 0 "" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 0 "" 2 # 1 "" % cpp --help=foobarbaz " # 0 "" # 0 "" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 0 "" 2 # 1 "" Given this help text, I would have expected any use of --help=... to prevent the normal behavior of cpp, and I would have expected a diagnostic for --help=foobarbaz.
[Bug c++/101150] New: null pointer dereference false positive disappears when compiling an additional function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101150 Bug ID: 101150 Summary: null pointer dereference false positive disappears when compiling an additional function Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- Created attachment 51042 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51042=edit source code, plus the three preprocessed versions I'm observing the following behavior with gcc-snapshot on Debian unstable as well as when using "x86-64 gcc (trunk)" and "x86-64 gcc (11.1)" on Godbolt. This false positive is not reported by gcc 10. % g++ --version | sed 1q g++ (Debian 20210527-1) 12.0.0 20210527 (experimental) [master revision 262e75d22c3:7bb6b9b2f47:9d3a953ec4d2695e9a6bfa5f22655e2aea47a973] % cat foo.cc #include #ifdef FOO void foo(const std::vector& other) { std::vector v; std::size_t sz = other.size(); v.resize(sz); int i = 0; for (int o: other) v[i++] = o; } #endif #ifdef BAR void bar(const std::vector& other) { std::vector v; unsigned sz = other.size(); v.resize(sz); int i = 0; for (int o: other) v[i++] = o; } #endif % g++ -O3 -Wnull-dereference -c foo.cc -DBAR % g++ -O3 -Wnull-dereference -c foo.cc -DFOO -DBAR % g++ -O3 -Wnull-dereference -c foo.cc -DFOO In function 'void foo(const std::vector&)': cc1plus: warning: potential null pointer dereference [-Wnull-dereference] The two functions differ only by the type of sz, and the warning occurs only if foo() is compiled but bar() is not. I *believe* the warning comes from the fact that if sz is 0, the data pointer of v will still be nullptr after resize(), and that would render v[i++]=o invalid. However if sz is 0, the loop will not do any iteration, so that's a false positive. However I can't explain - why changing size_t into unsigned makes the warning go away, - why compiling the two functions makes the warning go away. I was expecting the diagnostics about foo() to be independent of the presence of bar(), and I was expecting to get the same diagnostics for both functions (preferably none, but I understand it's only a "potential" issue)
[Bug c++/90309] Spurious warning shift-negative-value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90309 Alexandre Duret-Lutz changed: What|Removed |Added CC||adl at gnu dot org --- Comment #6 from Alexandre Duret-Lutz --- Came here to report a similar issue, except without the virtual. With gcc (Raspbian 8.3.0-6+rpi1) 8.3.0 from Raspbian buster on ARM: $ cat foo2.cc struct a { int nonempty; }; struct b { typedef unsigned (b::*unsigned_fun)() const; unsigned_fun fun; }; struct c: public a, public b { c() { fun = static_cast(::get_val); } unsigned get_val() const; }; $ g++ -c -Wall -W foo2.cc foo2.cc: In constructor ‘c::c()’: foo2.cc:16:51: warning: left shift of negative value [-Wshift-negative-value] fun = static_cast(::get_val); ^ https://gcc.godbolt.org/z/J08QVd Luckily in the project where this occurs I can simply swap the inheritance order (public b, public a) to get rid of this warning.
[Bug c++/91184] New: memory leak with enable_shared_from_this and pthread
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91184 Bug ID: 91184 Summary: memory leak with enable_shared_from_this and pthread Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- Created attachment 46604 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46604=edit preprocessed source % gcc --version gcc (Debian 20190706-1) 10.0.0 20190706 (experimental) [trunk revision 273162] This is the gcc-snapshot package from Debian, running on amd64. Since this update, I have been observing memory leaks when enable_shared_from_this is used with -pthread. % cat foo.cc #include struct foo: std::enable_shared_from_this { ~foo() { } }; int main() { std::make_shared(); } % g++ -W -Wall -g -o foo foo.cc -pthread % valgrind -q --leak-check=yes ./foo ==27467== 32 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==27467==at 0x4835DEF: operator new(unsigned long) (vg_replace_malloc.c:334) ==27467==by 0x401C59: __gnu_cxx::new_allocator, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (new_allocator.h:111) ==27467==by 0x401AB0: std::allocator_traits, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) (alloc_traits.h:444) ==27467==by 0x40189B: std::__allocated_ptr, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded, (__gnu_cxx::_Lock_policy)2> > >(std::allocator, (__gnu_cxx::_Lock_policy)2> >&) (allocated_ptr.h:97) ==27467==by 0x40172C: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count>(foo*&, std::_Sp_alloc_shared_tag >) (shared_ptr_base.h:677) ==27467==by 0x401691: std::__shared_ptr::__shared_ptr>(std::_Sp_alloc_shared_tag >) (shared_ptr_base.h:1368) ==27467==by 0x40162A: std::shared_ptr::shared_ptr>(std::_Sp_alloc_shared_tag >) (shared_ptr.h:408) ==27467==by 0x401425: std::shared_ptr std::allocate_shared>(std::allocator const&) (shared_ptr.h:844) ==27467==by 0x401344: std::shared_ptr std::make_shared() (shared_ptr.h:860) ==27467==by 0x4011C2: main (foo.cc:10) ==27467== Removing the std::enable_shared_from_this inheritance, or the -pthread option makes the leak disappear.
[Bug rtl-optimization/49054] useless cmp+jmp generated for switch when "default:" is unreachable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49054 --- Comment #6 from Alexandre Duret-Lutz --- I revisited this with GCC 8.2.1 (or more precisely the version called gcc-8.2.0-20 in Debian). The original code I gave now generate a jump table with no extra comparison: : 0: 48 8d 15 00 00 00 00lea0x0(%rip),%rdx# 7 7: 89 ff mov%edi,%edi 9: 48 63 04 ba movslq (%rdx,%rdi,4),%rax d: 48 01 d0add%rdx,%rax 10: ff e0 jmpq *%rax 12: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 18: e9 00 00 00 00 jmpq 1d 1d: 0f 1f 00nopl (%rax) 20: e9 00 00 00 00 jmpq 25 25: 0f 1f 00nopl (%rax) 28: e9 00 00 00 00 jmpq 2d 2d: 0f 1f 00nopl (%rax) 30: e9 00 00 00 00 jmpq 35 35: 0f 1f 00nopl (%rax) 38: e9 00 00 00 00 jmpq 3d However if I change the code to: unsigned f(void); unsigned g(void); unsigned h(void); unsigned i(void); unsigned j(void); unsigned int baz(unsigned int id) { switch (id) { case 0: return f(); case 1: return g(); case 23456: // <- changed return h(); case 3: return i(); case 4: return j(); default: __builtin_unreachable(); } } Then a non-optimal decision tree is generated: : 0: 83 ff 03cmp$0x3,%edi 3: 74 3b je 40 5: 77 09 ja 10 7: 85 ff test %edi,%edi 9: 75 15 jne20 b: e9 00 00 00 00 jmpq 10 10: 83 ff 04cmp$0x4,%edi 13: 75 1b jne30 15: e9 00 00 00 00 jmpq 1a 1a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 20: 83 ff 01cmp$0x1,%edi 23: 75 20 jne45 25: e9 00 00 00 00 jmpq 2a 2a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 30: 81 ff a0 5b 00 00 cmp$0x5ba0,%edi 36: 75 0d jne45 38: e9 00 00 00 00 jmpq 3d 3d: 0f 1f 00nopl (%rax) 40: e9 00 00 00 00 jmpq 45 When we reach line 0x20, we know that 0<%edi<3 so the comparison against 1 is unnecessary. Similarly, the comparison on line 0x30 is unnecessary as %edi must be equal to 23456 at this point. I'd expect the effect of __builtin_unreachable() to cause lines 0x20,0x23,0x30,0x36 to be removed from that output. It looks like that when building a decision tree over a switch, the presence of an unreachable default would allow to get rid of a comparison for all leaves of the tree.
[Bug rtl-optimization/89303] [8 Regression] memory leak with shared_ptr and enable_shared_from_this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89303 --- Comment #6 from Alexandre Duret-Lutz --- I mentioned in my first comment that I had also cases that threw bad_weak_ptr. I've been able to reproduce those as follows: % cat badwptr.cc #include class blob final: public std::enable_shared_from_this { }; int main() { std::shared_ptr tg = std::make_shared(); return tg->shared_from_this().use_count(); } % g++ -g -O badwptr.cc % ./a.out terminate called after throwing an instance of 'std::bad_weak_ptr' what(): bad_weak_ptr When compiled with -O2 or -O0, the program exits with $?=2 as expected.
[Bug libstdc++/89303] [8 Regression] memory leak with shared_ptr and enable_shared_from_this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89303 --- Comment #3 from Alexandre Duret-Lutz --- Created attachment 45665 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45665=edit preprocessed source Here is the preprocessed source.
[Bug c++/89303] New: memory leak with shared_ptr and enable_shared_from_this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89303 Bug ID: 89303 Summary: memory leak with shared_ptr and enable_shared_from_this Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- I'm not sure if this issue is compiler or library related, but since changing -O into -O0 or -O2 hides the issue, I'm assuming its the compiler. This is g++ 8.2.0-20 from Debian unstable (SVN 20190209 (r268721) from the gcc-8-branch) running on amd64. % cat issue.c #include class blob final: public std::enable_shared_from_this { int* data; public: blob() { data = new int; } ~blob() { delete data; } }; static int bar(std::shared_ptr) { return 0; } int main() { std::shared_ptr tg = std::make_shared(); return bar(tg); } % g++ -Wall -g -O issue.cc % valgrind -q --leak-check=full ./a.out ==13174== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==13174==at 0x4835DEF: operator new(unsigned long) (vg_replace_malloc.c:334) ==13174==by 0x1092F5: allocate (new_allocator.h:111) ==13174==by 0x1092F5: allocate (alloc_traits.h:436) ==13174==by 0x1092F5: __allocate_guarded, (__gnu_cxx::_Lock_policy)2> > > (allocated_ptr.h:97) ==13174==by 0x1092F5: __shared_count > (shared_ptr_base.h:675) ==13174==by 0x1092F5: std::__shared_ptr::__shared_ptr>(std::_Sp_alloc_shared_tag >) (shared_ptr_base.h:1342) ==13174==by 0x109185: shared_ptr > (shared_ptr.h:359) ==13174==by 0x109185: allocate_shared > (shared_ptr.h:706) ==13174==by 0x109185: make_shared (shared_ptr.h:722) ==13174==by 0x109185: main (issue.cc:20) ==13174== I've confirmed that this leak exist using GNU libc's mtrace(), i.e., this is not a valgrind bug. Note that changing -O into -O0 or -O2 removes the leak. This is a reduced test case from a larger project that started leaking memory after I upgraded Debian unstable's g++-8 package from version 8.2.0-13 to version 8.2.0-16. I also have some tests that started raising bad_weak_ptr exceptions, but so far I haven't reduced those. Note that 8.2.0-16 includes the patch for libstdc++/88782 ; could this be related?
[Bug c/78228] New: fstrict-overflow breaks code without overflow?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78228 Bug ID: 78228 Summary: fstrict-overflow breaks code without overflow? Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- I'm compiling for x86_64. These two functions used to work fine in gcc-5.4.1, but behave incorrectly with gcc-6.2 when optimizations are turned on. The job is to compute the number of characters needed to display a signed integer when represented in base 10. Assuming int is 32bits, this is most efficiently done using a series of comparisons (int_width_7) that can even be vectorized (int_width_8). Positive input values are negated before the comparisons start; working with negative values instead of positive values is a way to *avoid* signed overflow when processing INT_MIN. Because i = -i is the only operation done on int, and it is only applied to positive values, I don't think there is any undefined behavior in the following code, isn't it? #include #include __attribute__((noinline)) unsigned int_width_7(int i) { unsigned width = i < 0; if (i > 0) i = -i; if (i <= -10) return width + 10; if (i <= -1) return width + 9; if (i <= -1000) return width + 8; if (i <= -100) return width + 7; if (i <= -10) return width + 6; if (i <= -1) return width + 5; if (i <= -1000) return width + 4; if (i <= -100) return width + 3; if (i <= -10) return width + 2; return width + 1; } __attribute__((noinline)) unsigned int_width_8(int i) { unsigned width = i < 0; if (i > 0) i = -i; static const int v[] = { -10, -1, -1000, -100, -10, -1, -1000, -100, -10, 0 }; for (int vi = 0; vi < sizeof(v)/sizeof(*v); ++vi) width += (i <= v[vi]); return width; } int main() { printf("%d %d\n", int_width_7(INT_MIN), int_width_8(INT_MIN)); } % gcc-6 -Wall -O foo.c && ./a.out 11 11 % gcc-6 -Wall -O2 foo.c && ./a.out 2 11 % gcc-6 -Wall -O3 foo.c && ./a.out 2 10 The changes between -O and -O2 seems to be due to -fstrict-overflow: % gcc -Wall -O -fstrict-overflow foo.c && ./a.out 2 11 Looking into the assembly generated code for int_width_7, we can see that the following -O output int_width_7: .LFB11: .cfi_startproc movl%edi, %eax shrl$31, %eax movl%edi, %edx sarl$31, %edx xorl%edx, %edi subl%edi, %edx cmpl$-9, %edx jl .L12 cmpl$-, %edx jl .L13 cmpl$-999, %edx jl .L14 cmpl$-99, %edx jl .L15 cmpl$-9, %edx jl .L16 cmpl$-, %edx jl .L17 cmpl$-999, %edx jl .L18 cmpl$-99, %edx jl .L19 leal1(%rax), %ecx addl$2, %eax cmpl$-10, %edx cmovg %ecx, %eax ret becomes as follows once compiled with -O -fstrict-overflow: int_width_7: .LFB11: .cfi_startproc movl%edi, %eax shrl$31, %eax movl%edi, %edx sarl$31, %edx xorl%edx, %edi subl%edx, %edi cmpl$9, %edi jg .L12 cmpl$, %edi jg .L13 cmpl$999, %edi jg .L14 cmpl$99, %edi jg .L15 cmpl$9, %edi jg .L16 cmpl$, %edi jg .L17 cmpl$999, %edi jg .L18 cmpl$99, %edi jg .L19 leal2(%rax), %edx addl$1, %eax cmpl$10, %edi cmovge %edx, %eax ret Somehow, gcc decided to work with positive integers instead, even though that cannot work MIN_INT? I have not looked at the problem with int_width_8 in details: I can see that the constants are still negative, yet the result is clearly incorrect.
[Bug middle-end/48544] might be clobbered by ‘longjmp’ diagnostic for unmodified variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48544 --- Comment #1 from Alexandre Duret-Lutz adl at gnu dot org --- This works OK with 4.8 and 5.1, so not an issue anymore as far as I'm concerned. (Might be related to #48968 which is reported as half-fixed -- I haven't tried.)
[Bug c/49054] New: useless cmp+jmp generated for switch when default: is unreachable
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49054 Summary: useless cmp+jmp generated for switch when default: is unreachable Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: a...@gnu.org Host: x86-64 Build: x86-64 gcc (Debian 4.6.0-7) 4.6.1 20110507 (prerelease) When I compile the following switch, GCC generates code to check that id = 4 and to conditionally jump to... the next instruction. % cat foo.c unsigned f(void); unsigned g(void); unsigned h(void); unsigned i(void); unsigned j(void); unsigned int baz(unsigned int id) { switch (id) { case 0: return f(); case 1: return g(); case 2: return h(); case 3: return i(); case 4: return j(); default: __builtin_unreachable(); } } % gcc -march=core2 -m64 -O3 foo.c -c -o foo.o % objdump -DC foo.o | head -23 foo.o: file format elf64-x86-64 Disassembly of section .text: baz: 0: 83 ff 05cmp$0x4,%edi 3: 76 03 jbe8 baz+0x8 5: 0f 1f 00nopl (%rax) 8: 89 ff mov%edi,%edi a: ff 24 fd 00 00 00 00jmpq *0x0(,%rdi,8) 11: 0f 1f 80 00 00 00 00nopl 0x0(%rax) 18: e9 00 00 00 00 jmpq 1d baz+0x1d 1d: 0f 1f 00nopl (%rax) 20: e9 00 00 00 00 jmpq 25 baz+0x25 25: 0f 1f 00nopl (%rax) 28: e9 00 00 00 00 jmpq 2d baz+0x2d 2d: 0f 1f 00nopl (%rax) 30: e9 00 00 00 00 jmpq 35 baz+0x35 35: 0f 1f 00nopl (%rax) 38: e9 00 00 00 00 jmpq 3d baz+0x3d What is the point of the first three instructions? I would have expected baz to start at adress 8.
[Bug c/48544] New: might be clobbered by ‘longjmp’ diagnostic for unmodified variable
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48544 Summary: might be clobbered by ‘longjmp’ diagnostic for unmodified variable Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: a...@gnu.org Created attachment 23939 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=23939 preprocessed input % uname -a Linux hush 2.6.32-5-amd64 #1 SMP Wed Jan 12 03:40:32 UTC 2011 x86_64 GNU/Linux % gcc-4.6 --version gcc-4.6 (Debian 4.6.0-2) 4.6.1 20110329 (prerelease) Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % cat foo.c #include setjmp.h jmp_buf env; void foo(int); int bar(int r, int var) { if (var) return r; if (setjmp(env) == 0) foo(r); return 0; } % gcc-4.6 -Wall -Wextra -O2 -c foo.c foo.c: In function ‘bar’: foo.c:6:13: warning: argument ‘r’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] If I understand this message correctly, GCC is warning me that r might be reset to the value it had before calling setjmp(). However, I never changed the value of r, so I don't think this warning should be emitted. Note that removing the if (var) return r; lines makes the warning go away.
[Bug c++/42758] New: ICE on assert() in function with complex(?) template argument
The following code compiles fine with g++-4.4 and causes g++-4.5 to segfault. Removing the assert() or removing the int_less_than parameter no longer lead to a segfault. % g++-4.5 --version g++-4.5 (Debian 4.5-20091226-1) 4.5.0 20091226 (experimental) [trunk revision 155473] Copyright (C) 2009 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % cat bug.cc #include cassert #include set namespace spot { struct int_less_than { bool operator()(int, int) const { return 0; } }; int f(const std::setint, int_less_than) { assert(0); return 1; } } % g++-4.4 -c bug.cc# 4.4 runs OK % g++-4.5 -c bug.cc g++-4.5: Internal error: Segmentation fault (program cc1plus) Please submit a full bug report. See file:///usr/share/doc/gcc-4.5/README.Bugs for instructions. -- Summary: ICE on assert() in function with complex(?) template argument Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: adl at gnu dot org GCC build triplet: i686-linux-gnu GCC host triplet: i686-linux-gnu GCC target triplet: i486-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42758
[Bug c++/42758] ICE on assert() in function with complex(?) template argument
--- Comment #1 from adl at gnu dot org 2010-01-15 13:40 --- Created an attachment (id=19615) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=19615action=view) preprocessed source -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42758
[Bug c++/34073] New: overloaded template function resolves differently if one type is included in a namespace
Two files are appended at the end of this report: temp1.cc and temp2.cc. temp1.cc is the only file that causes a problem with recent releases of GCC. It contains : 1. a template definition of StructureS 2. a template definition of op_is_finiteS(const StructureS*) 3. a template definition of algebra::AlphabetSetL inheriting from Structure 4. a template definition of ElementL that calls op_is_finite(const algebra::AlphabetSetL*) in its ctor 5. a template overloaded definition for op_is_finiteL(const algebra::AlphabetSetL*) 6. a main function that instantiate Elementchar. Because all definitions but main() are template, I expect the call to op_is_finite() in the ctor of ElementL (#4) to be resolved during the instantiation of Elementchar (#6) after the second definition of op_is_finite() (#5) has been read. So the call would be bound to that second definition and not to the first. I have tested three GCC versions : g++-3.4 (GCC) 3.4.6 (Debian 3.4.6-6) g++-4.1 (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14) g++-4.2 (GCC) 4.2.3 20071014 (prerelease) (Debian 4.2.2-3) Both 4.1 and 4.2 behave identically: they seem to ignore the second definition of op_is_finite and try to call the first. 3.4 does what we expect: it calls the second definition. We have found at least two ways to alter temp1.cc such that 4.2 will compile it. - One is to move the second definition of op_is_finite() (#5) before its use in the constructor of ElementL (#4). This ordering would make sense to me if the functions were not template, but it's not clear why this would change anything in the resolution of template overloaded functions. I might be missing something. - Another possibility is to move AlphabetSetL struct out of the algebra:: namespace. temp2.cc contains the updated code. I'm really surprized that 4.2 compiles temp2.cc without problem and fails on temp1.cc. // temp1.cc starts here // templatetypename S struct Structure {}; templatetypename S bool op_is_finite (const StructureS*) { // Error on purpose, this function is not expected to be instantiated. return StructureS(); } namespace algebra { template typename L struct AlphabetSet : public StructureAlphabetSetL {}; } template typename L struct Element { Element() { op_is_finite(static_castconst algebra::AlphabetSetL*(0)); } }; template typename L bool op_is_finite(const algebra::AlphabetSetL*) { // This is the function we want to be called. return true; } int main() { Elementchar alpha; } // % g++-3.4 -Wall -W temp1.cc // % g++-4.2 -Wall -W temp1.cc // temp1.cc: In function 'bool op_is_finite(const StructureS*) [with S = algebra::AlphabetSetchar]': // temp1.cc:21: instantiated from 'ElementL::Element() [with L = char]' // temp1.cc:34: instantiated from here // temp1.cc:7: error: cannot convert 'Structurealgebra::AlphabetSetchar ' to 'bool' in return // temp2.cc starts here // templatetypename S struct Structure {}; templatetypename S bool op_is_finite (const StructureS*) { // Error on purpose, this function is not expected to be instantiated. return StructureS(); } template typename L struct AlphabetSet : public StructureAlphabetSetL {}; template typename L struct Element { Element() { op_is_finite(static_castconst AlphabetSetL*(0)); } }; template typename L bool op_is_finite(const AlphabetSetL*) { // This is the function that is called, as we expected. return true; } int main() { Elementchar alpha; } // % g++-3.4 -Wall -W temp2.cc // % g++-4.2 -Wall -W temp2.cc -- Summary: overloaded template function resolves differently if one type is included in a namespace Product: gcc Version: 4.2.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: adl at gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
[Bug c++/34073] overloaded template function resolves differently if one type is included in a namespace
--- Comment #4 from adl at gnu dot org 2007-11-12 22:08 --- Thank you for the very clear explanation, Andrew. Indeed, adding a namespace algebra around the second definition of op_is_finite() will solve my problem. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34073
[Bug c++/19808] New: miss a warning about uninitialized members in constructor
I just ran into bogus code similar to the following. (The code is bogus, not GCC, but I believe GCC could have helped.) // main.cc #include iostream struct A { A(int x) : x(x) {}; int call_me() { return x; } int x; }; struct B { B(A* a) : i(the_a-call_me()), the_a(a) {} int i; A* the_a; }; int main() { A a(20); B b(a); std::cout b.i std::endl; } % g++ -O2 -Wall main.cc % ./a.out 1328900 This displays 1328900 (or any other value) instead of 20 because the_a-call_me() is invoked before the_a is initialized in B's constructor. It would be useful if g++ could diagnose such use of uninitialized members in constructors, just like it does for local variables. -- Summary: miss a warning about uninitialized members in constructor Product: gcc Version: 3.4.4 Status: UNCONFIRMED Severity: enhancement Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: adl at gnu dot org CC: gcc-bugs at gcc dot gnu dot org GCC host triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19808