709 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s2 3#include "mock-types.h"4#include "mock-system-header.h"5 6void WTFBreakpointTrap();7void WTFCrashWithInfo(int, const char*, const char*, int);8void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);9void WTFReportBacktrace(void);10 11void WTFCrash(void);12void WTFCrashWithSecurityImplication(void);13 14inline void compilerFenceForCrash()15{16 asm volatile("" ::: "memory");17}18 19inline void isIntegralOrPointerType() { }20 21template<typename T, typename... Types>22void isIntegralOrPointerType(T, Types... types)23{24 static_assert(sizeof(char) < sizeof(short), "All types need to be bitwise_cast-able to integral type for logging");25 isIntegralOrPointerType(types...);26}27 28#define CRASH_WITH_INFO(...) do { \29 isIntegralOrPointerType(__VA_ARGS__); \30 compilerFenceForCrash(); \31 WTFBreakpointTrap(); \32 __builtin_unreachable(); \33} while (0)34 35#define RELEASE_ASSERT(assertion, ...) do { \36 if (!(assertion)) \37 CRASH_WITH_INFO(__VA_ARGS__); \38} while (0)39 40#define ASSERT(assertion, ...) do { \41 if (!(assertion)) { \42 WTFReportAssertionFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__, #assertion); \43 CRASH_WITH_INFO(__VA_ARGS__); \44 } \45} while (0)46 47#if !defined(ALWAYS_INLINE)48#define ALWAYS_INLINE inline49#endif50 51void WTFCrashWithInfoImpl(int line, const char* file, const char* function, int counter, unsigned long reason);52void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);53 54template<typename T>55ALWAYS_INLINE unsigned long wtfCrashArg(T* arg) { return reinterpret_cast<unsigned long>(arg); }56 57template<typename T>58ALWAYS_INLINE unsigned long wtfCrashArg(T arg) { return arg; }59 60template<typename T>61void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, T reason)62{63 WTFCrashWithInfoImpl(line, file, function, counter, wtfCrashArg(reason));64}65 66template<typename ToType, typename FromType>67ToType bitwise_cast(FromType from);68 69namespace std {70 71template<typename T>72T* addressof(T& arg);73 74template<typename T>75T&& forward(T& arg);76 77template<typename ToType, typename FromType>78ToType bit_cast(FromType from);79 80#define offsetof(t, d) __builtin_offsetof(t, d)81 82} // namespace std83 84bool isMainThread();85bool isMainThreadOrGCThread();86bool isMainRunLoop();87bool isWebThread();88bool isUIThread();89bool mayBeGCThread();90 91enum class Flags : unsigned short {92 Flag1 = 1 << 0,93 Flag2 = 1 << 1,94 Flag3 = 1 << 2,95};96 97template<typename E> class OptionSet {98public:99 using StorageType = unsigned short;100 101 static constexpr OptionSet fromRaw(StorageType rawValue) {102 return OptionSet(static_cast<E>(rawValue), FromRawValue);103 }104 105 constexpr OptionSet() = default;106 107 constexpr OptionSet(E e)108 : m_storage(static_cast<StorageType>(e)) {109 }110 111 constexpr StorageType toRaw() const { return m_storage; }112 113 constexpr bool isEmpty() const { return !m_storage; }114 115 constexpr explicit operator bool() const { return !isEmpty(); }116 117 constexpr bool contains(E option) const { return containsAny(option); }118 constexpr bool containsAny(OptionSet optionSet) const {119 return !!(*this & optionSet);120 }121 122 constexpr bool containsAll(OptionSet optionSet) const {123 return (*this & optionSet) == optionSet;124 }125 126 constexpr void add(OptionSet optionSet) { m_storage |= optionSet.m_storage; }127 128 constexpr void remove(OptionSet optionSet)129 {130 m_storage &= ~optionSet.m_storage;131 }132 133 constexpr void set(OptionSet optionSet, bool value)134 {135 if (value)136 add(optionSet);137 else138 remove(optionSet);139 }140 141 constexpr friend OptionSet operator|(OptionSet lhs, OptionSet rhs) {142 return fromRaw(lhs.m_storage | rhs.m_storage);143 }144 145 constexpr friend OptionSet operator&(OptionSet lhs, OptionSet rhs) {146 return fromRaw(lhs.m_storage & rhs.m_storage);147 }148 149 constexpr friend OptionSet operator-(OptionSet lhs, OptionSet rhs) {150 return fromRaw(lhs.m_storage & ~rhs.m_storage);151 }152 153 constexpr friend OptionSet operator^(OptionSet lhs, OptionSet rhs) {154 return fromRaw(lhs.m_storage ^ rhs.m_storage);155 }156 157private:158 enum InitializationTag { FromRawValue };159 constexpr OptionSet(E e, InitializationTag)160 : m_storage(static_cast<StorageType>(e)) {161 }162 StorageType m_storage { 0 };163};164 165int atoi(const char* str);166 167class Number {168public:169 Number(int v) : v(v) { }170 Number(double);171 Number(const char* str) : v(atoi(str)) { }172 Number operator+(const Number&);173 Number& operator++() { ++v; return *this; }174 Number operator++(int) { Number returnValue(v); ++v; return returnValue; }175 const int& value() const { return v; }176 void someMethod();177 178private:179 int v;180};181 182class DerivedNumber : public Number {183public:184 DerivedNumber(char c) : Number(c - '0') { }185 DerivedNumber(const char* str) : Number(atoi(str)) { }186};187 188class ComplexNumber {189public:190 ComplexNumber() : realPart(0), complexPart(0) { }191 ComplexNumber(int real, const char* str) : realPart(real), complexPart(str) { }192 ComplexNumber(const ComplexNumber&);193 ComplexNumber& operator++() { realPart.someMethod(); return *this; }194 ComplexNumber operator++(int);195 ComplexNumber& operator<<(int);196 ComplexNumber& operator+();197 198 const Number& real() const { return realPart; }199 const Number& complex() const;200 201 void ref() const;202 void deref() const;203 204private:205 Number realPart;206 Number complexPart;207};208 209class ObjectWithNonTrivialDestructor {210public:211 ObjectWithNonTrivialDestructor() { }212 ObjectWithNonTrivialDestructor(unsigned v) : v(v) { }213 ~ObjectWithNonTrivialDestructor() { }214 215 unsigned value() const { return v; }216 217private:218 unsigned v { 0 };219};220 221class ObjectWithMutatingDestructor {222public:223 ObjectWithMutatingDestructor() : n(0) { }224 ObjectWithMutatingDestructor(int n) : n(n) { }225 ~ObjectWithMutatingDestructor() { n.someMethod(); }226 227 unsigned value() const { return n.value(); }228 229private:230 Number n;231};232 233class BaseType {234public:235 BaseType() : n(0) { }236 BaseType(int v) : n(v) { }237 BaseType(const char*);238private:239 Number n;240};241 242class SomeType : public BaseType {243public:244 using BaseType::BaseType;245};246 247struct OtherObj {248 unsigned v { 0 };249 OtherObj* children[4] { nullptr };250};251 252void __libcpp_verbose_abort(const char *__format, ...);253 254class RefCounted {255public:256 void ref() const;257 void deref() const;258 259 void method();260 void someFunction();261 int otherFunction();262 unsigned recursiveTrivialFunction(int n) { return !n ? 1 : recursiveTrivialFunction(n - 1); }263 unsigned recursiveComplexFunction(int n) { return !n ? otherFunction() : recursiveComplexFunction(n - 1); }264 unsigned mutuallyRecursiveFunction1(int n) { return n < 0 ? 1 : (n % 2 ? mutuallyRecursiveFunction2(n - 2) : mutuallyRecursiveFunction1(n - 1)); }265 unsigned mutuallyRecursiveFunction2(int n) { return n < 0 ? 1 : (n % 3 ? mutuallyRecursiveFunction2(n - 3) : mutuallyRecursiveFunction1(n - 2)); }266 unsigned mutuallyRecursiveFunction3(int n) { return n < 0 ? 1 : (n % 5 ? mutuallyRecursiveFunction3(n - 5) : mutuallyRecursiveFunction4(n - 3)); }267 unsigned mutuallyRecursiveFunction4(int n) { return n < 0 ? 1 : (n % 7 ? otherFunction() : mutuallyRecursiveFunction3(n - 3)); }268 unsigned recursiveFunction5(unsigned n) { return n > 100 ? 2 : (n % 2 ? recursiveFunction5(n + 1) : recursiveFunction6(n + 2)); }269 unsigned recursiveFunction6(unsigned n) { return n > 100 ? 3 : (n % 2 ? recursiveFunction6(n % 7) : recursiveFunction7(n % 5)); }270 unsigned recursiveFunction7(unsigned n) { return n > 100 ? 5 : recursiveFunction7(n * 5); }271 272 void mutuallyRecursive8() { mutuallyRecursive9(); someFunction(); }273 void mutuallyRecursive9() { mutuallyRecursive8(); }274 275 int recursiveCost() {276 unsigned totalCost = 0;277 for (unsigned i = 0; i < sizeof(children)/sizeof(*children); ++i) {278 if (auto* child = children[i])279 totalCost += child->recursiveCost();280 }281 return totalCost;282 }283 284 int trivial1() { return 123; }285 float trivial2() { return 0.3; }286 float trivial3() { return (float)0.4; }287 float trivial4() { return 0.5f; }288 char trivial5() { return 'a'; }289 const char *trivial6() { return "abc"; }290 int trivial7() { return (1); }291 Number trivial8() { return Number { 5 }; }292 int trivial9() { return 3 + 4; }293 int trivial10() { return 0x1010 | 0x1; }294 int trivial11(int v) { return v + 1; }295 const char *trivial12(char *p) { return p ? "str" : "null"; }296 int trivial13(int v) {297 if (v)298 return 123;299 else300 return 0;301 }302 int trivial14(int v) {303 switch (v) {304 case 1:305 return 100;306 case 2:307 return 200;308 default:309 return 300;310 }311 return 0;312 }313 void *trivial15() { return static_cast<void*>(this); }314 unsigned long trivial16() { return *reinterpret_cast<unsigned long*>(this); }315 RefCounted& trivial17() const { return const_cast<RefCounted&>(*this); }316 RefCounted& trivial18() const { RELEASE_ASSERT(this, "this must be not null"); return const_cast<RefCounted&>(*this); }317 void trivial19() const { return; }318 319 static constexpr unsigned numBits = 4;320 int trivial20() { return v >> numBits; }321 322 const int* trivial21() { return number ? &number->value() : nullptr; }323 324 enum class Enum : unsigned short {325 Value1 = 1,326 Value2 = 2,327 };328 bool trivial22() { return enumValue == Enum::Value1; }329 330 bool trivial23() const { return OptionSet<Flags>::fromRaw(v).contains(Flags::Flag1); }331 int trivial24() const { ASSERT(v); return v; }332 unsigned trivial25() const { return __c11_atomic_load((volatile _Atomic(unsigned) *)&v, __ATOMIC_RELAXED); }333 bool trivial26() { bool hasValue = v; return !hasValue; }334 bool trivial27(int v) { bool value; value = v ? 1 : 0; return value; }335 bool trivial28() { return true; }336 bool trivial29() { return false; }337 unsigned trivial30(unsigned v) { unsigned r = 0xff; r |= v; return r; }338 int trivial31(int* v) { return v[0]; }339 unsigned trivial32() { return sizeof(int); }340 unsigned trivial33() { return ~0xff; }341 template <unsigned v> unsigned trivial34() { return v; }342 void trivial35() { v++; }343 void trivial36() { ++(*number); }344 void trivial37() { (*number)++; }345 void trivial38() { v++; if (__builtin_expect(!!(number), 1)) (*number)++; }346 int trivial39() { return -v; }347 int trivial40() { return v << 2; }348 unsigned trivial41() { v = ++s_v; return v; }349 unsigned trivial42() { return bitwise_cast<unsigned long>(nullptr); }350 Number* trivial43() { return std::addressof(*number); }351 Number* trivial44() { return new Number(1); }352 ComplexNumber* trivial45() { return new ComplexNumber(); }353 void trivial46() { ASSERT(isMainThread()); }354 void trivial47() { ASSERT(isMainThreadOrGCThread()); }355 void trivial48() { ASSERT(isMainRunLoop()); }356 void trivial49() { ASSERT(isWebThread()); }357 void trivial50() { ASSERT(isUIThread()); }358 void trivial51() { ASSERT(mayBeGCThread()); }359 void trivial52() { WTFCrash(); }360 void trivial53() { WTFCrashWithSecurityImplication(); }361 unsigned trivial54() { return ComplexNumber().real().value(); }362 Number&& trivial55() { return std::forward(*number); }363 unsigned trivial56() { Number n { 5 }; return std::move(n).value(); }364 void trivial57() { do { break; } while (1); }365 void trivial58() { do { continue; } while (0); }366 void trivial59() {367 do { goto label; }368 while (0);369 label:370 return;371 }372 unsigned trivial60() { return ObjectWithNonTrivialDestructor { 5 }.value(); }373 unsigned trivial61() { return DerivedNumber('7').value(); }374 void trivial62() { WTFReportBacktrace(); }375 SomeType trivial63() { return SomeType(0); }376 SomeType trivial64() { return SomeType(); }377 void trivial65() {378 __libcpp_verbose_abort("%s", "aborting");379 }380 RefPtr<RefCounted> trivial66() { return children[0]; }381 Ref<RefCounted> trivial67() { return *children[0]; }382 struct point {383 double x;384 double y;385 };386 void trivial68() { point pt = { 1.0 }; }387 unsigned trivial69() { return offsetof(OtherObj, children); }388 DerivedNumber* trivial70() { [[clang::suppress]] return static_cast<DerivedNumber*>(number); }389 unsigned trivial71() { return std::bit_cast<unsigned>(nullptr); }390 391 static RefCounted& singleton() {392 static RefCounted s_RefCounted;393 s_RefCounted.ref();394 return s_RefCounted;395 }396 397 static RefCounted& otherSingleton() {398 static RefCounted s_RefCounted;399 s_RefCounted.ref();400 return s_RefCounted;401 }402 403 Number nonTrivial1() { return Number(3) + Number(4); }404 Number nonTrivial2() { return Number { 0.3 }; }405 int nonTrivial3() { return v ? otherFunction() : 0; }406 int nonTrivial4() {407 if (v)408 return 8;409 else410 return otherFunction();411 }412 413 int nonTrivial5() {414 if (v)415 return otherFunction();416 else417 return 9;418 }419 420 int nonTrivial6() {421 if (otherFunction())422 return 1;423 else424 return 0;425 }426 427 int nonTrivial7() {428 switch (v) {429 case 1:430 return otherFunction();431 default:432 return 7;433 }434 }435 436 int nonTrivial8() {437 switch (v) {438 case 1:439 return 9;440 default:441 return otherFunction();442 }443 }444 445 int nonTrivial9() {446 switch (otherFunction()) {447 case 0:448 return -1;449 default:450 return 12;451 }452 }453 454 static unsigned* another();455 unsigned nonTrivial10() const {456 return __c11_atomic_load((volatile _Atomic(unsigned) *)another(), __ATOMIC_RELAXED);457 }458 459 void nonTrivial11() {460 Number num(0.3);461 }462 463 bool nonTrivial12() {464 bool val = otherFunction();465 return val;466 }467 468 int nonTrivial13() { return ~otherFunction(); }469 int nonTrivial14() { int r = 0xff; r |= otherFunction(); return r; }470 void nonTrivial15() { ++complex; }471 void nonTrivial16() { complex++; }472 ComplexNumber nonTrivial17() { return complex << 2; }473 ComplexNumber nonTrivial18() { return +complex; }474 ComplexNumber* nonTrivial19() { return new ComplexNumber(complex); }475 unsigned nonTrivial20() { return ObjectWithMutatingDestructor { 7 }.value(); }476 unsigned nonTrivial21() { return Number("123").value(); }477 unsigned nonTrivial22() { return ComplexNumber(123, "456").real().value(); }478 unsigned nonTrivial23() { return DerivedNumber("123").value(); }479 SomeType nonTrivial24() { return SomeType("123"); }480 virtual void nonTrivial25() { }481 virtual ComplexNumber* operator->() { return nullptr; }482 483 static unsigned s_v;484 unsigned v { 0 };485 Number* number { nullptr };486 ComplexNumber complex;487 Enum enumValue { Enum::Value1 };488 RefCounted* children[4];489};490 491unsigned RefCounted::s_v = 0;492 493RefCounted* refCountedObj();494 495void test()496{497 refCountedObj()->someFunction();498 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}499}500 501class UnrelatedClass {502 RefPtr<RefCounted> Field;503 bool value;504 505public:506 RefCounted &getFieldTrivial() { return *Field.get(); }507 RefCounted *getFieldTernary() { return value ? Field.get() : nullptr; }508 509 void test() {510 getFieldTrivial().trivial1(); // no-warning511 getFieldTrivial().trivial2(); // no-warning512 getFieldTrivial().trivial3(); // no-warning513 getFieldTrivial().trivial4(); // no-warning514 getFieldTrivial().trivial5(); // no-warning515 getFieldTrivial().trivial6(); // no-warning516 getFieldTrivial().trivial7(); // no-warning517 getFieldTrivial().trivial8(); // no-warning518 getFieldTrivial().trivial9(); // no-warning519 getFieldTrivial().trivial10(); // no-warning520 getFieldTrivial().trivial11(1); // no-warning521 getFieldTrivial().trivial12(nullptr); // no-warning522 getFieldTrivial().trivial13(0); // no-warning523 getFieldTrivial().trivial14(3); // no-warning524 getFieldTrivial().trivial15(); // no-warning525 getFieldTrivial().trivial16(); // no-warning526 getFieldTrivial().trivial17(); // no-warning527 getFieldTrivial().trivial18(); // no-warning528 getFieldTrivial().trivial19(); // no-warning529 getFieldTrivial().trivial20(); // no-warning530 getFieldTrivial().trivial21(); // no-warning531 getFieldTrivial().trivial22(); // no-warning532 getFieldTrivial().trivial23(); // no-warning533 getFieldTrivial().trivial24(); // no-warning534 getFieldTrivial().trivial25(); // no-warning535 getFieldTrivial().trivial26(); // no-warning536 getFieldTrivial().trivial27(5); // no-warning537 getFieldTrivial().trivial28(); // no-warning538 getFieldTrivial().trivial29(); // no-warning539 getFieldTrivial().trivial30(7); // no-warning540 int a[] = {1, 2};541 getFieldTrivial().trivial31(a); // no-warning542 getFieldTrivial().trivial32(); // no-warning543 getFieldTrivial().trivial33(); // no-warning544 getFieldTrivial().trivial34<7>(); // no-warning545 getFieldTrivial().trivial35(); // no-warning546 getFieldTrivial().trivial36(); // no-warning547 getFieldTrivial().trivial37(); // no-warning548 getFieldTrivial().trivial38(); // no-warning549 getFieldTrivial().trivial39(); // no-warning550 getFieldTrivial().trivial40(); // no-warning551 getFieldTrivial().trivial41(); // no-warning552 getFieldTrivial().trivial42(); // no-warning553 getFieldTrivial().trivial43(); // no-warning554 getFieldTrivial().trivial44(); // no-warning555 getFieldTrivial().trivial45(); // no-warning556 getFieldTrivial().trivial46(); // no-warning557 getFieldTrivial().trivial47(); // no-warning558 getFieldTrivial().trivial48(); // no-warning559 getFieldTrivial().trivial49(); // no-warning560 getFieldTrivial().trivial50(); // no-warning561 getFieldTrivial().trivial51(); // no-warning562 getFieldTrivial().trivial52(); // no-warning563 getFieldTrivial().trivial53(); // no-warning564 getFieldTrivial().trivial54(); // no-warning565 getFieldTrivial().trivial55(); // no-warning566 getFieldTrivial().trivial56(); // no-warning567 getFieldTrivial().trivial57(); // no-warning568 getFieldTrivial().trivial58(); // no-warning569 getFieldTrivial().trivial59(); // no-warning570 getFieldTrivial().trivial60(); // no-warning571 getFieldTrivial().trivial61(); // no-warning572 getFieldTrivial().trivial62(); // no-warning573 getFieldTrivial().trivial63(); // no-warning574 getFieldTrivial().trivial64(); // no-warning575 getFieldTrivial().trivial65(); // no-warning576 getFieldTrivial().trivial66()->trivial6(); // no-warning577 getFieldTrivial().trivial67()->trivial6(); // no-warning578 getFieldTrivial().trivial68(); // no-warning579 getFieldTrivial().trivial69(); // no-warning580 getFieldTrivial().trivial70(); // no-warning581 getFieldTrivial().trivial71(); // no-warning582 583 RefCounted::singleton().trivial18(); // no-warning584 RefCounted::singleton().someFunction(); // no-warning585 RefCounted::otherSingleton().trivial18(); // no-warning586 RefCounted::otherSingleton().someFunction(); // no-warning587 588 getFieldTrivial().recursiveTrivialFunction(7); // no-warning589 getFieldTrivial().recursiveComplexFunction(9);590 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}591 getFieldTrivial().mutuallyRecursiveFunction1(11); // no-warning592 getFieldTrivial().mutuallyRecursiveFunction2(13); // no-warning593 getFieldTrivial().mutuallyRecursiveFunction3(17);594 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}595 getFieldTrivial().mutuallyRecursiveFunction4(19);596 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}597 getFieldTrivial().recursiveFunction5(23); // no-warning598 getFieldTrivial().recursiveFunction6(29); // no-warning599 getFieldTrivial().recursiveFunction7(31); // no-warning600 601 getFieldTrivial().mutuallyRecursive8();602 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}603 getFieldTrivial().mutuallyRecursive9();604 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}605 606 getFieldTrivial().recursiveCost(); // no-warning607 608 getFieldTrivial().someFunction();609 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}610 getFieldTrivial().nonTrivial1();611 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}612 getFieldTrivial().nonTrivial2();613 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}614 getFieldTrivial().nonTrivial3();615 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}616 getFieldTrivial().nonTrivial4();617 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}618 getFieldTrivial().nonTrivial5();619 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}620 getFieldTrivial().nonTrivial6();621 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}622 getFieldTrivial().nonTrivial7();623 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}624 getFieldTrivial().nonTrivial8();625 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}626 getFieldTrivial().nonTrivial9();627 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}628 getFieldTrivial().nonTrivial10();629 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}630 getFieldTrivial().nonTrivial11();631 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}632 getFieldTrivial().nonTrivial12();633 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}634 getFieldTrivial().nonTrivial13();635 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}636 getFieldTrivial().nonTrivial14();637 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}638 getFieldTrivial().nonTrivial15();639 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}640 getFieldTrivial().nonTrivial16();641 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}642 getFieldTrivial().nonTrivial17();643 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}644 getFieldTrivial().nonTrivial18();645 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}646 getFieldTrivial().nonTrivial19();647 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}648 getFieldTrivial().nonTrivial20();649 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}650 getFieldTrivial().nonTrivial21();651 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}652 getFieldTrivial().nonTrivial22();653 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}654 getFieldTrivial().nonTrivial23();655 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}656 getFieldTrivial().nonTrivial24();657 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}658 getFieldTrivial().nonTrivial25();659 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}660 getFieldTrivial()->complex();661 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}662 }663 664 void setField(RefCounted*);665};666 667class UnrelatedClass2 {668 RefPtr<UnrelatedClass> Field;669 670public:671 UnrelatedClass &getFieldTrivial() { return *Field.get(); }672 RefCounted &getFieldTrivialRecursively() { return getFieldTrivial().getFieldTrivial(); }673 RefCounted *getFieldTrivialTernary() { return Field ? Field->getFieldTernary() : nullptr; }674 675 template<typename T, typename ... AdditionalArgs>676 void callSetField(T&& item, AdditionalArgs&&... args)677 {678 item.setField(std::forward<AdditionalArgs>(args)...);679 }680 681 template<typename T, typename ... AdditionalArgs>682 void callSetField2(T&& item, AdditionalArgs&&... args)683 {684 item.setField(std::move<AdditionalArgs>(args)...);685 }686 687 void test() {688 getFieldTrivialRecursively().trivial1(); // no-warning689 getFieldTrivialTernary()->trivial2(); // no-warning690 getFieldTrivialRecursively().someFunction();691 // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}692 callSetField(getFieldTrivial(), refCountedObj()); // no-warning693 }694};695 696RefPtr<RefCounted> object();697void someFunction(const RefCounted&);698 699void test2() {700 someFunction(*object());701}702 703void system_header() {704 callMethod<RefCountable>(object);705}706 707void log(RefCountable* obj) {708 os_log_msg(os_log_create("WebKit", "DOM"), OS_LOG_TYPE_INFO, "obj: %p next: %p", obj, obj->next());709}