tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestCanRunScript.cpp (43821B)


      1 #include <mozilla/RefPtr.h>
      2 #include <mozilla/Maybe.h>
      3 
      4 #define MOZ_CAN_RUN_SCRIPT __attribute__((annotate("moz_can_run_script")))
      5 #define MOZ_CAN_RUN_SCRIPT_BOUNDARY __attribute__((annotate("moz_can_run_script_boundary")))
      6 
      7 MOZ_CAN_RUN_SCRIPT void test() {
      8 
      9 }
     10 
     11 void test_parent() { // expected-note {{caller function declared here}}
     12  test(); // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT can only be called from functions also marked as MOZ_CAN_RUN_SCRIPT}}
     13 }
     14 
     15 MOZ_CAN_RUN_SCRIPT void test_parent2() {
     16  test();
     17 }
     18 
     19 struct RefCountedBase;
     20 MOZ_CAN_RUN_SCRIPT void test2(RefCountedBase* param) {
     21 
     22 }
     23 
     24 struct RefCountedBase {
     25  void AddRef();
     26  void Release();
     27 
     28  MOZ_CAN_RUN_SCRIPT void method_test() {
     29    test();
     30  }
     31 
     32  MOZ_CAN_RUN_SCRIPT void method_test2() {
     33    test2(this);
     34  }
     35 
     36  virtual void method_test3() { // expected-note {{caller function declared here}}
     37    test(); // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT can only be called from functions also marked as MOZ_CAN_RUN_SCRIPT}}
     38  }
     39 
     40  MOZ_CAN_RUN_SCRIPT void method_test4() {
     41    method_test();
     42  }
     43 
     44  MOZ_CAN_RUN_SCRIPT void method_test5() {
     45    this->method_test();
     46  }
     47 };
     48 
     49 MOZ_CAN_RUN_SCRIPT void testLambda() {
     50  auto doIt = []() MOZ_CAN_RUN_SCRIPT {
     51    test();
     52  };
     53 
     54  auto doItWrong = []() { // expected-note {{caller function declared here}}
     55    test(); // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT can only be called from functions also marked as MOZ_CAN_RUN_SCRIPT}}
     56  };
     57 
     58  doIt();
     59  doItWrong();
     60 }
     61 
     62 void test2_parent() { // expected-note {{caller function declared here}}
     63  test2(new RefCountedBase); // 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).  'new RefCountedBase' is neither.}} \
     64                             // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT can only be called from functions also marked as MOZ_CAN_RUN_SCRIPT}}
     65 }
     66 
     67 MOZ_CAN_RUN_SCRIPT void test2_parent2() {
     68  test2(new RefCountedBase); // 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).  'new RefCountedBase' is neither.}}
     69 }
     70 
     71 MOZ_CAN_RUN_SCRIPT void test2_parent3(RefCountedBase* param) {
     72  test2(param);
     73 
     74  RefCountedBase*& paramRef = param;
     75  test2(paramRef);
     76 }
     77 
     78 MOZ_CAN_RUN_SCRIPT void test2_parent4() {
     79  RefPtr<RefCountedBase> refptr = new RefCountedBase;
     80  test2(refptr);
     81  RefPtr<RefCountedBase>& refptrRef = refptr;
     82  test2(refptrRef);
     83  const RefPtr<RefCountedBase>& refptrConstRef = refptr;
     84  test2(refptrConstRef);
     85 
     86  RefPtr<RefCountedBase> refptrOther = refptr;
     87  RefPtr<RefCountedBase>& refptrRef2 = refptr ? refptr : refptrOther;
     88  test2(refptrRef2);
     89 
     90  RefPtr<RefCountedBase>* refPtrInHeap = new RefPtr<RefCountedBase>;
     91  RefPtr<RefCountedBase>& refptrRefUnsafe1 = *refPtrInHeap;
     92  test2(refptrRefUnsafe1); // 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).  'refptrRefUnsafe1' is neither.}}
     93 
     94  RefPtr<RefCountedBase>& refptrRefUnsafe2 = refPtrInHeap ? *refPtrInHeap : refptr;
     95  test2(refptrRefUnsafe2); // 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).  'refptrRefUnsafe2' is neither.}}
     96 
     97  RefPtr<RefCountedBase>& refptrRefUnsafe3 = refPtrInHeap ? refptr : *refPtrInHeap;
     98  test2(refptrRefUnsafe3); // 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).  'refptrRefUnsafe3' is neither.}}
     99 }
    100 
    101 MOZ_CAN_RUN_SCRIPT void test2_parent5() {
    102  test2(MOZ_KnownLive(new RefCountedBase));
    103 }
    104 
    105 MOZ_CAN_RUN_SCRIPT void test2_parent6() {
    106  RefPtr<RefCountedBase> refptr = new RefCountedBase;
    107  refptr->method_test();
    108  refptr->method_test2();
    109  RefPtr<RefCountedBase>& refptrRef = refptr;
    110  refptrRef->method_test();
    111  refptrRef->method_test2();
    112 
    113  RefPtr<RefCountedBase> refptrOther = refptr;
    114  RefPtr<RefCountedBase>& refptrRef2 = refptr ? refptr : refptrOther;
    115  refptrRef2->method_test();
    116  refptrRef2->method_test2();
    117 
    118  RefPtr<RefCountedBase>* refPtrInHeap = new RefPtr<RefCountedBase>;
    119  RefPtr<RefCountedBase>& refptrRefUnsafe1 = *refPtrInHeap;
    120  refptrRefUnsafe1->method_test(); // 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).  'refptrRefUnsafe1->' is neither.}}
    121  refptrRefUnsafe1->method_test2(); // 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).  'refptrRefUnsafe1->' is neither.}}
    122 
    123  RefPtr<RefCountedBase>& refptrRefUnsafe2 = refPtrInHeap ? *refPtrInHeap : refptr;
    124  refptrRefUnsafe2->method_test(); // 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).  'refptrRefUnsafe2->' is neither.}}
    125  refptrRefUnsafe2->method_test2(); // 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).  'refptrRefUnsafe2->' is neither.}}
    126 
    127  RefPtr<RefCountedBase>& refptrRefUnsafe3 = refPtrInHeap ? refptr : *refPtrInHeap;
    128  refptrRefUnsafe3->method_test(); // 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).  'refptrRefUnsafe3->' is neither.}}
    129  refptrRefUnsafe3->method_test2(); // 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).  'refptrRefUnsafe3->' is neither.}}
    130 }
    131 
    132 MOZ_CAN_RUN_SCRIPT void test2_parent7() {
    133  RefCountedBase* t = new RefCountedBase;
    134  t->method_test(); // 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).  't' is neither.}}
    135  t->method_test2(); // 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).  't' is neither.}}
    136 
    137  RefCountedBase*& tRef = t;
    138  tRef->method_test(); // 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).  'tRef' is neither.}}
    139  tRef->method_test2(); // 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).  'tRef' is neither.}}
    140 }
    141 
    142 MOZ_CAN_RUN_SCRIPT void test2_parent8() {
    143  test2(nullptr);
    144 }
    145 
    146 MOZ_CAN_RUN_SCRIPT void test3(int* param) {}
    147 
    148 MOZ_CAN_RUN_SCRIPT void test3_parent() {
    149  test3(new int);
    150 }
    151 
    152 struct RefCountedChild : public RefCountedBase {
    153  virtual void method_test3() override; // expected-note {{overridden function declared here}} expected-note {{overridden function declared here}} expected-note {{caller function declared here}}
    154 };
    155 
    156 void RefCountedChild::method_test3() {
    157  test(); // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT can only be called from functions also marked as MOZ_CAN_RUN_SCRIPT}}
    158 }
    159 
    160 struct RefCountedSubChild : public RefCountedChild {
    161  MOZ_CAN_RUN_SCRIPT void method_test3() override; // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT cannot override functions that are not marked MOZ_CAN_RUN_SCRIPT}}
    162 };
    163 
    164 void RefCountedSubChild::method_test3() { // expected-error {{functions marked as MOZ_CAN_RUN_SCRIPT cannot override functions that are not marked MOZ_CAN_RUN_SCRIPT}}
    165  test();
    166 }
    167 
    168 MOZ_CAN_RUN_SCRIPT void test4() {
    169  RefPtr<RefCountedBase> refptr1 = new RefCountedChild;
    170  refptr1->method_test3();
    171 
    172  RefPtr<RefCountedBase> refptr2 = new RefCountedSubChild;
    173  refptr2->method_test3();
    174 
    175  RefPtr<RefCountedChild> refptr3 = new RefCountedSubChild;
    176  refptr3->method_test3();
    177 
    178  RefPtr<RefCountedSubChild> refptr4 = new RefCountedSubChild;
    179  refptr4->method_test3();
    180 }
    181 
    182 MOZ_CAN_RUN_SCRIPT_BOUNDARY void test5() {
    183  RefPtr<RefCountedBase> refptr1 = new RefCountedChild;
    184  refptr1->method_test3();
    185 
    186  RefPtr<RefCountedBase> refptr2 = new RefCountedSubChild;
    187  refptr2->method_test3();
    188 
    189  RefPtr<RefCountedChild> refptr3 = new RefCountedSubChild;
    190  refptr3->method_test3();
    191 
    192  RefPtr<RefCountedSubChild> refptr4 = new RefCountedSubChild;
    193  refptr4->method_test3();
    194 }
    195 
    196 // We should be able to call test5 from a non-can_run_script function.
    197 void test5_b() {
    198  test5();
    199 }
    200 
    201 MOZ_CAN_RUN_SCRIPT void test6() {
    202  void* x = new RefCountedBase();
    203  test2((RefCountedBase*)x); // 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).  'x' is neither.}}
    204 }
    205 
    206 MOZ_CAN_RUN_SCRIPT void test_ref(const RefCountedBase&) {
    207 
    208 }
    209 
    210 MOZ_CAN_RUN_SCRIPT void test_ref_1() {
    211  RefCountedBase* t = new RefCountedBase;
    212  test_ref(*t); // 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).  '*t' is neither.}}
    213 }
    214 
    215 MOZ_CAN_RUN_SCRIPT void test_ref_2() {
    216  RefCountedBase* t = new RefCountedBase;
    217  (*t).method_test(); // 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).  '*t' is neither.}}
    218 }
    219 
    220 MOZ_CAN_RUN_SCRIPT void test_ref_3() {
    221  RefCountedBase* t = new RefCountedBase;
    222  auto& ref = *t;
    223  test_ref(ref); // 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).  'ref' is neither.}}
    224 }
    225 
    226 MOZ_CAN_RUN_SCRIPT void test_ref_4() {
    227  RefCountedBase* t = new RefCountedBase;
    228  auto& ref = *t;
    229  ref.method_test(); // 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).  'ref' is neither.}}
    230 }
    231 
    232 MOZ_CAN_RUN_SCRIPT void test_ref_5() {
    233  RefPtr<RefCountedBase> t = new RefCountedBase;
    234  test_ref(*t);
    235 }
    236 
    237 MOZ_CAN_RUN_SCRIPT void test_ref_6() {
    238  RefPtr<RefCountedBase> t = new RefCountedBase;
    239  (*t).method_test();
    240 }
    241 
    242 MOZ_CAN_RUN_SCRIPT void test_ref_7() {
    243  RefPtr<RefCountedBase> t = new RefCountedBase;
    244  auto& ref = *t;
    245  MOZ_KnownLive(ref).method_test();
    246 }
    247 
    248 MOZ_CAN_RUN_SCRIPT void test_ref_8() {
    249  RefPtr<RefCountedBase> t = new RefCountedBase;
    250  auto& ref = *t;
    251  test_ref(MOZ_KnownLive(ref));
    252 }
    253 
    254 MOZ_CAN_RUN_SCRIPT void test_ref_9() {
    255  void* x = new RefCountedBase();
    256  test_ref(*(RefCountedBase*)x); // 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).  '*(RefCountedBase*)x' is neither.}}
    257 }
    258 
    259 MOZ_CAN_RUN_SCRIPT void test_maybe() {
    260  mozilla::Maybe<RefCountedBase*> unsafe;
    261  unsafe.emplace(new RefCountedBase);
    262  (*unsafe)->method_test(); // 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).  '*unsafe' is neither.}}
    263 }
    264 
    265 MOZ_CAN_RUN_SCRIPT void test_maybe_2() {
    266  // FIXME(bz): This should not generate an error!
    267  mozilla::Maybe<RefPtr<RefCountedBase>> safe;
    268  safe.emplace(new RefCountedBase);
    269  (*safe)->method_test(); // expected-error-re {{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).  '(*safe){{(->)?}}' is neither.}}
    270 }
    271 
    272 MOZ_CAN_RUN_SCRIPT void test_defaults_helper_1(RefCountedBase* arg = nullptr) {
    273 }
    274 
    275 MOZ_CAN_RUN_SCRIPT void test_defaults_1() {
    276  test_defaults_helper_1();
    277 }
    278 
    279 MOZ_CAN_RUN_SCRIPT void test_defaults_2() {
    280  RefCountedBase* t = new RefCountedBase;
    281  test_defaults_helper_1(t); // 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).  't' is neither.}}
    282 }
    283 
    284 MOZ_CAN_RUN_SCRIPT void test_defaults_3() {
    285  RefPtr<RefCountedBase> t = new RefCountedBase;
    286  test_defaults_helper_1(t);
    287 }
    288 
    289 MOZ_CAN_RUN_SCRIPT void test_defaults_helper_2(RefCountedBase* arg = new RefCountedBase()) { // 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).  'new RefCountedBase()' is neither.}}
    290 }
    291 
    292 MOZ_CAN_RUN_SCRIPT void test_defaults_4() {
    293  test_defaults_helper_2();
    294 }
    295 
    296 MOZ_CAN_RUN_SCRIPT void test_defaults_5() {
    297  RefCountedBase* t = new RefCountedBase;
    298  test_defaults_helper_2(t); // 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).  't' is neither.}}
    299 }
    300 
    301 MOZ_CAN_RUN_SCRIPT void test_defaults_6() {
    302  RefPtr<RefCountedBase> t = new RefCountedBase;
    303  test_defaults_helper_2(t);
    304 }
    305 
    306 MOZ_CAN_RUN_SCRIPT void test_arg_deref_helper(RefCountedBase&) {
    307 }
    308 
    309 MOZ_CAN_RUN_SCRIPT void test_arg_deref(RefCountedBase* arg) {
    310  test_arg_deref_helper(*arg);
    311 }
    312 
    313 struct RefCountedDerefTester : public RefCountedBase {
    314  MOZ_CAN_RUN_SCRIPT void foo() {
    315    test_arg_deref_helper(*this);
    316  }
    317 };
    318 
    319 struct DisallowMemberArgs {
    320  RefPtr<RefCountedBase> mRefCounted;
    321  MOZ_CAN_RUN_SCRIPT void foo() {
    322    mRefCounted->method_test(); // expected-error-re {{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).  'mRefCounted{{(->)?}}' is neither.}}
    323 
    324    RefPtr<RefCountedBase>& unsafeMemberRef = mRefCounted;
    325    unsafeMemberRef->method_test(); // expected-error-re {{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).  'unsafeMemberRef{{(->)?}}' is neither.}}
    326 
    327    RefPtr<RefCountedBase> safeRefCounted = mRefCounted;
    328    RefPtr<RefCountedBase>& maybeUnsafeMemberRef1 = mRefCounted ? mRefCounted : safeRefCounted;
    329    maybeUnsafeMemberRef1->method_test(); // expected-error-re {{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).  'maybeUnsafeMemberRef1{{(->)?}}' is neither.}}
    330    RefPtr<RefCountedBase>& maybeUnsafeMemberRef2 = safeRefCounted ? safeRefCounted : mRefCounted;
    331    maybeUnsafeMemberRef2->method_test(); // expected-error-re {{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).  'maybeUnsafeMemberRef2{{(->)?}}' is neither.}}
    332  }
    333  MOZ_CAN_RUN_SCRIPT void bar() {
    334    test2(mRefCounted); // 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).  'mRefCounted' is neither.}}
    335 
    336    RefPtr<RefCountedBase>& unsafeMemberRef = mRefCounted;
    337    test2(unsafeMemberRef); // 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).  'unsafeMemberRef' is neither.}}
    338 
    339    RefPtr<RefCountedBase> safeRefCounted = mRefCounted;
    340    RefPtr<RefCountedBase>& maybeUnsafeMemberRef1 = mRefCounted ? mRefCounted : safeRefCounted;
    341    test2(maybeUnsafeMemberRef1); // 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).  'maybeUnsafeMemberRef1' is neither.}}
    342    RefPtr<RefCountedBase>& maybeUnsafeMemberRef2 = safeRefCounted ? safeRefCounted : mRefCounted;
    343    test2(maybeUnsafeMemberRef2); // 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).  'maybeUnsafeMemberRef2' is neither.}}
    344  }
    345 };
    346 
    347 struct DisallowMemberArgsWithGet {
    348  RefPtr<RefCountedBase> mRefCounted;
    349  MOZ_CAN_RUN_SCRIPT void foo() {
    350    mRefCounted.get()->method_test(); // 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).  'mRefCounted.get()' is neither.}}
    351  }
    352  MOZ_CAN_RUN_SCRIPT void bar() {
    353    test2(mRefCounted.get()); // 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).  'mRefCounted.get()' is neither.}}
    354  }
    355 };
    356 
    357 struct AllowKnownLiveMemberArgs {
    358  RefPtr<RefCountedBase> mRefCounted;
    359  MOZ_CAN_RUN_SCRIPT void foo() {
    360    MOZ_KnownLive(mRefCounted)->method_test();
    361 
    362    RefPtr<RefCountedBase>& unsafeMemberRef = mRefCounted;
    363    MOZ_KnownLive(unsafeMemberRef)->method_test();
    364  }
    365  MOZ_CAN_RUN_SCRIPT void bar() {
    366    test2(MOZ_KnownLive(mRefCounted));
    367 
    368    RefPtr<RefCountedBase>& unsafeMemberRef = mRefCounted;
    369    test2(MOZ_KnownLive(unsafeMemberRef));
    370  }
    371 };
    372 
    373 struct WeakPtrReturner : public RefCountedBase {
    374  RefCountedBase* getWeakPtr() { return new RefCountedBase(); }
    375 };
    376 
    377 struct DisallowMemberCallsOnRandomKnownLive {
    378  RefPtr<WeakPtrReturner> mWeakPtrReturner1;
    379  WeakPtrReturner* mWeakPtrReturner2;
    380 
    381  MOZ_CAN_RUN_SCRIPT void test_refptr_method() {
    382    MOZ_KnownLive(mWeakPtrReturner1)->getWeakPtr()->method_test(); // 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).  'MOZ_KnownLive(mWeakPtrReturner1)->getWeakPtr()' is neither.}}
    383  }
    384 
    385  MOZ_CAN_RUN_SCRIPT void test_refptr_function() {
    386    test2(MOZ_KnownLive(mWeakPtrReturner1)->getWeakPtr()); // 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).  'MOZ_KnownLive(mWeakPtrReturner1)->getWeakPtr()' is neither.}}
    387  }
    388 
    389  MOZ_CAN_RUN_SCRIPT void test_raw_method() {
    390    MOZ_KnownLive(mWeakPtrReturner2)->getWeakPtr()->method_test(); // 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).  'MOZ_KnownLive(mWeakPtrReturner2)->getWeakPtr()' is neither.}}
    391  }
    392 
    393  MOZ_CAN_RUN_SCRIPT void test_raw_function() {
    394    test2(MOZ_KnownLive(mWeakPtrReturner2)->getWeakPtr()); // 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).  'MOZ_KnownLive(mWeakPtrReturner2)->getWeakPtr()' is neither.}}
    395  }
    396 };
    397 
    398 struct AllowConstMemberArgs {
    399  const RefPtr<RefCountedBase> mRefCounted;
    400  MOZ_CAN_RUN_SCRIPT void foo() {
    401    mRefCounted->method_test();
    402 
    403    const RefPtr<RefCountedBase>& safeMemberRef1 = mRefCounted;
    404    safeMemberRef1->method_test();
    405 
    406    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    407    const RefPtr<RefCountedBase>& safeMemberRef2 = safeRefCounted ? safeRefCounted : mRefCounted;
    408    safeMemberRef2->method_test();
    409    const RefPtr<RefCountedBase>& safeMemberRef3 = mRefCounted ? mRefCounted : safeRefCounted;
    410    safeMemberRef3->method_test();
    411  }
    412  MOZ_CAN_RUN_SCRIPT void bar() {
    413    test2(mRefCounted);
    414 
    415    const RefPtr<RefCountedBase>& safeMemberRef1 = mRefCounted;
    416    test2(safeMemberRef1);
    417 
    418    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    419    const RefPtr<RefCountedBase>& safeMemberRef2 = safeRefCounted ? safeRefCounted : mRefCounted;
    420    test2(safeMemberRef2);
    421    const RefPtr<RefCountedBase>& safeMemberRef3 = mRefCounted ? mRefCounted : safeRefCounted;
    422    test2(safeMemberRef3);
    423  }
    424 };
    425 
    426 struct AllowConstMemberArgsWithExplicitThis {
    427  const RefPtr<RefCountedBase> mRefCounted;
    428  MOZ_CAN_RUN_SCRIPT void foo() {
    429    this->mRefCounted->method_test();
    430 
    431    const RefPtr<RefCountedBase>& safeMemberRef1 = this->mRefCounted;
    432    safeMemberRef1->method_test();
    433 
    434    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    435    const RefPtr<RefCountedBase>& safeMemberRef2 = safeRefCounted ? safeRefCounted : this->mRefCounted;
    436    safeMemberRef2->method_test();
    437    const RefPtr<RefCountedBase>& safeMemberRef3 = this->mRefCounted ? this->mRefCounted : safeRefCounted;
    438    safeMemberRef3->method_test();
    439  }
    440  MOZ_CAN_RUN_SCRIPT void bar() {
    441    test2(this->mRefCounted);
    442 
    443    const RefPtr<RefCountedBase>& safeMemberRef1 = this->mRefCounted;
    444    test2(safeMemberRef1);
    445 
    446    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    447    const RefPtr<RefCountedBase>& safeMemberRef2 = safeRefCounted ? safeRefCounted : this->mRefCounted;
    448    test2(safeMemberRef2);
    449    const RefPtr<RefCountedBase>& safeMemberRef3 = this->mRefCounted ? this->mRefCounted : safeRefCounted;
    450    test2(safeMemberRef3);
    451  }
    452 };
    453 
    454 struct DisallowConstMemberArgsOfMembers {
    455  RefPtr<AllowConstMemberArgs> mMember;
    456  MOZ_CAN_RUN_SCRIPT void foo() {
    457    mMember->mRefCounted->method_test(); // expected-error-re {{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->mRefCounted{{(->)?}}' is neither.}}
    458 
    459    const RefPtr<RefCountedBase>& unsafeMemberRef = mMember->mRefCounted;
    460    unsafeMemberRef->method_test(); // expected-error-re {{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).  'unsafeMemberRef{{(->)?}}' is neither.}}
    461 
    462    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    463    const RefPtr<RefCountedBase>& maybeUnsafeMemberRef1 = safeRefCounted ? safeRefCounted : mMember->mRefCounted;
    464    maybeUnsafeMemberRef1->method_test(); // expected-error-re {{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).  'maybeUnsafeMemberRef1{{(->)?}}' is neither.}}
    465    const RefPtr<RefCountedBase>& maybeUnsafeMemberRef2 = mMember->mRefCounted ? mMember->mRefCounted : safeRefCounted;
    466    maybeUnsafeMemberRef2->method_test(); // expected-error-re {{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).  'maybeUnsafeMemberRef2{{(->)?}}' is neither.}}
    467  }
    468  MOZ_CAN_RUN_SCRIPT void bar() {
    469    test2(mMember->mRefCounted); // 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->mRefCounted' is neither.}}
    470 
    471    const RefPtr<RefCountedBase>& unsafeMemberRef = mMember->mRefCounted;
    472    test2(unsafeMemberRef); // 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).  'unsafeMemberRef' is neither.}}
    473 
    474    const RefPtr<RefCountedBase> safeRefCounted = new RefCountedBase;
    475    const RefPtr<RefCountedBase>& maybeUnsafeMemberRef1 = safeRefCounted ? safeRefCounted : mMember->mRefCounted;
    476    test2(maybeUnsafeMemberRef1); // 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).  'maybeUnsafeMemberRef1' is neither.}}
    477    const RefPtr<RefCountedBase>& maybeUnsafeMemberRef2 = mMember->mRefCounted ? mMember->mRefCounted : safeRefCounted;
    478    test2(maybeUnsafeMemberRef2); // 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).  'maybeUnsafeMemberRef2' is neither.}}
    479  }
    480 };
    481 
    482 struct DisallowConstNonRefPtrMemberArgs {
    483  RefCountedBase* const mRefCounted;
    484  MOZ_CAN_RUN_SCRIPT void foo() {
    485    mRefCounted->method_test(); // 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).  'mRefCounted' is neither.}}
    486 
    487    RefCountedBase* const& unsafeMemberRefCounted = mRefCounted;
    488    unsafeMemberRefCounted->method_test(); // 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).  'unsafeMemberRefCounted' is neither.}}
    489  }
    490  MOZ_CAN_RUN_SCRIPT void bar() {
    491    test2(mRefCounted); // 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).  'mRefCounted' is neither.}}
    492 
    493    RefCountedBase* const& unsafeMemberRefCounted = mRefCounted;
    494    test2(unsafeMemberRefCounted); // 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).  'unsafeMemberRefCounted' is neither.}}
    495  }
    496 };
    497 
    498 MOZ_CAN_RUN_SCRIPT void test_temporary_1() {
    499 #ifdef MOZ_CLANG_PLUGIN_ALPHA
    500  RefPtr<RefCountedBase>(new RefCountedBase())->method_test(); // expected-warning {{performance issue: temporary 'RefPtr<RefCountedBase>' is only dereferenced here once which involves short-lived AddRef/Release calls}}
    501 #else
    502  RefPtr<RefCountedBase>(new RefCountedBase())->method_test();
    503 #endif
    504 }
    505 
    506 MOZ_CAN_RUN_SCRIPT void test_temporary_2() {
    507  test_ref(*RefPtr<RefCountedBase>(new RefCountedBase()));
    508 }
    509 
    510 struct WeakSmartPtr {
    511  RefCountedBase* member;
    512 
    513  explicit WeakSmartPtr(RefCountedBase* arg) : member(arg) {}
    514 
    515  RefCountedBase* operator->() const {
    516    return member;
    517  }
    518 
    519  RefCountedBase& operator*() const {
    520    return *member;
    521  }
    522 
    523  operator RefCountedBase*() const {
    524    return member;
    525  }
    526 };
    527 
    528 MOZ_CAN_RUN_SCRIPT void test_temporary_3() {
    529  WeakSmartPtr(new RefCountedBase())->method_test(); // expected-error-re {{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).  'WeakSmartPtr(new RefCountedBase()){{(->)?}}' is neither.}}
    530 }
    531 
    532 MOZ_CAN_RUN_SCRIPT void test_temporary_4() {
    533  test_ref(*WeakSmartPtr(new RefCountedBase())); // 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).  '*WeakSmartPtr(new RefCountedBase())' is neither.}}
    534 }
    535 
    536 MOZ_CAN_RUN_SCRIPT void test_temporary_5() {
    537  test2(WeakSmartPtr(new RefCountedBase())); // 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).  'WeakSmartPtr(new RefCountedBase())' is neither.}}
    538 }
    539 
    540 
    541 template<typename T>
    542 struct TArray {
    543  TArray() {
    544    mArray[0] = new RefCountedBase();
    545  }
    546  T& operator[](unsigned int index) { return mArray[index]; }
    547  T mArray[1];
    548 };
    549 
    550 struct DisallowRawTArrayElement {
    551  TArray<RefCountedBase*> mArray;
    552  MOZ_CAN_RUN_SCRIPT void foo() {
    553    mArray[0]->method_test(); // 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).  'mArray[0]' is neither.}}
    554  }
    555  MOZ_CAN_RUN_SCRIPT void bar() {
    556    test2(mArray[0]); // 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).  'mArray[0]' is neither.}}
    557  }
    558 };
    559 
    560 struct DisallowRefPtrTArrayElement {
    561  TArray<RefPtr<RefCountedBase>> mArray;
    562  MOZ_CAN_RUN_SCRIPT void foo() {
    563    mArray[0]->method_test(); // expected-error-re {{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).  'mArray[0]{{(->)?}}' is neither.}}
    564  }
    565  MOZ_CAN_RUN_SCRIPT void bar() {
    566    test2(mArray[0]); // 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).  'mArray[0]' is neither.}}
    567  }
    568 };
    569 
    570 struct AllowConstexprMembers {
    571  static constexpr RefCountedBase* mRefCounted = nullptr;
    572  static constexpr RefCountedBase* mRefCounted2 = nullptr;
    573  MOZ_CAN_RUN_SCRIPT void foo() {
    574    mRefCounted->method_test();
    575  }
    576  MOZ_CAN_RUN_SCRIPT void bar() {
    577    test2(mRefCounted);
    578  }
    579  MOZ_CAN_RUN_SCRIPT void baz() {
    580    test_ref(*mRefCounted);
    581  }
    582 };
    583 
    584 MOZ_CAN_RUN_SCRIPT void test_constexpr_1() {
    585  AllowConstexprMembers::mRefCounted->method_test();
    586 }
    587 
    588 MOZ_CAN_RUN_SCRIPT void test_constexpr_2() {
    589  test2(AllowConstexprMembers::mRefCounted);
    590 }
    591 
    592 MOZ_CAN_RUN_SCRIPT void test_constexpr_3() {
    593  test_ref(*AllowConstexprMembers::mRefCounted);
    594 }
    595 
    596 MOZ_CAN_RUN_SCRIPT void test_ternary_1(RefCountedBase* arg1, RefCountedBase* arg2) {
    597  (arg1 ? arg1 : arg2)->method_test();
    598  RefCountedBase*& safeArg = arg1 ? arg1 : arg2;
    599  safeArg->method_test();
    600 }
    601 
    602 MOZ_CAN_RUN_SCRIPT void test_ternary_2(RefCountedBase* arg1, RefCountedBase* arg2) {
    603  test2(arg1 ? arg1 : arg2);
    604  RefCountedBase*& safeArg = arg1 ? arg1 : arg2;
    605  test2(safeArg);
    606 }
    607 
    608 MOZ_CAN_RUN_SCRIPT void test_ternary_3(RefCountedBase* arg1, RefCountedBase& arg2) {
    609  (arg1 ? *arg1 : arg2).method_test();
    610  RefCountedBase& safeArg = arg1 ? *arg1 : arg2;
    611  safeArg.method_test();
    612 }
    613 
    614 MOZ_CAN_RUN_SCRIPT void test_ternary_4(RefCountedBase* arg1, RefCountedBase& arg2) {
    615  test_ref(arg1 ? *arg1 : arg2);
    616  RefCountedBase& safeArg = arg1 ? *arg1 : arg2;
    617  test_ref(safeArg);
    618 }
    619 
    620 MOZ_CAN_RUN_SCRIPT void test_ternary_5(RefCountedBase* arg) {
    621  RefPtr<RefCountedBase> local = new RefCountedBase();
    622  (arg ? arg : local.get())->method_test();
    623 }
    624 
    625 MOZ_CAN_RUN_SCRIPT void test_ternary_6(RefCountedBase* arg) {
    626  RefPtr<RefCountedBase> local = new RefCountedBase();
    627  test2(arg ? arg : local.get());
    628 }
    629 
    630 MOZ_CAN_RUN_SCRIPT void test_ternary_7(RefCountedBase* arg) {
    631  RefPtr<RefCountedBase> local = new RefCountedBase();
    632  (arg ? *arg : *local).method_test();
    633  RefCountedBase& safeArgOrLocal = arg ? *arg : *local;
    634  safeArgOrLocal.method_test();
    635 }
    636 
    637 MOZ_CAN_RUN_SCRIPT void test_ternary_8(RefCountedBase* arg) {
    638  RefPtr<RefCountedBase> local = new RefCountedBase();
    639  test_ref(arg ? *arg : *local);
    640  RefCountedBase& safeArgOrLocal = arg ? *arg : *local;
    641  test_ref(safeArgOrLocal);
    642 }
    643 
    644 MOZ_CAN_RUN_SCRIPT void test_ternary_9(RefCountedBase* arg) {
    645  (arg ? arg : AllowConstexprMembers::mRefCounted)->method_test();
    646 }
    647 
    648 MOZ_CAN_RUN_SCRIPT void test_ternary_10(RefCountedBase* arg) {
    649  test2(arg ? arg : AllowConstexprMembers::mRefCounted);
    650 }
    651 
    652 MOZ_CAN_RUN_SCRIPT void test_ternary_11(RefCountedBase* arg) {
    653  (arg ? *arg : *AllowConstexprMembers::mRefCounted).method_test();
    654  RefCountedBase& safeArgOrMember = arg ? *arg : *AllowConstexprMembers::mRefCounted;
    655  safeArgOrMember.method_test();
    656 }
    657 
    658 MOZ_CAN_RUN_SCRIPT void test_ternary_12(RefCountedBase* arg) {
    659  test_ref(arg ? *arg : *AllowConstexprMembers::mRefCounted);
    660  RefCountedBase& safeArgOrMember = arg ? *arg : *AllowConstexprMembers::mRefCounted;
    661  test_ref(safeArgOrMember);
    662 }
    663 
    664 MOZ_CAN_RUN_SCRIPT void test_ternary_13(RefCountedBase* arg1, RefCountedBase& arg2) {
    665  (arg1 ? arg1 : &arg2)->method_test();
    666 }
    667 
    668 MOZ_CAN_RUN_SCRIPT void test_ternary_44(RefCountedBase* arg1, RefCountedBase& arg2) {
    669  test2(arg1 ? arg1 : &arg2);
    670 }
    671 
    672 MOZ_CAN_RUN_SCRIPT void test_ternary_13(bool arg) {
    673  (arg ?
    674   AllowConstexprMembers::mRefCounted :
    675   AllowConstexprMembers::mRefCounted2)->method_test();
    676  RefCountedBase* const& safeConstexprMember = arg ? AllowConstexprMembers::mRefCounted : AllowConstexprMembers::mRefCounted2;
    677  safeConstexprMember->method_test();
    678 }
    679 
    680 MOZ_CAN_RUN_SCRIPT void test_ternary_14(bool arg) {
    681  test2(arg ?
    682 AllowConstexprMembers::mRefCounted :
    683 AllowConstexprMembers::mRefCounted2);
    684  RefCountedBase* const& safeConstexprMember = arg ? AllowConstexprMembers::mRefCounted : AllowConstexprMembers::mRefCounted2;
    685  test2(safeConstexprMember);
    686 }
    687 
    688 MOZ_CAN_RUN_SCRIPT void test_ternary_15(bool arg) {
    689  (arg ?
    690   *AllowConstexprMembers::mRefCounted :
    691   *AllowConstexprMembers::mRefCounted2).method_test();
    692  RefCountedBase& safeConstexprMember = arg ? *AllowConstexprMembers::mRefCounted : *AllowConstexprMembers::mRefCounted2;
    693  safeConstexprMember.method_test();
    694 }
    695 
    696 MOZ_CAN_RUN_SCRIPT void test_ternary_16(bool arg) {
    697  test_ref(arg ?
    698    *AllowConstexprMembers::mRefCounted :
    699    *AllowConstexprMembers::mRefCounted2);
    700  RefCountedBase& safeConstexprMember = arg ? *AllowConstexprMembers::mRefCounted : *AllowConstexprMembers::mRefCounted2;
    701  test_ref(safeConstexprMember);
    702 }
    703 
    704 MOZ_CAN_RUN_SCRIPT void test_pointer_to_ref_1(RefCountedBase& arg) {
    705  (&arg)->method_test();
    706 }
    707 
    708 MOZ_CAN_RUN_SCRIPT void test_pointer_to_ref_2(RefCountedBase& arg) {
    709  test2(&arg);
    710 }
    711 
    712 struct DisallowMemberArgsViaReferenceAlias {
    713  RefPtr<RefCountedBase> mRefCounted;
    714  MOZ_CAN_RUN_SCRIPT void foo() {
    715    RefPtr<RefCountedBase>& bogus = mRefCounted;
    716    bogus->method_test(); // expected-error-re {{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).  'bogus{{(->)?}}' is neither.}}
    717  }
    718  MOZ_CAN_RUN_SCRIPT void bar() {
    719    RefPtr<RefCountedBase>& bogus = mRefCounted;
    720    test2(bogus); // 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).  'bogus' is neither.}}
    721  }
    722 };
    723 
    724 struct DisallowMemberArgsViaReferenceAlias2 {
    725  RefPtr<RefCountedBase> mRefCountedArr[2];
    726  MOZ_CAN_RUN_SCRIPT void foo1() {
    727    for (RefPtr<RefCountedBase>& item : mRefCountedArr) {
    728      item->method_test(); // expected-error-re {{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).  'item{{(->)?}}' is neither.}}
    729    }
    730  }
    731  MOZ_CAN_RUN_SCRIPT void foo2() {
    732    for (auto& item : mRefCountedArr) {
    733      item->method_test(); // expected-error-re {{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).  'item{{(->)?}}' is neither.}}
    734    }
    735  }
    736  MOZ_CAN_RUN_SCRIPT void foo3() {
    737    for (RefPtr<RefCountedBase> item : mRefCountedArr) {
    738      item->method_test();
    739    }
    740  }
    741  MOZ_CAN_RUN_SCRIPT void foo4() {
    742    for (auto item : mRefCountedArr) {
    743      item->method_test();
    744    }
    745  }
    746  MOZ_CAN_RUN_SCRIPT void bar1() {
    747    for (RefPtr<RefCountedBase>& item : mRefCountedArr) {
    748      test2(item); // 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).  'item' is neither.}}
    749    }
    750  }
    751  MOZ_CAN_RUN_SCRIPT void bar2() {
    752    for (auto& item : mRefCountedArr) {
    753      test2(item); // 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).  'item' is neither.}}
    754    }
    755  }
    756  MOZ_CAN_RUN_SCRIPT void bar3() {
    757    for (RefPtr<RefCountedBase> item : mRefCountedArr) {
    758      test2(item);
    759    }
    760  }
    761  MOZ_CAN_RUN_SCRIPT void bar4() {
    762    for (auto item : mRefCountedArr) {
    763      test2(item);
    764    }
    765  }
    766 };
    767 
    768 struct AllowMozKnownLiveMember {
    769 public:
    770  MOZ_KNOWN_LIVE RefCountedBase* mWhatever;
    771  MOZ_KNOWN_LIVE RefPtr<RefCountedBase> mRefCountedWhatever;
    772  MOZ_CAN_RUN_SCRIPT void fooPtr(RefCountedBase* aWhatever) {}
    773  MOZ_CAN_RUN_SCRIPT void fooRef(RefCountedBase& aWhatever) {}
    774  MOZ_CAN_RUN_SCRIPT void bar() {
    775    fooPtr(mWhatever);
    776    fooRef(*mWhatever);
    777    fooPtr(mRefCountedWhatever);
    778    fooRef(*mRefCountedWhatever);
    779 
    780    RefCountedBase*& whateverRef = mWhatever;
    781    fooPtr(whateverRef);
    782    fooRef(*whateverRef);
    783    RefPtr<RefCountedBase>&  refCountedWhateverRef = mRefCountedWhatever;
    784    fooPtr(refCountedWhateverRef);
    785    fooRef(*refCountedWhateverRef);
    786  }
    787 };
    788 
    789 struct AllowMozKnownLiveMemberParent : AllowMozKnownLiveMember {
    790  MOZ_CAN_RUN_SCRIPT void baz() {
    791    fooPtr(mWhatever);
    792    fooRef(*mWhatever);
    793    fooPtr(mRefCountedWhatever);
    794    fooRef(*mRefCountedWhatever);
    795 
    796    RefCountedBase*& whateverRef = mWhatever;
    797    fooPtr(whateverRef);
    798    fooRef(*whateverRef);
    799    RefPtr<RefCountedBase>&  refCountedWhateverRef = mRefCountedWhatever;
    800    fooPtr(refCountedWhateverRef);
    801    fooRef(*refCountedWhateverRef);
    802  }
    803 };
    804 
    805 struct AllowMozKnownLiveParamMember {
    806 public:
    807  MOZ_CAN_RUN_SCRIPT void foo(AllowMozKnownLiveMember& aAllow) {
    808    aAllow.fooPtr(aAllow.mWhatever);
    809    aAllow.fooRef(*aAllow.mWhatever);
    810    aAllow.fooPtr(aAllow.mRefCountedWhatever);
    811    aAllow.fooRef(*aAllow.mRefCountedWhatever);
    812 
    813    RefCountedBase*& whateverRef = aAllow.mWhatever;
    814    aAllow.fooPtr(whateverRef);
    815    aAllow.fooRef(*whateverRef);
    816    RefPtr<RefCountedBase>&  refCountedWhateverRef = aAllow.mRefCountedWhatever;
    817    aAllow.fooPtr(refCountedWhateverRef);
    818    aAllow.fooRef(*refCountedWhateverRef);
    819  }
    820  MOZ_CAN_RUN_SCRIPT void bar(AllowMozKnownLiveMemberParent& aAllowParent) {
    821    aAllowParent.fooPtr(aAllowParent.mWhatever);
    822    aAllowParent.fooRef(*aAllowParent.mWhatever);
    823    aAllowParent.fooPtr(aAllowParent.mRefCountedWhatever);
    824    aAllowParent.fooRef(*aAllowParent.mRefCountedWhatever);
    825 
    826    RefCountedBase*& whateverRef = aAllowParent.mWhatever;
    827    aAllowParent.fooPtr(whateverRef);
    828    aAllowParent.fooRef(*whateverRef);
    829    RefPtr<RefCountedBase>&  refCountedWhateverRef = aAllowParent.mRefCountedWhatever;
    830    aAllowParent.fooPtr(refCountedWhateverRef);
    831    aAllowParent.fooRef(*refCountedWhateverRef);
    832  }
    833 };
    834 
    835 MOZ_CAN_RUN_SCRIPT void AllowMozKnownLiveMemberInAutoStorage() {
    836  AllowMozKnownLiveMember inStack;
    837  AllowMozKnownLiveMember* inHeap = new AllowMozKnownLiveMember();
    838  inStack.fooPtr(inStack.mWhatever);
    839  inStack.fooRef(*inStack.mWhatever);
    840  inStack.fooPtr(inStack.mRefCountedWhatever);
    841  inStack.fooRef(*inStack.mRefCountedWhatever);
    842  RefCountedBase*& whateverRefInStack = inStack.mWhatever;
    843  inStack.fooPtr(whateverRefInStack);
    844  inStack.fooRef(*whateverRefInStack);
    845  RefPtr<RefCountedBase>&  refCountedWhateverRefInStack = inStack.mRefCountedWhatever;
    846  inStack.fooPtr(refCountedWhateverRefInStack);
    847  inStack.fooRef(*refCountedWhateverRefInStack);
    848 
    849  inStack.fooPtr(inHeap->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).  'inHeap->mWhatever' is neither.}}
    850  inStack.fooRef(*inHeap->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).  '*inHeap->mWhatever' is neither.}}
    851  inStack.fooPtr(inHeap->mRefCountedWhatever); // 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).  'inHeap->mRefCountedWhatever' is neither.}}
    852  inStack.fooRef(*inHeap->mRefCountedWhatever); // 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).  '*inHeap->mRefCountedWhatever' is neither.}}
    853  RefCountedBase*& whateverRefInHeap = inHeap->mWhatever;
    854  inStack.fooPtr(whateverRefInHeap); // 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).  'whateverRefInHeap' is neither.}}
    855  inStack.fooRef(*whateverRefInHeap); // 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).  '*whateverRefInHeap' is neither.}}
    856  RefPtr<RefCountedBase>&  refCountedWhateverRefInHeap = inHeap->mRefCountedWhatever;
    857  inStack.fooPtr(refCountedWhateverRefInHeap); // 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).  'refCountedWhateverRefInHeap' is neither.}}
    858  inStack.fooRef(*refCountedWhateverRefInHeap); // 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).  '*refCountedWhateverRefInHeap' is neither.}}
    859 }
    860 
    861 struct DisallowMozKnownLiveMemberNotFromKnownLive {
    862  AllowMozKnownLiveMember* mMember;
    863  MOZ_CAN_RUN_SCRIPT void fooPtr(RefCountedBase* aWhatever) {}
    864  MOZ_CAN_RUN_SCRIPT void fooRef(RefCountedBase& aWhatever) {}
    865  MOZ_CAN_RUN_SCRIPT void bar() {
    866    fooPtr(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.}}
    867    fooRef(*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.}}
    868    fooPtr(mMember->mRefCountedWhatever); // 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->mRefCountedWhatever' is neither.}}
    869    fooRef(*mMember->mRefCountedWhatever); // 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->mRefCountedWhatever' is neither.}}
    870    RefCountedBase*& whateverRef = mMember->mWhatever;
    871    fooPtr(whateverRef); // 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).  'whateverRef' is neither.}}
    872    fooRef(*whateverRef); // 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).  '*whateverRef' is neither.}}
    873    RefPtr<RefCountedBase>& refCountedWhateverRef = mMember->mRefCountedWhatever;
    874    fooPtr(refCountedWhateverRef); // 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).  'refCountedWhateverRef' is neither.}}
    875    fooRef(*refCountedWhateverRef); // 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).  '*refCountedWhateverRef' is neither.}}
    876  }
    877 };
    878 
    879 void IncorrectlyUnmarkedEarlyDeclaration(); // expected-note {{The first declaration exists here}}
    880 
    881 MOZ_CAN_RUN_SCRIPT void IncorrectlyUnmarkedEarlyDeclaration() {}; // expected-error {{MOZ_CAN_RUN_SCRIPT must be put in front of the declaration, not the definition}}