Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression

2017-06-21 Thread Jason Merrill
On Wed, Jun 21, 2017 at 6:32 AM, Jakub Jelinek  wrote:
> 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

2017-06-21 Thread Jakub Jelinek
On Tue, Jun 20, 2017 at 09:45:10PM +0200, Andreas Schwab wrote:
> On Jun 20 2017, Jason Merrill  wrote:
> 
> > 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

2017-06-20 Thread Andreas Schwab
On Jun 20 2017, Jason Merrill  wrote:

> 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

2017-06-20 Thread Jason Merrill
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?

Jason


Re: C++ PATCH for c++/81073, constexpr and static var in statement-expression

2017-06-20 Thread Andreas Schwab
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

2017-06-19 Thread Jason Merrill
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 Merrill 
Date:   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