brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.0 KiB · a9cd77c Raw
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}