Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression
On Wed, Jun 21, 2017 at 6:32 AM, Jakub Jelinekwrote: > The following patch fixes it by allowing that wording too on the line 10. > Is this ok for trunk or do you have some other preference? OK, thanks. Jason
Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression
On Tue, Jun 20, 2017 at 09:45:10PM +0200, Andreas Schwab wrote: > On Jun 20 2017, Jason Merrillwrote: > > > On Tue, Jun 20, 2017 at 5:40 AM, Andreas Schwab wrote: > >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 10) > >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for excess errors) > >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for errors, line 10) > >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for excess errors) > > > > I'm not seeing this. Can you give more detail? > > http://gcc.gnu.org/ml/gcc-testresults/2017-06/msg02172.html It doesn't fail on LP64 targets, but does fail on ILP32, on x86_64-linux can be reproduced with e.g. make check-g++ RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} dg.exp=constexpr-cast.C' The difference is that for LP64, 1 has different sizeof from void * and thus you get one diagnostics, while on ILP32 int has the same precision as void *. So one gets: /usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C:10:22: error: reinterpret_cast from integer to pointer /usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C:11:22: error: 'reinterpret_cast (1)' is not a constant expression /usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C:24:26: in constexpr expansion of 'f()' /usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C:24:27: error: value '4' of type 'int*' is not a constant expression compiler exited with status 1 XFAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 bug c++/49171 (test for errors, line 8) FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 10) PASS: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 11) PASS: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 24) FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for excess errors) Excess errors: /usr/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C:10:22: error: reinterpret_cast from integer to pointer The following patch fixes it by allowing that wording too on the line 10. Is this ok for trunk or do you have some other preference? 2017-06-21 Jakub Jelinek * g++.dg/cpp0x/constexpr-cast.C: Adjust dg-error for ILP32. --- gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C.jj 2016-08-08 21:42:30.825683528 +0200 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C 2017-06-21 12:30:19.425955047 +0200 @@ -7,7 +7,7 @@ int i; // The following is accepted due to bug 49171. constexpr void *q = reinterpret_cast ();// { dg-error "" "bug c++/49171" { xfail *-*-* } } -constexpr void *r0 = reinterpret_cast (1);// { dg-error "not a constant expression" } +constexpr void *r0 = reinterpret_cast (1);// { dg-error "not a constant expression|reinterpret_cast from integer to pointer" } constexpr void *r1 = reinterpret_cast (sizeof 'x'); // { dg-error ".reinterpret_cast \\(1\[ul\]\*\\). is not a constant expression" } template Jakub
Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression
On Jun 20 2017, Jason Merrillwrote: > On Tue, Jun 20, 2017 at 5:40 AM, Andreas Schwab wrote: >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 10) >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for excess errors) >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for errors, line 10) >> FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for excess errors) > > I'm not seeing this. Can you give more detail? http://gcc.gnu.org/ml/gcc-testresults/2017-06/msg02172.html Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression
On Tue, Jun 20, 2017 at 5:40 AM, Andreas Schwabwrote: > FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 10) > FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for excess errors) > FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for errors, line 10) > FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for excess errors) I'm not seeing this. Can you give more detail? Jason
Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression
FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for errors, line 10) FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for errors, line 10) FAIL: g++.dg/cpp0x/constexpr-cast.C -std=c++14 (test for excess errors) Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
C++ PATCH for c++/81073, constexpr and static var in statement-expression
The testcase successfully compiles, but then fails to link because we've optimized away the declaration of the variable. We catch this in potential_constant_expression_1, but this path wasn't calling it. Fixed on trunk by always calling that function, not just in templates. With that change, I needed to adjust pce1 to not require that a variable be initialized yet, so that we can check it within the initializer. To avoid that causing some missed errors, decl_maybe_constant_var_p now considers the initializer if it is already known. Fixed on 7 branch more simply, by calling p_c_e from cxx_eval_constant_expression. Tested x86_64-pc-linux-gnu, applying to trunk and 7. commit 46761de0ab74a6983c931c13bfb78c095ae4f651 Author: Jason MerrillDate: Sat Jun 17 00:00:21 2017 -0400 PR c++/81073 - constexpr and static var in statement-expression. * typeck2.c (store_init_value): Always call require_potential_constant_expression. * pt.c (convert_nontype_argument): Likewise. * constexpr.c (potential_constant_expression_1): Adjust message. Use decl_maybe_constant_var_p instead of decl_constant_var_p. * decl2.c (decl_maybe_constant_var_p): Consider initializer. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index ae24e40..569a247 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5212,10 +5212,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, if (want_rval && !var_in_maybe_constexpr_fn (t) && !type_dependent_expression_p (t) - && !decl_constant_var_p (t) + && !decl_maybe_constant_var_p (t) && (strict || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t)) - || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)) + || (DECL_INITIAL (t) + && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t))) && COMPLETE_TYPE_P (TREE_TYPE (t)) && !is_really_empty_class (TREE_TYPE (t))) { @@ -5540,21 +5541,21 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, { if (flags & tf_error) error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared " - "% in % function", tmp); + "% in % context", tmp); return false; } else if (CP_DECL_THREAD_LOCAL_P (tmp)) { if (flags & tf_error) error_at (DECL_SOURCE_LOCATION (tmp), "%qD declared " - "% in % function", tmp); + "% in % context", tmp); return false; } else if (!DECL_NONTRIVIALLY_INITIALIZED_P (tmp)) { if (flags & tf_error) error_at (DECL_SOURCE_LOCATION (tmp), "uninitialized " - "variable %qD in % function", tmp); + "variable %qD in % context", tmp); return false; } } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 72239ec..a475146 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4145,10 +4145,19 @@ decl_maybe_constant_var_p (tree decl) /* A proxy isn't constant. */ return false; if (TREE_CODE (type) == REFERENCE_TYPE) -/* References can be constant. */ +/* References can be constant. */; + else if (CP_TYPE_CONST_NON_VOLATILE_P (type) + && INTEGRAL_OR_ENUMERATION_TYPE_P (type)) +/* And const integers. */; + else +return false; + + if (DECL_INITIAL (decl) + && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) +/* We know the initializer, and it isn't constant. */ +return false; + else return true; - return (CP_TYPE_CONST_NON_VOLATILE_P (type) - && INTEGRAL_OR_ENUMERATION_TYPE_P (type)); } /* Complain that DECL uses a type with no linkage. In C++98 mode this is diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e5238ad..69ca929 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6585,10 +6585,10 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (complain & tf_error) { int errs = errorcount, warns = warningcount + werrorcount; - if (processing_template_decl - && !require_potential_constant_expression (expr)) - return NULL_TREE; - expr = cxx_constant_value (expr); + if (!require_potential_constant_expression (expr)) + expr = error_mark_node; + else + expr = cxx_constant_value (expr); if (errorcount > errs || warningcount + werrorcount > warns) inform (loc, "in template argument for type %qT ", type); if (expr == error_mark_node) diff --git