Skip to content

Commit 655c223

Browse files
authored
[clang][dataflow] reland #96766 with fix (#98896)
- **Reapply "[clang][dataflow] Teach `AnalysisASTVisitor` that `typeid()` can be evaluated." (#96766)** - **Turn on RTTI explicitly in `checkDataflowWithNoopAnalysis()`.**
1 parent 27d961d commit 655c223

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

clang/include/clang/Analysis/FlowSensitive/ASTOps.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
113113
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
114114
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
115115
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
116-
bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; }
116+
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) {
117+
if (TIE->isPotentiallyEvaluated())
118+
return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE);
119+
return true;
120+
}
117121
bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
118122
return true;
119123
}

clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,18 @@ llvm::Error test::checkDataflowWithNoopAnalysis(
176176
DataflowAnalysisOptions Options, LangStandard::Kind Std,
177177
std::function<llvm::StringMap<QualType>(QualType)> SyntheticFieldCallback) {
178178
llvm::SmallVector<std::string, 3> ASTBuildArgs = {
179+
"-fsyntax-only",
179180
// -fnodelayed-template-parsing is the default everywhere but on Windows.
180181
// Set it explicitly so that tests behave the same on Windows as on other
181182
// platforms.
183+
"-fno-delayed-template-parsing",
182184
// Set -Wno-unused-value because it's often desirable in tests to write
183185
// expressions with unused value, and we don't want the output to be
184186
// cluttered with warnings about them.
185-
"-fsyntax-only", "-fno-delayed-template-parsing", "-Wno-unused-value",
187+
"-Wno-unused-value",
188+
// Some build environments don't have RTTI enabled by default.
189+
// Enable it explicitly to make sure tests work in all environments.
190+
"-frtti",
186191
"-std=" +
187192
std::string(LangStandard::getLangStandardForKind(Std).getName())};
188193
AnalysisInputs<NoopAnalysis> AI(

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,49 @@ TEST(TransferTest, StructModeledFieldsWithAccessor) {
16371637
});
16381638
}
16391639

1640+
TEST(TransferTest, StructModeledFieldsInTypeid) {
1641+
// Test that we model fields mentioned inside a `typeid()` expression only if
1642+
// that expression is potentially evaluated -- i.e. if the expression inside
1643+
// `typeid()` is a glvalue of polymorphic type (see
1644+
// `CXXTypeidExpr::isPotentiallyEvaluated()` and [expr.typeid]p3).
1645+
std::string Code = R"(
1646+
// Definitions needed for `typeid`.
1647+
namespace std {
1648+
class type_info {};
1649+
class bad_typeid {};
1650+
} // namespace std
1651+
1652+
struct NonPolymorphic {};
1653+
1654+
struct Polymorphic {
1655+
virtual ~Polymorphic() = default;
1656+
};
1657+
1658+
struct S {
1659+
NonPolymorphic *NonPoly;
1660+
Polymorphic *Poly;
1661+
};
1662+
1663+
void target(S &s) {
1664+
typeid(*s.NonPoly);
1665+
typeid(*s.Poly);
1666+
// [[p]]
1667+
}
1668+
)";
1669+
runDataflow(
1670+
Code,
1671+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
1672+
ASTContext &ASTCtx) {
1673+
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
1674+
auto &SLoc = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s");
1675+
std::vector<const ValueDecl *> Fields;
1676+
for (auto [Field, _] : SLoc.children())
1677+
Fields.push_back(Field);
1678+
EXPECT_THAT(Fields,
1679+
UnorderedElementsAre(findValueDecl(ASTCtx, "Poly")));
1680+
});
1681+
}
1682+
16401683
TEST(TransferTest, StructModeledFieldsWithComplicatedInheritance) {
16411684
std::string Code = R"(
16421685
struct Base1 {

0 commit comments

Comments
 (0)