[Bug c/89408] No constant folding when dereferencing string literals
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89408 --- Comment #7 from Stephen Kell --- Thanks for the backstory. I understand that 'accept as much as possible' isn't the goal, nor would it be wise. The pedwarn message you quoted, which explicitly makes reference to integer constant expressions, is a good one. What's not good is that the issued diagnostic is not that. It is not coming from c/c-typeck.cc. It seems to be coming from c-family/c-common.cc. I now understand why this behaviour has arisen -- the pre-4.5 compatibility hack, combined with whatever foldings the compiler happens to do. I would still say it's not a desirable or desired behaviour. Arguably more desirable would be a behaviour consistent with the analogous extension that is allowed for initializers. Of course keeping the pedwarn -- and adding one for the initializer case, which currently lacks one. Being neither stable nor documented is still fine for many purposes (including mine).
[Bug c/89408] No constant folding when dereferencing string literals
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89408 Stephen Kell changed: What|Removed |Added CC||srk31 at srcf dot ucam.org --- Comment #5 from Stephen Kell --- I just ran into this issue myself. Even though GCC is within the C language spec in not supporting this case, there are at least the following reasons to consider the reported behaviour a bug. - GCC doesn't need to reject this code. C11 6.6 pt 10 says "An implementation may accept other forms of constant expressions." - The error message suggests that the omission is not intentional. If it really was about language-lawyering, it should explicitly the C-language concept of "integer constant expressions". Currently, what it says is actually false and confusing, because the expression clearly *does* reduce to an integer constant. It just isn't an "integer constant expression". To me it looks like the compiler just happens not to be doing the necessary folding in that particular case (no pun intended). - GCC accepts these kinds of expressions in initializers, even though the C language also does not require this to work (because they're not in the classes of expression listed in C11 6.6 pt 7). Test case: int x = "C"[0]; - It makes the compiler more useful, has no apparent downside, Clang supports it, etc etc. :-)
[Bug c/96221] New: Constructor attribute priority is ignored if additional prototypes omit attribute
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96221 Bug ID: 96221 Summary: Constructor attribute priority is ignored if additional prototypes omit attribute Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Target Milestone: --- Created attachment 48882 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48882&action=edit Minimal test case I was surprised to find that my __attribute__((constructor(101))) on a function was not giving it priority over another constructor whose attribute used a higher number. It turns out this was owing to an additional prototype that did not mention the function as a constructor. This caused a really subtle initialization bug in my code, and was tough to track down. At the least, I would expect a warning when the information is discarded. I haven't tried on 8.4, but didn't see any relevant changelog entries. Note that this is not a duplicate of 87592, which is about when the priority is specified multiple times. $ cat test.c // comment these for correct behaviour, i.e. 1 then 2 static void do_init1(void); static void do_init2(void); static void do_init2(void) __attribute__((constructor(102))); static void do_init2(void) { printf("Init 2!\n"); } static void do_init1(void) __attribute__((constructor(101))); static void do_init1(void) { printf("Init 1!\n"); } int main(void) { return 0; } $ cc -save-tempstest.c -o test $ ./test Init 2! Init 1! $ grep -B2 init_array test.s .LFE0: .size do_init2, .-do_init2 .section.init_array,"aw" -- .LFE1: .size do_init1, .-do_init1 .section.init_array The attribute's priority argument is being discarded. It should be visible in the section name (".init_array.0101" etc.). If the extra prototypes are removed, the programmer-intended behaviour is restored.
[Bug preprocessor/91025] cpp man page incorrectly describes -MD option
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91025 --- Comment #2 from Stephen Kell --- Created attachment 47405 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47405&action=edit Patch to cpp manual page's description of -MD It took me long enough, but I'm fairly sure this patch results in a less-wrong cpp man page than the current one.
[Bug preprocessor/91025] New: cpp man page incorrectly describes -MD option
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91025 Bug ID: 91025 Summary: cpp man page incorrectly describes -MD option Product: gcc Version: 7.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Target Milestone: --- The cpp manual page's description of the -MD option is incorrect. It would be correct as a description of gcc's -MD option... indeed it is phrased in terms of "if -MD is used in conjunction with -E" and "the driver", neither of which makes sense when running cpp directly. As far as I can tell, when running "cpp" the "without -E" semantics always apply: if -o is given then its filename is used but with a ".d" suffix substituted; otherwise, the same substitution is done but on the input filename. In other words, "-o" never directly specifies the dependency output file, whether or not "-E" is on the command line (unlike when running gcc). I'm happy in principle to produce a patch... but haven't quite got my head around how the man pages are generated (from the texinfo?).
[Bug c++/81211] Unhelpful error messages using template instance with non-copyable type argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81211 --- Comment #5 from Stephen Kell --- I take the point in general, and I see the specific difficulty in how result_of works. In this specific case, there still seems to be a more low-hanging solution. Perhaps having a lambda that is not callable ought to raise a warning? That seems like a more straightforward diagnostic. In particular, by addressing the lambda rather than the std::function, the problem with pointers to member functions doesn't arise. As for the rule of five: a fine reference, but it's rather circular to say what amounts to "don't make mistakes in your code". :-) This error came up after a rather large bout of refactoring that deleted slightly too much stuff
[Bug c++/81211] Unhelpful error messages using template instance with non-copyable type argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81211 --- Comment #3 from Stephen Kell --- I agree that this message is better (my bad for not trying a supported release). It'd be nice if I didn't have to guess that the reason it's not callable is that I omitted the copy constructor. The rules for when constructors are defaulted/deleted are baroque enough to catch anybody out from time to time.
[Bug c++/81211] New: Unhelpful error messages using template instance with non-copyable type argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81211 Bug ID: 81211 Summary: Unhelpful error messages using template instance with non-copyable type argument Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Target Milestone: --- Created attachment 41631 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41631&action=edit Small test case The following code (also attached) fails to compile, and experiments show that the fix is to make T copy-constructible or move-constructible. The bug is that the error messages are worse than useless, because they are about constructing a std::function rather than a T. (It may also be a bug in libstdc++ that std::function should require this of its argument type, although that's not completely bonkers.) #include struct T { T() {} // uncomment one of the below to make the code compile //T(const T&) {} //T(T&& t) {} T& operator=(const T& arg) { return *this; } T& operator=(T&& arg) { return *this; } }; int main(int argc, char **argv) { std::function f([](T x) -> bool { return false; }); return 0; } gcc 4.9 (Debian 4.9.2-10) says: test.cc: In function ‘int main(int, char**)’: test.cc:15:3: error: no matching function for call to ‘std::function::function(main(int, char**)::)’ }); ^ test.cc:15:3: note: candidates are: In file included from test.cc:1:0: /usr/include/c++/4.9/functional:2226:2: note: template std::function<_Res(_ArgTypes ...)>::function(_Functor) function(_Functor); ^ /usr/include/c++/4.9/functional:2226:2: note: template argument deduction/substitution failed: /usr/include/c++/4.9/functional:2201:7: note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {T}] function(function&& __x) : _Function_base() ^ /usr/include/c++/4.9/functional:2201:7: note: no known conversion for argument 1 from ‘main(int, char**)::’ to ‘std::function&&’ /usr/include/c++/4.9/functional:2404:5: note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = bool; _ArgTypes = {T}] function<_Res(_ArgTypes...)>:: ^ /usr/include/c++/4.9/functional:2404:5: note: no known conversion for argument 1 from ‘main(int, char**)::’ to ‘const std::function&’ /usr/include/c++/4.9/functional:2181:7: note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = bool; _ArgTypes = {T}; std::nullptr_t = std::nullptr_t] function(nullptr_t) noexcept ^ /usr/include/c++/4.9/functional:2181:7: note: no known conversion for argument 1 from ‘main(int, char**)::’ to ‘std::nullptr_t’ /usr/include/c++/4.9/functional:2174:7: note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = bool; _ArgTypes = {T}] function() noexcept ^ /usr/include/c++/4.9/functional:2174:7: note: candidate expects 0 arguments, 1 provided Meanwhile, g++ 6 (Debian 6.3.0-18) says basically the same thing. Naively at least, I'd expect the error trace to reveal something about trying to copy a T, presumably in some non-viable constructor of std::function.
[Bug lto/78407] New: LTO breaks separate overriding of symbol aliases
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78407 Bug ID: 78407 Summary: LTO breaks separate overriding of symbol aliases Product: gcc Version: 5.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Target Milestone: --- Created attachment 40073 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40073&action=edit Test case tarball I have a library which tests, in a constructor function, whether another library is overriding one of its symbols. If so, it skips initialization (since the other library is taking care of it). This is necessary because constructors cannot meaningfully be overridden. To do this test, I create a hidden alias of the overridable symbol. This will always point to our copy, even if the global alias gets overridden. int foo = 0; extern int our_foo __attribute__((visibility("hidden"),alias("foo"))); static void (__attribute__((constructor)) init)(void) { if (&our_foo != &foo) { /* skip init */ } else { /* do init */ } } Building this library with LTO works fine on gcc 4.9.3 and earlier. On 5.x and 6.x the address comparison gets wrongly optimised away (tested on 5.2.1 and 6.2.0). In 4.9.x I get: 06c0 : 6c0: 55 push %rbp 6c1: 48 89 e5mov%rsp,%rbp 6c4: 48 8d 05 5e 09 20 00lea0x20095e(%rip),%rax 6cb: 48 8b 15 06 09 20 00mov0x200906(%rip),%rdx 6d2: 48 39 d0cmp%rdx,%rax 6d5: 74 1a je 6f1 ... i.e. a cmp instruction, whereas with 5.2.1 there is none. 06b0 : 6b0: 55 push %rbp 6b1: 48 89 e5mov%rsp,%rbp 6b4: 48 8d 35 f5 ff ff fflea-0xb(%rip),%rsi# 6b0 6bb: 48 8d 3d 17 00 00 00lea0x17(%rip),%rdi# 6d9 <_fini+0x9> 6c2: b8 00 00 00 00 mov$0x0,%eax 6c7: e8 c4 fe ff ff callq 590 6cc: 5d pop%rbp 6cd: c3 retq Unless I'm mistaken: for any two ELF symbol aliases, if at least one has global visibility, LTO cannot assume they will remain aliased at run time. Tarball attached. On doing "make run", "lib1" should only claim to initialize itself once, but it happens twice on 5.x+.
[Bug target/63373] New: ELF symbol sizes for variable-length objects are too small
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63373 Bug ID: 63373 Summary: ELF symbol sizes for variable-length objects are too small Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: srk31 at srcf dot ucam.org Created attachment 33569 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33569&action=edit Source files used in the bug description Suppose I have an object file containing a data object of some variable-length type. $ cat section-size-test.c struct blah { float foo; int i[]; }; struct blah b = { 42.0, { 1, 2, 3, 4, 0 } }; $ cc -c -o section-size-test.o section-size-test.c Now I have an object of size 24 bytes. From ELF's point of view, we have a section of size 24 but a symbol of size only 4. $ readelf -Ss section-size-test.o There are 9 section headers, starting at offset 0xc8: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0 0 0 [ 1] .text PROGBITS 0040 AX 0 0 1 [ 2] .data PROGBITS 0040 0018 WA 0 0 4 [ 3] .bss NOBITS 0058 WA 0 0 1 [ 4] .comment PROGBITS 0058 0024 0001 MS 0 0 1 [ 5] .note.GNU-stack PROGBITS 007c 0 0 1 [ 6] .shstrtab STRTAB 007c 0045 0 0 1 [ 7] .symtab SYMTAB 0308 00c0 0018 8 7 8 [ 8] .strtab STRTAB 03c8 0017 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) Symbol table '.symtab' contains 8 entries: Num:Value Size TypeBind Vis Ndx Name 0: 0 NOTYPE LOCAL DEFAULT UND 1: 0 FILELOCAL DEFAULT ABS section-size-test.c 2: 0 SECTION LOCAL DEFAULT1 3: 0 SECTION LOCAL DEFAULT2 4: 0 SECTION LOCAL DEFAULT3 5: 0 SECTION LOCAL DEFAULT5 6: 0 SECTION LOCAL DEFAULT4 7: 4 OBJECT GLOBAL DEFAULT2 b The bug is that when copy relocations are used, the variable-length part of the object will get thrown away. I think the symbol size should also be 24 (hence filing a gcc bug not a binutils bug). Continuing: I create a shared library out of this object file, and an executable that depends on my object. $ cat exe.c struct blah { float foo; int i[]; }; extern struct blah b; int main(void) { return (unsigned long long) &b % 32; } $ cc -shared -o section-size-test.so section-size-test.o $ cc -o exe exe.c section-size-test.so Now the executable is using a copy reloc to address my variable-length object. $ objdump -RT exe exe: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: w D *UND* _ITM_deregisterTMCloneTable DF *UND* GLIBC_2.2.5 __libc_start_main w D *UND* __gmon_start__ w D *UND* _Jv_RegisterClasses w D *UND* _ITM_registerTMCloneTable 00601038 gD .data Base_edata 00601040 gD .bss Base_end 00601038 gD .bss Base__bss_start 00400550 gDF .init Base_init 00601038 gDO .bss 0004 b 00400724 gDF .fini Base_fini DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00600ff8 R_X86_64_GLOB_DAT __gmon_start__ 00601038 R_X86_64_COPY b 0
[Bug c++/49609] No code emitted for address-taken instances of function templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49609 --- Comment #4 from Stephen Kell 2011-07-01 18:09:07 UTC --- (In reply to comment #2) > That paragraph says that if template argument deduction succeeds then an > instantiation is generated. In your case deduction doesn't succeed because the > target type is not available. The note added by DR 115 says that the > specialization can be identified if there's a template argument list, which is > what happens in your example, but it doesn't say that the function template is > instantiated in that case. Ah, I see... I was thinking that the error was spurious because I hadn't overloaded the function, but I guess the template argument-dependence defines a family of overloads. > > You can make it work by using an explicit type conversion to the correct > > type > > before doing the reinterpret_cast: > > > > void *(*my_function_ptr)(void*, void *) > > = reinterpret_cast( > > (void*(*)(float*,float*))&(value_convert_function) ); > > You can also make it work by not specifying an explicit template argument list > and letting them be deduced: > > void *(*my_function_ptr)(void*, void *) > = reinterpret_cast( > (void*(*)(float*,float*))&value_convert_function); Cool -- thanks for this! That teaches me for thinking I can get away without ever using C-style casts in C++
[Bug c++/49609] New: No code emitted for address-taken instances of function templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49609 Summary: No code emitted for address-taken instances of function templates Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: sr...@srcf.ucam.org In the following code template inline void * value_convert_function(From *from, To *to) { return 0; } void *(*my_table[])(void *, void *) = { reinterpret_cast(&(value_convert_function)), 0 }; void *(*my_function_ptr)(void*, void *) = reinterpret_cast(&(value_convert_function)); void *(*my_uncast_function_ptr)(bool *, bool *) = &(value_convert_function); ... I expect to see code output for each of the three template instances that I take the address of. But only the last one is actually generated. $ objdump -t test.o | c++filt test.o: file format elf64-x86-64 SYMBOL TABLE: ldf *ABS* test.cc ld .text .text ld .data .data ld .bss .bss ld .text._Z22value_convert_functionIbbEPvPT_PT0_ .text._Z22value_convert_functionIbbEPvPT_PT0_ ld .note.GNU-stack .note.GNU-stack ld .eh_frame .eh_frame ld .comment .comment ld .group .group g O .data 0010 my_table *UND* void* value_convert_function(double*, double*) 0010 g O .data 0008 my_function_ptr *UND* void* value_convert_function(float*, float*) 0018 g O .data 0008 my_uncast_function_ptr wF .text._Z22value_convert_functionIbbEPvPT_PT0_ 0013 void* value_convert_function(bool*, bool*) I notice that in g++ 4.4, the code for the first two is rejected with a clearly bogus error ("address of overloaded function with no contextual type information"). In 4.5.1 and later, it is accepted but yields an undefined symbol (causing link errors in my actual use-case). This also happens in the latest sources I've tried, which are a fairly recent subversion checkout: $ g++ --version | head -n1 g++ (GCC) 4.7.0 20110417 (experimental) One attempted workaround was to type my table entries as void *, insert no cast and compile with -fpermissive (to get the implicit conversion to void*). But that reverts to the 4.4-style bogus error, even in later versions: void *my_voidptr_table[] = { &value_convert_function, 0 }; test.cc:20: error: cannot resolve overloaded function ‘value_convert_function’ based on conversion to type ‘void*’ My workaround for now is to separately instantiate everything I want to put in the table, by defining a bunch of static function pointers. Thanks for reading!