зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1691515 - Add MOZ_KNOWN_LIVE member annotation r=andi
Differential Revision: https://phabricator.services.mozilla.com/D107321
This commit is contained in:
Родитель
c21715e694
Коммит
a2323b59a0
|
@ -54,9 +54,8 @@
|
|||
|
||||
void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
|
||||
auto Refcounted = qualType(hasDeclaration(cxxRecordDecl(isRefCounted())));
|
||||
auto StackSmartPtr =
|
||||
ignoreTrivials(declRefExpr(to(varDecl(hasAutomaticStorageDuration(),
|
||||
hasType(isSmartPtrToRefCounted())))));
|
||||
auto StackSmartPtr = ignoreTrivials(declRefExpr(to(varDecl(
|
||||
hasAutomaticStorageDuration(), hasType(isSmartPtrToRefCounted())))));
|
||||
auto ConstMemberOfThisSmartPtr =
|
||||
memberExpr(hasType(isSmartPtrToRefCounted()), hasType(isConstQualified()),
|
||||
hasObjectExpression(cxxThisExpr()));
|
||||
|
@ -76,13 +75,17 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
|
|||
|
||||
// Params of the calling function are presumed live, because it itself should
|
||||
// be MOZ_CAN_RUN_SCRIPT. Note that this is subject to
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 a the moment.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 at the moment.
|
||||
auto KnownLiveParam = anyOf(
|
||||
// "this" is OK
|
||||
cxxThisExpr(),
|
||||
// A parameter of the calling function is OK.
|
||||
declRefExpr(to(parmVarDecl())));
|
||||
|
||||
auto KnownLiveMemberOfParam =
|
||||
memberExpr(hasKnownLiveAnnotation(),
|
||||
hasObjectExpression(ignoreTrivials(KnownLiveParam)));
|
||||
|
||||
// A matcher that matches various things that are known to be live directly,
|
||||
// without making any assumptions about operators.
|
||||
auto KnownLiveBase = anyOf(
|
||||
|
@ -92,6 +95,8 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
|
|||
MozKnownLiveCall,
|
||||
// Params of the caller function.
|
||||
KnownLiveParam,
|
||||
// Members of the params that are marked as MOZ_KNOWN_LIVE
|
||||
KnownLiveMemberOfParam,
|
||||
// Constexpr things.
|
||||
declRefExpr(to(varDecl(isConstexpr()))));
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ ATTR(moz_heap_class)
|
|||
ATTR(moz_implicit)
|
||||
ATTR(moz_inherit_type_annotations_from_template_args)
|
||||
ATTR(moz_is_smartptr_to_refcounted)
|
||||
ATTR(moz_known_live)
|
||||
ATTR(moz_may_call_after_must_return)
|
||||
ATTR(moz_must_override)
|
||||
ATTR(moz_must_return_from_caller_if_this_is_arg)
|
||||
|
|
|
@ -420,6 +420,12 @@ AST_MATCHER(UsingDirectiveDecl, isUsingNamespaceMozillaJava) {
|
|||
!FQName.compare(0, sizeof(PREFIX) - 1, PREFIX);
|
||||
}
|
||||
|
||||
AST_MATCHER(MemberExpr, hasKnownLiveAnnotation) {
|
||||
ValueDecl *Member = Node.getMemberDecl();
|
||||
FieldDecl *Field = dyn_cast<FieldDecl>(Member);
|
||||
return Field && hasCustomAttribute<moz_known_live>(Field);
|
||||
}
|
||||
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
@ -619,3 +619,36 @@ struct DisallowMemberArgsViaReferenceAlias2 {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct AllowMozKnownLiveMember {
|
||||
public:
|
||||
MOZ_KNOWN_LIVE RefCountedBase* mWhatever;
|
||||
MOZ_CAN_RUN_SCRIPT void foo(RefCountedBase* aWhatever) {}
|
||||
MOZ_CAN_RUN_SCRIPT void bar() {
|
||||
foo(mWhatever);
|
||||
}
|
||||
};
|
||||
|
||||
struct AllowMozKnownLiveMemberParent : AllowMozKnownLiveMember {
|
||||
MOZ_CAN_RUN_SCRIPT void baz() {
|
||||
foo(mWhatever);
|
||||
}
|
||||
};
|
||||
|
||||
struct AllowMozKnownLiveParamMember {
|
||||
public:
|
||||
MOZ_CAN_RUN_SCRIPT void foo(AllowMozKnownLiveMember& aAllow) {
|
||||
aAllow.foo(aAllow.mWhatever);
|
||||
}
|
||||
MOZ_CAN_RUN_SCRIPT void bar(AllowMozKnownLiveMemberParent& aAllowParent) {
|
||||
aAllowParent.foo(aAllowParent.mWhatever);
|
||||
}
|
||||
};
|
||||
|
||||
struct DisallowMozKnownLiveMemberNotFromKnownLive {
|
||||
AllowMozKnownLiveMember* mMember;
|
||||
MOZ_CAN_RUN_SCRIPT void foo(RefCountedBase* aWhatever) {}
|
||||
MOZ_CAN_RUN_SCRIPT void bar() {
|
||||
foo(mMember->mWhatever); // expected-error {{arguments must all be strong refs or caller's parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument). 'mMember->mWhatever' is neither.}}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3105,8 +3105,8 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
|
|||
WidgetKeyboardEvent* keyEvent = aVisitor.mEvent->AsKeyboardEvent();
|
||||
if (keyEvent && keyEvent->mKeyCode == NS_VK_RETURN) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
rv = DispatchClickEvent(MOZ_KnownLive(aVisitor.mPresContext), keyEvent,
|
||||
this, false, nullptr, &status);
|
||||
rv = DispatchClickEvent(aVisitor.mPresContext, keyEvent, this, false,
|
||||
nullptr, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
|
|
@ -66,11 +66,9 @@ class MOZ_STACK_CLASS EventChainVisitor {
|
|||
|
||||
/**
|
||||
* The prescontext, possibly nullptr.
|
||||
* Note that the lifetime of mPresContext is guaranteed by the creators so
|
||||
* that you can use this with MOZ_KnownLive() when you set argument
|
||||
* of can-run-script methods to this.
|
||||
* Note that the lifetime of mPresContext is guaranteed by the creators.
|
||||
*/
|
||||
nsPresContext* const mPresContext;
|
||||
MOZ_KNOWN_LIVE nsPresContext* const mPresContext;
|
||||
|
||||
/**
|
||||
* The WidgetEvent which is being dispatched. Never nullptr.
|
||||
|
@ -307,7 +305,7 @@ class MOZ_STACK_CLASS EventChainPostVisitor final
|
|||
// of this class is alive.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
explicit EventChainPostVisitor(EventChainVisitor& aOther)
|
||||
: EventChainVisitor(MOZ_KnownLive(aOther.mPresContext), aOther.mEvent,
|
||||
: EventChainVisitor(aOther.mPresContext, aOther.mEvent,
|
||||
MOZ_KnownLive(aOther.mDOMEvent),
|
||||
aOther.mEventStatus) {}
|
||||
};
|
||||
|
|
|
@ -4192,8 +4192,7 @@ class MOZ_STACK_CLASS ESMEventCB : public EventDispatchingCallback {
|
|||
if (aVisitor.mPresContext) {
|
||||
nsIFrame* frame = aVisitor.mPresContext->GetPrimaryFrameFor(mTarget);
|
||||
if (frame) {
|
||||
frame->HandleEvent(MOZ_KnownLive(aVisitor.mPresContext),
|
||||
aVisitor.mEvent->AsGUIEvent(),
|
||||
frame->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent->AsGUIEvent(),
|
||||
&aVisitor.mEventStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3796,7 +3796,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
// Checkbox and Radio try to submit on Enter press
|
||||
if (keyEvent->mKeyCode != NS_VK_SPACE &&
|
||||
aVisitor.mPresContext) {
|
||||
MaybeSubmitForm(MOZ_KnownLive(aVisitor.mPresContext));
|
||||
MaybeSubmitForm(aVisitor.mPresContext);
|
||||
|
||||
break; // If we are submitting, do not send click event
|
||||
}
|
||||
|
@ -3874,7 +3874,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
mType == NS_FORM_INPUT_NUMBER || IsDateTimeInputType(mType))) {
|
||||
FireChangeEventIfNeeded();
|
||||
if (aVisitor.mPresContext) {
|
||||
rv = MaybeSubmitForm(MOZ_KnownLive(aVisitor.mPresContext));
|
||||
rv = MaybeSubmitForm(aVisitor.mPresContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,8 +162,8 @@ nsresult HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
// will actually create a new event.
|
||||
EventFlags eventFlags;
|
||||
eventFlags.mMultipleActionsPrevented = true;
|
||||
DispatchClickEvent(MOZ_KnownLive(aVisitor.mPresContext), mouseEvent,
|
||||
content, false, &eventFlags, &status);
|
||||
DispatchClickEvent(aVisitor.mPresContext, mouseEvent, content, false,
|
||||
&eventFlags, &status);
|
||||
// Do we care about the status this returned? I don't think we do...
|
||||
// Don't run another <label> off of this click
|
||||
mouseEvent->mFlags.mMultipleActionsPrevented = true;
|
||||
|
|
|
@ -522,8 +522,7 @@ class MOZ_STACK_CLASS nsPresShellEventCB : public EventDispatchingCallback {
|
|||
frame = mPresShell->GetRootFrame();
|
||||
}
|
||||
if (frame) {
|
||||
frame->HandleEvent(MOZ_KnownLive(aVisitor.mPresContext),
|
||||
aVisitor.mEvent->AsGUIEvent(),
|
||||
frame->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent->AsGUIEvent(),
|
||||
&aVisitor.mEventStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -807,6 +807,7 @@
|
|||
# define MOZ_MAY_CALL_AFTER_MUST_RETURN \
|
||||
__attribute__((annotate("moz_may_call_after_must_return")))
|
||||
# define MOZ_LIFETIME_BOUND __attribute__((annotate("moz_lifetime_bound")))
|
||||
# define MOZ_KNOWN_LIVE __attribute__((annotate("moz_known_live")))
|
||||
|
||||
/*
|
||||
* It turns out that clang doesn't like void func() __attribute__ {} without a
|
||||
|
@ -860,6 +861,7 @@
|
|||
# define MOZ_MUST_RETURN_FROM_CALLER_IF_THIS_IS_ARG /* nothing */
|
||||
# define MOZ_MAY_CALL_AFTER_MUST_RETURN /* nothing */
|
||||
# define MOZ_LIFETIME_BOUND /* nothing */
|
||||
# define MOZ_KNOWN_LIVE /* nothing */
|
||||
# endif /* defined(MOZ_CLANG_PLUGIN) || defined(XGILL_PLUGIN) */
|
||||
|
||||
# define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS
|
||||
|
|
Загрузка…
Ссылка в новой задаче