Bug 1506439 part 1. Fix CanRunScript analysis handling of arguments that default to null. r=andi
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 13 Mar 2019 02:33:57 +0000
changeset 521642 9b6190dc000dd50c2a971bb795c8df29099eb864
parent 521641 2b58359864c3558a91e6b55e34055830fd769f5e
child 521643 fcaf6f3d0497b245166c01521e3223c58bbd9ed4
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersandi
bugs1506439
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1506439 part 1. Fix CanRunScript analysis handling of arguments that default to null. r=andi Differential Revision: https://phabricator.services.mozilla.com/D23064
build/clang-plugin/CanRunScriptChecker.cpp
build/clang-plugin/CustomMatchers.h
build/clang-plugin/tests/TestCanRunScript.cpp
--- a/build/clang-plugin/CanRunScriptChecker.cpp
+++ b/build/clang-plugin/CanRunScriptChecker.cpp
@@ -37,16 +37,19 @@ void CanRunScriptChecker::registerMatche
               callExpr(allOf(
                 hasAnyArgument(StackSmartPtr),
                 argumentCountIs(1)
               ))
             )
           ),
           // and which is not a parameter of the parent function,
           unless(declRefExpr(to(parmVarDecl()))),
+          // and which is not a default arg with value nullptr, since those are
+          // always safe.
+          unless(cxxDefaultArgExpr(isNullDefaultArg())),
           // and which is not a MOZ_KnownLive wrapped value.
           unless(
             anyOf(
               MozKnownLiveCall,
               // MOZ_KnownLive applied to a RefPtr or nsCOMPtr just returns that
               // same RefPtr/nsCOMPtr type which causes us to have a conversion
               // operator applied after the MOZ_KnownLive.
               cxxMemberCallExpr(on(allOf(hasType(isSmartPtrToRefCounted()),
--- a/build/clang-plugin/CustomMatchers.h
+++ b/build/clang-plugin/CustomMatchers.h
@@ -284,16 +284,23 @@ AST_MATCHER(CXXMethodDecl, isNonVirtual)
   return Decl && !Decl->isVirtual();
 }
 
 AST_MATCHER(FunctionDecl, isMozMustReturnFromCaller) {
   const FunctionDecl *Decl = Node.getCanonicalDecl();
   return Decl && hasCustomAttribute<moz_must_return_from_caller>(Decl);
 }
 
+/// This matcher will select default args which have nullptr as the value.
+AST_MATCHER(CXXDefaultArgExpr, isNullDefaultArg) {
+  const Expr *Expr = Node.getExpr();
+  return Expr && Expr->isNullPointerConstant(Finder->getASTContext(),
+                                             Expr::NPC_NeverValueDependent);
+}
+
 #if CLANG_VERSION_FULL < 309
 /// DISCLAIMER: This is a copy/paste from the Clang source code starting from
 /// Clang 3.9, so that this matcher is supported in lower versions.
 ///
 /// \brief Matches declaration of the function the statement belongs to
 ///
 /// Given:
 /// \code
--- a/build/clang-plugin/tests/TestCanRunScript.cpp
+++ b/build/clang-plugin/tests/TestCanRunScript.cpp
@@ -80,16 +80,20 @@ MOZ_CAN_RUN_SCRIPT void test2_parent6() 
 }
 
 MOZ_CAN_RUN_SCRIPT void test2_parent7() {
   RefCountedBase* t = new RefCountedBase;
   t->method_test(); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
   t->method_test2(); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
 }
 
+MOZ_CAN_RUN_SCRIPT void test2_parent8() {
+  test2(nullptr);
+}
+
 MOZ_CAN_RUN_SCRIPT void test3(int* param) {}
 
 MOZ_CAN_RUN_SCRIPT void test3_parent() {
   test3(new int);
 }
 
 struct RefCountedChild : public RefCountedBase {
   virtual void method_test3() override; // expected-note {{overridden function declared here}} expected-note {{overridden function declared here}}
@@ -197,16 +201,50 @@ MOZ_CAN_RUN_SCRIPT void test_maybe() {
 
 MOZ_CAN_RUN_SCRIPT void test_maybe_2() {
   // FIXME(bz): This should not generate an error!
   mozilla::Maybe<RefPtr<RefCountedBase>> safe;
   safe.emplace(new RefCountedBase);
   (*safe)->method_test(); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
 }
 
+MOZ_CAN_RUN_SCRIPT void test_defaults_helper_1(RefCountedBase* arg = nullptr) {
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_1() {
+  test_defaults_helper_1();
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_2() {
+  RefCountedBase* t = new RefCountedBase;
+  test_defaults_helper_1(t); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_3() {
+  RefPtr<RefCountedBase> t = new RefCountedBase;
+  test_defaults_helper_1(t);
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_helper_2(RefCountedBase* arg = new RefCountedBase()) {
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_4() {
+  test_defaults_helper_2(); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_5() {
+  RefCountedBase* t = new RefCountedBase;
+  test_defaults_helper_2(t); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
+}
+
+MOZ_CAN_RUN_SCRIPT void test_defaults_6() {
+  RefPtr<RefCountedBase> t = new RefCountedBase;
+  test_defaults_helper_2(t);
+}
+
 struct DisallowMemberArgs {
   RefPtr<RefCountedBase> mRefCounted;
   MOZ_CAN_RUN_SCRIPT void foo() {
     mRefCounted->method_test(); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
   }
   MOZ_CAN_RUN_SCRIPT void bar() {
     test2(mRefCounted); // expected-error {{arguments must all be strong refs or parent parameters when calling a function marked as MOZ_CAN_RUN_SCRIPT (including the implicit object argument)}}
   }