Bug 1321014 - Respect MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS for the purpose of identifying GC types and pointers, r=jonco

--HG--
extra : topic : hazard
extra : rebase_source : bdaf0ae60a6b45c9d44294aa9c2bc31a8811bdbd
extra : source : c7b32ffa822e353b5479b6224194e3cdfd135e65
This commit is contained in:
Steve Fink 2018-07-20 18:36:20 -07:00
parent 6c7cf8b65e
commit b5b78d5525
15 changed files with 225 additions and 53 deletions

View file

@ -36,9 +36,12 @@ ac_add_options --without-ccache
ac_add_options --disable-replace-malloc ac_add_options --disable-replace-malloc
CFLAGS="$CFLAGS -Wno-attributes" # -Wattributes is very verbose due to attributes being ignored on template
CPPFLAGS="$CPPFLAGS -Wno-attributes" # instantiations. -Wignored-attributes is very verbose due to attributes being
CXXFLAGS="$CXXFLAGS -Wno-attributes" # ignored on template parameters.
CFLAGS="$CFLAGS -Wno-attributes -Wno-ignored-attributes"
CPPFLAGS="$CPPFLAGS -Wno-attributes -Wno-ignored-attributes"
CXXFLAGS="$CXXFLAGS -Wno-attributes -Wno-ignored-attributes"
NODEJS="$TOOLTOOL_DIR/node/bin/node" NODEJS="$TOOLTOOL_DIR/node/bin/node"

View file

@ -15,15 +15,18 @@
# define JS_HAZ_GC_THING __attribute__((annotate("GC Thing"))) # define JS_HAZ_GC_THING __attribute__((annotate("GC Thing")))
// Mark a type as holding a pointer to a GC thing (eg JS::Value has this // Mark a type as holding a pointer to a GC thing (eg JS::Value has this
// annotation.) // annotation.) "Inherited" by templatized types with
// MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS.
# define JS_HAZ_GC_POINTER __attribute__((annotate("GC Pointer"))) # define JS_HAZ_GC_POINTER __attribute__((annotate("GC Pointer")))
// Mark a type as a rooted pointer, suitable for use on the stack (eg all // Mark a type as a rooted pointer, suitable for use on the stack (eg all
// Rooted<T> instantiations should have this.) // Rooted<T> instantiations should have this.) "Inherited" by templatized types with
// MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS.
# define JS_HAZ_ROOTED __attribute__((annotate("Rooted Pointer"))) # define JS_HAZ_ROOTED __attribute__((annotate("Rooted Pointer")))
// Mark a type as something that should not be held live across a GC, but which // Mark a type as something that should not be held live across a GC, but which
// is not itself a GC pointer. // is not itself a GC pointer. Note that this property is *not* inherited by
// templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS.
# define JS_HAZ_GC_INVALIDATED __attribute__((annotate("Invalidated by GC"))) # define JS_HAZ_GC_INVALIDATED __attribute__((annotate("Invalidated by GC")))
// Mark a class as a base class of rooted types, eg CustomAutoRooter. All // Mark a class as a base class of rooted types, eg CustomAutoRooter. All

View file

@ -56,7 +56,7 @@ class MOZ_STACK_CLASS JS_FRIEND_API(AutoStableStringChars) final
/* Ensure the string is kept alive while we're using its chars. */ /* Ensure the string is kept alive while we're using its chars. */
Rooted<JSString*> s_; Rooted<JSString*> s_;
MOZ_INIT_OUTSIDE_CTOR union { union MOZ_INIT_OUTSIDE_CTOR {
const char16_t* twoByteChars_; const char16_t* twoByteChars_;
const Latin1Char* latin1Chars_; const Latin1Char* latin1Chars_;
}; };

View file

