[Bug c++/52224] New: [C++0x] Generic operator gets pulled into compile-time expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52224 Bug #: 52224 Summary: [C++0x] Generic operator gets pulled into compile-time expression Classification: Unclassified Product: gcc Version: 4.6.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: solo...@mail.com Created attachment 26644 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26644 Code reproducing bug Hi, I have a piece of code that crashes gcc 4.5.2 and runs out of template instantiation depth in 4.6.1, while I believe it should be well formed. The command line I used for both compilers is: g++ -std=c++0x gcc_bug_mini.cpp #include #include // I can have multiple my_... classes, template struct my_class {}; // Which is why for convenience I introduce this predicate template struct is_mine{ enum { value = false }; }; template struct is_mine> { enum { value = true }; }; // Note the use of || here, use of + would make things compile template struct either_is_mine { enum { value = is_mine::value || is_mine::value }; }; // Generic || that should only be used when one of arguments is my_... template inline auto operator||(E1&& e1, E2&& e2) throw() -> typename std::enable_if::value, int>::type; template auto test(E1&& e1, E2&& e2) -> typename std::enable_if::value, int>::type; int main() { test(3,12); } The problem is in || in the definition of either_is_mine: for some reason the generic operator enabled only when one of the arguments is from my_... set is considered as a possible overload (note that there is no constexpr on generic operator, just inline). GCC in both cases is running under MinGW on Windows 7 laptop. Thanks, Yuriy
[Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52224 --- Comment #4 from Yuriy Solodkyy 2012-02-13 21:17:36 UTC --- Was wondering myself if that can be a design issue - here is a related report I did earlier for VC++ 11: https://connect.microsoft.com/VisualStudio/feedback/details/724557/vs11-compiler-stack-overflow-only-when-used-from-command-line The weird thing there was that the compiler runs out of stack only when compiled from command line, while when compiled from IDE (with same arguments) it was behaving correctly.
[Bug c++/51710] New: decltype and SFINAE
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710 Bug #: 51710 Summary: decltype and SFINAE Classification: Unclassified Product: gcc Version: 4.6.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: solo...@mail.com Hi, I think the following code is well formed, but it fails to compile in g++ 4.6.1 and 4.5.2 (those that I had available). The code compiles in MS Visual C++ 2010. The problem is that decltype(foo(e1,e2)) in the result_type of enable_if below fails the compilation instead of SFINAE. #include /// Some meta-predicate on two types template struct some_condition { enum { value = false }; // Change to true to see it compile }; /// Class can only be instantiated when some_condition::value is true template struct some_result_type { /// Just an expression that will only compile when E1 and E2 are such int m[0-!some_condition::value]; }; /// This function doesn't have enable_if on it because /// I will only call it on the right types template some_result_type foo(E1&& e1, E2&& e2) { return some_result_type(); } /// operator+ is overloaded for E1,E2 satisfying some_condition only template inline auto operator+(E1&& e1, E2&& e2) -> typename std::enable_if< some_condition::value, // We check condition decltype(foo(e1,e2)) // but this part fails the compilation >::type { return foo(std::forward(e1),std::forward(e2)); } std::string my() { return "a"; } void foo() { // The operator+ above should be disabled on arguments of these types // and regular addition of strings should be picked std::string result = "a" + my(); } int main() { foo(); } When I compile this program I get: In instantiation of 'some_result_type >': exp2.cpp: 53:39: instantiated from here exp2.cpp: 26:42: error: size of array is negative My system is Windows 7 Professional, with g++ 4.6.1 coming from MinGW release from 2011-11-18 and g++ 4.5.2 coming from an earlier MinGW release. Command line used: g++.exe -Wall -m32 -time -O2 -std=c++0x -o "exp2" "exp2.cpp" Thanks, Yuriy
[Bug c++/51710] decltype and SFINAE
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710 --- Comment #3 from Yuriy Solodkyy 2012-01-02 21:35:56 UTC --- Thank you, I am aware of the workaround and that is exactly what I do in my code, however I think the current behavior is counter intuitive: 1. I get error message about instantiation that I have not made myself in the code or expected to be made, but because compiler had failure during substitution in decltype. 2. The error message is missing the instantiation context as in regular cases, which made me wonder for a long time what exactly fails and why, especially since Visual C++ was doing what I expected. 3. The purpose of decltype is now less clear as for each such case I cannot just use decltype, but have to create a dedicated meta-function again, that uses the decltype inside. 4. Once the concept based overloading is there, I expect the function be thrown out of the overload set because the types don't match the concept emulated here with condition. There won't be compilation error then and with this code I am simply trying to emulate the concept-based overloading with tools i have today. Thank you, Yuriy
[Bug c++/55460] New: Template-dependent name is not looked up at instantiation point
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55460 Bug #: 55460 Summary: Template-dependent name is not looked up at instantiation point Classification: Unclassified Product: gcc Version: 4.6.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: solo...@mail.com Created attachment 28768 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28768 Code reproducing bug Howdy, I think this is a bug in G++. I have a call to a template function filter(T) in a template context. filter() is further overloaded before the instantiation point. G++ 4.6.1 and 4.5.2 (both under MinGW, sorry, I don't have access to a more recent version) seems to resolve it at declaration point (see attachment for the exact code reproducing bug): namespace my { ... // A function template that by default behaves as identity template typename std::remove_reference::type filter(P&& p) throw() { return std::move(p); } ... } // of namespace my // Since this is unrestricted template, ADL won't work, so we have to stick // this overloaded operator building an expression template into the global scope template inline auto operator&(P1&& p1) throw() -> typename std::enable_if< my::is_mine::value, my::address(p1)))> >::type { // NOTE: call to filter depends on template argument, thus have to be // resolved at instantiation point. But it doesn't! return my::address(p1)))> (my::filter(std::forward(p1))); } // We now declare few more classes modeling our concept: var and ref namespace my { template class var; template class ref; ... // and specialize function filter on them template inline ref> filter( var& t) throw() { return ref>(t); } } // of namespace my int main() { my::var h; auto&& a = &h; // Instantiate expression template via overloaded operator& std::cout << typeid(a).name() << std::endl; } GCC 4.6.1 output is: N2my7addressINS_3varIi which indicates that there is no ref<> applied to var<> in instantiation of address<>. Visual C++ 10 and 11 produce: struct my::address > > which have ref<> in between and is what I was actually expecting to have. If I move the definition of overloaded operator& after the second namespace my is closed, the ref<> does properly appear on top of the var<>. Can you please have a look at this? Thank you!
[Bug c++/55460] Template-dependent name is not looked up at instantiation point
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55460 --- Comment #2 from Yuriy Solodkyy 2012-11-25 01:07:36 UTC --- Not sure I understand your comment - ADL with respect to what: my::filter or the ::operator&? Can you elaborate please?
[Bug c++/50080] New: error: 'template' (as a disambiguator) is only allowed within templates
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50080 Bug #: 50080 Summary: error: 'template' (as a disambiguator) is only allowed within templates Classification: Unclassified Product: gcc Version: 4.5.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: solo...@mail.com Hi, Consider the following code snippet compiled as: g++ -std=c++0x test.cpp In particular the two instantiations of B: one in the template context and the other one in non-dependent scope. template struct A { template struct B {}; }; template void test() { typename A::template B b; } int main() { typename A::template B b; } My GCC complains about the second instantiation saying: error: 'template' (as a disambiguator) is only allowed within templates and surely enough removing template there fixes the problem. The keyword typename used for a similar purpose of disambiguating a type in a non-template context is accepted even though redundant. Allowing typename seems to be in line with the relaxed rule of C++0x. I think, however, that the template keyword should similarly be allowed in non-dependent context accordingly to the C++0x standard (and not allowed accordingly to C++03). Here is a snippet from C++0x standard draft (FDIS n3291, section 14.2[5]) I could get a hold of: ``A name prefixed by the keyword template shall be a template-id or the name shall refer to a class template. [ Note: The keyword template may not be applied to non-template members of class templates. -end note ] [ Note: As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the -> or . is not dependent on a template-parameter, or the use does not appear in the scope of a template. -end note ]'' I think that the second note implies that template keyword should have been allowed in the example above in much the same way the typename is, please correct me if I'm wrong. The practical reason I need this behavior for is that I have a code snippet that is generated by a macro. With template being allowed in non-dependent context I can have a single macro that can be used in dependent and non-dependent contexts, while without this behavior (as well as in C++03) I will need to have 2 separate (largely duplicated) macros for each of the uses. Thanks, Yuriy
[Bug c++/68288] botched floating-point UDL
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68288 Yuriy Solodkyy changed: What|Removed |Added CC||solodon at mail dot com --- Comment #3 from Yuriy Solodkyy --- This seems to be a genuine bug in GCC, not specific to floating-point UDL. It is still present in GCC 10.2. ICC barks on it as well, but Clang and MSVC accepts. Consider: struct s_points { unsigned long long value; }; inline s_points operator"" _sp(unsigned long long v) { return {v}; } s_points operator+(s_points, s_points); s_points operator-(s_points, s_points); s_points foo(s_points p) { return p-42_sp+1_sp; // Put space before + here and GCC will accept the code } I get the following error on return statement line above: :9:14: error: unable to find numeric literal operator 'operator""_sp+1_sp' 9 | return p-42_sp+1_sp; | ^~ Since ud-suffix is just an identifier in the grammar, it should not grab + while parsing, which according to error is what it seems to be doing. Here is this snippet on Compiler Explorer: https://godbolt.org/z/4bfs6P
[Bug c++/68288] botched floating-point UDL
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68288 --- Comment #4 from Yuriy Solodkyy --- P.S. I added my previous example to this bug as they seemed to be related, feel free to split it into a separate bug if they are not. P.P.S. Change that return expression to 42_sp-p and the parser seems to think the entire _sp-p is a UDL suffix: :9:12: error: unable to find numeric literal operator 'operator""_sp-p' 9 | return 42_sp-p; |^~~