From 89dea017ae18c6fcc6dda06a9accffc32c7e61cc Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 26 Mar 2019 20:56:36 +0000 Subject: [PATCH] Bug 1539016 part 2. Teach MOZ_CAN_RUN_SCRIPT analysis about conditional operators. r=andi Differential Revision: https://phabricator.services.mozilla.com/D24839 --HG-- extra : moz-landing-system : lando --- build/clang-plugin/CanRunScriptChecker.cpp | 14 +++- build/clang-plugin/tests/TestCanRunScript.cpp | 77 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/build/clang-plugin/CanRunScriptChecker.cpp b/build/clang-plugin/CanRunScriptChecker.cpp index 939eff199f05..35243dfe372d 100644 --- a/build/clang-plugin/CanRunScriptChecker.cpp +++ b/build/clang-plugin/CanRunScriptChecker.cpp @@ -133,6 +133,18 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) { // just use ignoreTrivials to strip off the cast. ignoreTrivials(KnownLiveBase)))); + auto KnownLive = anyOf( + // Anything above, of course. + KnownLiveSimple, + // Conditional operators where both arms are live. + conditionalOperator( + hasFalseExpression(ignoreTrivials(KnownLiveSimple)), + hasTrueExpression(ignoreTrivials(KnownLiveSimple))) + // We're not handling cases like a dereference of a conditional operator, + // mostly because handling a dereference in general is so ugly. I + // _really_ wish I could just write a recursive matcher here easily. + ); + auto InvalidArg = ignoreTrivialsConditional( // We want to consider things if there is anything refcounted involved, @@ -146,7 +158,7 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) { // We want to find any expression, expr( // which is not known live, - unless(KnownLiveSimple), + unless(KnownLive), // and which is not a default arg with value nullptr, since those are // always safe, unless(cxxDefaultArgExpr(isNullDefaultArg())), diff --git a/build/clang-plugin/tests/TestCanRunScript.cpp b/build/clang-plugin/tests/TestCanRunScript.cpp index b61bf501c95c..6f4462846d1c 100644 --- a/build/clang-plugin/tests/TestCanRunScript.cpp +++ b/build/clang-plugin/tests/TestCanRunScript.cpp @@ -444,6 +444,7 @@ struct DisallowRefPtrTArrayElement { struct AllowConstexprMembers { static constexpr RefCountedBase* mRefCounted = nullptr; + static constexpr RefCountedBase* mRefCounted2 = nullptr; MOZ_CAN_RUN_SCRIPT void foo() { mRefCounted->method_test(); } @@ -466,3 +467,79 @@ MOZ_CAN_RUN_SCRIPT void test_constexpr_2() { MOZ_CAN_RUN_SCRIPT void test_constexpr_3() { test_ref(*AllowConstexprMembers::mRefCounted); } + +MOZ_CAN_RUN_SCRIPT void test_ternary_1(RefCountedBase* arg1, RefCountedBase* arg2) { + (arg1 ? arg1 : arg2)->method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_2(RefCountedBase* arg1, RefCountedBase* arg2) { + test2(arg1 ? arg1 : arg2); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_3(RefCountedBase* arg1, RefCountedBase& arg2) { + (arg1 ? *arg1 : arg2).method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_4(RefCountedBase* arg1, RefCountedBase& arg2) { + test_ref(arg1 ? *arg1 : arg2); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_5(RefCountedBase* arg) { + RefPtr local = new RefCountedBase(); + (arg ? arg : local.get())->method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_6(RefCountedBase* arg) { + RefPtr local = new RefCountedBase(); + test2(arg ? arg : local.get()); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_7(RefCountedBase* arg) { + RefPtr local = new RefCountedBase(); + (arg ? *arg : *local).method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_8(RefCountedBase* arg) { + RefPtr local = new RefCountedBase(); + test_ref(arg ? *arg : *local); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_9(RefCountedBase* arg) { + (arg ? arg : AllowConstexprMembers::mRefCounted)->method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_10(RefCountedBase* arg) { + test2(arg ? arg : AllowConstexprMembers::mRefCounted); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_11(RefCountedBase* arg) { + (arg ? *arg : *AllowConstexprMembers::mRefCounted).method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_12(RefCountedBase* arg) { + test_ref(arg ? *arg : *AllowConstexprMembers::mRefCounted); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_13(bool arg) { + (arg ? + AllowConstexprMembers::mRefCounted : + AllowConstexprMembers::mRefCounted2)->method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_14(bool arg) { + test2(arg ? + AllowConstexprMembers::mRefCounted : + AllowConstexprMembers::mRefCounted2); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_15(bool arg) { + (arg ? + *AllowConstexprMembers::mRefCounted : + *AllowConstexprMembers::mRefCounted2).method_test(); +} + +MOZ_CAN_RUN_SCRIPT void test_ternary_16(bool arg) { + test_ref(arg ? + *AllowConstexprMembers::mRefCounted : + *AllowConstexprMembers::mRefCounted2); +}