aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Analysis/CFG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Analysis/CFG.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Analysis/CFG.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/contrib/llvm-project/clang/lib/Analysis/CFG.cpp b/contrib/llvm-project/clang/lib/Analysis/CFG.cpp
index 4c1ea8995f9f..fc74226951a4 100644
--- a/contrib/llvm-project/clang/lib/Analysis/CFG.cpp
+++ b/contrib/llvm-project/clang/lib/Analysis/CFG.cpp
@@ -223,8 +223,6 @@ private:
///
class LocalScope {
public:
- friend class const_iterator;
-
using AutomaticVarsTy = BumpVector<VarDecl *>;
/// const_iterator - Iterates local scope backwards and jumps to previous
@@ -720,10 +718,10 @@ private:
// These sorts of call expressions don't have a common superclass,
// hence strict duck-typing.
template <typename CallLikeExpr,
- typename = typename std::enable_if<
- std::is_same<CallLikeExpr, CallExpr>::value ||
- std::is_same<CallLikeExpr, CXXConstructExpr>::value ||
- std::is_same<CallLikeExpr, ObjCMessageExpr>::value>>
+ typename = std::enable_if_t<
+ std::is_base_of<CallExpr, CallLikeExpr>::value ||
+ std::is_base_of<CXXConstructExpr, CallLikeExpr>::value ||
+ std::is_base_of<ObjCMessageExpr, CallLikeExpr>::value>>
void findConstructionContextsForArguments(CallLikeExpr *E) {
for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Expr *Arg = E->getArg(i);
@@ -2839,11 +2837,30 @@ CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) {
/// DeclStmts and initializers in them.
CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
assert(DS->isSingleDecl() && "Can handle single declarations only.");
+
+ if (const auto *TND = dyn_cast<TypedefNameDecl>(DS->getSingleDecl())) {
+ // If we encounter a VLA, process its size expressions.
+ const Type *T = TND->getUnderlyingType().getTypePtr();
+ if (!T->isVariablyModifiedType())
+ return Block;
+
+ autoCreateBlock();
+ appendStmt(Block, DS);
+
+ CFGBlock *LastBlock = Block;
+ for (const VariableArrayType *VA = FindVA(T); VA != nullptr;
+ VA = FindVA(VA->getElementType().getTypePtr())) {
+ if (CFGBlock *NewBlock = addStmt(VA->getSizeExpr()))
+ LastBlock = NewBlock;
+ }
+ return LastBlock;
+ }
+
VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
if (!VD) {
- // Of everything that can be declared in a DeclStmt, only VarDecls impact
- // runtime semantics.
+ // Of everything that can be declared in a DeclStmt, only VarDecls and the
+ // exceptions above impact runtime semantics.
return Block;
}
@@ -2905,6 +2922,8 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
}
// If the type of VD is a VLA, then we must process its size expressions.
+ // FIXME: This does not find the VLA if it is embedded in other types,
+ // like here: `int (*p_vla)[x];`
for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) {
if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
@@ -3997,6 +4016,11 @@ CFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
}
// VLA types have expressions that must be evaluated.
+ // Evaluation is done only for `sizeof`.
+
+ if (E->getKind() != UETT_SizeOf)
+ return Block;
+
CFGBlock *lastBlock = Block;
if (E->isArgumentType()) {