On 1/22/21 4:01 PM, Marek Polacek wrote:
On Thu, Jan 21, 2021 at 09:47:35PM -0500, Jason Merrill via Gcc-patches wrote:
On 1/21/21 5:45 PM, Marek Polacek wrote:
I discovered very strange code in inject_parm_decls:

     if (args && is_this_parameter (args))
       {
         gcc_checking_assert (current_class_ptr == NULL_TREE);
         current_class_ptr = NULL_TREE;

We are tripping up on the assert because when we call inject_parm_decls,
current_class_ptr is set to 'A'.  It was set by inject_this_parameter
after we've parsed the parameter-declaration-clause of the member
function foo.

But then it should be restored (to null) by the ccp = save_ccp a few lines
later.

Indeed.  I glossed over that.  :(
It seems correct to set ccp/ccr to A::B when we're
late parsing the noexcept-specifiers of bar* functions in B, so that
this-> does the right thing.

Agreed.

Since inject_parm_decls can mess with
ccp/ccr, I think best if we properly restore it after the late parsing
of noexcept-specifiers.

pop_injected_parms clears them, which is restoring them if we keep the
assert.

It should also work to clear ccp before calling inject_parm_decls, and
removing the assignment following the assert, should the assert stay.

But why is it non-null before parsing the unparsed_noexcepts?

Now that I've taken another look I see that ccp/ccr are being set
in start_preparsed_function (around line 16566), when we parse the
body of foo in cp_parser_late_parsing_for_member.  Therefore it's
sort of expected that it's still set when we get to B in foo.

Ah! Yes, it's set because we're parsing a local class of A::foo. This all makes more sense to me now. So:

-      gcc_checking_assert (current_class_ptr == NULL_TREE);

Let's keep the assert, and...

+      tree save_ccp = current_class_ptr;
+      tree save_ccr = current_class_ref;

...clear cc* after saving so the assert succeeds

       vec_safe_truncate (unparsed_noexcepts, 0);
+      current_class_ptr = save_ccp;
+      current_class_ref = save_ccr;

No point restoring the original values (for A::foo) here, it won't be usable for any DMI in a local class of A.

OK with those changes.

Jason

Reply via email to