1 //=======- ASTUtils.cpp ------------------------------------------*- C++ -*-==//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "PtrTypesSemantics.h"
11 #include "clang/AST/CXXInheritance.h"
12 #include "clang/AST/Decl.h"
13 #include "clang/AST/DeclCXX.h"
14 #include "clang/AST/ExprCXX.h"
19 std::pair
<const Expr
*, bool>
20 tryToFindPtrOrigin(const Expr
*E
, bool StopAtFirstRefCountedObj
) {
22 if (auto *cast
= dyn_cast
<CastExpr
>(E
)) {
23 if (StopAtFirstRefCountedObj
) {
24 if (auto *ConversionFunc
=
25 dyn_cast_or_null
<FunctionDecl
>(cast
->getConversionFunction())) {
26 if (isCtorOfRefCounted(ConversionFunc
))
30 // FIXME: This can give false "origin" that would lead to false negatives
31 // in checkers. See https://reviews.llvm.org/D37023 for reference.
32 E
= cast
->getSubExpr();
35 if (auto *call
= dyn_cast
<CallExpr
>(E
)) {
36 if (auto *memberCall
= dyn_cast
<CXXMemberCallExpr
>(call
)) {
37 std::optional
<bool> IsGetterOfRefCt
= isGetterOfRefCounted(memberCall
->getMethodDecl());
38 if (IsGetterOfRefCt
&& *IsGetterOfRefCt
) {
39 E
= memberCall
->getImplicitObjectArgument();
40 if (StopAtFirstRefCountedObj
) {
47 if (auto *operatorCall
= dyn_cast
<CXXOperatorCallExpr
>(E
)) {
48 if (operatorCall
->getNumArgs() == 1) {
49 E
= operatorCall
->getArg(0);
54 if (auto *callee
= call
->getDirectCallee()) {
55 if (isCtorOfRefCounted(callee
)) {
56 if (StopAtFirstRefCountedObj
)
63 if (isPtrConversion(callee
)) {
69 if (auto *unaryOp
= dyn_cast
<UnaryOperator
>(E
)) {
70 // FIXME: Currently accepts ANY unary operator. Is it OK?
71 E
= unaryOp
->getSubExpr();
77 // Some other expression.
81 bool isASafeCallArg(const Expr
*E
) {
83 if (auto *Ref
= dyn_cast
<DeclRefExpr
>(E
)) {
84 if (auto *D
= dyn_cast_or_null
<VarDecl
>(Ref
->getFoundDecl())) {
85 if (isa
<ParmVarDecl
>(D
) || D
->isLocalVarDecl())
90 // TODO: checker for method calls on non-refcounted objects
91 return isa
<CXXThisExpr
>(E
);