@ -480,7 +480,7 @@ static inline void js_free(void* p)
#define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \ #define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \
template <class T, typename... Args> \ template <class T, typename... Args> \
QUALIFIERS T * \ QUALIFIERS T * \
NEWNAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ MOZ_HEAP_ALLOCATOR NEWNAME(Args&&... args) { \
void* memory = ALLOCATOR(sizeof(T)); \ void* memory = ALLOCATOR(sizeof(T)); \
return MOZ_LIKELY(memory) \ return MOZ_LIKELY(memory) \
? new(memory) T(std::forward<Args>(args)...) \ ? new(memory) T(std::forward<Args>(args)...) \
@ -500,7 +500,7 @@ static inline void js_free(void* p)
#define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS)\ #define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS)\
template <class T, typename... Args> \ template <class T, typename... Args> \
QUALIFIERS mozilla::UniquePtr<T, JS::DeletePolicy<T>> \ QUALIFIERS mozilla::UniquePtr<T, JS::DeletePolicy<T>> \
MAKENAME(Args&&... args) MOZ_HEAP_ALLOCATOR { \ MOZ_HEAP_ALLOCATOR MAKENAME(Args&&... args) { \
T* ptr = NEWNAME<T>(std::forward<Args>(args)...); \ T* ptr = NEWNAME<T>(std::forward<Args>(args)...); \
return mozilla::UniquePtr<T, JS::DeletePolicy<T>>(ptr); \ return mozilla::UniquePtr<T, JS::DeletePolicy<T>>(ptr); \
} }

View file

@ -316,7 +316,7 @@ CanonicalizeNaN(double d)
* conditional move (not speculated) to zero the payload register if the type * conditional move (not speculated) to zero the payload register if the type
* doesn't match. * doesn't match.
*/ */
union MOZ_NON_PARAM alignas(8) Value union alignas(8) Value
{ {
private: private:
uint64_t asBits_; uint64_t asBits_;
@ -929,7 +929,7 @@ union MOZ_NON_PARAM alignas(8) Value
bool isPrivateGCThing() const { bool isPrivateGCThing() const {
return toTag() == JSVAL_TAG_PRIVATE_GCTHING; return toTag() == JSVAL_TAG_PRIVATE_GCTHING;
} }
} JS_HAZ_GC_POINTER; } JS_HAZ_GC_POINTER MOZ_NON_PARAM;
static_assert(sizeof(Value) == 8, static_assert(sizeof(Value) == 8,
"Value size must leave three tag bits, be a binary power, and " "Value size must leave three tag bits, be a binary power, and "

View file

@ -11,11 +11,13 @@ var typeInfo_filename = scriptArgs[1] || "typeInfo.txt";
var typeInfo = { var typeInfo = {
'GCPointers': [], 'GCPointers': [],
'GCThings': [], 'GCThings': [],
'GCInvalidated': [],
'NonGCTypes': {}, // unused 'NonGCTypes': {}, // unused
'NonGCPointers': {}, 'NonGCPointers': {},
'RootedGCThings': {}, 'RootedGCThings': {},
'RootedPointers': {}, 'RootedPointers': {},
'RootedBases': {'JS::AutoGCRooter': true}, 'RootedBases': {'JS::AutoGCRooter': true},
'InheritFromTemplateArgs': {},
// RAII types within which we should assume GC is suppressed, eg // RAII types within which we should assume GC is suppressed, eg
// AutoSuppressGC. // AutoSuppressGC.
@ -44,7 +46,7 @@ function processCSU(csu, body)
if (tag == 'GC Pointer') if (tag == 'GC Pointer')
typeInfo.GCPointers.push(csu); typeInfo.GCPointers.push(csu);
else if (tag == 'Invalidated by GC') else if (tag == 'Invalidated by GC')
typeInfo.GCPointers.push(csu); typeInfo.GCInvalidated.push(csu);
else if (tag == 'GC Thing') else if (tag == 'GC Thing')
typeInfo.GCThings.push(csu); typeInfo.GCThings.push(csu);
else if (tag == 'Suppressed GC Pointer') else if (tag == 'Suppressed GC Pointer')
@ -55,6 +57,8 @@ function processCSU(csu, body)
typeInfo.RootedBases[csu] = true; typeInfo.RootedBases[csu] = true;
else if (tag == 'Suppress GC') else if (tag == 'Suppress GC')
typeInfo.GCSuppressors[csu] = true; typeInfo.GCSuppressors[csu] = true;
else if (tag == 'moz_inherit_type_annotations_from_template_args')
typeInfo.InheritFromTemplateArgs[csu] = true;
} }
for (let { 'Base': base } of (body.CSUBaseClass || [])) for (let { 'Base': base } of (body.CSUBaseClass || []))
@ -139,6 +143,47 @@ for (const csu of typeInfo.GCThings)
addGCType(csu); addGCType(csu);
for (const csu of typeInfo.GCPointers) for (const csu of typeInfo.GCPointers)
addGCPointer(csu); addGCPointer(csu);
for (const csu of typeInfo.GCInvalidated)
addGCPointer(csu);
// GC Thing and GC Pointer annotations can be inherited from template args if
// this annotation is used. Think of Maybe<T> for example: Maybe<JSObject*> has
// the same GC rules as JSObject*. But this needs to be done in a conservative
// direction: Maybe<AutoSuppressGC> should not be regarding as suppressing GC
// (because it might still be None).
//
// Note that there is an order-dependence here that is being mostly ignored (eg
// Maybe<Maybe<Cell*>> -- if that is processed before Maybe<Cell*> is
// processed, we won't get the right answer). We'll at least sort by string
// length to make it hard to hit that case.
var inheritors = Object.keys(typeInfo.InheritFromTemplateArgs).sort((a, b) => a.length - b.length);
for (const csu of inheritors) {
// Unfortunately, we just have a string type name, not the full structure
// of a templatized type, so we will have to resort to loose (buggy)
// pattern matching.
//
// Currently, the simplest ways I know of to break this are:
//
// foo<T>::bar<U>
// foo<bar<T,U>>
//
const [_, params_str] = csu.match(/<(.*)>/);
for (let param of params_str.split(",")) {
param = param.replace(/^\s+/, '')
param = param.replace(/\s+$/, '')
const pieces = param.split("*");
const core_type = pieces[0];
const ptrdness = pieces.length - 1;
if (ptrdness > 1)
continue;
const paramDesc = 'template-param-' + param;
const why = '(inherited annotations from ' + param + ')';
if (typeInfo.GCThings.indexOf(core_type) != -1)
markGCType(csu, paramDesc, why, ptrdness, 0, "");
if (typeInfo.GCPointers.indexOf(core_type) != -1)
markGCType(csu, paramDesc, why, ptrdness + 1, 0, "");
}
}
// Everything that inherits from a "Rooted Base" is considered to be rooted. // Everything that inherits from a "Rooted Base" is considered to be rooted.
// This is for things like CustomAutoRooter and its subclasses. // This is for things like CustomAutoRooter and its subclasses.

View file

@ -0,0 +1,46 @@
# This mozconfig is used when compiling the browser for the rooting hazard
# analysis build (labeled H on treeherder). See
# https://wiki.mozilla.org/Javascript:SpiderMonkey:ExactStackRooting
# Do NOT include build/unix/mozconfig.linux because it points directly at the
# tooltool-installed gcc, and the analysis works by wrapping the gcc invocation
# with a script that invokes the real gcc with -fplugin and its configuration
# directives. Instead, duplicate the contents of that mozconfig here:
MOZ_HAZARD=1
# Skip as many non-compile steps as we can.
MOZ_AUTOMATION_BUILD_SYMBOLS=0
MOZ_AUTOMATION_L10N_CHECK=0
MOZ_AUTOMATION_PACKAGE=0
MOZ_AUTOMATION_PACKAGE_TESTS=0
MOZ_AUTOMATION_UPLOAD=0
ac_add_options --enable-js-shell
# The objdir must be at a known location so its path can be stripped from the
# filenames stored by the analysis
mk_add_options MOZ_OBJDIR=obj-analyzed
export LLVM_CONFIG=$TOOLTOOL_DIR/clang/bin/llvm-config
export CBINDGEN="${TOOLTOOL_DIR}/cbindgen/cbindgen"
# The configuration options are chosen to compile the most code
# (--enable-debug, --enable-tests) in the trickiest way possible
# (--enable-optimize) to maximize the chance of seeing tricky static orderings.
ac_add_options --enable-debug
ac_add_options --enable-tests
ac_add_options --enable-optimize
ac_add_options --with-compiler-wrapper=$TOOLTOOL_DIR/sixgill/usr/libexec/sixgill/scripts/wrap_gcc/basecc
ac_add_options --without-ccache
ac_add_options --disable-replace-malloc
# -Wattributes is very verbose due to attributes being ignored on template
# instantiations. -Wignored-attributes is very verbose due to attributes being
# ignored on template parameters.
CFLAGS="$CFLAGS -Wno-attributes -Wno-ignored-attributes"
CPPFLAGS="$CPPFLAGS -Wno-attributes -Wno-ignored-attributes"
CXXFLAGS="$CXXFLAGS -Wno-attributes -Wno-ignored-attributes"
NODEJS="$TOOLTOOL_DIR/node/bin/node"

View file

@ -2,6 +2,11 @@
struct Cell { int f; } ANNOTATE("GC Thing"); struct Cell { int f; } ANNOTATE("GC Thing");
template<typename T, typename U>
struct UntypedContainer {
char data[sizeof(T) + sizeof(U)];
} ANNOTATE("moz_inherit_type_annotations_from_template_args");
struct RootedCell { RootedCell(Cell*) {} } ANNOTATE("Rooted Pointer"); struct RootedCell { RootedCell(Cell*) {} } ANNOTATE("Rooted Pointer");
class AutoSuppressGC_Base { class AutoSuppressGC_Base {
@ -57,6 +62,12 @@ struct GCInDestructor {
} }
}; };
template <typename T>
void
usecontainer(T* value) {
if (value) asm("");
}
Cell* Cell*
f() f()
{ {
@ -85,6 +96,23 @@ f()
Cell* cell5 = &cell; Cell* cell5 = &cell;
usecell(cell5); usecell(cell5);
{
// Templatized container that inherits attributes from Cell*, should
// report a hazard.
UntypedContainer<int, Cell*> container1;
usecontainer(&container1);
GC();
usecontainer(&container1);
}
{
// As above, but with a non-GC type.
UntypedContainer<int, double> container2;
usecontainer(&container2);
GC();
usecontainer(&container2);
}
// Hazard in return value due to ~GCInDestructor // Hazard in return value due to ~GCInDestructor
Cell* cell6 = &cell; Cell* cell6 = &cell;
return cell6; return cell6;

View file

@ -35,6 +35,9 @@ assert(hazmap['cell3'].GCFunction in (
'void halfSuppressedFunction()', 'void unsuppressedFunction()')) 'void halfSuppressedFunction()', 'void unsuppressedFunction()'))
assert(hazmap['<returnvalue>'].GCFunction == 'void GCInDestructor::~GCInDestructor()') assert(hazmap['<returnvalue>'].GCFunction == 'void GCInDestructor::~GCInDestructor()')
assert('container1' in hazmap);
assert('container2' not in hazmap);
# Type names are handy to have in the report. # Type names are handy to have in the report.
assert(hazmap['cell2'].type == 'Cell*') assert(hazmap['cell2'].type == 'Cell*')
assert(hazmap['<returnvalue>'].type == 'Cell*') assert(hazmap['<returnvalue>'].type == 'Cell*')

View file

@ -214,7 +214,7 @@ protected:
// AccessibleCaretEventHub::Terminate() which is called in // AccessibleCaretEventHub::Terminate() which is called in
// PresShell::Destroy(), it frees us automatically. No need to worry if we // PresShell::Destroy(), it frees us automatically. No need to worry if we
// outlive mPresShell. // outlive mPresShell.
nsIPresShell* MOZ_NON_OWNING_REF const mPresShell = nullptr; nsIPresShell* const MOZ_NON_OWNING_REF mPresShell = nullptr;
RefPtr<dom::AnonymousContent> mCaretElementHolder; RefPtr<dom::AnonymousContent> mCaretElementHolder;

View file

@ -262,13 +262,13 @@ public:
}; // class AccessibleCaretEventHubTester }; // class AccessibleCaretEventHubTester
TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret) TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent); TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret) TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchEndEvent); TestPressReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchEndEvent);
} }
@ -296,13 +296,13 @@ AccessibleCaretEventHubTester::TestPressReleaseOnNoCaret(
} }
TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret) TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent); TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret) TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressReleaseOnCaret(CreateTouchStartEvent, CreateTouchEndEvent); TestPressReleaseOnCaret(CreateTouchStartEvent, CreateTouchEndEvent);
} }
@ -340,14 +340,14 @@ AccessibleCaretEventHubTester::TestPressReleaseOnCaret(
} }
TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret) TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent, TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent,
CreateMouseReleaseEvent); CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret) TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressMoveReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchMoveEvent, TestPressMoveReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
CreateTouchEndEvent); CreateTouchEndEvent);
@ -396,14 +396,14 @@ AccessibleCaretEventHubTester::TestPressMoveReleaseOnNoCaret(
} }
TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret) TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent, TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent,
CreateMouseReleaseEvent); CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret) TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestPressMoveReleaseOnCaret(CreateTouchStartEvent, CreateTouchMoveEvent, TestPressMoveReleaseOnCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
CreateTouchEndEvent); CreateTouchEndEvent);
@ -465,7 +465,7 @@ AccessibleCaretEventHubTester::TestPressMoveReleaseOnCaret(
TEST_F(AccessibleCaretEventHubTester, TEST_F(AccessibleCaretEventHubTester,
TestTouchStartMoveEndOnCaretWithTouchCancelIgnored) TestTouchStartMoveEndOnCaretWithTouchCancelIgnored)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
nscoord x0 = 0, y0 = 0; nscoord x0 = 0, y0 = 0;
nscoord x1 = 100, y1 = 100; nscoord x1 = 100, y1 = 100;
@ -524,14 +524,14 @@ MOZ_CAN_RUN_SCRIPT
nsEventStatus_eIgnore);} nsEventStatus_eIgnore);}
TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful) TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestLongTapWithSelectWordSuccessful(CreateMousePressEvent, TestLongTapWithSelectWordSuccessful(CreateMousePressEvent,
CreateMouseReleaseEvent); CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful) TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestLongTapWithSelectWordSuccessful(CreateTouchStartEvent, TestLongTapWithSelectWordSuccessful(CreateTouchStartEvent,
CreateTouchEndEvent); CreateTouchEndEvent);
@ -606,14 +606,14 @@ AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful(
} }
TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed) TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestLongTapWithSelectWordFailed(CreateMousePressEvent, TestLongTapWithSelectWordFailed(CreateMousePressEvent,
CreateMouseReleaseEvent); CreateMouseReleaseEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed) TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestLongTapWithSelectWordFailed(CreateTouchStartEvent, TestLongTapWithSelectWordFailed(CreateTouchStartEvent,
CreateTouchEndEvent); CreateTouchEndEvent);
@ -649,14 +649,14 @@ AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed(
} }
TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll) TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent, TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent,
CreateTouchEndEvent); CreateTouchEndEvent);
} }
TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll) TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent, TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent,
CreateMouseReleaseEvent); CreateMouseReleaseEvent);
@ -750,7 +750,8 @@ AccessibleCaretEventHubTester::TestEventDrivenAsyncPanZoomScroll(
nsEventStatus_eIgnore); nsEventStatus_eIgnore);
} }
TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll) MOZ_CAN_RUN_SCRIPT TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll)
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
TestAsyncPanZoomScroll(); TestAsyncPanZoomScroll();
} }
@ -801,7 +802,7 @@ AccessibleCaretEventHubTester::TestAsyncPanZoomScroll()
} }
TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur) TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
{ {
InSequence dummy; InSequence dummy;
@ -822,7 +823,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur) TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
{ {
InSequence dummy; InSequence dummy;

View file

@ -138,7 +138,7 @@ public:
}; // class AccessibleCaretManagerTester }; // class AccessibleCaretManagerTester
TEST_F(AccessibleCaretManagerTester, TestUpdatesInSelectionMode) TEST_F(AccessibleCaretManagerTester, TestUpdatesInSelectionMode)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Selection)); .WillRepeatedly(Return(CaretMode::Selection));
@ -160,7 +160,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestSingleTapOnNonEmptyInput) TEST_F(AccessibleCaretManagerTester, TestSingleTapOnNonEmptyInput)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -231,7 +231,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestSingleTapOnEmptyInput) TEST_F(AccessibleCaretManagerTester, TestSingleTapOnEmptyInput)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -301,7 +301,8 @@ MOZ_CAN_RUN_SCRIPT
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown); EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
} }
TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput) MOZ_CAN_RUN_SCRIPT TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput)
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -344,7 +345,7 @@ TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput) MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode) TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Selection)); .WillRepeatedly(Return(CaretMode::Selection));
@ -430,7 +431,7 @@ MOZ_CAN_RUN_SCRIPT
TEST_F(AccessibleCaretManagerTester, TEST_F(AccessibleCaretManagerTester,
TestScrollInSelectionModeWithAlwaysTiltPref) TestScrollInSelectionModeWithAlwaysTiltPref)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
// Simulate Firefox Android preference. // Simulate Firefox Android preference.
bool oldPref = StaticPrefs::layout_accessiblecaret_always_tilt(); bool oldPref = StaticPrefs::layout_accessiblecaret_always_tilt();
@ -537,7 +538,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible) TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -598,7 +599,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden) TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -653,7 +654,7 @@ MOZ_CAN_RUN_SCRIPT
} }
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent) TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
EXPECT_CALL(mManager, GetCaretMode()) EXPECT_CALL(mManager, GetCaretMode())
.WillRepeatedly(Return(CaretMode::Cursor)); .WillRepeatedly(Return(CaretMode::Cursor));
@ -725,7 +726,7 @@ MOZ_CAN_RUN_SCRIPT
TEST_F(AccessibleCaretManagerTester, TEST_F(AccessibleCaretManagerTester,
TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref) TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref)
MOZ_CAN_RUN_SCRIPT MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{ {
// Simulate Firefox Android preference. // Simulate Firefox Android preference.
bool oldPref = StaticPrefs::layout_accessiblecaret_caret_shown_when_long_tapping_on_empty_content(); bool oldPref = StaticPrefs::layout_accessiblecaret_caret_shown_when_long_tapping_on_empty_content();

View file

@ -536,7 +536,13 @@
* *
* MOZ_CAN_RUN_SCRIPT: Applies to functions which can run script. Callers of * MOZ_CAN_RUN_SCRIPT: Applies to functions which can run script. Callers of
* this function must also be marked as MOZ_CAN_RUN_SCRIPT, and all refcounted * this function must also be marked as MOZ_CAN_RUN_SCRIPT, and all refcounted
* arguments must be strongly held in the caller. * arguments must be strongly held in the caller. Note that MOZ_CAN_RUN_SCRIPT
* should only be applied to function declarations, not definitions. If you
* need to apply it to a definition (eg because both are generated by a macro)
* use MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION.
* MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION: Same as MOZ_CAN_RUN_SCRIPT, but usable on
* a definition. If the declaration is in a header file, users of that header
* file may not see the annotation.
* MOZ_CAN_RUN_SCRIPT_BOUNDARY: Applies to functions which need to call * MOZ_CAN_RUN_SCRIPT_BOUNDARY: Applies to functions which need to call
* MOZ_CAN_RUN_SCRIPT functions, but should not themselves be considered * MOZ_CAN_RUN_SCRIPT functions, but should not themselves be considered
* MOZ_CAN_RUN_SCRIPT. This is important for some bindings and low level code * MOZ_CAN_RUN_SCRIPT. This is important for some bindings and low level code
@ -714,8 +720,29 @@
* Calls to these methods may be made in functions after calls a * Calls to these methods may be made in functions after calls a
* MOZ_MUST_RETURN_FROM_CALLER function or method. * MOZ_MUST_RETURN_FROM_CALLER function or method.
*/ */
#ifdef MOZ_CLANG_PLUGIN
// gcc emits a nuisance warning -Wignored-attributes because attributes do not
// affect mangled names, and therefore template arguments do not propagate
// their attributes. It is rare that this would affect anything in practice,
// and most compilers are silent about it. Similarly, -Wattributes complains
// about attributes being ignored during template instantiation.
//
// Be conservative and only suppress the warning when running in a
// configuration where it would be emitted, namely when compiling with the
// XGILL_PLUGIN for the rooting hazard analysis (which runs under gcc.) If we
// end up wanting these attributes in general GCC builds, change this to
// something like
//
// #if defined(__GNUC__) && ! defined(__clang__)
//
#ifdef XGILL_PLUGIN
#pragma GCC diagnostic ignored "-Wignored-attributes"
#pragma GCC diagnostic ignored "-Wattributes"
#endif
#if defined(MOZ_CLANG_PLUGIN) || defined(XGILL_PLUGIN)
# define MOZ_CAN_RUN_SCRIPT __attribute__((annotate("moz_can_run_script"))) # define MOZ_CAN_RUN_SCRIPT __attribute__((annotate("moz_can_run_script")))
# define MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION __attribute__((annotate("moz_can_run_script")))
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY __attribute__((annotate("moz_can_run_script_boundary"))) # define MOZ_CAN_RUN_SCRIPT_BOUNDARY __attribute__((annotate("moz_can_run_script_boundary")))
# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
# define MOZ_STATIC_CLASS __attribute__((annotate("moz_global_class"))) # define MOZ_STATIC_CLASS __attribute__((annotate("moz_global_class")))
@ -762,16 +789,20 @@
__attribute__((annotate("moz_may_call_after_must_return"))) __attribute__((annotate("moz_may_call_after_must_return")))
/* /*
* It turns out that clang doesn't like void func() __attribute__ {} without a * It turns out that clang doesn't like void func() __attribute__ {} without a
* warning, so use pragmas to disable the warning. This code won't work on GCC * warning, so use pragmas to disable the warning.
* anyways, so the warning is safe to ignore.
*/ */
# define MOZ_HEAP_ALLOCATOR \ # ifdef __clang__
_Pragma("clang diagnostic push") \ # define MOZ_HEAP_ALLOCATOR \
_Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ _Pragma("clang diagnostic push") \
__attribute__((annotate("moz_heap_allocator"))) \ _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
_Pragma("clang diagnostic pop") __attribute__((annotate("moz_heap_allocator"))) \
_Pragma("clang diagnostic pop")
# else
# define MOZ_HEAP_ALLOCATOR __attribute__((annotate("moz_heap_allocator")))
# endif
#else #else
# define MOZ_CAN_RUN_SCRIPT /* nothing */ # define MOZ_CAN_RUN_SCRIPT /* nothing */
# define MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION /* nothing */
# define MOZ_CAN_RUN_SCRIPT_BOUNDARY /* nothing */ # define MOZ_CAN_RUN_SCRIPT_BOUNDARY /* nothing */
# define MOZ_MUST_OVERRIDE /* nothing */ # define MOZ_MUST_OVERRIDE /* nothing */
# define MOZ_STATIC_CLASS /* nothing */ # define MOZ_STATIC_CLASS /* nothing */
@ -806,10 +837,21 @@
# define MOZ_REQUIRED_BASE_METHOD /* nothing */ # define MOZ_REQUIRED_BASE_METHOD /* nothing */
# define MOZ_MUST_RETURN_FROM_CALLER /* nothing */ # define MOZ_MUST_RETURN_FROM_CALLER /* nothing */
# define MOZ_MAY_CALL_AFTER_MUST_RETURN /* nothing */ # define MOZ_MAY_CALL_AFTER_MUST_RETURN /* nothing */
#endif /* MOZ_CLANG_PLUGIN */ #endif /* defined(MOZ_CLANG_PLUGIN) || defined(XGILL_PLUGIN) */
#define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS #define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS
// gcc has different rules governing attribute placement. Since none of these
// attributes are actually used by the gcc-based static analysis, just
// eliminate them rather than updating all of the code.
#ifdef XGILL_PLUGIN
# undef MOZ_MUST_OVERRIDE
# define MOZ_MUST_OVERRIDE /* nothing */
# undef MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
# define MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION /* nothing */
#endif
#endif /* __cplusplus */ #endif /* __cplusplus */
/** /**

View file

@ -558,7 +558,7 @@ public:
* argument is valid. * argument is valid.
*/ */
template<typename U> template<typename U>
MOZ_IMPLICIT constexpr CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT MOZ_IMPLICIT MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT constexpr CheckedInt(U aValue)
: mValue(T(aValue)), : mValue(T(aValue)),
mIsValid(detail::IsInRange<T>(aValue)) mIsValid(detail::IsInRange<T>(aValue))
{ {

View file

@ -5,6 +5,6 @@ TOP=$(cd ..; pwd)
export MOZBUILD_STATE_PATH=$TOP/mozbuild-state export MOZBUILD_STATE_PATH=$TOP/mozbuild-state
[ -d $MOZBUILD_STATE_PATH ] || mkdir $MOZBUILD_STATE_PATH [ -d $MOZBUILD_STATE_PATH ] || mkdir $MOZBUILD_STATE_PATH
export MOZCONFIG=$SOURCE/browser/config/mozconfigs/linux64/hazards export MOZCONFIG=$SOURCE/js/src/devtools/rootAnalysis/mozconfig.haz
exec ./mach build -v -j8 exec ./mach build -v -j8