Skip to content

Commit

Permalink
[alpha.webkit.UncountedCallArgsChecker] Support more trivial expressi…
Browse files Browse the repository at this point in the history
…ons. (#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.
  • Loading branch information
rniwa committed May 1, 2024
1 parent aca5117 commit 1ca6005
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
23 changes: 22 additions & 1 deletion clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ class TrivialFunctionAnalysisVisitor
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()) {
Expand All @@ -331,6 +331,16 @@ class TrivialFunctionAnalysisVisitor
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);
Expand Down Expand Up @@ -360,6 +370,16 @@ class TrivialFunctionAnalysisVisitor
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;
Expand Down Expand Up @@ -463,6 +483,7 @@ class TrivialFunctionAnalysisVisitor
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.
Expand Down
23 changes: 23 additions & 0 deletions clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ class RefCounted {
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;
Expand Down Expand Up @@ -273,6 +280,9 @@ class RefCounted {
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 };
Expand Down Expand Up @@ -322,6 +332,15 @@ class UnrelatedClass {
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

Expand Down Expand Up @@ -351,6 +370,10 @@ class UnrelatedClass {
// 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}}
}
};

Expand Down

0 comments on commit 1ca6005

Please sign in to comment.