The following code prints i = 0 N = 0 when it should print i = 0 N = 1 This seems to be a regression since GCC 7, although I am not sure exactly which minor version introduced it. The problem only triggers when 'N' is constexpr, when it is assigned from a variable template, and when we go through enough templates (randomly making functions not templates seems to fix the issue). The code is (sorry, I reduced a lot but could not reduce further): #include <iostream> template <int i> struct integral_constant { constexpr operator int() const { return i; } }; template <int i> constexpr integral_constant<i> int_{}; template <typename F> void with_index(F f) { f(integral_constant<0>{}); } template <typename Dummy> void print(Dummy) { constexpr auto N = ::int_<1>; (void)N; // otherwise we get [warning: variable 'N' set but not used] // this may be a hint that something is wrong auto f = [&](auto i) { std::cout << "i = " << static_cast<int>(i) << std::endl; std::cout << "N = " << static_cast<int>(N) << std::endl; }; with_index(f); } int main() { ::print(0); } Live example with GCC 6.3.0: https://wandbox.org/permlink/lclToxN6mnRAS3ol Live example with GCC 7.1.0: https://wandbox.org/permlink/AUqaHBYlsfwHLUrU Live example with GCC trunk: https://wandbox.org/permlink/8wxi8MqrS03MbujE This bug report was lifted from a failure in Boost.Hana's test suite [1], with the relevant original code being [2]. This is quite worrisome as this breaks mundane constexpr-utilizing code in a nasty way. [1]: https://travis-ci.org/boostorg/hana/jobs/256518824#L7663 [2]: https://github.com/boostorg/hana/blob/e50749/example/tutorial/tag_dispatching.cpp#L72-L85
Started with r239267. Simplified testcase: template <int i> struct A { constexpr operator int () const { return i; } }; template <int i> constexpr A<i> a{}; template <typename F> void foo (F f) { f (A<0>{}); } template <typename T> void bar (T) { constexpr auto N = a<1>; auto f = [&] (auto i) { static_assert (static_cast<int>(N) == 1, ""); }; foo (f); } int main () { bar (0); }
The bug is that GCC is replacing the auto with the implicit template argument of the generic lambda.
Author: jason Date: Wed Aug 9 19:21:49 2017 New Revision: 250999 URL: https://gcc.gnu.org/viewcvs?rev=250999&root=gcc&view=rev Log: PR c++/81525 - wrong constant value with generic lambda * pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto. (tsubst_copy) [VAR_DECL]: Handle auto. Added: trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c
Author: jason Date: Wed Aug 9 20:17:55 2017 New Revision: 251001 URL: https://gcc.gnu.org/viewcvs?rev=251001&root=gcc&view=rev Log: PR c++/81525 - wrong constant value with generic lambda * pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto. (tsubst_copy) [VAR_DECL]: Handle auto. Added: branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C Modified: branches/gcc-7-branch/gcc/cp/ChangeLog branches/gcc-7-branch/gcc/cp/pt.c
(In reply to Jason Merrill from comment #4) > Modified: > branches/gcc-7-branch/gcc/cp/ChangeLog > branches/gcc-7-branch/gcc/cp/pt.c Reverted for now, as 7.2 is frozen.
A quick reminder that 7.2 has been released and that you probably want to put the patch back in.
Created attachment 42155 [details] Rejects-valid testcase This rather complex testcase was auto-reduced and provided on IRC. It fails with current gcc-7-branch and compiles OK (with warnings) on trunk and gcc-6-branch. It was fixed on trunk by r250999, so presumably would be fixed on the gcc-7-branch by re-applying r251001 now that the branch is unfrozen.
Author: aldyh Date: Wed Sep 13 16:44:25 2017 New Revision: 252364 URL: https://gcc.gnu.org/viewcvs?rev=252364&root=gcc&view=rev Log: PR c++/81525 - wrong constant value with generic lambda * pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto. (tsubst_copy) [VAR_DECL]: Handle auto. Added: branches/range-gen2/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C Modified: branches/range-gen2/gcc/cp/ChangeLog branches/range-gen2/gcc/cp/pt.c
Author: jason Date: Mon Sep 18 18:36:47 2017 New Revision: 252941 URL: https://gcc.gnu.org/viewcvs?rev=252941&root=gcc&view=rev Log: PR c++/81525 - wrong constant value with generic lambda * pt.c (tsubst_decl) [VAR_DECL]: Avoid clobbering auto. (tsubst_copy) [VAR_DECL]: Handle auto. Added: branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C Modified: branches/gcc-7-branch/gcc/cp/ChangeLog branches/gcc-7-branch/gcc/cp/pt.c
Author: jason Date: Wed Oct 4 15:37:09 2017 New Revision: 253414 URL: https://gcc.gnu.org/viewcvs?rev=253414&root=gcc&view=rev Log: PR c++/81525 - broken handling of auto in generic lambda. * pt.c (tsubst_decl) [VAR_DECL]: Use strip_innermost_template_args. Added: trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-auto1.C trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4a.C - copied, changed from r253410, trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-const4.C
Author: jason Date: Wed Oct 4 15:38:24 2017 New Revision: 253415 URL: https://gcc.gnu.org/viewcvs?rev=253415&root=gcc&view=rev Log: PR c++/81525 - broken handling of auto in generic lambda. * pt.c (tsubst_decl) [VAR_DECL]: Use strip_innermost_template_args. Added: branches/gcc-7-branch/gcc/testsuite/g++.dg/cpp1y/lambda-generic-auto1.C Modified: branches/gcc-7-branch/gcc/cp/ChangeLog branches/gcc-7-branch/gcc/cp/pt.c
Fixed.