parser.c (cp_parser_constant_expression): Set non_integral_constant_expression correctly for C++0x too.
* parser.c (cp_parser_constant_expression): Set non_integral_constant_expression correctly for C++0x too. (cp_parser_static_assert): Allow non-constant expression. (cp_parser_direct_declarator): Expect non_constant_p to be set properly for C++0x. * pt.c (value_dependent_expression_p): Handle TYPEID_EXPR. * semantics.c (maybe_constant_value): Check type_unknown_p too. (potential_rvalue_constant_expression): New. (require_potential_rvalue_constant_expression): New. From-SVN: r170488
This commit is contained in:
parent
8da6ac3b5b
commit
4be5e5b12d
12 changed files with 97 additions and 16 deletions
|
@ -1,3 +1,15 @@
|
|||
2011-02-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* parser.c (cp_parser_constant_expression): Set
|
||||
non_integral_constant_expression correctly for C++0x too.
|
||||
(cp_parser_static_assert): Allow non-constant expression.
|
||||
(cp_parser_direct_declarator): Expect non_constant_p to be set
|
||||
properly for C++0x.
|
||||
* pt.c (value_dependent_expression_p): Handle TYPEID_EXPR.
|
||||
* semantics.c (maybe_constant_value): Check type_unknown_p too.
|
||||
(potential_rvalue_constant_expression): New.
|
||||
(require_potential_rvalue_constant_expression): New.
|
||||
|
||||
2011-02-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-tree.h (DECL_PARM_LEVEL): New.
|
||||
|
|
|
@ -5256,7 +5256,9 @@ extern tree register_constexpr_fundef (tree, tree);
|
|||
extern bool check_constexpr_ctor_body (tree, tree);
|
||||
extern tree ensure_literal_type_for_constexpr_object (tree);
|
||||
extern bool potential_constant_expression (tree);
|
||||
extern bool potential_rvalue_constant_expression (tree);
|
||||
extern bool require_potential_constant_expression (tree);
|
||||
extern bool require_potential_rvalue_constant_expression (tree);
|
||||
extern tree cxx_constant_value (tree);
|
||||
extern tree maybe_constant_value (tree);
|
||||
extern tree maybe_constant_init (tree);
|
||||
|
|
|
@ -5824,12 +5824,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
if (init && TREE_CODE (decl) == VAR_DECL)
|
||||
{
|
||||
DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
|
||||
/* FIXME we rely on TREE_CONSTANT below; basing that on
|
||||
init_const_expr_p is probably wrong for C++0x. */
|
||||
if (init_const_expr_p)
|
||||
{
|
||||
/* Set these flags now for C++98 templates. We'll update the
|
||||
flags in store_init_value for instantiations and C++0x. */
|
||||
/* Set these flags now for templates. We'll update the flags in
|
||||
store_init_value for instantiations. */
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
|
||||
if (decl_maybe_constant_var_p (decl))
|
||||
TREE_CONSTANT (decl) = 1;
|
||||
|
|
|
@ -7266,10 +7266,19 @@ cp_parser_constant_expression (cp_parser* parser,
|
|||
= saved_integral_constant_expression_p;
|
||||
parser->allow_non_integral_constant_expression_p
|
||||
= saved_allow_non_integral_constant_expression_p;
|
||||
if (cxx_dialect >= cxx0x)
|
||||
{
|
||||
/* Require an rvalue constant expression here; that's what our
|
||||
callers expect. Reference constant expressions are handled
|
||||
separately in e.g. cp_parser_template_argument. */
|
||||
bool is_const = potential_rvalue_constant_expression (expression);
|
||||
parser->non_integral_constant_expression_p = !is_const;
|
||||
if (!is_const && !allow_non_constant_p)
|
||||
require_potential_rvalue_constant_expression (expression);
|
||||
}
|
||||
if (allow_non_constant_p)
|
||||
*non_constant_p = parser->non_integral_constant_expression_p;
|
||||
else if (parser->non_integral_constant_expression_p
|
||||
&& cxx_dialect < cxx0x)
|
||||
else if (parser->non_integral_constant_expression_p)
|
||||
expression = error_mark_node;
|
||||
parser->non_integral_constant_expression_p
|
||||
= saved_non_integral_constant_expression_p;
|
||||
|
@ -10212,6 +10221,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
|
|||
tree message;
|
||||
cp_token *token;
|
||||
location_t saved_loc;
|
||||
bool dummy;
|
||||
|
||||
/* Peek at the `static_assert' token so we can keep track of exactly
|
||||
where the static assertion started. */
|
||||
|
@ -10231,11 +10241,12 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
|
|||
/* Parse the `(' starting the static assertion condition. */
|
||||
cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
|
||||
|
||||
/* Parse the constant-expression. */
|
||||
/* Parse the constant-expression. Allow a non-constant expression
|
||||
here in order to give better diagnostics in finish_static_assert. */
|
||||
condition =
|
||||
cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant_p=*/false,
|
||||
/*non_constant_p=*/NULL);
|
||||
/*allow_non_constant_p=*/true,
|
||||
/*non_constant_p=*/&dummy);
|
||||
|
||||
/* Parse the separating `,'. */
|
||||
cp_parser_require (parser, CPP_COMMA, RT_COMMA);
|
||||
|
@ -15115,7 +15126,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant=*/true,
|
||||
&non_constant_p);
|
||||
if (!non_constant_p || cxx_dialect >= cxx0x)
|
||||
if (!non_constant_p)
|
||||
/* OK */;
|
||||
/* Normally, the array bound must be an integral constant
|
||||
expression. However, as an extension, we allow VLAs
|
||||
|
|
|
@ -18091,6 +18091,7 @@ value_dependent_expression_p (tree expression)
|
|||
|
||||
case SIZEOF_EXPR:
|
||||
case ALIGNOF_EXPR:
|
||||
case TYPEID_EXPR:
|
||||
/* A `sizeof' expression is value-dependent if the operand is
|
||||
type-dependent or is a pack expansion. */
|
||||
expression = TREE_OPERAND (expression, 0);
|
||||
|
|
|
@ -7138,6 +7138,7 @@ maybe_constant_value (tree t)
|
|||
tree r;
|
||||
|
||||
if (type_dependent_expression_p (t)
|
||||
|| type_unknown_p (t)
|
||||
|| !potential_constant_expression (t)
|
||||
|| value_dependent_expression_p (t))
|
||||
return t;
|
||||
|
@ -7727,6 +7728,14 @@ potential_constant_expression (tree t)
|
|||
return potential_constant_expression_1 (t, false, tf_none);
|
||||
}
|
||||
|
||||
/* As above, but require a constant rvalue. */
|
||||
|
||||
bool
|
||||
potential_rvalue_constant_expression (tree t)
|
||||
{
|
||||
return potential_constant_expression_1 (t, true, tf_none);
|
||||
}
|
||||
|
||||
/* Like above, but complain about non-constant expressions. */
|
||||
|
||||
bool
|
||||
|
@ -7734,6 +7743,14 @@ require_potential_constant_expression (tree t)
|
|||
{
|
||||
return potential_constant_expression_1 (t, false, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Cross product of the above. */
|
||||
|
||||
bool
|
||||
require_potential_rvalue_constant_expression (tree t)
|
||||
{
|
||||
return potential_constant_expression_1 (t, true, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Constructor for a lambda expression. */
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2011-02-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/constexpr-array-tparm.C: New.
|
||||
* g++.dg/cpp0x/regress/parse-ambig5.C: Copy from parse/ambig5.C.
|
||||
* g++.dg/cpp0x/regress/debug-debug7.C: Copy from debug/debug7.C.
|
||||
* g++.dg/cpp0x/variadic20.C: Adjust expected errors.
|
||||
* g++.dg/cpp0x/regress/template-function1.C: Likewise.
|
||||
|
||||
2011-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR fortran/47878
|
||||
|
|
5
gcc/testsuite/g++.dg/cpp0x/constexpr-array-tparm.C
Normal file
5
gcc/testsuite/g++.dg/cpp0x/constexpr-array-tparm.C
Normal file
|
@ -0,0 +1,5 @@
|
|||
// { dg-options -std=c++0x }
|
||||
|
||||
template <const int I[2]> struct A { int ir[I[0]]; };
|
||||
extern constexpr int ar[2] = { 1, 2 };
|
||||
A<ar> a;
|
19
gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/regress/debug-debug7.C
Normal file
|
@ -0,0 +1,19 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
void f (int);
|
||||
|
||||
int
|
||||
main() {
|
||||
|
||||
int a = 4;
|
||||
int b = 5;
|
||||
int (*x)[b] = new int[a][b]; // { dg-error "" }
|
||||
|
||||
x[2][1] = 7;
|
||||
|
||||
for (int i = 0; i < a; ++i)
|
||||
for (int j = 0; j < b; ++j)
|
||||
f (x[i][j]);
|
||||
delete [] x;
|
||||
}
|
8
gcc/testsuite/g++.dg/cpp0x/regress/parse-ambig5.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/regress/parse-ambig5.C
Normal file
|
@ -0,0 +1,8 @@
|
|||
// PR c++/41786
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
struct A { A(int, char const*); };
|
||||
int main() {
|
||||
int i = 0, *b = &i;
|
||||
A a(int(b[i]), "hello");
|
||||
}
|
|
@ -4,25 +4,25 @@
|
|||
|
||||
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" }
|
||||
template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid|not a valid|not declared constexpr" }
|
||||
|
||||
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" }
|
||||
template<int N> struct B<__FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
|
||||
|
||||
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" }
|
||||
template<int N> struct C<__PRETTY_FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|not declared constexpr" }
|
||||
|
||||
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" }
|
||||
template<int N> struct D<__func__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|function scope|not declared constexpr" }
|
||||
|
||||
char d1[1];
|
||||
D<d1, 0> d;
|
||||
|
|
|
@ -37,9 +37,9 @@ struct metatuple<First, Second, Metafunctions...> { // { dg-error "struct" }
|
|||
|
||||
int a0[metatuple<>::value == 0? 1 : -1];
|
||||
int a1[metatuple<add_pointer>::value == 1? 1 : -1];
|
||||
int a2a[metatuple<add_pointer, add_pointer>::value == 2? 1 : -1]; // { dg-error "ambiguous" }
|
||||
int a2a[metatuple<add_pointer, add_pointer>::value == 2? 1 : -1]; // { dg-error "ambiguous|array bound" }
|
||||
int a2b[metatuple<add_reference, add_reference>::value == 2? 1 : -1];
|
||||
int a3[metatuple<add_pointer, add_reference>::value == 3? 1 : -1]; // { dg-error "ambiguous" }
|
||||
int a3[metatuple<add_pointer, add_reference>::value == 3? 1 : -1]; // { dg-error "ambiguous|array bound" }
|
||||
int a4[metatuple<add_reference>::value == 4? 1 : -1];
|
||||
int a5[metatuple<add_reference, add_pointer>::value == 5? 1 : -1];
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue