[Bug c++/48920] typename specifier should not ignore non-type names
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920 --- Comment #6 from Johannes Schaub --- Well then you can replace the class with a nameepace, I think, to remove the class-scope complication. I think GCC would still incorrectly apply typename lookup.
[Bug c++/71425] GCC does not implement C++/WG21 DR 1399/1388
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71425 --- Comment #1 from Johannes Schaub --- (This bug report is due to https://stackoverflow.com/questions/37645347/clang-does-not-infer-template-argument-in-variadic-template-function-with-vararg)
[Bug c++/71425] New: GCC does not implement C++/WG21 DR 1399/1388
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71425 Bug ID: 71425 Summary: GCC does not implement C++/WG21 DR 1399/1388 Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: schaub.johannes at googlemail dot com Target Milestone: --- The following testcase should fail to compile because Args is not deduced (stays empty), but surprisingly, GCC accept it #include template T method(std::tuple, Args..., T, ...) { return T(); } int main() { method(std::make_tuple<int, float, double>(1, 1.0f, 1.0), 1, 1.0f, 1.0, 1); } Here, "Args..." in the "tuple" cannot be deduced because DR1388 says that "Args" is never deduced, because it appears in a non-deduced context in the second function parameter. GCC however seems to deduce it by the tuple<...>, and then expands its value into the second function parameter. However, as Jason notes in DR1399, this is not sensible at all. T will have been deduced by the first "1", rather than by the last "1". GCC will happily accept the code if the last "1" is changed to "1.0", with T staying "int".
[Bug c++/71377] SFINAE expression compiles, but it should not because of 14.5.5p8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71377 Johannes Schaub changed: What|Removed |Added CC||schaub.johannes@googlemail. ||com --- Comment #1 from Johannes Schaub --- GCC should also diagnose the use of `S` at instantiation time, right? `S<2, 1>` is always going to be ill-formed, given that the type of the third argument is ill-formed for N=M+1=2. This is not SFINAE.
[Bug c++/71007] Divergence between treatment of char[0] between OR (=> SFINAE failure) and diagnostic printing (no failure)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71007 --- Comment #1 from Johannes Schaub --- Sorry, forgot to actually add the code of the reduced testcase: template void f(char(&)[N]) { } int main() { char x[1]; f(x); }
[Bug c++/71007] New: Divergence between treatment of char[0] between OR (=> SFINAE failure) and diagnostic printing (no failure)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71007 Bug ID: 71007 Summary: Divergence between treatment of char[0] between OR (=> SFINAE failure) and diagnostic printing (no failure) Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: schaub.johannes at googlemail dot com Target Milestone: --- The following is supposed to tell the user that char[0] is an invalid type, during diagnostic printing. But instead, it infinitely recurses up to SIZE_MAX or something during printing the diagnostic message, eventually crashing #include #include template auto ignore_n(std::integer_sequence<T, I...>) { return std::make_tuple((I, std::ignore)...); } template auto function(Ts... ts) -> decltype((std::tuple_cat( ignore_n(std::make_index_sequence<sizeof(char[int(sizeof...(Ts))-1])-1> ()), std::tuple<double, bool>()) = std::forward_as_tuple(ts...)), void()) { } int main() { function(2); function(1, 2, 3); } Reduced test-case. Here it prints nothing when detailing on why "function" is not callable: main.cpp: In function 'int main()': main.cpp:9:7: error: no matching function for call to 'f(char [1])' f(x); ^ main.cpp:4:6: note: candidate: template void f(char (&)[N]) void f(char(&)[N]) ^ main.cpp:4:6: note: template argument deduction/substitution failed:
[Bug c++/70241] New: Enumerators introduced out-of-line by extending an opaque enum definition always get private accessibility
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70241 Bug ID: 70241 Summary: Enumerators introduced out-of-line by extending an opaque enum definition always get private accessibility Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: schaub.johannes at googlemail dot com Target Milestone: --- The following fails to compile. This is a big show-stopper for this feature // -std=c++11 class A { public: enum B : int; }; enum A::B : int { x }; int main() { A::x; } Expected output: nothing, but compile Actual output: main.cpp: In function 'int main()': main.cpp:7:4: error: 'A::B x' is private x, y ^ main.cpp:11:7: error: within this context A::x; ^
[Bug c++/68386] error: invalid initialization of reference of type 'void (&&)()' from expression of type 'void()'
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68386 Johannes Schaub changed: What|Removed |Added CC||schaub.johannes@googlemail. ||com --- Comment #1 from Johannes Schaub --- This can be further reduced to struct A { static void mf() { } }; int main() { A a; void ()() = a.mf; // error }
[Bug c++/68313] "using" shadows declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68313 Johannes Schaub changed: What|Removed |Added CC||schaub.johannes@googlemail. ||com --- Comment #1 from Johannes Schaub --- If instead of namespaces you would have used a class, and class N1 would be a baseclass of N2, your code would be ill-formed to the letter of the Standard: "A non-template member function ([dcl.fct]) with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied." What happens if you use unqualified names, i.e. if you declare the explicit instantiation directly in namespace N2. And what happens if you use a "<>" to try and explicitly refer to the template? Just as a question of interest.
[Bug libstdc++/35763] std::cout loses whole blocks of output if interrupted by signal without SA_RESTART
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35763 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes@googlemail. ||com --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com --- Created attachment 31309 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=31309action=edit Reproduction of badbit
[Bug libstdc++/35763] std::cout loses whole blocks of output if interrupted by signal without SA_RESTART
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35763 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com --- We also have this bug and it took us several days to find the cause. Testcase by my colleague attached. Perhaps this should fire an assertion if it is hard to fix efficiently, instead of simply letting things go wrong unnoticed.
[Bug c++/36587] Feature: add warning for constructor call with discarded return.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36587 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes@googlemail. ||com --- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com --- (In reply to Jonathan Wakely from comment #3) This would have prevented bugs I've dealt with where critical sections where not protected: { lock_guard (mutex); // mutex NOT locked here! } Jonathan, unfortunately that code won't create and discard a temporary object, so I am not sure whether this patch would have caught the mistake of creating a default constructed lock_guard (whatever that means).
[Bug c++/56190] New: GCC fails deducing a void(*)(int, float, double) to a void(*)(T..., float, double) with T={int}
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56190 Bug #: 56190 Summary: GCC fails deducing a void(*)(int, float, double) to a void(*)(T..., float, double) with T={int} Classification: Unclassified Product: gcc Version: 4.7.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com From http://stackoverflow.com/questions/14664589/variadic-template-code-compiles-on-gcc-4-6-but-not-on-clang-or-gcc-4-7 : class Test { public: template class... A2 void print (void(*function)(A2..., float, double)) { } }; void test_print (int a, float b, double c) { } int main () { Test test; test.printint (test_print); } Fails with source.cpp:14:33: note: candidate is: source.cpp:3:33: note: templateclass ... A2 void Test::print(void (*)(A2 ..., float, double)) source.cpp:3:33: note: template argument deduction/substitution failed: source.cpp:14:33: note: mismatched types 'float' and 'int' GCC does apparently not substitute the explicitly specified arguments of A2 before attempting the argument deduction.
[Bug c++/55809] New: Doesn't differentiate elaborated type specifier and typename specifier in dependent types
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55809 Bug #: 55809 Summary: Doesn't differentiate elaborated type specifier and typename specifier in dependent types Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following looks well-formed templatetypename T, typename T::X * void f() { } templatetypename T, class T::X * void f() { } struct A { typedef int X; }; struct B { void X(); class X { }; }; class B::X x1; int x2; int main() { fA, x2(); fB, x1(); } But GCC shouts: prog.cpp:1:94: error: redefinition of 'templateclass T, class T::X* anonymous void f()' prog.cpp:1:46: error: 'templateclass T, typename T::X* anonymous void f()' previously declared here Related Bugreport (responsible for accepting the above testcase too, when it's fixed): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920 . Clang accepts the above code, so my statement in PR48920 that the Itanium ABI does not allow to distiguish between the different signatures appears to be wrong and GCC should support this code.
[Bug libstdc++/55713] New: std::tupleElementType incorrectly is convertible to ElementType when it is an empty class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55713 Bug #: 55713 Summary: std::tupleElementType incorrectly is convertible to ElementType when it is an empty class Classification: Unclassified Product: gcc Version: 4.7.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This code cannot be compiled with libstdc++ struct A {}; void f(A); struct B { B(std::tupleA); }; void f(B); int main() { f(std::make_tuple(A())); } GCC shouts error: 'A' is an inaccessible base of 'tupleA' Libstdc++ should not make std::tupleEmptyClass derive from the empty class directly.
[Bug libstdc++/55713] std::tupleElementType incorrectly is convertible to ElementType when it is an empty class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55713 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2012-12-16 17:52:14 UTC --- (In reply to comment #1) This was done for an optimization. And I think it is allowed by the C++ standard too. From the feedback I received from Stackoverflow ( http://stackoverflow.com/q/13902910/34509 ) I assumed that this behavior is not permissible. There also appear to be ways to make it not behave that way (see LLVM libc++'s implementation).
[Bug c++/49372] Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2012-12-10 16:42:59 UTC --- (In reply to comment #4) (In reply to comment #3) Kai, I don't think anyone disputes that B's constructor is called, the question is why 12.2/4 doesn't apply. Well, we have here 5.2.2 which says A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of expressions which constitute the arguments to the function. But we don't have here an explicit function-call. And an implicit call is not an expression, hence, not a part of any full expression, and so we don't have a sequence-point. Not sure if specification intended it differently, but by its current wording I would assume that current implementation is right. See 1.9p10. The implicit function call is considered to be an expression.
[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2012-11-18 21:29:15 UTC --- (In reply to comment #3) Is this a duplicate of Bug 41933 ? This looks like a different one. I am not trying to capture a list of variables that result of expansion of a function parameter pack, but I'm just trying to use an element (a type or in this case, a non-type template parameter) of a pack expansion within a lambda. For a real life example, consider http://stackoverflow.com/a/13444602/34509
[Bug c++/54165] New: Cast to void should not implicitly call conversion functions
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54165 Bug #: 54165 Summary: Cast to void should not implicitly call conversion functions Classification: Unclassified Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC should not print what!? in the following code, according to the C++ spec #include iostream struct A { templatetypename T operator T() { std::cout what!?; } }; int main() { A a; (void)a; }
[Bug c++/53499] New: Incorrect partial ordering result with member vs non-member
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53499 Bug #: 53499 Summary: Incorrect partial ordering result with member vs non-member Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com I think that this is ambiguous for partial ordering ambiguities, but GCC accepts this code, selecting the non-member template class P class ptr { public: // Picked in C++11 mode. templateclass T void operator- (T) const { static_assert(sizeof(T) == 0, #1); } }; // Picked in default C++ mode. templateclass T1, class T2 void operator- (const ptrT1, const ptrT2) { static_assert(sizeof(T1) == 0, #2); } int main () { ptr int a, b; (void) (b - a); }
[Bug c++/53499] Incorrect partial ordering result with member vs non-member
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53499 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2012-05-27 14:00:20 UTC --- Sorry, GCC picks the same function (non-member) disregarding of the C++ Standards mode. The comments were a left-over from a clang bug report.
[Bug c++/53464] Invalid default value for non-type template parameter is accepted
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53464 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2012-05-24 07:51:09 UTC --- Daniel, nice to meet you again :) See my SO answer and Richard's opinion at http://stackoverflow.com/a/10727719/34509 .
[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050 --- Comment #16 from Johannes Schaub schaub.johannes at googlemail dot com 2012-04-02 07:43:23 UTC --- (In reply to comment #15) (In reply to comment #14) Good point, I've pointed out the problem with the proposed resolution. Note that we currently have http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581 open. Even when 12.1 would have allowed both the injected class name and it followed by template-arguments, the name lookup rules would never allow it to match the second condition because the injected class name would always have been translated to a name denoting the constructor instead of the class. So ultimately, 12.1 allowing the injected class name followed by template arguments could only be used in an unqualified-id constructor declaration in C++03.
[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #13 from Johannes Schaub schaub.johannes at googlemail dot com 2012-04-01 14:03:40 UTC --- Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435 not render the explicit specialization ill-formed for C++11TC1? It only allows a simple identifier, and not a template-id.
[Bug c++/9050] [DR 147] Can't explicitly specialize C++ constructor templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9050 --- Comment #14 from Johannes Schaub schaub.johannes at googlemail dot com 2012-04-01 14:14:46 UTC --- (In reply to comment #13) Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1435 not render the explicit specialization ill-formed for C++11TC1? It only allows a simple identifier, and not a template-id. FWIW I don't like the resolution of that issue. For a qualified-id, the injected-class-name is an excellent way for us to know when and when not we name a constructor, and it is entirely based on name-lookup rules; I don't see the need to dictate that in clause 12. Only for an unqualified-id, we actually need the rule to know when we declare a constructor. The allowed decl-specifiers in a constructor declaration can be stated separately.
[Bug c++/51805] New: Invalid list-initialization accepted
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51805 Bug #: 51805 Summary: Invalid list-initialization accepted Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com Either I'm missing something or GCC should reject this code according to 13.3.3.1p4 (the initializer-list constructor is non-viable and the copy/move constructors would require user defined conversions respectively to accept {1, 2, 3}): struct A { A(initializer_listint); }; A a{{1, 2, 3}}; People were initializing their vectors using {{1, 2, 3}}, perhaps they are used to do such by following the analogous array initialization notion.
[Bug c++/51805] Invalid list-initialization accepted
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51805 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2012-01-09 22:53:42 UTC --- Yes I *was* missing something. The initializer list constructor can accept {1, 2, 3} - of course it is not absent when overload resolution is done again after initially not being able to accept {{1, 2, 3}} as a whole. Closing as invalid...
[Bug c++/47226] [C++0x] GCC doesn't expand template parameter pack that appears in a lambda-expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2012-01-08 11:41:18 UTC --- I asked the committee at that time, and they reinforced that this is intended to work as specified in the C++11 spec.
[Bug c++/51789] New: GCC does not consider SFINAE in template parameter list of template parameter pack
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51789 Bug #: 51789 Summary: GCC does not consider SFINAE in template parameter list of template parameter pack Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This code should not be accepted, but GCC accepts it struct A { template typename ...T, templatetypename std::enable_if std::is_sameT, int::value, int ::type ... class... A(T...); }; A a = {1, 2.0, 3};
[Bug c++/51689] New: GCC apparently is inconsistent with warning about invalid brace-elision use
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51689 Bug #: 51689 Summary: GCC apparently is inconsistent with warning about invalid brace-elision use Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC gives a warning about std::arrayint, 2{1, 2} But it gives an error about struct A { A():a{1, 2} { } std::{arrayint, 2 a; }; I would expect consistent handling of the two cases.
[Bug c++/50921] New: GCC cannot find dependent conversion-function-id even if there's a using declaration for it
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50921 Bug #: 50921 Summary: GCC cannot find dependent conversion-function-id even if there's a using declaration for it Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following code should compile but doesn't. --- snip templatetypename T struct Type { int x; }; templatetypename T struct Base { operator Typeint(); }; templatetypename T struct Derived : BaseT { using BaseT::operator TypeT; void f() { int x = operator TypeT().x; (void) x; } }; int main() { Derivedint d; d.f(); } --- snap Error: --- snip main1.cpp:13:30: error: there are no arguments to 'operator TypeT' that depend on a template parameter, so a declaration of 'operator TypeT' must be available --- snap The function call is dependent by the dependent function name itself, it doesn't need dependent call arguments in this case in order to be dependent.
[Bug c++/50921] GCC cannot find dependent conversion-function-id even if there's a using declaration for it
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50921 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-10-30 13:54:21 UTC --- Someone notified me that you can substantially reduce this to the following templatetypename T struct Base { operator int(); }; templatetypename T struct Derived : BaseT { using BaseT::operator int; void f() { int x = operator int(); (void) x; } }; int main() { Derivedint d; d.f(); } Same diagnostic is given.
[Bug c++/41796] ambiguous subobject diagnostic given too early
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41796 --- Comment #10 from Johannes Schaub schaub.johannes at googlemail dot com 2011-09-29 06:10:26 UTC --- (In reply to comment #9) Excellent, then could you possibly comment on the implication for this PR? (for you it's easy, I'm sure) Hi, wanna chime in here. It has no implication on my original PR (I'm not taking a pointer to member), and has no implication on the example code Jason quoted from the draft (so CWG983 was just noise -.-). Perhaps it's useful to show more examples: struct A { int a; }; struct B : A { }; struct C : A { }; struct D : B, C { }; struct E : D { // valid, refers to one declaration using D::a; }; The above is valid in C++0x, and invalid in C++03. Certain uses of the alias name E::a are valid, while others are invalid (those that check subobject affinity) decltype(E::a) x; // valid int x = E().a; // invalid See WMM's paper at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1543.pdf and the usenet discussion at http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/4ae640b13b0bd334/ .
[Bug c++/41796] ambiguous subobject diagnostic given too early
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41796 --- Comment #11 from Johannes Schaub schaub.johannes at googlemail dot com 2011-09-29 06:14:32 UTC --- (In reply to comment #10) (In reply to comment #9) Excellent, then could you possibly comment on the implication for this PR? (for you it's easy, I'm sure) ... Perhaps it's useful to show more examples: struct A { int a; }; struct B : A { }; struct C : A { }; struct D : B, C { }; struct E : D { // valid, refers to one declaration using D::a; }; Fail, I forgot I showed the same example above already :) Please forgive.
[Bug c++/48562] [C++0x] warn about uses of initializer_list that will lead to dangling pointers
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562 --- Comment #6 from Johannes Schaub schaub.johannes at googlemail dot com 2011-09-25 14:22:33 UTC --- (In reply to comment #5) Johannes, sorry about the dumb question: now I understand the issue decently well - and after all boils down to adding a warning - but I'm not sure to understand your code snippet: is it meant to crash at runtime? Trigger valgrind errors? In the C++11 spec, it is said that the lifetime of the backing-up array is the same as the lifetime of the initializer_list object which was initialized by the array (not considering the DRs and their resolution that Jason has pointed to). My code was just meant to test whether GCC obeys those rules. struct X { X(int) { cout +; } X(X const) { cout +; } ~X() { cout -; } }; auto *p = new initalizer_listX{1, 2, 3}; // ... not at this delete p; // C++11 requires now at this point ... (again not considering those DRs that revise these rules). I think that a warning against ({...}) would be useful too // fine initializer_listint a{1, 2, 3}; // this is bad initializer_listint b({1, 2, 3}); Second one is bad because it will destroy the array after initializing 'b', and won't lengthen the lifetime (because it will use the copy/move constructor).
[Bug c++/47436] [C++0x] Variadic base-specifier-list of union rejected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47436 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2011-09-22 19:01:51 UTC --- (In reply to comment #3) (In reply to comment #2) Suggestions about a better error message? (should be easy to change) What about: error: every valid template specialization requires an empty template parameter pack ? I don't know how much local information is available, if there is more available, so following would be better: error: every valid specialization of template A requires an empty template parameter pack T Hmm, this is very technical though. When the user wrote that code, most probably they either don't want an union, but a class/struct, or they don't want to derive from something. For the tiny fraction of users that *do* want to write that exact code, they most probably expect it to be valid because they most probably think that if T is empty, it will expand to nothing. With the proposed wording of the diagnostics, in both cases the diagnostic is suboptimal
[Bug c++/50445] New: Rejects use of constant expression using a pointer non-type template parameter
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50445 Bug #: 50445 Summary: Rejects use of constant expression using a pointer non-type template parameter Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This is rejected by GCC: extern int const values[] = { 1, 2, 3 }; templateint const *values struct X { static int const val0 = values[0]; }; int array[Xvalues::val0]; GCC error message: error: non-constant in-class initialization invalid for static member 'X((const int*)( values))::val0' However, as far as I can see, values[0] is a valid integral constant expression.
[Bug preprocessor/50387] New: Doesn't process _Pragma when expanding a token sequence for #include
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50387 Bug #: 50387 Summary: Doesn't process _Pragma when expanding a token sequence for #include Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following code works fine with Clang and as far as I can see, C++11 requires this to work (modulo the pragma's content interpretation): #define GET(H) _Pragma(diagnostic push) H #include GET(stdio.h) The code I'm working on uses this feature to implement something and it would be nice if GCC would support this too.
[Bug c++/50169] New: new struct X {{}}; incorrectly treated as an invalid struct-definition
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50169 Bug #: 50169 Summary: new struct X {{}}; incorrectly treated as an invalid struct-definition Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following looks like valid code: struct A { int a; }; int main() { new struct A {{ }}; } The type-specifier-seq struct A is followed by a braced-init-list {{}}. But GCC says: main1.cpp: In function 'int main()': main1.cpp:3:16: error: types may not be defined in a new-type-id main1.cpp:3:17: error: expected unqualified-id before '{' token As far as I can see, I would only define a new type if I would say: new struct A { }; But the two-braces disambiguates it.
[Bug c++/47453] [DR 1214] Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 --- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com 2011-08-03 19:17:04 UTC --- (In reply to comment #6) You can define it as follows to make it work in both cases #define PTHREAD_COND_INITIALIZER {} I cannot define/redefine this value. It's already defined in system headers... Ah I wasn't aware. You can at least workaround it though. class cond_variable { struct { ::pthread_cond_t cond; } wrapper; public: constexpr cond_variable() : wrapper{PTHREAD_COND_INITIALIZER} {} };
[Bug preprocessor/49928] New: Only workaround for -Wundef is defined(Macro) Macro, but it is undefined behavior?
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49928 Summary: Only workaround for -Wundef is defined(Macro) Macro, but it is undefined behavior? Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com It appears that to inhibit a warning about using an undefined macro identifier, one has to employ the following work-around #define FOO BAR #if FOO // warns about 'BAR' Instead: #define FOO defined BAR BAR #if FOO Doesn't warn anymore then. But that yields to undefined behavior and IMO it's not intuitive, because BAR is still used but is undefined (this doesn't work like short circuiting or something), so I would think GCC provides another way to do this. If it doesn't exist yet, I would like to ask for a builtin, like #define FOO __possibly_undefined(BAR) // , or #define FOO ((BAR)) See https://bugs.webkit.org/show_bug.cgi?id=65401
[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-07-29 12:23:35 UTC --- (In reply to comment #4) struct A { int a[2]; A():a({1, 2}) { } }; Should be valid. Example: class cond_variable { ::pthread_cond_t cond; public: constexpr cond_variable() : cond(PTHREAD_COND_INITIALIZER) {} }; What is pthread_cond_t? Struct? Array? Scalar? How I can be sure this code is accepted in any case? Uniform initialization initially address this issue. Why not say constexpr cond_variable() : cond PTHREAD_COND_INITIALIZER { } Out of constructor one can use =: ::pthread_cond_t cond = PTHREAD_COND_INITIALIZER; You can define it as follows to make it work in both cases #define PTHREAD_COND_INITIALIZER {}
[Bug c++/49637] template function overload incorrectly ambiguous
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-07-05 16:36:14 UTC --- (In reply to comment #1) Created attachment 24686 [details] minimal test case IMO this is ambiguous. When doing partial ordering, in both cases the 'T' remains undeduced. Recall that partial ordering is, apart from stripping parameters that have no corresponding argument in a function call context, independent from the context of the ordering. So you cannot take the 'S' that you passed explicitly into account. The spec says (FDIS, C++0x) In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering. [ Note: A template parameter used in a non-deduced context is considered used. — end note ]
[Bug c/49653] Undefined reference to inlined function with -O0,-std=c99
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49653 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-07-06 05:27:41 UTC --- (In reply to comment #1) This is correct for C99. inline alone in C99 is the same GNU's C90's extern inline. For an explanation, see http://stackoverflow.com/questions/2217628/multiple-definition-of-inline-functions-when-linking-static-libs/2218034#2218034 . In particular In a call to an inline function it's unspecified whether the external or the inline definition is used.
[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-06-26 13:40:34 UTC --- (In reply to comment #4) Hmm, the example in 14.8.2p8 does seem to contradict my interpretation of the normative wording. I'll raise this with core. A related question, if in the end we in fact don't SFINAE or error out with T[N] is, whether substitution for N is done at all. Because the type would be T*, not T[N] anymore. templatetypename T void f(char[T::size]); int main() { fint(); } Does the substitution succeed?
[Bug c++/49531] New: Doesn't resolve to conversion function template specialization in expressions
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49531 Summary: Doesn't resolve to conversion function template specialization in expressions Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC rejects this code, which I think is valid in both C++03 and C++0x // snip struct A { templatetypename T operator T(); }; void f() { A::operator int; } main1.cpp:5:28: error: statement cannot resolve address of overloaded function // snap There is no overloaded function. The provisions of 13.4 apply when we are faced with a function template name. We are not, in this case. A specialization of a conversion function template is not found by name lookup. Instead, any conversion function templates visible in the context of the use are considered. For each such operator, if argument deduction succeeds (14.8.2.3), the resulting specialization is used as if found by name lookup. Before we even enter 13.4, we will do argument deduction and resolve to a single function template specialization. After we resolved to that function *as if by name lookup*, we will just skip 13.4 because we have a single function name, rather than an overload set.
[Bug c++/49514] New: Crashes on valid use of constexpr constructor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49514 Summary: Crashes on valid use of constexpr constructor Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC crashes on this code: /// snip struct Vector4D { constexpr Vector4D(double x=0, double y=0, double z=0, double t=0) :components{x, y, z, t}, x(components[0]), y(components[1]), z(components[2]), t(components[3]) { } double components[4]; double x, y, z, t; }; Vector4D a{1, 2, 3}; /// snap Error: main1.cpp:11:19: in constexpr expansion of ‘a.Vector4D::Vector4D(1.0e+0, 2.0e+0, 3.0e+0, 0.0)’ main1.cpp:11:19: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See https://bugs.archlinux.org/ for instructions.
[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205 --- Comment #7 from Johannes Schaub schaub.johannes at googlemail dot com 2011-06-20 15:56:42 UTC --- (In reply to comment #6) (In reply to comment #1) While this behavior is erroneous, consensus at clang was that WG21 made an oversight in allowing this. Template constructors are banned from being copy or move constructors, and historically this prohibition was not necessary for default constructors since there was no special handling of them except when implicit. I disagree with this. As Johannes points out, it is possible to have a template default constructor in C++03, so changing this would be a significant change. We should just treat the variadic template as a default constructor. To be fair to Sean, I should note that my example relied on a C++0x feature. If we remove the template default argument: templatetypename T A(T = 0); This constructor cannot really be called with arguments anymore (there's no deduction from default arguments), which is the condition under which a constructor becomes a default constructor.
[Bug c++/49372] New: Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372 Summary: Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?) Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This testcase outputs a surprising result: struct A { A() { std::cout C std::endl; } ~A() { std::cout D std::endl; } }; struct B { B(A const a = A()) { } }; typedef B array[2]; int main() { array{}; } GCC prints CCDD. I would have expected CDCD, as it seems that is the intent of the wording in the spec (FDIS). The FDIS however seems to be contradicting here, but it appears to me that GCC should better print CDCD, so as to follow the intent. Originated from http://stackoverflow.com/questions/6315670/when-an-array-is-created-by-a-subexpression-what-happens-with-the-temporaries-th .
[Bug c++/49372] Temporaries evaluated for arguments of a default constructors of array elements not destructed properly (?)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49372 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-06-11 13:46:46 UTC --- To elaborate on it, I have the following weird behavior: - GCC4.6 outputs nothing for the program (on my linux machine). That seems definitely wrong in any case. - GCC4.7 4.7.0 20110517 (experimental), using a mingw nightly build, generates an executable that crashes when running: [js@HOST2 cpp]$ ~/w64/bin/i686-w64-mingw32-g++ -std=c++0x -O1 -o a.exe main1.cpp [js@HOST2 cpp]$ wine ./a.exe Cwine: Unhandled page fault on read access to 0x at address (nil) (thread 0025), starting debugger... - The same GCC4.7 when using -O2 does not crash and print CCDD: [js@HOST2 cpp]$ ~/w64/bin/i686-w64-mingw32-g++ -std=c++0x -O2 -o a.exe main1.cpp [js@HOST2 cpp]$ wine ./a.exe fixme:ntoskrnl:KeInitializeSpinLock stub: 0x5477a4 C C D D I don't know precisely whether this is a problem with wine or a temporary problem with that nightly build of GCC I was using. My apologies if GCC trunk works differently!
[Bug c++/49267] New: Ambiguity with conversion functions T and T, initializing a T
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49267 Summary: Ambiguity with conversion functions T and T, initializing a T Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This is ambiguous with GCC, but probably should select the T: struct X { operator int(); operator int(); }; intx = X(); GCC says: main1.cpp:7:16: error: conversion from ‘X’ to ‘int’ is ambiguous main1.cpp:7:16: note: candidates are: main1.cpp:4:7: note: X::operator int() main1.cpp:3:7: note: X::operator int()
[Bug c++/49224] New: Scoped enumeration instantiated even if not required
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49224 Summary: Scoped enumeration instantiated even if not required Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC should not instantiate the definition of the scoped enumeration: templatetypename T struct A { enum class B { X = T::value }; }; int main() { Aint a; } GCC error: main1.cpp: In instantiation of ‘Aint’: main1.cpp:9:10: instantiated from here main1.cpp:3:14: error: ‘value’ is not a member of ‘int’ This code looks well-formed. Only if we look into the enumeration, as Aint::B::X, the definition of the enumeration is required to exist and thus implicitly instantiated. This is specified at 14.7.1p1 and p2.
[Bug c++/49205] New: Default constructor with pack expansion parameter not detected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205 Summary: Default constructor with pack expansion parameter not detected Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com This is rejected as ambiguous by GCC: struct A { templatetypename ...T A(T...); A(initializer_listshort); A(initializer_listlong); }; A a{}; But in fact, 8.5.4p3: If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized. And 12.1p5: A default constructor for a class X is a constructor of class X that can be called without an argument. So, there is no ambiguity. The default ctor is called, and T is deduced to (empty pack).
[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-28 01:45:29 UTC --- (In reply to comment #1) While this behavior is erroneous, consensus at clang was that WG21 made an oversight in allowing this. Template constructors are banned from being copy or move constructors, and historically this prohibition was not necessary for default constructors since there was no special handling of them except when implicit. That rationale makes sense. I wonder about the implications for value initialization though. If that constructor is not a default constructor, then A(); appears to be ill-formed, because of the saying in 8.5p7 that we shall call the default constructor. Also, how should the rules be drawn? Is any template not a default constructor? Then what about the following? templatetypename T = int A(T = 0); GCC appears to deem it a default constructor. Is the following rule acceptable? - A default constructor is a constructor with zero parameters or that only has parameters with default arguments and with an optional trailing ellipsis (A(int, ...)).
[Bug c++/49205] [C++0x] Default constructor with pack expansion parameter not detected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49205 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-28 02:06:07 UTC --- (In reply to comment #3) I would expect that the initialization text would be amended appropriately. I think that we should go for consistency and say non-templates only, the same as for copy and move constructors. Ah I see. That seems to make sense.
[Bug c++/49102] New: Use of deleted copy constructor not diagnosed
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49102 Summary: Use of deleted copy constructor not diagnosed Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following program should be diagnosed at the call to f for using a deleted copy constructor in an lvalue to rvalue conversion struct A { A() = default; private: A(A const) = default; }; void f(...) { } int main() { A a; f(a); } GCC compiles and links this code without complaining.
[Bug c++/49102] [C++0x] Use of deleted copy constructor not diagnosed
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49102 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-21 20:04:16 UTC --- (In reply to comment #0) The following program should be diagnosed at the call to f for using a deleted copy constructor in an lvalue to rvalue conversion I'm sorry. I meant: for using a inaccessible copy constructor, of course.
[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-19 16:26:30 UTC --- (In reply to comment #1) I disagree. The transformation of array to pointer is done immediately at declaration time (8.3.5/6), so there is no substitution into an array type. In resolving issue 1001, core agreed that the transformations in 8.3.5/6 are done at template definition time, not deferred until the instantiation. http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1001 http://wiki.dinkumware.com/twiki/bin/view/Wg21batavia/CoreWorkingGroup#Core_issue_1001_Parameter_type_a jason, the transformation is immediately done at declaration time. I agree: That's why these two are equivalent: templatetypename T void f(T[1]); templatetypename T void f(T*); For equivalence, both shall have identical parameter-type-lists, which these have. But before argument deduction, explicit template arguments are substituted, and those explicit arguments are substituted into the *unadjusted* parameter type. See 14.8.2p3 (FDIS): After this substitution is performed, the function parameter type adjustments described in 8.3.5 are performed. The note that contains a list of substitution failures also has an example like that at 14.8.2p8: template class T int f(T[5]); int I = fint(0); int j = fvoid(0); // invalid array
[Bug c++/49051] [C++0x] Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051 --- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-19 16:56:07 UTC --- (In reply to comment #2) (In reply to comment #1) I disagree. The transformation of array to pointer is done immediately at declaration time (8.3.5/6), so there is no substitution into an array type. In resolving issue 1001, core agreed that the transformations in 8.3.5/6 are done at template definition time, not deferred until the instantiation. http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1001 http://wiki.dinkumware.com/twiki/bin/view/Wg21batavia/CoreWorkingGroup#Core_issue_1001_Parameter_type_a jason, the transformation is immediately done at declaration time. I agree: That's why these two are equivalent: templatetypename T void f(T[1]); templatetypename T void f(T*); For equivalence, both shall have identical parameter-type-lists, which these have. But before argument deduction, explicit template arguments are substituted, and those explicit arguments are substituted into the *unadjusted* parameter type. See 14.8.2p3 (FDIS): After this substitution is performed, the function parameter type adjustments described in 8.3.5 are performed. The note that contains a list of substitution failures also has an example like that at 14.8.2p8: template class T int f(T[5]); int I = fint(0); int j = fvoid(0); // invalid array Ah I see now: The substitution for explicit arguments uses the *function type*, not the parameter types (according to p6). So in the example above, it uses T* and becomes void*. It doesn't use T[5]. p3 only applies when the dependent type was adjusted and substitution made it a non-adjusted type. So on a second read of this, I agree to you. The note at 14.8.2p8 and the example of p3 were confusing me, both tricking me into thinking that for substitution, the parameter types themselves somehow would be used.
[Bug c++/49051] New: Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N]
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49051 Summary: Doesn't SFINAE away an invalid substitution into toplevel parameter type T[N] Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC incorrectly fails to compile this code templatetypename T void f(T[1]) = delete; templatetypename T void f(...); int main() { fvoid(0); } The substitution into T should fail, because T[1] is an invalid type, and hence the call should use the second template. Note that I think it's unspecified in the spec what happens when we tweak things as follows templatetypename T void f(T[1]) = delete; templatetypename T void f(T*); templatetypename T void f(...); int main() { fvoid(0); } The first two templates are equivalent, but behave different during substitution. The spec doesn't specify what the outcome of this is, I think.
[Bug c++/43453] Initialization of char array with string literal fails in mem-initializer
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43453 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-14 16:18:58 UTC --- (In reply to comment #3) (In reply to comment #2) (In reply to comment #1) (In reply to comment #0) Fails to compile, but should work: struct A { char x[4]; A():x(bug) { } }; Error i get is: main.cpp:3: error: array used as initializer Why do you think it should work? For example, the following equivalent code is invalid as well: char x [4] (bug); This code is equivalent and is valid. At least, I don't see the Standard forbidding it. GCC is the only compiler I tested (comeau/edg, clang) that rejects it. I'm not actually sure anymore about the validity of this code. One can make a point about the initializer not being a mere string literal. At least the draft n3126 makes a difference of this, in that an initializer like ({a, b, c}) is not regarded as a braced-init-list, but rather as a parenthesized expression-list where the initializer list is handed as one argument. So I'm unsure whether an initializer like `(foo)` should be regarded as a string literal or not. I think I will send an issue report about this. Subsequent discussion with Jason showed that this is covered by 8.5p13: The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; As this is an array, the text in the Standard in general has to be interpreted that a = or a (..) initializer are equivalent, unless otherwise stated. So this is indeed a GCC bug (both that it rejects the member initialization and the parenthesized non-member initialization).
[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 --- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-12 05:23:15 UTC --- I think we have the FDIS clear about these cases now. To update: // invalid struct A { int a[2]; A():a({1, 2}) { } }; // invalid int a({0}); // invalid int const b({0}); struct A { explicit A(int, int); A(int, long); }; // invalid A c({1, 2}); // valid (by copy constructor). A d({1, 2L}); // valid A e{1, 2}; struct B { templatetypename ...T B(initializer_listint, T ...); }; // invalid (the first phase only considers init-list ctors) // (for the second phase, no constructor is viable) B f{1, 2, 3}; // valid (T deduced to ). B g({1, 2, 3});
[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-10 14:49:18 UTC --- (In reply to comment #0) gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at the line marked with #: //--- struct B { friend constexpr int f(B) { return 0; } // # }; //--- error: invalid type for parameter 1 of constexpr function 'constexpr int f(B)' This code should be accepted. The same problem occurs with friend operators, like this case friend constexpr int operator+(B) { return 0; } within B resulting in: error: invalid type for parameter 1 of constexpr function 'constexpr int operator+(B)' Well, class B is incomplete in the parameter type list of f. The spec allows B to be incomplete for that parameter type (8.3.5p9), but it doesn't say anything what that means for determining whether or not the parameter has literal class type (several of the bullets of 3.9p10 require a complete class type to be checked). I don't know whether an implementation is supposed to reject the code, or supposed to wait until B is complete. Same would apply for non-static member functions. Any hints?
[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948 --- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-10 16:46:18 UTC --- (In reply to comment #2) (In reply to comment #1) I don't think that this is intended, but I would like to await feedback from the developer group before submitting a corresponding core issue. IMO there are some core wordings in regard to type completeness that are not intended to be read strictly, e.g. 3.2 p.4 — a function with a return type or argument type of type T is defined (3.1) [..] can be read to disallow any of the following function definitions: struct A { A f(A a) { return a; } friend A g(A a) { return a; } }; I haven't seen a compiler who rejects this code, because they all contribute more weight to 9.2 p.2. Within A a (the parameters) and within A f / A g (the return types), the class A is incomplete. Only within the function bodies, the class A is complete by 9.2p2. The compilers accept that code because of 8.3.5p9. 3.2 p4 is a non-normative big note, which can impossibly achieve the precision of covering every detail. It only provides a rough description.
[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-10 16:59:50 UTC --- (In reply to comment #0) gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at the line marked with #: //--- struct B { friend constexpr int f(B) { return 0; } // # }; //--- error: invalid type for parameter 1 of constexpr function 'constexpr int f(B)' This code should be accepted. I remember that Gaby (I hope I remember correctly, hehe) argued that the body of f is late-parsed. Hence, the argument, until after the end of definition of B, f is only considered declared but not defined. I don't share that view though. That view is an implementation detail. In the language, the function marked by # is defined as soon as its body has been completely seen. If something else is intended, the specification needs to be explicit about this. Unless I've missed the text, it is not explicit about that.
[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-10 17:07:30 UTC --- (In reply to comment #4) (In reply to comment #0) gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at the line marked with #: //--- struct B { friend constexpr int f(B) { return 0; } // # }; //--- error: invalid type for parameter 1 of constexpr function 'constexpr int f(B)' This code should be accepted. I remember that Gaby (I hope I remember correctly, hehe) argued that the body of f is late-parsed. Hence, the argument, until after the end of definition of B, f is only considered declared but not defined. Consider also this, which I think demonstrates that position: struct A { struct B; void f(B) { } struct B { }; }; I think this is ill-formed by the spec, because B is incomplete in f's parameter and f is defined at that point. And this is not one of the contexts that B is allowed to be incomplete by 8.3.5p9. However, clang, gcc and comeau online all accept this. Apparently, they consider f only declared and not defined. I would be glad if someone points me to the rule that says that f is only considered defined at the closing } of A though.
[Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48948 --- Comment #6 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-10 17:20:31 UTC --- (In reply to comment #4) (In reply to comment #0) gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at the line marked with #: //--- struct B { friend constexpr int f(B) { return 0; } // # }; //--- error: invalid type for parameter 1 of constexpr function 'constexpr int f(B)' This code should be accepted. I remember that Gaby (I hope I remember correctly, hehe) argued that the body of f is late-parsed. Hence, the argument, until after the end of definition of B, f is only considered declared but not defined. I don't share that view though. That view is an implementation detail. In the language, the function marked by # is defined as soon as its body has been completely seen. If something else is intended, the specification needs to be explicit about this. Unless I've missed the text, it is not explicit about that. But I can live with that. Having remembered the intent as described, I see that the friend function you already showed is valid, because when the body is late parsed, and the function is then considered defined only when the enclosing class is complete, it makes sense. I wouldn't intuitively get to this result though, but I think it's an interpretation I can live with! I'm sorry for that load of nonsense in the comment boxes. I promise this is the last comment in this row of this PR! :)
[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-09 10:55:06 UTC --- (In reply to comment #4) Indeed, C has no user-provided constructors, so it is an aggregate. Jason, what about c1? It seems that it is default-initialized, which would want to call the default constructor. Am I missing something?
[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-08 21:22:20 UTC --- I think it can be argued that this is a bug in the Standard rather than in GCC. The Standard says that members of C are zero initialized. It says that the default constructor is called only if it is non-trivial. Since there is no default constructor here, there is nothing to be non-trivial. For sure this is arguing about things that are not intended this way, but I think non-the-less it can be argued this way. This special behavior is more clear in the following case struct C { C() = delete; }; C c{}; There is a default constructor, but it is not called because it's trivial.
[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-08 21:47:01 UTC --- (In reply to comment #1) I think it can be argued that this is a bug in the Standard rather than in GCC. The Standard says that members of C are zero initialized. Let me please be more precise than that. I wanted those notes to only apply to the value initialization of c2. I agree that the default initialization for c1 is still ill-formed and should be diagnosed.
[Bug c++/48930] [C++0x] Invalid implicitly declared default c'tor
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48930 --- Comment #3 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-08 22:02:29 UTC --- (In reply to comment #2) (In reply to comment #1) I think it can be argued that this is a bug in the Standard rather than in GCC. The Standard says that members of C are zero initialized. Let me please be more precise than that. I wanted those notes to only apply to the value initialization of c2. I agree that the default initialization for c1 is still ill-formed and should be diagnosed. .. and final comment for today, I missed that this only value-initializes c2 if it has a default constructor! Since it doesn't have a default constructor, 8.5.4 will not hit bullet p3bullet1, but p3bullet2 because C is an aggregate class. As a consequence, I believe aggregate initialization happens and the initialization of c2 is well-formed this way too. Shouldn't comment this late in the day. Perhaps I missed something again :)
[Bug c++/48920] New: typename specifier should not ignore non-type names
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920 Summary: typename specifier should not ignore non-type names Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following is ill-formed code struct A { struct B { }; int B; }; typename A::B a; GCC accepts it. As a perhaps related issue, the following looks well-formed: templatetypename T void f(typename T::B) { } templatetypename T void f(struct T::B) { } GCC rejects it as a redefinition. The dependent parameter types of both look different.
[Bug c++/48920] typename specifier should not ignore non-type names
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48920 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-05-06 23:47:33 UTC --- (In reply to comment #0) […] As a perhaps related issue, the following looks well-formed: templatetypename T void f(typename T::B) { } templatetypename T void f(struct T::B) { } GCC rejects it as a redefinition. The dependent parameter types of both look different. The Itanium ABI does not include any way to distinguish these two cases, so I suspect GCC can do nothing about this. And if one were to include typename as a hint into the mangling, I can see how this quickly can get out of hand.
[Bug c++/48814] New: Incorrect scalar increment result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814 Summary: Incorrect scalar increment result Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following test-case should output 2 3, but GCC outputs 1 2: #include stdio.h int arr[] = {1,2,3,4}; int count = 0; int incr(){ return ++count; } int main(){ arr[count++]=incr(); printf(%d %d,count,arr[count]); return 0; } (it may not be obvious; see http://stackoverflow.com/questions/5827707/why-this-output/5828578#5828578 ). Clang correctly handles this case.
[Bug c++/48814] Incorrect scalar increment result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-04-29 10:42:12 UTC --- Since the order of evaluation is undefined it may evaluate count++ and incr() in any order, as it pleases. Since there is a sequence point before entering a function, and before leaving a function, and since function invocations do not interleave, we know that no matter whether we evaluate count++ before or after executing incr, the side effects of both count++ and ++count do not happen without an intervening sequence point. Sequence points have that effect of guaranteeing that side effects of previous evaluations have been finished, and side effects of subsequent evaluations have not yet occured. Undefined behavior would occur if the two side effects would occur without an intervening sequence point. For example, if we were to replace incr() by a plain ++count.
[Bug c++/48814] Incorrect scalar increment result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48814 --- Comment #5 from Johannes Schaub schaub.johannes at googlemail dot com 2011-04-29 16:20:44 UTC --- (In reply to comment #4) I think the relevant wording in the C1X DIS is With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation.; C++ N3291 has the same wording. Yes, I agree. This makes it clearer than my C++03 description using sequence points that GCC is in error.
[Bug c++/48562] New: Prematurely destroys initializer_list array when using new-expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562 Summary: Prematurely destroys initializer_list array when using new-expression Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The C++0x spec requires that GCC destroys the backing-up array at delete p, but GCC appears to destroy it immediately after the first declaration (as checked by using a class type that has a side-effecting destructor). auto *p= new initializer_listint{1, 2, 3}; { auto q(*p); } delete p;
[Bug c++/47828] New: GCC instantiates function template with auto type
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47828 Summary: GCC instantiates function template with auto type Product: gcc Version: 4.5.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com The following causes GCC to instantiate a function template using auto as a template argument: templatetypename T T *f() { // funny: T is auto here return 0; } int main() { auto *(*g)() = f; g(); } No error is generated: The compiled code runs. My best guess is, when taking the address of an overloaded function, GCC deduces the overloaded function against the target type, which apparently still is auto*() at that point, and therefor deduces T to auto, and then when it declares variable g deduces its type to auto*(*)(). Frankly, I'm not sure what the Standard says how such cases need to be handled. A reasonable action is to not do deduction against the target type auto*() and keep 'f' being a set of overloaded functions until initialization. Then, when it deduces the type of 'g', it would deduce it against a set of overloaded functions containing function templates, thus creating a non-deduced context and error out at that point. This matches clang's behavior, which accepts the following: void f(); void f(int); int main() { auto (*g)() = f; } GCC rejects that currently, because it tries to deduce 'f' against the target type early on, when g's function type is still auto(), while clang waits and first deduces g's type using a set of overloaded functions, deducing the auto to 'void'.
[Bug c++/47604] GCC doesn't accept auto *f() - int, but only accepts auto f() - int.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47604 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-02-10 10:54:15 UTC --- I have been mistaken. The declaration auto *f() - int; does not conform to the syntax.
[Bug c++/47651] New: new (T(*[1])) is parsed as a functional-cast getting a lambda-expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47651 Summary: new (T(*[1])) is parsed as a functional-cast getting a lambda-expression Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC rejects the following code, which I think is a regression: struct A { }; int main() { new (A(*[1])); } warning: lambda expressions only available with -std=c++0x or -std=gnu++0x. error: no matching function for call to 'A::A(void ()())' It should really create an array of 1 A* pointer. Credits go do this guy: http://stackoverflow.com/q/4925647/34509
[Bug c++/47604] New: GCC doesn't accept auto *f() - int, but only accepts auto f() - int.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47604 Summary: GCC doesn't accept auto *f() - int, but only accepts auto f() - int. Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC does not like the following auto *f() - int; error: 'f' function with late return type has 'auto*' as its type rather than plain 'auto' Nothing in N3225 forbids that, AFAICS. See also http://llvm.org/bugs/show_bug.cgi?id=9132
[Bug c++/47436] New: Variadic base-specifier-list of union rejected
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47436 Summary: Variadic base-specifier-list of union rejected Product: gcc Version: 4.5.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC doesn't accept this templatetypename ...T union A : T... { }; A a; It complains at parse time of A about error: derived union 'AT' invalid. However it doesn't know at that time whether or not the union will have bases yet when instantiated.
[Bug c++/47453] New: Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 Summary: Various non-conforming behaviors with braced-init-list initialization Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com According to n3225, GCC is apparently not conforming to the latest specs. The following points out some flaws. // should be invalid (takes bullet 5 of 8.5p16, for data-member a) // incorrectly accepted by GCC. struct A { int a[2]; A():a({1, 2}) { } }; The spec is not clear about what behavior the following should exhibit according to 8.5p16. As long as it's not cleared up, GCC should reconsider whether it's desirable to accept it, it seems: int a({0}); // spec is not clear. doesn't define this case? The following is ill-formed, because it takes bullet 2 and then hits 8.5.3p1: int const b({0}); // incorrectly accepted by GCC If both of those have different meanings with regard to validity, this is very disgusting. In short, the intent seems to be that a ({ ... }) initializer is only allowed for class types, where it will hit 8.5.16p6. That's the only valid way such an initialize can be interpreted for classes, in order not to accept the following struct A { explicit A(int, int); }; A a({1, 2}); // this must be invalid, and GCC correctly rejects it. In the end, I think the spec is very unclear about this, and GCC possibly should reconsider some of its behavior here.
[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||jason at gcc dot gnu.org --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2011-01-25 03:16:21 UTC --- Adding Jason. AFAIK he's implemented this for GCC.
[Bug c++/47453] Various non-conforming behaviors with braced-init-list initialization
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47453 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-01-25 03:37:01 UTC --- (In reply to comment #0) In short, the intent seems to be that a ({ ... }) initializer is only allowed for class types, where it will hit 8.5.16p6. I'm sorry. I meant 8.5p16 bullet 6. I don't want to add unnecessarily more confusion to this :)
[Bug c++/47226] New: GCC doesn't expand template parameter pack that appears in a lambda-expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226 Summary: GCC doesn't expand template parameter pack that appears in a lambda-expression Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC doesn't like this: void slurp(...) { } templateint ...N void print() { slurp([]() - int { (void) N; // or something fancy... return 0; }() ...); } void f() { print1, 2(); } Error: error: parameter packs not expanded with '...': I think the draft (n3225) says this should expand N and result in: slurp( []() - int { (void) 1; // or something fancy... return 0; }(), []() - int { (void) 2; // or something fancy... return 0; }());
[Bug c++/47227] New: GCC ignores conversion function template specializatons if a derived class' conversion function converts to the same type
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47227 Summary: GCC ignores conversion function template specializatons if a derived class' conversion function converts to the same type Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com Unless I'm missing something, the following is ambiguous: templatetypename T1, typename T2 struct A { }; struct base { templatetypename T2, typename T1 operator AT1, T2(); }; struct derived : base { templatetypename T1, typename T2 operator AT1, T2(); }; int main() { derived().operator Aint, int(); } However, GCC always wants to take the derived class version. The reason for ambiguity is: Aparam-#1#1, param-#1#2 is another type than Aparam-#1#2, param-#1#1 (prior to deduction. When collecting candidates, 14.5.2/6 says: A specialization of a conversion function template is not found by name lookup. Instead, any conversion function templates visible in the context of the use are considered. For each such operator, if argument deduction succeeds (14.8.2.3), the resulting specialization is used as if found by name lookup. In the context of the use, both functions templates are visible, so both are sent to argument deduction. Deduction will succeed, so *the specialization is used as if found by name lookup*. Name lookup cannot find declarations that are hidden, so this quite clearly requires the above to be ambiguous, and doesn't allow the base-class version to be filtered out later on. Hiding only takes place prior to deduction: templatetypename T1, typename T2 struct A { }; struct base { templatetypename T1, typename T2 operator AT1, T2(); }; struct derived : base { templatetypename T1, typename T2 operator AT1, T2(); }; int main() { derived().operator Aint, int(); } Now that is not ambiguous anymore, and will call the derived class version, because in the context of the use, the base-class version is hidden (12.3/5 and 3/8). Note that by constructing cases making the base-class version more specialized than the derived class version, we could actually make this a rejects-valid bug: templatetypename T1, typename T2 struct A { }; struct base { templatetypename T1, typename T2 operator AT1*, T2(); }; struct derived : base { private: templatetypename T1, typename T2 operator AT1, T2(); }; int main() { derived().operator Aint*, int(); } Comeau accepts this one just fine, while GCC rejects it, thinking the base-version is hidden.
[Bug c++/47144] [4.5 Regression] Doesn't reject attempt to define type in template argument; results in weird parse
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144 --- Comment #2 from Johannes Schaub schaub.johannes at googlemail dot com 2011-01-01 18:11:27 UTC --- (In reply to comment #1) 4.4 rejects it: inv.cc:1: error: expected class-name before ‘int’ inv.cc:1: error: expected ‘(’ before ‘int’ 4.5 accepts it without error current 4.6 rejects it with the following inv.cc:1:48: error: expected ‘;’ after struct definition inv.cc:1:48: error: expected template-argument before ‘;’ token inv.cc:1:48: error: expected ‘’ before ‘;’ token inv.cc:1:48: error: expected ‘::’ before ‘;’ token inv.cc:1:48: error: expected unqualified-id before ‘;’ token inv.cc:1:48: error: declaration does not declare anything [-fpermissive] inv.cc:1:50: error: expected unqualified-id before ‘’ token what 4.6.0 version are you using? Hmm, 4.6.0 20101113 (experimental). I found the following does not error out on 4.1.2: templatetypename T struct A { }; templatetypename T struct C { typename A struct B { } ::A x; }; Cint c; Maybe it also works on 4.4. Note that this relies on typename X::Y to ignore non-type names, which I think is not according to the spec. See http://stackoverflow.com/questions/4420828/another-bug-in-g-clang-c-templates-are-fun and http://llvm.org/bugs/show_bug.cgi?id=8263 .
[Bug c++/47144] [4.5 Regression] Doesn't reject attempt to define type in template argument; results in weird parse
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144 --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2011-01-01 18:41:53 UTC --- (In reply to comment #3) (In reply to comment #2) what 4.6.0 version are you using? Hmm, 4.6.0 20101113 (experimental). Ah, maybe that accepted it, but current 4.6 rejects it. I assume it was changed by Nathan Froyd's recent changes to diagnostics about missing ';' after a class definition. Ah I see. Have you found any combination of this that fails on trunk? Could be worth putting it here. Maybe adding declarators prevents it from wanting to see a semicolon? templatetypename struct A { }; A struct B { }* ::SomeNonSense int y; Thanks!
[Bug c++/47144] New: Doesn't reject attempt to define type in template argument; results in weird parse
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47144 Summary: Doesn't reject attempt to define type in template argument; results in weird parse Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com GCC accepts the following: templatetypename struct A { }; A struct B { } ::SomeNonSense int y; Seems like internally it creates the specialization for A ::B , but its parser goes mad at some part. It's not allowed to define types in template arguments. C++03 seems to have missed to explicitly state that, but n3225 says so explicitly.
[Bug c++/47080] New: explicit conversion function return conversions not restricted to qualifications
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47080 Summary: explicit conversion function return conversions not restricted to qualifications Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: schaub.johan...@googlemail.com n3225 only allows a qualification conversion for the return of an explicit conversion function when converting to a non-class type: struct A { explicit operator int(); }; int main() { bool b((A())); // should not work !A(); // should not work! } Both are not valid according to 13.3.1.5/1 (second case uses candidate function provided by 13.6/23, for which the bool parameter uses contextual conversion). GCC accepts both.
[Bug c++/47080] explicit conversion function return conversions not restricted to qualifications
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47080 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2010-12-28 19:10:25 UTC --- It should be noted that this can yield to ambiguities in combination with other conversion functions. Consider enum E { }; struct A { explicit operator int(); operator E(); }; bool operator!(E); int main() { !A(); // should work, but GCC rejects! } In this case, since GCC considers both operator int and operator E for the contextual conversion to bool, but neither is better than the other, it assigns the ambiguous conversion sequence for the builtin operator. For conversion to the E-taking one, it unambiguously uses operator E. Since the ambiguous conversion sequence cannot be compared to any other conversion sequence, we have an ambiguity between the builtin operator and our own defined one. On a n3225-conforming implementation, both operator functions would use operator E, and then it would be found that operator!(E) matches the return of the conversion function better than the built-in candidate, and would thus be selected. So it's really a rejects-valid, as is basically any C++ issue of this sort anyway, since they can all be exploited by using SFINAE.
[Bug c++/37213] Declaration/expression ambiguity resolution does not extend beyond initializer
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37213 Johannes Schaub schaub.johannes at googlemail dot com changed: What|Removed |Added CC||schaub.johannes at ||googlemail dot com --- Comment #4 from Johannes Schaub schaub.johannes at googlemail dot com 2010-12-27 11:24:36 UTC --- Same problem happens with int m; int(m), m++; I think GCC is wrong rejecting this.
[Bug c++/46831] [C++0x] Crash when it tries to do an invalid ICS with a conversion function template
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46831 --- Comment #1 from Johannes Schaub schaub.johannes at googlemail dot com 2010-12-07 04:09:25 UTC --- - GCC also rejects this valid code: -- struct A { templatetypename T = void operator short(); templatetypename T = void operator long(); }; void f(long); void f(int); // this call is not ambiguous, but GCC claims it is int main() { f(A()); } Also, if we make the second conversion functon a non-template, GCC suddenly accepts the code (right at it, the code is still valid). But that indicates that GCC has internally the handling of 13.3.3[over.match.best]p1 bullet 4 and bullet 5 reversed: It first checks whether one is a template and the other is a non-template, and only then checks whether the return type of F1 converts better than the return type of F2. -- We can make this to crash on valid code, too: struct B { }; struct D : B { }; struct A { templatetypename T = void operator D(); operator long(); }; void f(long); void f(B); int main() { f(A()); }