summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-25 06:22:51 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-25 06:22:51 +0000
commitcfa61f8435164f3205d70c7e1c5038b2d881aa1d (patch)
tree49b81324ade09d98696d503e866b68909cbe56f6 /gcc/cp
parent9e6b512cd861d5822518aef24fb9bb9a3267cbb1 (diff)
downloadgcc-cfa61f8435164f3205d70c7e1c5038b2d881aa1d.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170488 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/parser.c23
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/semantics.c17
6 files changed, 51 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8637ee0b369..3dba66e335b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ee72322a354..d5a6d5c0763 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 14d530ac988..93c184845f9 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1e8f03bddca..314a2ff2c49 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8d28219fc88..ed9d28b0b2f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8a7dd7d5e62..199084a6008 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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. */