diff options
author | Ryosuke Niwa <rniwa@webkit.org> | 2024-05-01 11:27:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-01 11:27:45 -0700 |
commit | 1ca600586a61cee41e117a188d880417de3e1c00 (patch) | |
tree | 070103d5f9fa66c8253eaf0b9e551fb3ee0418e8 | |
parent | aca511734f5ff6204fdc65427566c8bd3b810a24 (diff) |
[alpha.webkit.UncountedCallArgsChecker] Support more trivial expressions. (#90414)
Treat a compound operator such as |=, array subscription, sizeof, and
non-type template parameter as trivial so long as subexpressions are
also trivial.
Also treat true/false boolean literal as trivial.
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp | 23 | ||||
-rw-r--r-- | clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp | 23 |
2 files changed, 45 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 287f6a528700..6901dbb415bf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -311,7 +311,7 @@ public: bool VisitUnaryOperator(const UnaryOperator *UO) { // Operator '*' and '!' are allowed as long as the operand is trivial. auto op = UO->getOpcode(); - if (op == UO_Deref || op == UO_AddrOf || op == UO_LNot) + if (op == UO_Deref || op == UO_AddrOf || op == UO_LNot || op == UO_Not) return Visit(UO->getSubExpr()); if (UO->isIncrementOp() || UO->isDecrementOp()) { @@ -331,6 +331,16 @@ public: return Visit(BO->getLHS()) && Visit(BO->getRHS()); } + bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO) { + // Compound assignment operator such as |= is trivial if its + // subexpresssions are trivial. + return VisitChildren(CAO); + } + + bool VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE) { + return VisitChildren(ASE); + } + bool VisitConditionalOperator(const ConditionalOperator *CO) { // Ternary operators are trivial if their conditions & values are trivial. return VisitChildren(CO); @@ -360,6 +370,16 @@ public: return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); } + bool + VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) { + // Non-type template paramter is compile time constant and trivial. + return true; + } + + bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E) { + return VisitChildren(E); + } + bool VisitPredefinedExpr(const PredefinedExpr *E) { // A predefined identifier such as "func" is considered trivial. return true; @@ -463,6 +483,7 @@ public: bool VisitFixedPointLiteral(const FixedPointLiteral *E) { return true; } bool VisitCharacterLiteral(const CharacterLiteral *E) { return true; } bool VisitStringLiteral(const StringLiteral *E) { return true; } + bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return true; } bool VisitConstantExpr(const ConstantExpr *CE) { // Constant expressions are trivial. diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp index 80a9a263dab1..63a68a994a5c 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp @@ -201,6 +201,13 @@ public: unsigned trivial25() const { return __c11_atomic_load((volatile _Atomic(unsigned) *)&v, __ATOMIC_RELAXED); } bool trivial26() { bool hasValue = v; return !hasValue; } bool trivial27(int v) { bool value; value = v ? 1 : 0; return value; } + bool trivial28() { return true; } + bool trivial29() { return false; } + unsigned trivial30(unsigned v) { unsigned r = 0xff; r |= v; return r; } + int trivial31(int* v) { return v[0]; } + unsigned trivial32() { return sizeof(int); } + unsigned trivial33() { return ~0xff; } + template <unsigned v> unsigned trivial34() { return v; } static RefCounted& singleton() { static RefCounted s_RefCounted; @@ -273,6 +280,9 @@ public: return val; } + int nonTrivial13() { return ~otherFunction(); } + int nonTrivial14() { int r = 0xff; r |= otherFunction(); return r; } + unsigned v { 0 }; Number* number { nullptr }; Enum enumValue { Enum::Value1 }; @@ -322,6 +332,15 @@ public: getFieldTrivial().trivial25(); // no-warning getFieldTrivial().trivial26(); // no-warning getFieldTrivial().trivial27(5); // no-warning + getFieldTrivial().trivial28(); // no-warning + getFieldTrivial().trivial29(); // no-warning + getFieldTrivial().trivial30(7); // no-warning + int a[] = {1, 2}; + getFieldTrivial().trivial31(a); // no-warning + getFieldTrivial().trivial32(); // no-warning + getFieldTrivial().trivial33(); // no-warning + getFieldTrivial().trivial34<7>(); // no-warning + RefCounted::singleton().trivial18(); // no-warning RefCounted::singleton().someFunction(); // no-warning @@ -351,6 +370,10 @@ public: // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} getFieldTrivial().nonTrivial12(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().nonTrivial13(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().nonTrivial14(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} } }; |