Skip to content

Commit 1ca6005

Browse files
authored
[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.
1 parent aca5117 commit 1ca6005

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ class TrivialFunctionAnalysisVisitor
311311
bool VisitUnaryOperator(const UnaryOperator *UO) {
312312
// Operator '*' and '!' are allowed as long as the operand is trivial.
313313
auto op = UO->getOpcode();
314-
if (op == UO_Deref || op == UO_AddrOf || op == UO_LNot)
314+
if (op == UO_Deref || op == UO_AddrOf || op == UO_LNot || op == UO_Not)
315315
return Visit(UO->getSubExpr());
316316

317317
if (UO->isIncrementOp() || UO->isDecrementOp()) {
@@ -331,6 +331,16 @@ class TrivialFunctionAnalysisVisitor
331331
return Visit(BO->getLHS()) && Visit(BO->getRHS());
332332
}
333333

334+
bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO) {
335+
// Compound assignment operator such as |= is trivial if its
336+
// subexpresssions are trivial.
337+
return VisitChildren(CAO);
338+
}
339+
340+
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE) {
341+
return VisitChildren(ASE);
342+
}
343+
334344
bool VisitConditionalOperator(const ConditionalOperator *CO) {
335345
// Ternary operators are trivial if their conditions & values are trivial.
336346
return VisitChildren(CO);
@@ -360,6 +370,16 @@ class TrivialFunctionAnalysisVisitor
360370
return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache);
361371
}
362372

373+
bool
374+
VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
375+
// Non-type template paramter is compile time constant and trivial.
376+
return true;
377+
}
378+
379+
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E) {
380+
return VisitChildren(E);
381+
}
382+
363383
bool VisitPredefinedExpr(const PredefinedExpr *E) {
364384
// A predefined identifier such as "func" is considered trivial.
365385
return true;
@@ -463,6 +483,7 @@ class TrivialFunctionAnalysisVisitor
463483
bool VisitFixedPointLiteral(const FixedPointLiteral *E) { return true; }
464484
bool VisitCharacterLiteral(const CharacterLiteral *E) { return true; }
465485
bool VisitStringLiteral(const StringLiteral *E) { return true; }
486+
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return true; }
466487

467488
bool VisitConstantExpr(const ConstantExpr *CE) {
468489
// Constant expressions are trivial.

clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@ class RefCounted {
201201
unsigned trivial25() const { return __c11_atomic_load((volatile _Atomic(unsigned) *)&v, __ATOMIC_RELAXED); }
202202
bool trivial26() { bool hasValue = v; return !hasValue; }
203203
bool trivial27(int v) { bool value; value = v ? 1 : 0; return value; }
204+
bool trivial28() { return true; }
205+
bool trivial29() { return false; }
206+
unsigned trivial30(unsigned v) { unsigned r = 0xff; r |= v; return r; }
207+
int trivial31(int* v) { return v[0]; }
208+
unsigned trivial32() { return sizeof(int); }
209+
unsigned trivial33() { return ~0xff; }
210+
template <unsigned v> unsigned trivial34() { return v; }
204211

205212
static RefCounted& singleton() {
206213
static RefCounted s_RefCounted;
@@ -273,6 +280,9 @@ class RefCounted {
273280
return val;
274281
}
275282

283+
int nonTrivial13() { return ~otherFunction(); }
284+
int nonTrivial14() { int r = 0xff; r |= otherFunction(); return r; }
285+
276286
unsigned v { 0 };
277287
Number* number { nullptr };
278288
Enum enumValue { Enum::Value1 };
@@ -322,6 +332,15 @@ class UnrelatedClass {
322332
getFieldTrivial().trivial25(); // no-warning
323333
getFieldTrivial().trivial26(); // no-warning
324334
getFieldTrivial().trivial27(5); // no-warning
335+
getFieldTrivial().trivial28(); // no-warning
336+
getFieldTrivial().trivial29(); // no-warning
337+
getFieldTrivial().trivial30(7); // no-warning
338+
int a[] = {1, 2};
339+
getFieldTrivial().trivial31(a); // no-warning
340+
getFieldTrivial().trivial32(); // no-warning
341+
getFieldTrivial().trivial33(); // no-warning
342+
getFieldTrivial().trivial34<7>(); // no-warning
343+
325344
RefCounted::singleton().trivial18(); // no-warning
326345
RefCounted::singleton().someFunction(); // no-warning
327346

@@ -351,6 +370,10 @@ class UnrelatedClass {
351370
// expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}
352371
getFieldTrivial().nonTrivial12();
353372
// expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}
373+
getFieldTrivial().nonTrivial13();
374+
// expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}
375+
getFieldTrivial().nonTrivial14();
376+
// expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}}
354377
}
355378
};
356379

0 commit comments

Comments
 (0)