[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; |^~~
[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++/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 P typename std::remove_referenceP::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 typename P1 inline auto operator(P1 p1) throw() - typename std::enable_if my::is_mineP1::value, my::addressdecltype(my::filter(std::forwardP1(p1))) ::type { // NOTE: call to filter depends on template argument, thus have to be // resolved at instantiation point. But it doesn't! return my::addressdecltype(my::filter(std::forwardP1(p1))) (my::filter(std::forwardP1(p1))); } // We now declare few more classes modeling our concept: var and ref namespace my { template typename T class var; template typename T class ref; ... // and specialize function filter on them template typename T inline refvarT filter( varT t) throw() { return refvarT(t); } } // of namespace my int main() { my::varint 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::addressstruct my::refstruct my::varint 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 solodon at mail dot com 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++/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 solodon at mail dot com 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++/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 iostream #include type_traits // I can have multiple my_... classes, template class T struct my_class {}; // Which is why for convenience I introduce this predicate template typename T struct is_mine{ enum { value = false }; }; template typename T struct is_minemy_classT { enum { value = true }; }; // Note the use of || here, use of + would make things compile template typename E1, typename E2 struct either_is_mine { enum { value = is_mineE1::value || is_mineE2::value }; }; // Generic || that should only be used when one of arguments is my_... template typename E1, typename E2 inline auto operator||(E1 e1, E2 e2) throw() - typename std::enable_ifeither_is_mineE1,E2::value, int::type; template typename E1, typename E2 auto test(E1 e1, E2 e2) - typename std::enable_ifeither_is_mineE1,E2::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++/51710] decltype and SFINAE
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710 --- Comment #3 from Yuriy Solodkyy solodon at mail dot com 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++/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 string /// Some meta-predicate on two types template typename E1, typename E2 struct some_condition { enum { value = false }; // Change to true to see it compile }; /// Class can only be instantiated when some_conditionE1,E2::value is true template typename E1, typename E2 struct some_result_type { /// Just an expression that will only compile when E1 and E2 are such int m[0-!some_conditionE1,E2::value]; }; /// This function doesn't have enable_if on it because /// I will only call it on the right types template typename E1, typename E2 some_result_typeE1,E2 foo(E1 e1, E2 e2) { return some_result_typeE1,E2(); } /// operator+ is overloaded for E1,E2 satisfying some_condition only template typename E1, typename E2 inline auto operator+(E1 e1, E2 e2) - typename std::enable_if some_conditionE1,E2::value, // We check condition decltype(foo(e1,e2)) // but this part fails the compilation ::type { return foo(std::forwardE1(e1),std::forwardE2(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_typeconst char ()[6], basic_stringchar ': 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++/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 typename T struct A { template typename U struct B {}; }; template typename T void test() { typename AT::template Bint b; } int main() { typename Adouble::template Bint 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