[Bug c++/40261] New: confusing diagnostic on ill-formed template definition
The diagnostic issued for the ill-formed definition of B::foo() below is quite confusing. EDG eccp issues a better message: template argument list must match the parameter list. $ cat z.cpp && gcc -c z.cpp template struct A { }; template > struct B: U { void foo (); }; template void B::foo () { } int main () { B b; } z.cpp:4: error: invalid use of incomplete type struct B > z.cpp:2: error: declaration of struct B > -- Summary: confusing diagnostic on ill-formed template definition Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40261
[Bug middle-end/38126] suboptimal code for (a && b || !a && !b)
--- Comment #1 from msebor at gmail dot com 2009-09-12 23:33 --- Code involving bool variables is similarly suboptimal: $ cat t.cpp && gcc -O2 -S t.cpp && cat t.s bool foo (bool a, bool b) { return a && b || !a && !b; } bool bar (bool a, bool b) { return a == b; } .file "t.cpp" .text .p2align 4,,15 .globl _Z3foobb .type _Z3foobb, @function _Z3foobb: .LFB0: .cfi_startproc .cfi_personality 0x3,__gxx_personality_v0 movl%esi, %edx movl%esi, %eax xorl$1, %edx testb %dil, %dil cmove %edx, %eax ret .cfi_endproc .LFE0: .size _Z3foobb, .-_Z3foobb .p2align 4,,15 .globl _Z3barbb .type _Z3barbb, @function _Z3barbb: .LFB1: .cfi_startproc .cfi_personality 0x3,__gxx_personality_v0 cmpb%dil, %sil sete%al ret .cfi_endproc .LFE1: .size _Z3barbb, .-_Z3barbb .ident "GCC: (GNU) 4.4.1 20090725 (Red Hat 4.4.1-2)" .section.note.GNU-stack,"",@progbits -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38126
[Bug c++/41423] New: missing warning for an uncallable function template
There is no way for a program to refer to the template constructor defined in the class below. EDG eccp issues a warning to point this out, but gcc silently accepts the code. It would be helpful if gcc were enhanced to issue a similar diagnostic. $ cat t.cpp && gcc -dumpversion && gcc -W -Wall -Wextra -pedantic -c t.cpp && eccp -c -v t.cpp struct S { template S () { } }; 4.4.1 Edison Design Group C/C++ Front End, version 3.10.1 (Apr 22 2008 17:02:08) Copyright 1988-2007 Edison Design Group, Inc. "t.cpp", line 1: warning: template parameter "" is not used in declaring the parameter types of function template "S::S" struct S { template S () { } }; ^ -- Summary: missing warning for an uncallable function template Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41423
[Bug c++/41423] missing warning for an uncallable function template
-- msebor at gmail dot com changed: What|Removed |Added Severity|normal |enhancement http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41423
[Bug preprocessor/41540] New: -dM -E doesn't #define __FILE__
The documentation for the -dM -E option states that "Instead of the normal output, generate a list of `#define' directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor." but the predefined standard macro __FILE__ does not appear in the output (and neither does __LINE__): $ echo >t.c && gcc -dM -E t.c | grep __FILE__ || echo "__FILE__ not #defined" __FILE__ not #defined $ I believe __FILE__ should always appear in the output. Since __LINE__ changes its value from line to line it should either be documented as not being output at all or, perhaps preferably, it should be output with the value of 0. -- Summary: -dM -E doesn't #define __FILE__ Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41540
[Bug preprocessor/41540] -dM -E doesn't #define __FILE__
--- Comment #2 from msebor at gmail dot com 2009-10-02 16:39 --- I don't have a strong objection to not including __FILE__ and the rest of standard predefined macros (e.g., __LINE__, __DATE__ and __TIME__) in the output if that's by design but I would expect the documentation to mention that some macros are deliberately left out. As it stands, it states that all macros are defined, which is clearly not the case. I suggest clarifying the documentation by changing the paragraph quoted above to read: "Instead of the normal output, generate a list of `#define' directives for the majority of macros defined during the execution of the preprocessor, including predefined macros (the standard macros __DATE__, __FILE__, __LINE__, and __TIME__ are excluded from this list). This gives you a way of finding out what is predefined in your version of the preprocessor." I'm not familiar with the process for updating gcc docs but if you point me in the right direction I would be happy to submit a patch. -- msebor at gmail dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41540
[Bug preprocessor/41540] -dM -E doesn't #define __FILE__
--- Comment #4 from msebor at gmail dot com 2009-10-02 18:00 --- I understand that the values of __FILE__ and __LINE__ change within the same translation unit and thus may not be meaningful in the output of -dM -E. But the values of __DATE__ and __TIME__ do not change within a translation unit and so they could and IMO should be included in the output. In any case, since the preprocessed output contains all the standard macros expanded, I think it's reasonable to either see them all in the output of -dM -E or the discrepancies between the two kinds of output to be mentioned in the docs. I don't insist on including an exhaustive list of all macros excluded from the output if this list is large or changes depending on compiler options etc. but I do think that the docs ought to be clarified so as not to state that *all* macros are output. Here's a small test program to show the discrepancies: $ cat u.c && gcc -E u.c && gcc -E -dM u.c | grep -e__DATE__ -e__FILE__ -e__LINE__ -e__STDC__ -e__STDC_HOSTED__ -e__STDC_VERSION__ -e__TIME__ char date[] = __DATE__; int line = __LINE__; char file[] = __FILE__; char time[] = __TIME__; int stdc = __STDC__; int stdc_hosted = __STDC_HOSTED__; # 1 "u.c" # 1 "" # 1 "" # 1 "u.c" char date[] = "Oct 2 2009"; int line = 2; char file[] = "u.c"; char time[] = "11:52:51"; int stdc = 1; int stdc_hosted = 1; #define __STDC_HOSTED__ 1 #define __STDC__ 1 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41540
[Bug c++/41561] New: warning on a large hex literal in C++ 0x mode
According to [lex.icon], Table 5 of the C++ 0x spec (e.g., N21914), the type of the integer literal in the snippet below in ILP32 is long long. gcc does the right thing (i.e., interprets the literal correctly) but the warning it issues (with -m32 only) is unwarranted. $ cat t.cpp && g++ -dumpversion && g++ -c -m32 -std=c++0x t.cpp long long foo () { return 0x123456789abcd; } 4.4.1 t.cpp:3: warning: integer constant is too large for long type -- Summary: warning on a large hex literal in C++ 0x mode Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41561
[Bug c++/41561] warning on a large hex literal in C++ 0x mode
--- Comment #2 from msebor at gmail dot com 2009-10-04 16:08 --- I'm not positive which stage issues the warning but the preprocessor does not warn on large integer literals in preprocessor directives involving integer arithmetic (e.g., #if 0x123456789abcd > LONG_MAX). Strictly speaking, the warning isn't incorrect (it's true that 0x123456789abcd is too large for the long type in ILP32), but it's also not relevant or useful in any way. The section of the C++ 0x draft that I pointed to specifies that the type of a hex integer literal with no suffix is the first standard integer type from the following list in which the value of the literal can be represented: int, unsigned int, long, unsigned long, long long, unsigned long long. These are the same rules as in C which the C99 compiler interprets without issuing a warning. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41561
[Bug c++/41672] New: missing diagnostic on an ill-formed rvalue reference initialization
According to [dcl.init.ref], p5 of the latest working paper (N2960), A reference to type cv1 T1 is initialized by an expression of type cv2 T2 as follows: ... ...the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference and the initializer expression shall be an rvalue. The following ill-formed program is accepted by gcc 4.4.1: $cat u.cpp && gcc -dumpversion \ && gcc -W -Wall -c -std=c++0x u.cpp && echo FAIL extern int &ir; int &&irr = ir; // ill-formed 4.4.1 FAIL -- Summary: missing diagnostic on an ill-formed rvalue reference initialization Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41672
[Bug c++/41825] New: useless -Wshadow warning on function argument in local class
The warning on the code below isn't useful since the formal argument of foo() named i cannot be referenced in the body of the local struct. I.e., there is no potential for referring to it by mistake since doing so would be a hard error. $ cat t.cpp && g++ -c -Wshadow t.cpp int foo (int i) { struct { int bar (int i) { return i; } } s; return s.bar (i); }; t.cpp: In member function int foo(int)bar(int): t.cpp:4: warning: declaration of int i shadows a parameter t.cpp:1: warning: shadowed declaration is here -- Summary: useless -Wshadow warning on function argument in local class Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com GCC build triplet: all GCC host triplet: all GCC target triplet: all http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41825
[Bug c++/42000] New: missing -Wuninitialized warning on a user-defined class ctor
gcc misses the access to the uninitialized member S::i in the program below and fails to issue a warning for it. I would expect to see a warning not only for the access to the member but also for the definition of the user-defined constructor that fails to initialize the data member. $ cat t.cpp && gcc -Wuninitialized -Wall -Wextra -W -c t.cpp int main () { struct S { int i; S() { } } s; return s.i; } -- Summary: missing -Wuninitialized warning on a user-defined class ctor Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42000
[Bug c/47931] New: missing -Waddress warning for comparison with NULL
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47931 Summary: missing -Waddress warning for comparison with NULL Product: gcc Version: 4.4.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: mse...@gmail.com The -Waddress option causes gcc to emit a warning for suspicious tests of addresses of functions and objects. The patch that implemented the feature and the current test for it indicate that the diagnostic is intended to include the NULL pointer constant. However, gcc fails to diagnose the pointless comparison against NULL in the test case below. http://gcc.gnu.org/ml/gcc-patches/2005-12/msg00972.html http://gcc.gnu.org/viewcvs/trunk/gcc/testsuite/gcc.dg/Walways-true-1.c I note that Wstring-literal-comparison-1.c test exercises the ability to diagnose comparisons of string literals against 0 while at the same time allowing such comparisons against null pointer constant. Perhaps this feature conflicts with the ability to issue warnings for constants of other types. Alternatively, it's possible that the ability to avoid a diagnostic when a null pointer constant is used is deliberate. This is a request to either issue the warning in all cases, or to document the existing behavior so that it can be relied on with some assurance that it will continue to work this way in future versions of gcc. $ cat -n t.c && gcc -Waddress -c t.c 1 #define NULL (void*)0 2 3 int i; 4 5 int f() { return &i != 0; } 6 int g() { return &i != NULL; } t.c: In function ‘f’: t.c:5: warning: the address of ‘i’ will never be NULL
[Bug c/47931] missing -Waddress warning for comparison with NULL
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47931 --- Comment #1 from Martin Sebor 2011-02-28 19:38:15 UTC --- To add a suggested solution to my report: Since many (most?) comparisons will be against NULL which can be defined as either 0 or (void*)0 I think it would be best to diagnose both forms. To make it possible to easily silence the warning I suggest not diagnosing cases of comparison against a null pointer constant of the same type. I.e., like so: int i; if (&i); // warning if (&i == 0); // warning if (&i == (void*)0); // warning if (&i == (int*)0);// NO warning
[Bug c/47932] New: __typeof__ prevents VLA from being evaluated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47932 Summary: __typeof__ prevents VLA from being evaluated Product: gcc Version: 4.4.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: mse...@gmail.com The program below shows that the __typeof__ macro prevents the evaluation of the variable-length array in a context where one would expect it to be evaluated according to the documentation: The operand of typeof is evaluated for its side effects if and only if it is an expression of variably modified type or the name of such a type. $ cat <
[Bug c/59219] New: ____builtin___memcpy_chk and -fno-builtin-memcpy
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59219 Bug ID: 59219 Summary: builtin___memcpy_chk and -fno-builtin-memcpy Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com The __builtin___xxx_chk intrinsics are useful in detecting buffer overflows via the Object Size Checking feature. But in a freestanding/embeeded environment with its own implementation of function xxx (such as memcpy), the __builtin___xxx_chk intrinsics cannot be used even with the -ffreestanding or -fno-builtin option because they result in the inline expansion of the related xxx function irrespective of the option (see the test program below). To get the benefit of Object Size Checking in these environments, it's necessary to hand-code __builtin___xxx_chk instead. It would simplify the adoption of Object Size Checking in these environments if instead of expanding xxx inline when -fno-builtin is specified, GCC emitted a call to xxx. (As a side note, this happens to be the behavior of the Intel compiler.) $ cat v.c && gcc -O2 -c -fno-builtin -std=c11 v.c && objdump -d v.o | sed -n "/:/,/^$/p" typedef __typeof__ (sizeof 0) size_t; extern inline __attribute__ ((always_inline, artificial)) void* memcpy (void* restrict d, const void* restrict s, size_t n) { return __builtin___memcpy_chk (d, s, n, __builtin_object_size (d, 1)); } char b [4]; void foo (const void *p) { memcpy (b, p, sizeof b); } 0010 : 10:8b 07mov(%rdi),%eax 12:89 05 00 00 00 00mov%eax,0(%rip)# 18 18:c3 retq
[Bug c/59220] New: bogus warning: packed attribute is unnecessary on an overaligned char
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59220 Bug ID: 59220 Summary: bogus warning: packed attribute is unnecessary on an overaligned char Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com GCC 4.8.2 and prior incorrectly issue a warning for one-byte struct members declared with the packed attribute when the member is of an over-aligned type. The program below shows that the attribute is not unnecessary (it changes the alignment of the struct member and the whole struct). $ cat v.c && gcc -Wpacked v.c && ./a.out extern int printf (const char*, ...); typedef char C __attribute__ ((aligned (4))); struct S { C c __attribute__ ((packed)); }; int main (void) { struct S s; printf ("%zu %zu %zu\n", __alignof__ (s), __alignof__ (s.c), __alignof__ (C)); return 0; } v.c:6:6: warning: packed attribute is unnecessary for ‘c’ [-Wattributes] C c __attribute__ ((packed)); ^ 1 1 4
[Bug c/59219] ____builtin___memcpy_chk and -fno-builtin-memcpy
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59219 --- Comment #2 from Martin Sebor --- I'm suggesting that when -fno-builtin is used, __builtin___memcpy_chk (and other __bultin_xxx_chk) invocations that are determined not to exceed the size of the buffer boundaries expand to a call to memcpy instead of being expanded inline. Invocations that aren't guaranteed to be safe will continue to expand to calls to __memcpy_chk as they do now (i.e., I'm not suggesting a change there because freestanding implementations can and provide their own implementation of __memcpy_chk). I understand the convention of expanding __builtin_xxx invocations inline regardless of -fno-builtin but this convention makes the __builtin_xxx_chk intrinsics unusable in freestanding environments where the xxx functions have different semantics than those required of hosted implementations (and those assumed by GCC). A simple example where the inline expansion of __builtin___memcpy_chk is undesirable is a freestanding environment with a null-safe memcpy. This example can be dealt with by modifying the extern inline definiton of memcpy to avoid invoking __builtin___memcpy_chk when either of the pointers is null, so that can be easily solved with no compiler change. An example that can't be as easily solved without the proposed change is one involving __builtin___sprintf_chk where the freestanding implementation of sprintf behaves differently than the standard specifies for hosted implementations (and GCC's inline expansion assumes). For instance, the implementation could treat the $ character as the beginning of a formatting directive.
[Bug c/59219] ____builtin___memcpy_chk and -fno-builtin-memcpy
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59219 --- Comment #4 from Martin Sebor --- I understand. The current semantics of __builtin__xxx_chk are to: a) check the constraints of the xxx function at compile time, and b) diagnose constraint violations detected in (a) and call __xxx_chk, or c) expand xxx inline if constraints are satisfied I'm suggesting that it would be useful to change the semantics in (c): c) if constraints are satisfied, then if -fbuiltin is used, expand xxx inline, or d) if -fno-builtin is used, call xxx I.e., reduce the effects of the __builtin__xxx_chk intrinsics to just checking the constraints, and (when -fno-builtin is used) make it possible to customize the implementation within those constraints. This would let freestanding implementations use the __builtin__xxx_chk intrinsics and also provide their own semantics for the xxx functions within the constraints specified by the language. (PS I belatedly realized that my mention of a freestanding sprintf using '$' to introduce a freestanding format directive didn't make sense as it would violate the function's constraint. Please diregard that part.)
[Bug middle-end/17308] nonnull attribute not as useful as it could
--- Comment #5 from msebor at gmail dot com 2010-02-15 20:51 --- I second Ulrich's request. Besides nonnull, this enhancement would be useful in attribute printf as well. For example, in the program below, both calls to printf() have undefined behavior in C99 and should be diagnosed: $ cat t.c && gcc -Wformat -pedantic -std=c99 -O3 t.c int printf(const char*, ...) __attribute__((__nonnull__((1 __attribute__ ((__format__ (__printf__, 1, 2))); int main() { char *s = 0; printf(s, ""); printf("%s", s); } $ -- msebor at gmail dot com changed: What|Removed |Added CC| |msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308
[Bug c++/60063] New: -Wunused-local-typedefs warning despite attribute used in a template
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60063 Bug ID: 60063 Summary: -Wunused-local-typedefs warning despite attribute used in a template Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com GCC 4.8.2 issues the following bogus warning on the defintion of Y in bar despite attribute used. The same definition in an ordinary function emits no warning. $ cat t.cpp && g++ -Wunused-local-typedefs -c -o/dev/null t.cpp template struct S; void foo (int i) { typedef __attribute__ ((used)) S X; } template void bar (T i) { typedef __attribute__ ((used)) S Y; } t.cpp: In function ‘void bar(T)’: t.cpp:9:41: warning: typedef ‘Y’ locally defined but not used [-Wunused-local-typedefs] typedef __attribute__ ((used)) S Y; ^
[Bug c++/60067] New: bogus error default template arguments may not be used in function templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60067 Bug ID: 60067 Summary: bogus error default template arguments may not be used in function templates Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com GCC 4.8.2 issues the bogus error below on the following valid C++ '98 program. Instantiating C (or the whole definition of foo) isn't necessary to trigger the error. $ cat u.cpp && g++ -c -o/dev/null u.cpp template struct A; template struct B { enum { v = 1 }; }; template )> struct C { void f () { void g (int [B::v]); } }; void foo (void) { C().f (); } u.cpp: In member function ‘void C::f()’: u.cpp:7:26: error: default template arguments may not be used in function templates without -std=c++11 or -std=gnu++11 void g (int [B::v]); ^
[Bug c++/60068] New: missing diagnostic on array with negative bounds in template
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60068 Bug ID: 60068 Summary: missing diagnostic on array with negative bounds in template Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com GCC 4.8.2 and all versions prior to it fail to diagnose the following ill-formed C++ '98 program: $ cat u.cpp && g++ -Wall -Wextra -Werror -pedantic -c -o/dev/null u.cpp && echo success template void f (int [N]) { } void g (void) { f<-1>(0); } success
[Bug c++/60063] -Wunused-local-typedefs warning despite attribute used in a template
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60063 --- Comment #1 from Martin Sebor --- I confused attribute used with unused in the test case. With the latter, the warning is not emitted as one would expect. Attribute used isn't documented for types, so it's not completely clear whether the test is valid. Searching through the test suite, I came across Wunused-local-typedefs.c (apparently added for bug 33255) which exercises attribute used with a typedef, albeit in C code, so the test case might be valid after all and the documentation might need updating.
[Bug c/60294] New: missing diagnostic with -Wmaybe-uninitialized
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60294 Bug ID: 60294 Summary: missing diagnostic with -Wmaybe-uninitialized Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com The documentation for the -Wmaybe-uninitialized option includes an example similar to the one below to demonstrate the conditions under which GCC is expected to issue a diagnostic. However, GCC fails to issue the expected diagnostic when the option is used (it does issue it with -Wall, -Wextra, and, contrary to expectations, with -Wuninitialized). $ (set -x && cat t.c && for w in all extra uninitialized maybe-uninitialized; do gcc -O2 -Werror -W$w -c -o/dev/null t.c && echo success; done) + cat t.c void foo (int); void bar (int y) { int x; switch (y) { case 1: x = 1; break; case 2: x = 4; break; case 3: x = 5; } foo (x); } + for w in all extra uninitialized maybe-uninitialized + gcc -O2 -Werror -Wall -c -o/dev/null t.c t.c: In function ‘bar’: t.c:12:9: error: ‘x’ may be used uninitialized in this function [-Werror=maybe-uninitialized] foo (x); ^ cc1: all warnings being treated as errors + for w in all extra uninitialized maybe-uninitialized + gcc -O2 -Werror -Wextra -c -o/dev/null t.c t.c: In function ‘bar’: t.c:12:9: error: ‘x’ may be used uninitialized in this function [-Werror=maybe-uninitialized] foo (x); ^ cc1: all warnings being treated as errors + for w in all extra uninitialized maybe-uninitialized + gcc -O2 -Werror -Wuninitialized -c -o/dev/null t.c t.c: In function ‘bar’: t.c:12:9: error: ‘x’ may be used uninitialized in this function [-Werror=maybe-uninitialized] foo (x); ^ cc1: all warnings being treated as errors + for w in all extra uninitialized maybe-uninitialized + gcc -O2 -Werror -Wmaybe-uninitialized -c -o/dev/null t.c + echo success success
[Bug c/60488] New: missing -Wmaybe-uninitialized on a conditional with goto
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60488 Bug ID: 60488 Summary: missing -Wmaybe-uninitialized on a conditional with goto Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com The -Wmaybe-uninitialized option is documented like so: "For an automatic variable, if there exists a path from the function entry to a use of the variable that is initialized, but there exist some other paths for which the variable is not initialized, the compiler emits a warning if it cannot prove the uninitialized paths are not executed at run time." In the program below, when f(&a) returns zero, the variable b is considered to have been initialized by the call to f(&b) when it's used as the argument in the first call to g(b). However, when f(&a) returns non-zero, the variable b is used uninitialized in the second call to g(b). Therefore, there exists a path through the function where b is used initialized as well as one where it's used uninitialized. Thus, GCC should issue a warning. It, however, does not. $ cat t.c && gcc -O2 -Wuninitialized -Wmaybe-uninitialized -c -o/dev/null t.c int f (int**); void g (int*); int foo (void) { int *a, *b; if (f (&a) || f (&b)) goto end; g (a); g (b); return 0; end: g (b); return 1; }
[Bug c/65029] New: aggregate copy invokes memcpy on overlapping regions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65029 Bug ID: 65029 Summary: aggregate copy invokes memcpy on overlapping regions Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com According to 7.24.2.1 of C11, "If copying takes place between objects that overlap, the behavior [of memcpy] is undefined." The script below shows that GCC generates code with undefined behavior for a strictly conforming C11 program (the code is the same with -fno-builtin-memcpy or -ffreestanding). This was brought to light by the valgrind error (also shown). $ cat t.c && gcc -DMEMCPY -DN=65 -O2 -Wall -std=c11 t.c && ./a.out || gcc -DN=65 -O2 -Wall -std=c11 t.c && valgrind ./a.out #include #include struct S { char c [N]; }; void __attribute__ ((weak)) foo (struct S *a, struct S *b) { *a = *b; } #if MEMCPY void* memcpy (void* restrict d, const void* restrict s, size_t n) { typedef unsigned char UChar; UChar *pd; const UChar *ps; assert (d != s); for (pd = (UChar*)d, ps = (const UChar*)s; n--; ++pd, ++ps) *pd = *ps; return d; } #endif int main (void) { struct S s = { { 0 } }; foo (&s, &s); return 0; } a.out: t.c:22: memcpy: Assertion `d != s' failed. Aborted ==62960== Memcheck, a memory error detector ==62960== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==62960== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==62960== Command: ./a.out ==62960== ==62960== Source and destination overlap in memcpy(0xfff00eb30, 0xfff00eb30, 65) ==62960==at 0x408C908: memcpy (in /usr/lib64/valgrind/vgpreload_memcheck-ppc64be-linux.so) ==62960==by 0x1643: foo (in /home/remote/msebor/tmp/a.out) ==62960==by 0x1433: main (in /home/remote/msebor/tmp/a.out) ==62960== ==62960== ==62960== HEAP SUMMARY: ==62960== in use at exit: 0 bytes in 0 blocks ==62960== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==62960== ==62960== All heap blocks were freed -- no leaks are possible ==62960== ==62960== For counts of detected and suppressed errors, rerun with: -v ==62960== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[Bug libstdc++/65113] New: string::copy violates traits requirements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65113 Bug ID: 65113 Summary: string::copy violates traits requirements Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com libstdc++ string goes to quite a bit of trouble to avoid self-modifying calls that could potentially corrupt the controlled sequence but there is at least one case that has escaped this treatment. The test case below shows that basic_string::copy(char*, size_t) calls char_traits::copy with arguments that violate the preconditions on the function. That function in turn calls memcpy with arguments that violate its own constraints. I suspect that this use case may not have been intended when string was designed. It might be perhaps be worth checking with the LWG to see if basic_string::copy should require the argument to be distinct from the object on which it's called. $ cat t.cpp && for dbg in -DNDEBUG ""; do g++ $dbg -Wall t.cpp && ./a.out && valgrind ./a.out; done #include #include template struct Traits: std::char_traits { static char* copy (CharT *d, const CharT *s, size_t n) { assert (d < s || s + n < d); return std::char_traits::copy (d, s, n); } }; template void f (const CharT *a, size_t len) { typedef std::basic_string String; String str (a, len); CharT* const s = &str [2]; const typename String::size_type n = str.size () - 2; str.copy (s, n, 0); } int main () { const char S[] = "0123456789"; f >(S, sizeof S - 1); } ==14329== Memcheck, a memory error detector ==14329== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==14329== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==14329== Command: ./a.out ==14329== ==14329== Source and destination overlap in memcpy(0x5a2005a, 0x5a20058, 8) ==14329==at 0x4C2E13D: memcpy@@GLIBC_2.14 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==14329==by 0x400DBD: std::char_traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==14329==by 0x401407: Traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==14329==by 0x4012A6: std::basic_string, std::allocator >::_M_copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==14329==by 0x40105B: std::basic_string, std::allocator >::copy(char*, unsigned long, unsigned long) const (in /home/msebor/tmp/a.out) ==14329==by 0x400E54: void f >(char const*, unsigned long) (in /home/msebor/tmp/a.out) ==14329==by 0x400D3D: main (in /home/msebor/tmp/a.out) ==14329== ==14329== ==14329== HEAP SUMMARY: ==14329== in use at exit: 0 bytes in 0 blocks ==14329== total heap usage: 1 allocs, 1 frees, 35 bytes allocated ==14329== ==14329== All heap blocks were freed -- no leaks are possible ==14329== ==14329== For counts of detected and suppressed errors, rerun with: -v ==14329== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) a.out: t.cpp:7: static char* Traits::copy(CharT*, const CharT*, size_t) [with CharT = char; size_t = long unsigned int]: Assertion `d < s || s + n < d' failed. Aborted (core dumped)
[Bug libstdc++/65114] New: char_traits::copy violates memcpy constraints, own postcondition
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65114 Bug ID: 65114 Summary: char_traits::copy violates memcpy constraints, own postcondition Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com The precondition on char_traits::copy(s, p, n), namely that p not be in the range [s, s + n), is weaker than the precondition on a call to memcpy(s, p, n). The latter requires that none of the characters accessed via s is also accessed via p. The program below shows an example of a call to char_traits::copy that satisfies the C++ precondition but violates the C precondition (as indicated by the Valgrind error). The element a[1] is accessed by both s and p. As a result, the program also fails the C++ postcondition. $ cat t.cpp && g++ -Wall t.cpp && valgrind ./a.out #include #include #include struct Traits: std::char_traits { static char* copy (char *s, const char *p, size_t n) { assert (p < s || s + n < p); return std::char_traits::copy (s, p, n); } }; int main () { char a[] = "abc"; const size_t n = 2; const char *p = a; char *s = a + 1; for (size_t i = 0; i != n; ++i) Traits::assign (s[i], p[i]); char b[] = "abc"; p = b; s = b + 1; Traits::copy (s, p, n); printf ("%s == %s\n", a, b); assert (0 == Traits::compare (a, b, sizeof a)); } ==15497== Memcheck, a memory error detector ==15497== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==15497== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==15497== Command: ./a.out ==15497== ==15497== Source and destination overlap in memcpy(0xffefffe41, 0xffefffe40, 2) ==15497==at 0x4C2E13D: memcpy@@GLIBC_2.14 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==15497==by 0x400859: std::char_traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==15497==by 0x4008BA: Traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==15497==by 0x40078A: main (in /home/msebor/tmp/a.out) ==15497== aaa == aab a.out: t.cpp:30: int main(): Assertion `0 == Traits::compare (a, b, sizeof a)' failed. ==15497== ==15497== HEAP SUMMARY: ==15497== in use at exit: 0 bytes in 0 blocks ==15497== total heap usage: 2 allocs, 2 frees, 188 bytes allocated ==15497== ==15497== All heap blocks were freed -- no leaks are possible ==15497== ==15497== For counts of detected and suppressed errors, rerun with: -v ==15497== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Aborted (core dumped)
[Bug target/65109] [5 Regression] r220674 causes FAIL: gcc.target/powerpc/ppc64-abi-1.c execution test
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65109 --- Comment #4 from Martin Sebor --- There's the following comment in the test: /* Testcase could break on future gcc's, if parameter regs are changed before this asm. */ Moving the locals out of the function lets the test pass. The attached patch eliminates the local copy of the volatile reg_parms_t struct as well as the sp pointer and moves the remaining locals out of all the test functions to minimize the risk of the volatile registers getting clobbered before they are saved.
[Bug target/65109] [5 Regression] r220674 causes FAIL: gcc.target/powerpc/ppc64-abi-1.c execution test
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65109 --- Comment #5 from Martin Sebor --- Created attachment 34809 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34809&action=edit Test patch to let it pass.
[Bug c++/61882] New: attribute weak ignored for function templates
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61882 Bug ID: 61882 Summary: attribute weak ignored for function templates Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com In GCC 4.5 and later, and at -O and above, attribute weak (but not weak alias) is silently ignored on declarations of function templates and calls to specializations of such templates are inlined into their callers. The program below shows that GCC inlines calls to the function template specialization instantiated from the weak primary template baz, but emits a weak symbol for the weak alias foo. GCC 4.2 honored the attribute and emitted a weak symbol for both foo and baz. Clang 3.4 also emits a weak symbol for both as expected. Disabling optimization changes the current behavior to match that of GCC 4.2.1 and Clang 3.4. The GCC documentation of attribute weak doesn't say whether or not the attribute is intended to have the same effect on specializations of function templates as it does on ordinary functions. If the current GCC behavior is intended, the documentation should be updated to make it clear when attribute weak is ignored, and GCC should be enhanced to issue a warning when the attribute is ignored. $ (set -x; cc=/auto/compiler-dev/msebor/contrib/cel-5.50/bin/g++; cat z.c && $cc -c -fpic -DFOO=1 -O -Wall -Wextra z.c && $cc -fpic -Wall -Wextra z.c z.o && ./a.out) + cc=/auto/compiler-dev/msebor/contrib/cel-5.50/bin/g++ + cat z.c template void foo (T); template void baz (T); void foobar (); #if FOO template void __attribute__ ((weak, alias ("bar"))) foo (T); static void bar (int) { } template void __attribute__ ((weak)) baz (T) { } void foobar () { foo (0), baz (0); } #else # include template <> void foo (int) { puts (__func__); } template <> void baz (int) { puts (__func__); } int main (void) { foobar (); } #endif + /auto/compiler-dev/msebor/contrib/cel-5.50/bin/g++ -c -fpic -DFOO=1 -O -Wall -Wextra z.c + /auto/compiler-dev/msebor/contrib/cel-5.50/bin/g++ -fpic -Wall -Wextra z.c z.o + ./a.out foo
[Bug c/48985] New: bogus buffer overflow warning and abort on static flexible array member
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48985 Summary: bogus buffer overflow warning and abort on static flexible array member Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: mse...@gmail.com GCC emits a bogus warning on the program below which then aborts at runtime. Note that when the strncpy (s.c, "012", 4) call in line 24 is removed GCC doesn't emit a warning but the program still aborts even though there is no buffer overflow. For statically allocated flexible array members I would expect __builtin_object_size() to report the actual size of the array rather than zero, analogously to the case when the array is allocated dynamically. $ cat z.c && gcc -D_FORTIFY_SOURCE -O2 z.c && ./a.out #include #include #include struct s { int i; char c[]; } s = { 1, "01234" }; size_t f (void) { return __builtin_object_size(&s.c, 0); } size_t g (struct s *p) { return __builtin_object_size(p->c, 0); } int main (void) { struct s *p; p = (struct s*)malloc (sizeof *p + 6); printf ("%zu %zu\n", f (), g (p)); fflush (stdout); strncpy (p->c, "012", strlen(s.c)); if (puts ("###")) strncpy (s.c, "012", 4); /* line 24 */ strncpy (s.c, "012", strlen(s.c) + 1); return 0; } In file included from /usr/include/string.h:642:0, from z.c:3: In function ‘strncpy’, inlined from ‘main’ at z.c:24:17: /usr/include/bits/string3.h:121:3: warning: call to __builtin___strncpy_chk will always overflow destination buffer [enabled by default] 0 6 ### *** buffer overflow detected ***: ./a.out terminated ... Aborted (core dumped)
[Bug c++/44486] New: missing space in __PRETTY_FUNCTION__ expansion in anonymous namespace
The "S::f()" text reads as though S were a template. I suspect the text is simply missing a space between the S and but I wonder if the bit could actually be replaced by something less ambiguous in C++ (such as /* unnamed */ or perhaps better still, /* anonymous */). Btw., since glibc uses __PRETTY_FUNCTION__ in its definition of the assert() macro this shows up in quite a bit of output. $ cat t.cpp && g++ -dumpversion && g++ t.cpp && ./a.out #include struct S { }; namespace { S f() { std::puts(__PRETTY_FUNCTION__); return S(); } } int main() { f(); } 4.4.3 S::f() -- Summary: missing space in __PRETTY_FUNCTION__ expansion in anonymous namespace Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44486
[Bug c++/44648] New: missing -Wunused warning on a const variable in if statement
gcc warns about the unused variable on line 3 below but not for the one on line 8. I would expect to see a warning in both cases. $ cat -n z.cpp && g++ -O2 -Wunused z.cpp 1 int main() 2 { 3 if (bool b = 1) 4 return 0; 5 else 6 return 1; 7 8 if (const bool b = 1) 9 return 0; 10 else 11 return 1; 12 } z.cpp: In function int main(): z.cpp:3: warning: unused variable b -- Summary: missing -Wunused warning on a const variable in if statement Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: msebor at gmail dot com GCC build triplet: all GCC host triplet: all GCC target triplet: all http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44648
[Bug c/41138] Inconsistent (incorrect?) "overflow in implicit constant conversion" warning
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41138 Martin Sebor changed: What|Removed |Added CC||msebor at gmail dot com --- Comment #2 from Martin Sebor 2011-06-09 23:03:38 UTC --- I think this is a bug since there can be no overflow (or slicing) here. Here's my reasoning. According to 6.5.16.2 Compound assignment of C99: A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once. and 6.5.16.1 Simple assignment: In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand. and finally 6.5.16 Assignment operators: The type of an assignment expression is the type of the left operand... So all cases are equivalent to foo = foo & 65280; The result of the expression (foo & 65280) is an int (or unsigned int, long, unsigned long, depending on the suffix of the constant) which is converted to char (the type of the assignment expression). In all cases in the first test case, the value of the result is guaranteed to be representable in unsigned char. There is no overflow or slicing and the code is strictly conforming with safe semantics. That said, a warning stating that foo &= 65280 always evaluates to zero might be useful in case the intent wasn't to clear the variable (otherwise the code could be rewritten as foo = 0).
[Bug c/41138] Inconsistent (incorrect?) "overflow in implicit constant conversion" warning
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41138 --- Comment #3 from Martin Sebor 2011-06-10 17:44:47 UTC --- Here's another test case, one that does involve slicing and where a consistent but differently phrased warning would, IMO, be useful. Perhaps something like: warning: slicing high order bits in implicit constant conversion cat << EOF | gcc -c -xc - struct S { unsigned a:1; unsigned b:1; }; void f (struct S *s, int i) { s->a = i & 0x10; /* line 7: no warning */ s->b = i & 0x80; /* line 8: warning */ } EOF : In function ‘f’: :8:5: warning: overflow in implicit constant conversion [-Woverflow]
[Bug c/49535] New: __builtin_object_size incorrect for array arguments
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49535 Summary: __builtin_object_size incorrect for array arguments Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: mse...@gmail.com When compiled with gcc 4.4 and 4.5 (at -O1 or above) the program below prints the following output: 800 800 800 800 800 800 800 800 800 800 800 800 800 800 800 800 When compiled with 4.6 (regardless of the -O setting) it prints this instead: 800 800 800 800 18446744073709551615 18446744073709551615 0 0 18446744073709551615 18446744073709551615 0 0 18446744073709551615 18446744073709551615 0 0 I believe the first output is expected and the second is wrong. extern int printf (const char* fmt, ...); #define BOS(a) \ printf ("%zu %zu %zu %zu\n", \ __builtin_object_size (a, 0), \ __builtin_object_size (a, 1), \ __builtin_object_size (a, 2), \ __builtin_object_size (a, 3)) inline void f0 (int *a) { BOS (a); } inline void f1 (int a[20]) { BOS (a); } inline void f2 (int a[10][20]) { BOS (a); } int main (void) { int a[10][20]; BOS (a); f0 (a[0]); f1 (a[0]); f2 (a); }