[Bug c++/27141] New: Unexpected requirement for usual deallocation function
This code: struct D { D() {} virtual ~D() {} void operator delete(void*, void*) {} }; void f() { D d(); } is rejected with "no suitable 'operator delete' for 'D'". It is true that the placement deallocation function hides any "usual" one, but surely it is only necessary for a usual one to be found when implementing a delete-expression, as described in 12.5#4. This code is accepted by Comeau and HP aC++ (but faulted by Sun C++ with a similar error to g++). -- Summary: Unexpected requirement for usual deallocation function Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27141
[Bug c++/27141] [4.0/4.1/4.2 Regression] Unexpected requirement for usual deallocation function
--- Comment #2 from algrant at acm dot org 2006-05-02 07:20 --- Actually, I now wonder if the g++ 4.1 behavior would be correct by the proposed resolution of (still open) Core Language Issue 252. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27141
[Bug c/38397] New: gcc -E -dD changes the meaning of source
compile with -E -dD: enum { A, B }; #define B A #define A B+1 int x = A; This will print something like enum { A, B }; #define B A #define A B+1 int x = A+1; This defines x as 2 instead of 1. Recycle the output bad in and x gets bigger and bigger. Although it doesn't seem to be formally defined that the output of -E -dD is valid source code equivalent to the original, the output is presented as if it is. There are at least two solutions: - present the #define and #undef as comments - suppress macro expansion when -dD is used The ability to suppress macro expansion is a useful feature in its own right and could make some sources more readable, when the intention of -E is simply to flatten the input. -- Summary: gcc -E -dD changes the meaning of source Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38397
[Bug c++/21025] New: ICE on template
3.4.3 seg faults on this: template struct X { char x[N]; }; template X<1 + sizeof(T) - sizeof(T)> F(T const &); template struct S { int d() { F(1); } }; Appears to be quite dependent on the fact that the template argument involves "sizeof(T) - sizeof(T)" - if the - is changed to a +, it works. Ok in 3.3.2, and ok if S is not a template. -- Summary: ICE on template Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21025
[Bug c++/37697] New: dynamic_cast to void cv* wrongly allowed with -fno-rtti
Compiled -fno-rtti, g2 and g3 are faulted but g1 is not. Code for g1 (on ARM target) shows use of RTTI which we have asserted is absent. struct B1 { virtual int f(); }; struct B2 { virtual int g(); }; struct D: B1, B2 { }; /* These should be allowed even with -fno-rtti */ B1 *f2(B1 *p) { return dynamic_cast(p); } B1 *f3(D *p) { return dynamic_cast(p); } /* These should not be allowed with -fno-rtti */ /* gABI 2.9.4 case #1: dynamic cast, which returns a pointer to the complete lvalue */ void *g1(B1 *p) { return dynamic_cast(p); } /* gABI 2.9.4 case #2: dynamic cast operation from a proper base class to a derived clasB1 */ D *g2(B1 *p) { return dynamic_cast(p); } /* gABI 2.9.4 case #3: dynamic_cast across the hierarchy which can be seen as a cast to the complete lvalue and back to a sibling base */ B1 *g3(B2 *p) { return dynamic_cast(p); } -- Summary: dynamic_cast to void cv* wrongly allowed with -fno-rtti Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org GCC target triplet: ARM http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37697
[Bug c++/37701] New: dynamic_cast to void cv* wrongly allowed with -fno-rtti
Compiled -fno-rtti, g2 and g3 are faulted but g1 is not. Code for g1 (on ARM target) shows use of RTTI which we have asserted is absent. struct B1 { virtual int f(); }; struct B2 { virtual int g(); }; struct D: B1, B2 { }; /* These should be allowed even with -fno-rtti */ B1 *f2(B1 *p) { return dynamic_cast(p); } B1 *f3(D *p) { return dynamic_cast(p); } /* These should not be allowed with -fno-rtti */ /* gABI 2.9.4 case #1: dynamic cast, which returns a pointer to the complete lvalue */ void *g1(B1 *p) { return dynamic_cast(p); } /* gABI 2.9.4 case #2: dynamic cast operation from a proper base class to a derived clasB1 */ D *g2(B1 *p) { return dynamic_cast(p); } /* gABI 2.9.4 case #3: dynamic_cast across the hierarchy which can be seen as a cast to the complete lvalue and back to a sibling base */ B1 *g3(B2 *p) { return dynamic_cast(p); } -- Summary: dynamic_cast to void cv* wrongly allowed with -fno-rtti Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org GCC target triplet: ARM http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37701
[Bug c++/37697] dynamic_cast to void cv* wrongly allowed with -fno-rtti
--- Comment #1 from algrant at acm dot org 2008-10-01 15:35 --- *** Bug 37701 has been marked as a duplicate of this bug. *** -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37697
[Bug c++/37701] dynamic_cast to void cv* wrongly allowed with -fno-rtti
--- Comment #1 from algrant at acm dot org 2008-10-01 15:35 --- *** This bug has been marked as a duplicate of 37697 *** -- algrant at acm dot org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||DUPLICATE http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37701
[Bug c++/37697] dynamic_cast to void cv* wrongly allowed with -fno-rtti
--- Comment #2 from algrant at acm dot org 2008-10-01 16:40 --- Bug report in error. -- algrant at acm dot org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37697
[Bug c/39383] New: sizeof object with zero-length array ignores initializer
Example from docs: struct f1 { int x; int y[]; } f1 = { 1, { 2, 3, 4 } }; Currently sizeof(f1) == sizeof(int) rather than 4*sizeof(int), i.e. sizeof the object is determined by the type only, not the actual object size taking into account its initializer. If this is intentional the docs could benefit from clarification, as otherwise it's natural to want to use sizeof to find out how big the object actually ended up as. -- Summary: sizeof object with zero-length array ignores initializer Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39383
[Bug c/39383] sizeof object with zero-length array ignores initializer
--- Comment #2 from algrant at acm dot org 2009-03-05 13:19 --- No, the case is an extension to C. 6.5.3.4 was obviously written without this case in mind. In this case "the size... of its operand" cannot be "determined from the type". Either sizeof doesn't return the (real) size of the operand, or it isn't determined from the type. Current GCC behavior is to have it not return the size of the operand. That's a valid point of view but it does mean one needs to take care when using sizeof on such objects, and it's worth documenting. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39383
[Bug c/39384] New: sizeof object with zero-length array ignores initializer
Example from docs: struct f1 { int x; int y[]; } f1 = { 1, { 2, 3, 4 } }; Currently sizeof(f1) == sizeof(int) rather than 4*sizeof(int), i.e. sizeof the object is determined by the type only, not the actual object size taking into account its initializer. If this is intentional the docs could benefit from clarification, as otherwise it's natural to want to use sizeof to find out how big the object actually ended up as. -- Summary: sizeof object with zero-length array ignores initializer Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39384
[Bug c/39384] sizeof object with zero-length array ignores initializer
--- Comment #1 from algrant at acm dot org 2009-03-05 14:48 --- Unwanted duplicate entry of 39383 caused by refreshing browser page. *** This bug has been marked as a duplicate of 39383 *** -- algrant at acm dot org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||DUPLICATE http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39384
[Bug c/39383] sizeof object with zero-length array ignores initializer
--- Comment #5 from algrant at acm dot org 2009-03-05 14:48 --- *** Bug 39384 has been marked as a duplicate of this bug. *** -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39383
[Bug c/39383] sizeof object with zero-length array ignores initializer
--- Comment #6 from algrant at acm dot org 2009-03-06 14:44 --- Right. The existence of a statically initialized object whose size can be determined at compile-time to be larger than the (notional) type size, is specific to GCC. Here's another thing: the assembler output shows .type f1, %object .size f1, 4 f1: .word 1 .word 2 .word 3 .word 4 Whatever you think about sizeof(), surely the object's symbol should have its true size (16 in this case)? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39383
[Bug c++/39415] New: static_cast used as downcast can silently lose const
This is silently accepted: struct T { }; struct T_impl: public T { }; T_impl *g(T *tp) { return static_cast(tp); } The result type of the static_cast is pointer-to-const and should not convert to a pointer-to-non-const. This seems to be specific to when it is used as a downcast. Replacing the last line with T *g(T *tp) { return static_cast(tp); } is faulted as expected. -- Summary: static_cast used as downcast can silently lose const Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39415
[Bug c/39430] New: GCC does not put 'const auto' structure on the stack
This code creates an 'activation record' structure for each active call to the function: struct frame { char const *name; int line; }; extern void trace(struct frame const *); int f(int n) { const struct frame v = { __FUNCTION__, __LINE__ }; trace(&v); return n ? n*f(n-1) : 1; } These should be distinct, i.e. their addresses are distinct to any observer. But GCC evaluates &v to refer to one instance in static storage. Surely the standard doesn't allow an implementation to do this. It doesn't happen if 'v' is not marked 'const'. -- Summary: GCC does not put 'const auto' structure on the stack Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39430
[Bug c/39488] ARM ABI: enum comparison against zero optimized away
--- Comment #2 from algrant at acm dot org 2009-03-18 09:45 --- No, the enum is signed, see AAPCS 7.1.3: "the container type is int unless the upper bound is greater than 2147483647". -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39488
[Bug c/39488] New: ARM ABI: enum comparison against zero optimized away
With ARM ABI variant selected by -fno-short-enums the compare shouldn't be optimized away: enum RC { X, Y, Z }; int check_error(enum RC a) { return a < 0; } C 6.3#2 guarantees that any value of the compatible type can be assigned to and from values of the enumerator type "with no change to the value or the representation". So if the implementation defines the compatible type to be a signed type (which ARM ABI -fno-short-enums does in this case, see AAPCS 7.1.3), objects of the enumerator type can validly have negative values and the test is not redundant. (Of course, a strictly conforming program cannot rely on this or any other property of the ABI.) (Aside: this optimization is valid for C++, following 7.2#6.) -- Summary: ARM ABI: enum comparison against zero optimized away Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org GCC target triplet: arm-none-eabi-gcc http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39488
[Bug target/59448] New: ARM code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 Bug ID: 59448 Summary: ARM code generation doesn't respect C11 address-dependency Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: algrant at acm dot org int f2(int const *p, int const *q) { int flag = *p; return flag ? *(q + flag - flag) : 0; } The evaluation *(q + flag - flag) is ordered after *p by 5.1.2.4#14; writing it this way is a recognized way of forcing the ordering. AArch64 GCC 4.8 -O2 --std=c11 generates f2: ldr w2, [x0] mov w0, 0 cbz w2, .L2 ldr w0, [x1] .L2 which doesn't preserve the ordering in the target memory model. The compiler needs to introduce an address dependency, e.g. and w2, w2, #0 ldr w0, [x1, w2] or insert a memory barrier instruction. According to the target architecture's own rules, this is sufficient to order the loads. In general, the C source-level address dependency (defined by the syntactic rules of 5.1.2.4#14) might not involve arithmetic. For example: inline int makedep(int flag, ...) { return flag; } // variadic int f3(int const *p, int const *q) { int flag = *p; return flag ? makedep(*q, flag) : 0; } An access might even be formally dependent on multiple expressions. The compiler just has to keep track.
[Bug c/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #2 from algrant at acm dot org --- Just realised that that last example is bogus, it should read: inline int const *makedep(int const *a, ...) { return a; } // variadic int f3(int const *p, int const *q) { int flag = *p; return flag ? *makedep(q, flag) : 0; } In C++, makedep could be a template - the counterpart of kill_dependency.
[Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #4 from algrant at acm dot org --- So using g++, #include int f1(std::atomic const *p, std::atomic const *q) { int flag = p->load(std::memory_order_consume); return flag ? (q + flag - flag)->load(std::memory_order_relaxed) : 0; } demonstrates the same lack of ordering. You suggest that this might be a problem with the atomic built-ins - and yes, if this had been a load-acquire, it would be a problem with the built-in not introducing a barrier or using a load-acquire instruction. But for a load-consume on this architecture, no barrier is necessary to separate the load-consume from a load that is address-dependent on it. The programmer wrote a dependency but the compiler lost track of it. It's not necessary to demonstrate failure - there's an architectural race condition here. Even if it doesn't fail now there's no guarantee it will never fail on future more aggressively reordering cores.
[Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #6 from algrant at acm dot org --- Here is a complete C++11 test case. The code generated for the two loads in thread B doesn't maintain the required ordering: ... ldrbw1, [x0] uxtbw1, w1 adrpx0, .LANCHOR0 ldr w2, [x3] ... According to the architecture specification, to achieve the ordering it's sufficient to use the result of the first load in the calculation of the address of the second, even if it's done in such a way as to have no dependence on the value. /* Reproducer for 59448: compile with -std=c++11 -lpthread */ #include #include #include #include static std::atomic flag(0); static int data; /* Thread A tries to release a data value 1 to thread B via a release/consume sequence. In the demonstration, this is tried repeatedly. The iterations of the two threads are synchronized via a release/acquire sequence from B to A. This is not relevant to the ordering problem. */ void threadA(void) { for (;;) { data = 1; // A.A flag.store(1, std::memory_order_release); // A.B /* By 1.9#14, A.A is sequenced before A.B */ /* Now wait for thread B to accept the data. */ while (flag.load(std::memory_order_acquire) == 1); assert(data == 0); } } void threadB(void) { for (;;) { int f, d; do { f = flag.load(std::memory_order_consume); // B.A d = *(&data + f - f); // B.B /* By 1.10#9, B.A carries a dependency to B.B */ /* By 1.10#10, A.B is dependency-ordered before B.B */ /* By 1.10#11, A.A intra-thread happens before B.B */ /* By 1.10#12, A.A happens before B.B */ /* By 1.10#13, A.A is a visible side-effect with respect to B.B and the value determined by B.B shall be the value (1) stored by A.A. */ } while (!f); assert(d == 1); /* Release thread A to start another iteration. */ data = 0; flag.store(0, std::memory_order_release); } } int main(void) { std::thread a(&threadA); std::thread b(&threadB); a.join(); b.join(); return 0; }
[Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #8 from algrant at acm dot org --- I don't see how f can not be 0 or 1 here, but to make this even more clear that there is no UB, define flag this way: static std::atomic flag(0); and calculate the address this way: d = *(&data + (f - f)); // B.B The ordering requirements are the same, and there is no possibility of UB.
[Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #11 from algrant at acm dot org --- Where do you get that this is racy if the access to data is not atomic? By design, release/acquire and release/consume sequences don't require wholesale changes to the way the data payload (in the general case, multiple fields within a structure) is first constructed and then used. 1.10#13 makes clear that as a result of the intra-thread sequencing between atomic and non-atomic operations (1.9#14), and the inter-thread ordering between atomic operations (1.10 various), there is a resulting ordering on operations to "ordinary" (sic) objects. Please see the references to the C++ standard in the source example, for the chain of reasoning here.
[Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448 --- Comment #13 from algrant at acm dot org --- I see what you mean - there is a race if threadB reads the data when the flag is not set, i.e. in the case when the read value is never used. Moving the read of data after the test (as in the fragment in comment 4) would fix the race.
[Bug c++/36685] New: clarify/diagnose use of weak constant
Consider this: __attribute__((weak)) extern int const K = 7; int f(void) { return K; } int a[K]; Assuming the combination of 'weak' and 'const' is legitimate (and it seems useful enough to allow), the compiler should avoid the constant-promotion optimization when generating f(), and should fault a[]. -- Summary: clarify/diagnose use of weak constant Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685
[Bug c++/36685] clarify/diagnose use of weak constant
--- Comment #1 from algrant at acm dot org 2008-07-01 10:21 --- Similar argument applies to __attribute__((visibility("default"))) . -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36685
[Bug c/26841] New: extern inline fails to create external definition in C99 mode
In C99 this extern inline int f(int n) { return n + 1; } does not meet the criteria in 6.7.4#6 for 'inline definition' and is therefore an external definition. gcc -std=c99 fails to emit an external definition, though it does for the separate definition/declaration case in the 6.7.4#7 example. -- Summary: extern inline fails to create external definition in C99 mode Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: algrant at acm dot org GCC build triplet: -std=c99 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26841