re PR c++/47897 ([C++0x] static const member variable is not constant expression)
authorJason Merrill <jason@redhat.com>
Sun, 27 Feb 2011 08:13:16 +0000 (03:13 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 27 Feb 2011 08:13:16 +0000 (03:13 -0500)
PR c++/47897
* semantics.c (non_const_var_error): Split out from...
(cxx_eval_constant_expression): ...here.
(potential_constant_expression_1) [VAR_DECL]: Use it.
Allow dependent variables.

From-SVN: r170532

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C
gcc/testsuite/g++.dg/debug/debug7.C
gcc/testsuite/g++.dg/template/function1.C

index 3dba66e335bbc7a16e5e77bc6a58af33d2fcd458..828336212b3d266c7128e2aee4661e7e5f55ee46 100644 (file)
@@ -1,3 +1,11 @@
+2011-02-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/47897
+       * semantics.c (non_const_var_error): Split out from...
+       (cxx_eval_constant_expression): ...here.
+       (potential_constant_expression_1) [VAR_DECL]: Use it.
+       Allow dependent variables.
+
 2011-02-24  Jason Merrill  <jason@redhat.com>
 
        * parser.c (cp_parser_constant_expression): Set
index 199084a60081fd187fac86869866ca057d95a34e..a33a7edd314f7d30d325aa889b1588149bb809d7 100644 (file)
@@ -6704,6 +6704,46 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t,
   return r;
 }
 
+/* Complain about R, a VAR_DECL, not being usable in a constant expression.
+   Shared between potential_constant_expression and
+   cxx_eval_constant_expression.  */
+
+static void
+non_const_var_error (tree r)
+{
+  tree type = TREE_TYPE (r);
+  error ("the value of %qD is not usable in a constant "
+        "expression", r);
+  if (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))
+    {
+      if (!CP_TYPE_CONST_P (type))
+       inform (DECL_SOURCE_LOCATION (r),
+               "%q#D is not const", r);
+      else if (CP_TYPE_VOLATILE_P (type))
+       inform (DECL_SOURCE_LOCATION (r),
+               "%q#D is volatile", r);
+      else if (!DECL_INITIAL (r))
+       inform (DECL_SOURCE_LOCATION (r),
+               "%qD was not initialized with a constant "
+               "expression", r);
+      else
+       gcc_unreachable ();
+    }
+  else
+    {
+      if (cxx_dialect >= cxx0x && !DECL_DECLARED_CONSTEXPR_P (r))
+       inform (DECL_SOURCE_LOCATION (r),
+               "%qD was not declared %<constexpr%>", r);
+      else
+       inform (DECL_SOURCE_LOCATION (r),
+               "%qD does not have integral or enumeration type",
+               r);
+    }
+}
+
 /* Attempt to reduce the expression T to a constant value.
    On failure, issue diagnostic and return error_mark_node.  */
 /* FIXME unify with c_fully_fold */
@@ -6744,39 +6784,7 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
       if (DECL_P (r))
        {
          if (!allow_non_constant)
-           {
-             tree type = TREE_TYPE (r);
-             error ("the value of %qD is not usable in a constant "
-                    "expression", r);
-             if (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))
-               {
-                 if (!CP_TYPE_CONST_P (type))
-                   inform (DECL_SOURCE_LOCATION (r),
-                           "%q#D is not const", r);
-                 else if (CP_TYPE_VOLATILE_P (type))
-                   inform (DECL_SOURCE_LOCATION (r),
-                           "%q#D is volatile", r);
-                 else if (!DECL_INITIAL (r))
-                   inform (DECL_SOURCE_LOCATION (r),
-                           "%qD was not initialized with a constant "
-                           "expression", r);
-                 else
-                   gcc_unreachable ();
-               }
-             else
-               {
-                 if (cxx_dialect >= cxx0x && !DECL_DECLARED_CONSTEXPR_P (r))
-                   inform (DECL_SOURCE_LOCATION (r),
-                           "%qD was not declared %<constexpr%>", r);
-                 else
-                   inform (DECL_SOURCE_LOCATION (r),
-                           "%qD does not have integral or enumeration type",
-                           r);
-               }
-           }
+           non_const_var_error (r);
          *non_constant_p = true;
        }
       break;
@@ -7371,10 +7379,11 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
       return potential_constant_expression_1 (TREE_OPERAND (t, 0), rval, flags);
 
     case VAR_DECL:
-      if (want_rval && !decl_constant_var_p (t))
+      if (want_rval && !decl_constant_var_p (t)
+         && !dependent_type_p (TREE_TYPE (t)))
         {
           if (flags & tf_error)
-            error ("variable %qD is not declared constexpr", t);
+            non_const_var_error (t);
           return false;
         }
       return true;
