aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-02-27 03:13:16 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-02-27 03:13:16 -0500
commitacfd3fffee80262c74de0e4480b983d7bf7fbd8e (patch)
treea340fb7ef2eb7e37ddb07f9b7a12717239727292
parentfe8e67ef97640f9f65c05dbf96401d2bcb3d75d7 (diff)
downloadgcc-acfd3fffee80262c74de0e4480b983d7bf7fbd8e.zip
gcc-acfd3fffee80262c74de0e4480b983d7bf7fbd8e.tar.gz
gcc-acfd3fffee80262c74de0e4480b983d7bf7fbd8e.tar.bz2
re PR c++/47897 ([C++0x] static const member variable is not constant expression)
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/semantics.c79
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C9
-rw-r--r--gcc/testsuite/g++.dg/debug/debug7.C1
-rw-r--r--gcc/testsuite/g++.dg/template/function1.C9
8 files changed, 82 insertions, 45 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3dba66e..8283362 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 199084a..a33a7ed 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3cb2809..b23419a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C b/gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
index 8ee8824..ea8f1eb 100644
--- a/gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
@@ -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
index 0000000..32db1f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C
@@ -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;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C b/gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C
index 028669e..66cbd4b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/template-function1.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/debug/debug7.C b/gcc/testsuite/g++.dg/debug/debug7.C
index 31d47ed..8731cf8 100644
--- a/gcc/testsuite/g++.dg/debug/debug7.C
+++ b/gcc/testsuite/g++.dg/debug/debug7.C
@@ -1,4 +1,5 @@
// { dg-do compile }
+// { dg-prune-output "note" }
void f (int);
diff --git a/gcc/testsuite/g++.dg/template/function1.C b/gcc/testsuite/g++.dg/template/function1.C
index 8a112c1..bceed9d 100644
--- a/gcc/testsuite/g++.dg/template/function1.C
+++ b/gcc/testsuite/g++.dg/template/function1.C
@@ -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;