On Fri, Jan 12, 2018 at 01:13:17PM -0500, Jason Merrill wrote:
> On Thu, Jan 11, 2018 at 5:11 PM, Paolo Carlini <paolo.carl...@oracle.com> 
> wrote:
> > On 11/01/2018 21:33, Jason Merrill wrote:
> >> On 01/10/2018 06:50 PM, Paolo Carlini wrote:
> >>>
> >>> thus the below is a rather "dull" solution at the level of
> >>> cplus_decl_attributes itself: cp_check_const_attributes is tweaked to 
> >>> check
> >>> for error_mark_node at each outer iteration
> >>
> >> This shouldn't be necessary; we should have returned error_mark_node for
> >> the attribute list rather than append it to something else, in which case
> >> the existing check for attributes == error_mark_node would have done the
> >> job.
> >
> > Indeed. That seems the most straightforward way to approach the issue.
> > Thanks.
> >
> > In grokdeclarator we could either explicitly assign error_mark_node to
> > *attrlist (instead of chaining) or simply drop the erroneous
> > declarator->std_attributes. Both solutions appear to work fine in practice,
> > pass testing.
> 
> Hmm, I think dropping the attributes is reasonable for grokdeclarator
> to do as error-recovery, similarly to how it discards an ill-formed
> exception-specification.  But let's assert seen_error() in that case.

PR83824 is simiar to this PR, just in a different spot, but again:
13406               decl_specs->attributes
13407                 = chainon (decl_specs->attributes,
13408                            attrs);
in parser.c and decl_specs->attributes is error_mark_node and attrs
is error_mark_node too, yet seen_error () is false.  The reason for that
is that we are doing tentative parsing here, so e.g.
      if (!parens.require_close (parser))
        return error_mark_node;
doesn't report any error but just returns error_mark_node.
So, either we want to go with what Paolo posted even in this case,
i.e. turn decl_specs->attributes into error_mark_node if attrs
is error_mark_node, and don't chainon anything to it if decl_specs->attributes
is already error_mark_node, e.g. something like:
if (attrs == error_mark_node || decl_specs->attributes == error_mark_node)
  decl_specs->attributes = error_mark_node;
else
  decl_specs->attributes = chainon (decl_specs->attributes, attrs);
or we can not add error_mark_node attributes at all, but we can't assert
seen_error () in that case; perhaps track in a side boolean in decl_specs
whether attributes is errorneous.

        Jakub

Reply via email to