This is an archive of the discontinued LLVM Phabricator instance.

[libc++abi] Handle null pointer-to-object [PR64593]
AbandonedPublic

Authored by iains on Aug 24 2023, 1:11 PM.

Details

Reviewers
ldionne
rjmccall
urnathan
Group Reviewers
Restricted Project
Summary

This addresses cases (currently failing) where we throw a null pointer-to-object and is a proposed fix for https://github.com/llvm/llvm-project/issues/64953

We are trying to satisfy the following bullet from the C++ ABI 15.3:

  • the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of:

    o a standard pointer conversion (4.10 [conv.ptr]) not involving conversions to private or protected or ambiguous classes.

    o a qualification conversion.

The existing implementation assesses the ambiguity of bases by computing the offsets to them; ambiguous cases are then when the same base appears at different offsets. This includes indirecting through the vtables to find the offsets to virtual bases.

When the thrown pointer points to a real object, this is quite efficient since if the base is found, not ambiguous and on a public path, the offset is needed to return the adjusted pointer (and the indirections are not particularly expensive to compute).

However, when we throw a null pointer-to-object, this scheme is no longer applicable (and the code currently bypasses the relevant computations, leading to the incorrect catches).


The solution proposed here takes a composite approach:

  1. When the pointer-to-object points to a real instance (well, at least, it is non-null), we use the existing scheme.
  1. When the pointer-to-object is null:
    • We note that there is no real object.
    • When we are processing non-virtual bases, we continue to compute the offsets, but for a notional dummy object based at 0. This is OK, since we never need to access the object content for non-virtual bases.
    • When we are processing a path with one or more virtual bases, we remember a cookie corresponding to the inner-most virtual base found so far (and set the notional offset to 0). Offsets to inner non-virtual bases are then computed as normal.

A base is then ambiguous iff:

  • There is a recorded virtual base cookie and that is different from the current one or..
  • The non-virtual base offsets differ.

When a handler for a pointer succeeds in catching a base pointer for a thrown null pointer-to-object, we still return a nullptr (so the adjustment to the pointer is not required and need not be computed).

Since we noted that there was no object when starting the search for ambiguous bases, we know that we can skip the pointer adjustment.

Diff Detail

Event Timeline

iains created this revision.Aug 24 2023, 1:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 24 2023, 1:11 PM
iains updated this revision to Diff 553740.Aug 26 2023, 9:30 AM
iains retitled this revision from [libc++abi] WIP for PR64953. to [libc++abi] Handle null pointer-to-object [PR64593]..
iains edited the summary of this revision. (Show Details)

added handling for virtual bases and a testcase

iains edited the summary of this revision. (Show Details)Aug 26 2023, 9:33 AM
iains edited the summary of this revision. (Show Details)Aug 26 2023, 9:35 AM
iains edited the summary of this revision. (Show Details)Aug 26 2023, 9:53 AM
iains edited the summary of this revision. (Show Details)
iains updated this revision to Diff 553746.Aug 26 2023, 10:25 AM
iains retitled this revision from [libc++abi] Handle null pointer-to-object [PR64593]. to [libc++abi] Handle null pointer-to-object [PR64593].
iains edited the summary of this revision. (Show Details)

update the testcase to remove a case that triggers a GCC warning.

iains published this revision for review.Aug 26 2023, 10:38 AM

Some background since it is relevant to the testing done so far.

@urnathan : I think the strategy outlined in the patch header is necessary - I would welcome your opinion on whether it is sufficient.

There is clearly scope for lots of fallout from changes in this library ... so some notes on testing so far:

Mostly, I work on macOS - where the installed system C++abi lib is libc++abi.
I am working on a patch to allow GCC's libstdc++ to sit on top of libc++abi (to try and resolve some of the issues we face when multiple C++ and C++abi libraries get linked into a single executable).

Testing this combination on the GCC testsuite reveals a number of cases where c++abi has different behaviour (or possibly bugs) w.r.t. to supc++. The cases here are completely reproducible in stand-alone tests and reported in the referenced issue.

The patch does resolve around 85 failing cases where the the common factor is a thrown null pointer-to-object.
The test case passes natively on arm64-apple-darwin21 and on x86_64-apple-darwin21 (via rosetta 2) - I plan to test more widely if there is interest in pursuing this.

Herald added a project: Restricted Project. · View Herald TranscriptAug 26 2023, 10:38 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

Since we are moving to GitHub PRs and there hasn't been any activity here yet, could you move this patch over?

iains added a comment.Sep 2 2023, 8:59 AM

Since we are moving to GitHub PRs and there hasn't been any activity here yet, could you move this patch over?

OK, will do.
I am still trying to get a handle on the new process (especially w.r.t draft patches, stacked ones, stuff already partially reviewed in Phab and not very likely to be completed by Oct... and rebasing). However, this one is stand-alone :)

Since we are moving to GitHub PRs and there hasn't been any activity here yet, could you move this patch over?

OK, will do.
I am still trying to get a handle on the new process (especially w.r.t draft patches, stacked ones, stuff already partially reviewed in Phab and not very likely to be completed by Oct... and rebasing). However, this one is stand-alone :)

Since we are moving to GitHub PRs and there hasn't been any activity here yet, could you move this patch over?

OK, will do.
I am still trying to get a handle on the new process (especially w.r.t draft patches, stacked ones, stuff already partially reviewed in Phab and not very likely to be completed by Oct... and rebasing). However, this one is stand-alone :)

Thanks can you abandon this review after moving it to GitHub?

ldionne added a comment.EditedSep 11 2023, 2:56 PM

This is now https://github.com/llvm/llvm-project/pull/65902, let's abandon here please.

Nevermind me, I got confused.

iains added a comment.Sep 11 2023, 3:17 PM

sorry I did not get to moving this yet - but will try during this week.