balazske updated this revision to Diff 258011.
balazske added a comment.
- Adding tests.
- Type alias is supported.
- Updated comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77809/new/
https://reviews.llvm.org/D77809
Files:
clang/lib/Analysis/CFG.cpp
clang/test/Analysis/cfg.cpp
Index: clang/test/Analysis/cfg.cpp
===================================================================
--- clang/test/Analysis/cfg.cpp
+++ clang/test/Analysis/cfg.cpp
@@ -568,6 +568,71 @@
return 2;
}
+// CHECK-LABEL: void vla_simple(int x)
+// CHECK: [B1]
+// CHECK-NEXT: 1: x
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: int vla[x];
+void vla_simple(int x) {
+ int vla[x];
+}
+
+// CHECK-LABEL: void vla_typedef(int x)
+// CHECK: [B1]
+// CHECK-NEXT: 1: x
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: typedef int VLA[x];
+void vla_typedef(int x) {
+ typedef int VLA[x];
+}
+
+// CHECK-LABEL: void vla_typealias(int x)
+// CHECK: [B1]
+// CHECK-NEXT: 1: x
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: using VLA = int [x];
+void vla_typealias(int x) {
+ using VLA = int[x];
+}
+
+// CHECK-LABEL: void vla_typedef_multi(int x, int y)
+// CHECK: [B1]
+// CHECK-NEXT: 1: y
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: x
+// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 5: typedef int VLA[x][y];
+void vla_typedef_multi(int x, int y) {
+ typedef int VLA[x][y];
+}
+
+// CHECK-LABEL: void vla_typedefname_multi(int x, int y)
+// CHECK: [B1]
+// CHECK-NEXT: 1: x
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 3: typedef int VLA[x];
+// CHECK-NEXT: 4: y
+// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 6: typedef VLA VLA1[y];
+// CHECK-NEXT: 7: 3
+// CHECK-NEXT: 8: using VLA2 = VLA1 [3];
+// CHECK-NEXT: 9: 4
+// CHECK-NEXT: 10: VLA2 vla[4];
+void vla_typedefname_multi(int x, int y) {
+ typedef int VLA[x];
+ typedef VLA VLA1[y];
+ using VLA2 = VLA1[3];
+ VLA2 vla[4];
+}
+
+// CHECK-LABEL: void vla_embedded(int x)
+// CHECK: [B1]
+// CHECK-NEXT: 1: void (*vla)(int *);
+void vla_embedded(int x) {
+ // FIXME: 'x' is not generated but should be.
+ void (*vla)(int[x]);
+}
+
// CHECK-LABEL: template<> int *PR18472<int>()
// CHECK: [B2 (ENTRY)]
// CHECK-NEXT: Succs (1): B1
Index: clang/lib/Analysis/CFG.cpp
===================================================================
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -2839,11 +2839,30 @@
/// 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 +2924,8 @@
}
// 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: `void (*vla)(int[x]);`
for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) {
if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits