C++ PATCH for c++/86608, reading constexpr volatile variable

Marek Polacek polacek@redhat.com
Tue Dec 11 01:49:00 GMT 2018


A template-argument for a non-type template-parameter shall be a converted
constant expression.  But an lvalue-to-rvalue conversion applied to a volatile
glvalue is not allowed to be part of the evaluation of a constant expression.
So this test should be rejected.

The non_const_var_error tweaks are needed to give the correct diagnostic.

I don't plan to backport this to older branches, unless you think otherwise.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-12-10  Marek Polacek  <polacek@redhat.com>

	PR c++/86608 - reading constexpr volatile variable.
	* constexpr.c (non_const_var_error): Add a boolean parameter.  Use it.
	(cxx_eval_constant_expression): Adjust call to non_const_var_error.
	(potential_constant_expression_1): Also give error when reading a
	constexpr volatile variable.

	* g++.dg/cpp0x/constexpr-volatile2.C: New test.
	* g++.dg/cpp0x/pr65327.C: Add dg-error.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 1c844a8c2ef..e78cc4a81d6 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -3431,10 +3431,11 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
 
 /* Complain about R, a VAR_DECL, not being usable in a constant expression.
    Shared between potential_constant_expression and
-   cxx_eval_constant_expression.  */
+   cxx_eval_constant_expression.  If SKIP_OWN_INIT_P is true, don't report
+   that R was used in its own initializer, as the problem is elsewhere.  */
 
 static void
-non_const_var_error (tree r)
+non_const_var_error (tree r, bool skip_own_init_p)
 {
   tree type = TREE_TYPE (r);
   error ("the value of %qD is not usable in a constant "
@@ -3442,7 +3443,7 @@ non_const_var_error (tree r)
   /* Avoid error cascade.  */
   if (DECL_INITIAL (r) == error_mark_node)
     return;
-  if (DECL_DECLARED_CONSTEXPR_P (r))
+  if (!skip_own_init_p && DECL_DECLARED_CONSTEXPR_P (r))
     inform (DECL_SOURCE_LOCATION (r),
 	    "%qD used in its own initializer", r);
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
@@ -4251,7 +4252,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       if (DECL_P (r))
 	{
 	  if (!ctx->quiet)
-	    non_const_var_error (r);
+	    non_const_var_error (r, /*skip_own_init_p=*/false);
 	  *non_constant_p = true;
 	}
       break;
@@ -5692,7 +5693,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
       if (want_rval
 	  && !var_in_maybe_constexpr_fn (t)
 	  && !type_dependent_expression_p (t)
-	  && !decl_maybe_constant_var_p (t)
+	  && (!decl_maybe_constant_var_p (t) || TREE_THIS_VOLATILE (t))
 	  && (strict
 	      || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
 	      || (DECL_INITIAL (t)
@@ -5701,7 +5702,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
 	  && !is_really_empty_class (TREE_TYPE (t)))
         {
           if (flags & tf_error)
-            non_const_var_error (t);
+	    non_const_var_error (t, TREE_THIS_VOLATILE (t));
           return false;
         }
       return true;
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-volatile2.C gcc/testsuite/g++.dg/cpp0x/constexpr-volatile2.C
new file mode 100644
index 00000000000..2054fb83768
--- /dev/null
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-volatile2.C
@@ -0,0 +1,13 @@
+// PR c++/86608
+// { dg-do compile { target c++11 } }
+
+template<typename T, T v> struct X {};
+
+int
+main ()
+{
+  static constexpr volatile int a = 3;
+  constexpr volatile int b = 2;
+  return (sizeof(X<decltype(a), a>) // { dg-error "not usable in a constant expression" }
+	  + sizeof(X<decltype(b), b>)); // { dg-error "not usable in a constant expression" }
+}
diff --git gcc/testsuite/g++.dg/cpp0x/pr65327.C gcc/testsuite/g++.dg/cpp0x/pr65327.C
index c6cefaba692..0ba189a24b8 100644
--- gcc/testsuite/g++.dg/cpp0x/pr65327.C
+++ gcc/testsuite/g++.dg/cpp0x/pr65327.C
@@ -15,4 +15,4 @@ constexpr volatile int
 bar ()
 {
   return i;
-}
+} // { dg-error "not usable in a constant expression" }



More information about the Gcc-patches mailing list