Since DR 1030 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030 was accepted, I expect that the following code is well-defined and exits with the status code 0. However, GCC 4.7.0 20111112 (experimental) with -std=c++11 produces a wrong executable. In addition, it spuriously warns about undefined operations with -Wsequence-point option. ////////////////////////////////// struct swallow{ template<typename... Types> swallow(Types &&...){} }; template<int... IS> int f() { int i = 2; swallow{ i = i * IS + IS... }; return i; } int main() { // `i = i * 2 + 2' should be sequenced before `i = i * 3 + 3' return f<2, 3>() == 21 ? 0 : 1; } //////////////////////////////////
Confirming.
Ping. Still there with released 4.8.1 on GNU/Linux. Using initializer lists this way is a very handy way to handle variadic templates. Cheers, and thanks for all the good work!
Confirmed, hit the bug with 4.7.3 in c++11 mode.
I just stumbled over this bug with the current trunk version of GCC. It's a pretty ugly bug.
Happy two-year birthday, bug! Sorry I'm (slightly more that) off-by-one.
FWIW, because of this issue, I no longer use g++ for my project, which saddens me. If there were a means to put money on some bugs, I'd be happy to drop say $50. I do not pretend that should suffice, but maybe other people would be happy to put money on their bugs, and maybe in end some bugs might be worth shooting at. Sort of crowd-funding. Of course it would require some infrastructure to support this, but maybe this would be worth considering? Best regards.
Hi all, I'd really love to have some feedback on this issue. It looks like nobody is having a look at this. Thanks for all the good work, and sorry for insisting.
Let's add Jason in CC.
(In reply to Akim Demaille from comment #6) > FWIW, because of this issue, I no longer use g++ for my project, which > saddens me. If there were a means to put money on some bugs, I'd be happy > to drop say $50. I do not pretend that should suffice, but maybe other > people would be happy to put money on their bugs, and maybe in end some bugs > might be worth shooting at. Sort of crowd-funding. Of course it would > require some infrastructure to support this, but maybe this would be worth > considering? It would be nice if such infrastructure existed. Perhaps it would motivate more people to contribute to GCC (current contributors have their hands pretty full already). I know of: https://www.bountysource.com/trackers/384568-gcc but I have never used it, so I don't know how it works.
Well, I have finally found a simple workaround for some of the cases: GCC seems to be right in the order of evaluation when initializing an array so: template<int... IS> int f1() { int i = 0; swallow{ i = 10 * i + IS... }; return i; } fails, but template<int... IS> int f2() { using swallow = int[]; int i = 0; (void) swallow{ i = 10 * i + IS... }; return i; } succeeds. However, GCC's own libstdc++ is exposed to this bug, for instance make_tuple. $ cat foo.cc #include <iostream> #include <tuple> struct swallow { template<typename... Types> swallow(Types &&...){} }; int incr() { static int res = 2; return res++; } template<int... IS> int f1() { int i = 0; swallow{ i = 10 * i + IS... }; return i; } template<int... IS> int f2() { using swallow = int[]; int i = 0; (void) swallow{ i = 10 * i + IS... }; return i; } int main() { // `i = i * 2 + 2' should be sequenced before `i = i * 3 + 3' std::cerr << f1<2, 3>() << '\t'; std::cerr << f2<2, 3>() << '\t'; auto t = std::make_tuple(incr(), incr()); std::cerr << std::get<0>(t) << std::get<1>(t) << '\n'; } $ ./a.32 23 23 23 $ ./a.33 23 23 23 $ ./a.34 23 23 23 $ ./a.35 23 23 23 $ ./a.48 32 23 32 $ ./a.49 32 23 32 where 32...35 is clang++, and 48,49 is gcc.
Author: jason Date: Fri Apr 11 17:08:47 2014 New Revision: 209309 URL: http://gcc.gnu.org/viewcvs?rev=209309&root=gcc&view=rev Log: DR 1030 PR c++/51253 * cp-tree.h (CALL_EXPR_LIST_INIT_P): New. * call.c (struct z_candidate): Add flags field. (add_candidate): Add flags parm. (add_function_candidate, add_conv_candidate, build_builtin_candidate) (add_template_candidate_real): Pass it. (build_over_call): Set CALL_EXPR_LIST_INIT_P. * tree.c (build_aggr_init_expr): Copy it. * semantics.c (simplify_aggr_init_expr): Preevaluate args if it's set. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/semantics.c trunk/gcc/cp/tree.c
Fixed on trunk so far.
(In reply to Akim Demaille from comment #10) > auto t = std::make_tuple(incr(), incr()); That's not an initializer-list, it's a function call, so the order of evaluation is not specified and that example is not relevant AFAICT.
Trunk still gives -Wsequence-point warnings, and PR 61382 has an example that still fails
(In reply to Jonathan Wakely from comment #13) > (In reply to Akim Demaille from comment #10) > > auto t = std::make_tuple(incr(), incr()); > > That's not an initializer-list, it's a function call, so the order of > evaluation is not specified and that example is not relevant AFAICT. Yes, you are right, I had also realized that afterwards. It would be nice though if the standard could ensure that perfect forwarding could preserve the guarantee on left-to-right "upward": convenience functions, that wrap constructors for instance, could still be used safely.
Author: jason Date: Wed Jun 4 15:51:01 2014 New Revision: 211235 URL: http://gcc.gnu.org/viewcvs?rev=211235&root=gcc&view=rev Log: PR c++/51253 PR c++/61382 gcc/ * gimplify.c (gimplify_arg): Non-static. * gimplify.h: Declare it. gcc/cp/ * cp-gimplify.c (cp_gimplify_expr): Handle CALL_EXPR_LIST_INIT_P here. * semantics.c (simplify_aggr_init_expr): Not here, just copy it. Added: trunk/gcc/testsuite/g++.dg/cpp0x/initlist86.C Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-gimplify.c trunk/gcc/cp/semantics.c trunk/gcc/gimplify.c trunk/gcc/gimplify.h
Author: jason Date: Mon Jun 30 14:25:21 2014 New Revision: 212150 URL: https://gcc.gnu.org/viewcvs?rev=212150&root=gcc&view=rev Log: DR 1030 PR c++/51253 PR c++/61382 * cp-tree.h (CALL_EXPR_LIST_INIT_P): New. * call.c (struct z_candidate): Add flags field. (add_candidate): Add flags parm. (add_function_candidate, add_conv_candidate, build_builtin_candidate) (add_template_candidate_real): Pass it. (build_over_call): Set CALL_EXPR_LIST_INIT_P. * tree.c (build_aggr_init_expr): Copy it. * semantics.c (simplify_aggr_init_expr): Copy it. * cp-gimplify.c (cp_gimplify_expr): Handle it. Added: branches/gcc-4_9-branch/gcc/testsuite/g++.dg/cpp0x/initlist86.C Modified: branches/gcc-4_9-branch/gcc/ChangeLog branches/gcc-4_9-branch/gcc/cp/ChangeLog branches/gcc-4_9-branch/gcc/cp/call.c branches/gcc-4_9-branch/gcc/cp/cp-gimplify.c branches/gcc-4_9-branch/gcc/cp/cp-tree.h branches/gcc-4_9-branch/gcc/cp/semantics.c branches/gcc-4_9-branch/gcc/cp/tree.c branches/gcc-4_9-branch/gcc/gimplify.c branches/gcc-4_9-branch/gcc/gimplify.h
On 4.9 branch, I've noticed that commit 212150 adds new FAILs on some configurations. g++.dg/cpp0x/initlist86.C fails at execution in the following cases (tested with qemu): target mode cpu arm-none-eabi arm cortex-a9 arm-none-linux-gnueabi arm cortex-a9 arm-none-linux-gnueabi thumb cortex-a9 arm-none-linux-gnueabihf arm cortex-a9 arm-none-linux-gnueabihf thumb cortex-a9 arm-none-linux-gnueabihf arm cortex-a9 armeb-none-linux-gnueabihf arm cortex-a9 armeb-none-linux-gnueabihf thumb cortex-a9 aarch64-none-linux the same test passes when: target mode cpu arm-none-eabi thumb cortex-a9 aarch64-none-elf aarch64_be-none-elf
That's odd. Can you investigate further?
The problem was fixed by Jakub's commit 212289. Thanks.
Fixed in 4.9.1.
*** Bug 62036 has been marked as a duplicate of this bug. ***
There appears to be a regression of this bug. See bug 70792.
There's no regression (see bug 70792 comment 5). G++ still warns for the testcasese here, even though it produces the right code now.
I wasn't referring to the warnings though but incorrect code generation. Since is exhibited by pretty trivial test cases (testsuite/g++.dg/cpp0x/initlist86.C confirms that { i++, i++ } works but the analogous test for { ++i, ++i } fails) yet was first reported long after this bug was marked "FIXED" I kind of assumed it was a regression, but apparently it was just never really fixed to begin with.