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
This commit is contained in:
parent
fe8e67ef97
commit
acfd3fffee
8 changed files with 82 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
9
gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/regress/template-const1.C
Normal file
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// { dg-do compile }
|
||||
// { dg-prune-output "note" }
|
||||
|
||||
void f (int);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue