aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authoryronglin <yronglin777@gmail.com>2024-05-23 23:27:05 +0800
committerGitHub <noreply@github.com>2024-05-23 23:27:05 +0800
commit905b402a5d8f1490d668f40942390ebd6e87aa8f (patch)
tree9ee3588fefbb493c6294e3fcf435de77c4f6227d /clang/lib/Analysis
parent5064ff9bec006e7553c5da90328b81a360e52cd9 (diff)
downloadllvm-905b402a5d8f1490d668f40942390ebd6e87aa8f.zip
llvm-905b402a5d8f1490d668f40942390ebd6e87aa8f.tar.gz
llvm-905b402a5d8f1490d668f40942390ebd6e87aa8f.tar.bz2
[Analyzer][CFG] Correctly handle rebuilt default arg and default init expression (#91879)
Depends on https://github.com/llvm/llvm-project/pull/92527 Clang now support the following: - Extending lifetime of object bound to reference members of aggregates, that are created from default member initializer. - Rebuild `CXXDefaultArgExpr` and `CXXDefaultInitExpr` as needed where called or constructed. But CFG and ExprEngine need to be updated to address this change. This PR add `CXXDefaultArgExpr` and `CXXDefaultInitExpr` into CFG, and correct handle these expressions in ExprEngine --------- Signed-off-by: yronglin <yronglin777@gmail.com>
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/CFG.cpp50
1 files changed, 41 insertions, 9 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 64e6155..0231725 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -556,6 +556,10 @@ public:
private:
// Visitors to walk an AST and construct the CFG.
+ CFGBlock *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Default,
+ AddStmtChoice asc);
+ CFGBlock *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Default,
+ AddStmtChoice asc);
CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc);
CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
CFGBlock *VisitAttributedStmt(AttributedStmt *A, AddStmtChoice asc);
@@ -2254,16 +2258,10 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc,
asc, ExternallyDestructed);
case Stmt::CXXDefaultArgExprClass:
+ return VisitCXXDefaultArgExpr(cast<CXXDefaultArgExpr>(S), asc);
+
case Stmt::CXXDefaultInitExprClass:
- // FIXME: The expression inside a CXXDefaultArgExpr is owned by the
- // called function's declaration, not by the caller. If we simply add
- // this expression to the CFG, we could end up with the same Expr
- // appearing multiple times (PR13385).
- //
- // It's likewise possible for multiple CXXDefaultInitExprs for the same
- // expression to be used in the same function (through aggregate
- // initialization).
- return VisitStmt(S, asc);
+ return VisitCXXDefaultInitExpr(cast<CXXDefaultInitExpr>(S), asc);
case Stmt::CXXBindTemporaryExprClass:
return VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), asc);
@@ -2433,6 +2431,40 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) {
return B;
}
+CFGBlock *CFGBuilder::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Arg,
+ AddStmtChoice asc) {
+ if (Arg->hasRewrittenInit()) {
+ if (asc.alwaysAdd(*this, Arg)) {
+ autoCreateBlock();
+ appendStmt(Block, Arg);
+ }
+ return VisitStmt(Arg->getExpr(), asc);
+ }
+
+ // We can't add the default argument if it's not rewritten because the
+ // expression inside a CXXDefaultArgExpr is owned by the called function's
+ // declaration, not by the caller, we could end up with the same expression
+ // appearing multiple times.
+ return VisitStmt(Arg, asc);
+}
+
+CFGBlock *CFGBuilder::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Init,
+ AddStmtChoice asc) {
+ if (Init->hasRewrittenInit()) {
+ if (asc.alwaysAdd(*this, Init)) {
+ autoCreateBlock();
+ appendStmt(Block, Init);
+ }
+ return VisitStmt(Init->getExpr(), asc);
+ }
+
+ // We can't add the default initializer if it's not rewritten because multiple
+ // CXXDefaultInitExprs for the same sub-expression to be used in the same
+ // function (through aggregate initialization). we could end up with the same
+ // expression appearing multiple times.
+ return VisitStmt(Init, asc);
+}
+
CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) {
if (asc.alwaysAdd(*this, ILE)) {
autoCreateBlock();