// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s #include "mock-types.h" class Base { public: void ref(); void deref(); void doWork(); }; class Derived : public Base { public: virtual ~Derived(); void ref() const; void deref() const; }; class SubDerived final : public Derived { }; class OtherObject { public: Derived* obj(); Base* base(); }; class String { }; template inline Target* dynamicDowncast(Source* source) { return static_cast(source); } template inline Target* checkedDowncast(Source* source) { return static_cast(source); } template inline Target* uncheckedDowncast(Source* source) { return static_cast(source); } template Target* [[clang::annotate_type("webkit.pointerconversion")]] newCastFunction(Source*); template Target* [[clang::annotate_type("unrelated-annotation")]] badCastFunction(Source*); template String toString(const Types&... values); void foo(OtherObject* other) { dynamicDowncast(other->obj()); checkedDowncast(other->obj()); uncheckedDowncast(other->obj()); newCastFunction(other->obj()); badCastFunction(other->obj()); // expected-warning@-1{{Call argument is uncounted and unsafe}} toString(other->obj()); } struct SomeStruct { Derived* [[clang::annotate_type("webkit.pointerconversion")]] ptrConversion(Base*); void foo(OtherObject& otherObj) { RefPtr ptr = otherObj.base(); ptrConversion(ptr.get())->doWork(); } };