-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Webkit Checkers] Treat const member variables as a safe origin #115594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
28ee832
8bda965
4b7233a
4efb59c
b74c55a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -145,25 +145,36 @@ bool isCtorOfSafePtr(const clang::FunctionDecl *F) { | |
| return isCtorOfRefCounted(F) || isCtorOfCheckedPtr(F); | ||
| } | ||
|
|
||
| bool isSafePtrType(const clang::QualType T) { | ||
| template <typename Predicate> | ||
| static bool isPtrOfType(const clang::QualType T, Predicate Pred) { | ||
| QualType type = T; | ||
| while (!type.isNull()) { | ||
| if (auto *elaboratedT = type->getAs<ElaboratedType>()) { | ||
| type = elaboratedT->desugar(); | ||
| continue; | ||
| } | ||
| if (auto *specialT = type->getAs<TemplateSpecializationType>()) { | ||
| if (auto *decl = specialT->getTemplateName().getAsTemplateDecl()) { | ||
| auto name = decl->getNameAsString(); | ||
| return isRefType(name) || isCheckedPtr(name); | ||
| } | ||
| if (auto *decl = specialT->getTemplateName().getAsTemplateDecl()) | ||
| return Pred(decl->getNameAsString()); | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool isSafePtrType(const clang::QualType T) { | ||
| return isPtrOfType( | ||
| T, [](auto Name) { return isRefType(Name) || isCheckedPtr(Name); }); | ||
| } | ||
|
|
||
| bool isOwnerPtrType(const clang::QualType T) { | ||
| return isPtrOfType(T, [](auto Name) { | ||
| return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" || | ||
| Name == "UniqueRef" || Name == "LazyUniqueRef"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity: Is this (
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There also |
||
| }); | ||
| } | ||
|
|
||
| std::optional<bool> isUncounted(const QualType T) { | ||
| if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T)) { | ||
| if (auto *Decl = Subst->getAssociatedDecl()) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedCallArgsChecker -verify %s | ||
|
|
||
| #include "mock-types.h" | ||
|
|
||
| namespace call_args_const_checkedptr_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const CheckedPtr<CheckedObj> m_obj1; | ||
| CheckedPtr<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is unchecked and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_checkedptr_member | ||
|
|
||
| namespace call_args_const_checkedref_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const CheckedRef<CheckedObj> m_obj1; | ||
| CheckedRef<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is unchecked and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_checkedref_member | ||
|
|
||
| namespace call_args_const_unique_ptr { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const std::unique_ptr<CheckedObj> m_obj1; | ||
| std::unique_ptr<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is unchecked and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_unique_ptr |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s | ||
|
|
||
| #include "mock-types.h" | ||
|
|
||
| namespace std { | ||
| } | ||
|
|
||
| namespace call_args_const_refptr_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const RefPtr<RefCountable> m_obj1; | ||
| RefPtr<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_refptr_member | ||
|
|
||
| namespace call_args_const_ref_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const Ref<RefCountable> m_obj1; | ||
| Ref<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_ref_member | ||
|
|
||
| namespace call_args_const_unique_ptr { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const std::unique_ptr<RefCountable> m_obj1; | ||
| std::unique_ptr<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| m_obj1->method(); | ||
| m_obj2->method(); | ||
| // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} | ||
| } | ||
|
|
||
| } // namespace call_args_const_unique_ptr | ||
rniwa marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLocalVarsChecker -verify %s | ||
|
|
||
| #include "mock-types.h" | ||
| #include "mock-system-header.h" | ||
|
|
||
| void someFunction(); | ||
|
|
||
| namespace local_vars_const_checkedptr_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const CheckedPtr<CheckedObj> m_obj1; | ||
| CheckedPtr<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto* obj1 = m_obj1.get(); | ||
| obj1->method(); | ||
| auto* obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} | ||
| obj2->method(); | ||
| } | ||
|
|
||
| } // namespace local_vars_const_checkedptr_member | ||
|
|
||
| namespace local_vars_const_checkedref_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const CheckedRef<CheckedObj> m_obj1; | ||
| CheckedRef<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto& obj1 = m_obj1.get(); | ||
| obj1.method(); | ||
| auto& obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} | ||
| obj2.method(); | ||
| } | ||
|
|
||
| } // namespace local_vars_const_ref_member | ||
|
|
||
| namespace call_args_const_unique_ptr { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const std::unique_ptr<CheckedObj> m_obj1; | ||
| std::unique_ptr<CheckedObj> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto* obj1 = m_obj1.get(); | ||
| obj1->method(); | ||
| auto* obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} | ||
| obj2->method(); | ||
| } | ||
|
|
||
| } // namespace call_args_const_unique_ptr |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedLocalVarsChecker -verify %s | ||
|
|
||
| #include "mock-types.h" | ||
| #include "mock-system-header.h" | ||
|
|
||
| void someFunction(); | ||
|
|
||
| namespace local_vars_const_refptr_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const RefPtr<RefCountable> m_obj1; | ||
| RefPtr<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto* obj1 = m_obj1.get(); | ||
| obj1->method(); | ||
| auto* obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} | ||
| obj2->method(); | ||
| } | ||
|
|
||
| } // namespace local_vars_const_refptr_member | ||
|
|
||
| namespace local_vars_const_ref_member { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const Ref<RefCountable> m_obj1; | ||
| Ref<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto& obj1 = m_obj1.get(); | ||
| obj1.method(); | ||
| auto& obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} | ||
| obj2.method(); | ||
| } | ||
|
|
||
| } // namespace local_vars_const_ref_member | ||
|
|
||
| namespace call_args_const_unique_ptr { | ||
|
|
||
| class Foo { | ||
| public: | ||
| Foo(); | ||
| void bar(); | ||
|
|
||
| private: | ||
| const std::unique_ptr<RefCountable> m_obj1; | ||
| std::unique_ptr<RefCountable> m_obj2; | ||
| }; | ||
|
|
||
| void Foo::bar() { | ||
| auto* obj1 = m_obj1.get(); | ||
| obj1->method(); | ||
| auto* obj2 = m_obj2.get(); | ||
| // expected-warning@-1{{Local variable 'obj2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} | ||
| obj2->method(); | ||
| } | ||
|
|
||
| } // namespace call_args_const_unique_ptr |
Uh oh!
There was an error while loading. Please reload this page.