Hi,
On 10/03/2013 04:02 PM, Jason Merrill wrote:
On 10/02/2013 09:02 PM, Paolo Carlini wrote:
- save_template_attributes (&attributes, decl);
+ if (attributes != error_mark_node)
+ save_template_attributes (&attributes, decl);
I'd rather make save_template_attributes handle error_mark_node
appropriately.
+ if (attributes != error_mark_node)
+ cp_check_const_attributes (attributes);
Likewise.
Indeed. It occurred to me that we may have preferred this solution,
consistent with most of other places where we handle error_mark_node. I
hesitated only because the helpers are called only from that one place.
Anyway, I tested the below.
Thanks,
Paolo.
////////////////////
/cp
2013-10-04 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/58584
* decl2.c (save_template_attributes): Handle error_mark_node as
*attr_p argument.
(cp_check_const_attributes): Likewise for attributes.
* parser.c (cp_parser_std_attribute_spec): When alignas_expr is an
error_mark_node call cp_parser_skip_to_end_of_statement.
/testsuite
2013-10-04 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/58584
* g++.dg/cpp0x/gen-attrs-55.C: New.
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 203152)
+++ cp/decl2.c (working copy)
@@ -1218,10 +1218,12 @@ splice_template_attributes (tree *attr_p, tree dec
static void
save_template_attributes (tree *attr_p, tree *decl_p)
{
- tree late_attrs = splice_template_attributes (attr_p, *decl_p);
tree *q;
- tree old_attrs = NULL_TREE;
+ if (attr_p && *attr_p == error_mark_node)
+ return;
+
+ tree late_attrs = splice_template_attributes (attr_p, *decl_p);
if (!late_attrs)
return;
@@ -1230,7 +1232,7 @@ save_template_attributes (tree *attr_p, tree *decl
else
q = &TYPE_ATTRIBUTES (*decl_p);
- old_attrs = *q;
+ tree old_attrs = *q;
/* Merge the late attributes at the beginning with the attribute
list. */
@@ -1318,6 +1320,9 @@ cp_reconstruct_complex_type (tree type, tree botto
static void
cp_check_const_attributes (tree attributes)
{
+ if (attributes == error_mark_node)
+ return;
+
tree attr;
for (attr = attributes; attr; attr = TREE_CHAIN (attr))
{
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 203152)
+++ cp/parser.c (working copy)
@@ -21458,6 +21466,8 @@ cp_parser_std_attribute_spec (cp_parser *parser)
alignas_expr =
cp_parser_assignment_expression (parser, /*cast_p=*/false,
/**cp_id_kind=*/NULL);
+ if (alignas_expr == error_mark_node)
+ cp_parser_skip_to_end_of_statement (parser);
if (alignas_expr == NULL_TREE
|| alignas_expr == error_mark_node)
return alignas_expr;
Index: testsuite/g++.dg/cpp0x/gen-attrs-55.C
===================================================================
--- testsuite/g++.dg/cpp0x/gen-attrs-55.C (revision 0)
+++ testsuite/g++.dg/cpp0x/gen-attrs-55.C (working copy)
@@ -0,0 +1,12 @@
+// PR c++/58584
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ int i alignas(this); // { dg-error "17:invalid use of 'this'" }
+};
+
+template<int> struct B
+{
+ int j alignas(this); // { dg-error "17:invalid use of 'this'" }
+};