index 3cb2809056b13631ece174cfba809700020e7a07..b23419a322c02cbafcb1c903b3ba2a62d49a02ea 100644 (file)
@@ -1,3 +1,11 @@
+2011-02-26  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/regress/template-const1.C: New.
+       * g++.dg/cpp0x/regress/template-function1.C: Adjust.
+       * g++.dg/template/function1.C: Adjust.
+       * g++.dg/cpp0x/regress/debug-debug7.C: Adjust.
+       * g++.dg/debug/debug7.C: Adjust.
+
 2011-02-26  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/47886
index 8ee8824719d84ec71011030745145d720eee675a..ea8f1eb2e6c119b5f972307d3914985b2673ff46 100644 (file)
@@ -7,8 +7,8 @@ int
 main() {
 
   int a = 4;
-  int b = 5;
-  int (*x)[b] = new int[a][b]; // { dg-error "" }
+  int b = 5;                   // { dg-message "not const" }
+  int (*x)[b] = new int[a][b]; // { dg-error "not usable" }
 
   x[2][1] = 7;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C b/gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C
new file mode 100644 (file)
index 0000000..32db1f8
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/47897
+// { dg-options -std=c++0x }
+
+template < typename T, T N >
+struct S
+{
+    static const T value = N;
+    typedef S< T, value + 1 > next;
+};
index 028669e511e23ad7963b48d9449b78018e3e4028..66cbd4ba124efe8ae15cf7673b5393a5001ceda7 100644 (file)
@@ -1,28 +1,29 @@
 // PR c++/38647
 // { dg-do compile }
 // { dg-options "-std=c++0x" }
+// { dg-prune-output "note" }
 
 template<const char *, int> struct A {};
 const char func[] = "abc";
-template<int N> struct A<func, N> {};  // { dg-error "cannot appear|is invalid|not a valid|not declared constexpr" }
+template<int N> struct A<func, N> {};  // { dg-error "cannot appear|is invalid|not a valid|constant expression" }
 
 char a1[1];
 A<a1, 0> a;
 
 template<const char *, int> struct B {};
-template<int N> struct B<__FUNCTION__, N> {};  // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
+template<int N> struct B<__FUNCTION__, N> {};  // { dg-error "cannot appear|is invalid|is not a valid|constant expression" }
 
 char b1[1];
 B<b1, 0> b;
 
 template<const char *, int> struct C {};
-template<int N> struct C<__PRETTY_FUNCTION__, N> {};   // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
+template<int N> struct C<__PRETTY_FUNCTION__, N> {};   // { dg-error "cannot appear|is invalid|is not a valid|constant expression" }
 
 char c1[1];
 C<c1, 0> c;
 
 template<const char *, int> struct D {};
-template<int N> struct D<__func__, N> {};      // { dg-error "cannot appear|is invalid|is not a valid|function scope|not declared constexpr" }
+template<int N> struct D<__func__, N> {};      // { dg-error "cannot appear|is invalid|is not a valid|function scope|constant expression" }
 
 char d1[1];
 D<d1, 0> d;
index 31d47eda78f4178b62fdaa03432692d017260fe1..8731cf81da7b1661676d11238813512be5c14a5c 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile }
+// { dg-prune-output "note" }
 
 void f (int);
 
index 8a112c1459f81f33132f80771fd02780e01cdf54..bceed9d68f92fa4a17e99b095aff7f9def110ef8 100644 (file)
@@ -1,27 +1,28 @@
 // PR c++/38647
 // { dg-do compile }
+// { dg-prune-output "note" }
 
 template<const char *, int> struct A {};
 const char func[] = "abc";
-template<int N> struct A<func, N> {};  // { dg-error "cannot appear|is invalid|not a valid|not declared constexpr" }
+template<int N> struct A<func, N> {};  // { dg-error "cannot appear|is invalid|not a valid|constant expression" }
 
 char a1[1];
 A<a1, 0> a;
 
 template<const char *, int> struct B {};
-template<int N> struct B<__FUNCTION__, N> {};  // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
+template<int N> struct B<__FUNCTION__, N> {};  // { dg-error "cannot appear|is invalid|is not a valid|constant expression" }
 
 char b1[1];
 B<b1, 0> b;
 
 template<const char *, int> struct C {};
-template<int N> struct C<__PRETTY_FUNCTION__, N> {};   // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
+template<int N> struct C<__PRETTY_FUNCTION__, N> {};   // { dg-error "cannot appear|is invalid|is not a valid|constant expression" }
 
 char c1[1];
 C<c1, 0> c;
 
 template<const char *, int> struct D {};
-template<int N> struct D<__func__, N> {};      // { dg-error "cannot appear|is invalid|is not a valid|function scope|not declared constexpr" }
+template<int N> struct D<__func__, N> {};      // { dg-error "cannot appear|is invalid|is not a valid|function scope|constant expression" }
 
 char d1[1];
 D<d1, 0> d;