File tree Expand file tree Collapse file tree 2 files changed +48
-1
lines changed
include/clang/Analysis/FlowSensitive
unittests/Analysis/FlowSensitive Expand file tree Collapse file tree 2 files changed +48
-1
lines changed Original file line number Diff line number Diff 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 }
Original file line number Diff line number Diff 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+
16401683TEST (TransferTest, StructModeledFieldsWithComplicatedInheritance) {
16411684 std::string Code = R"(
16421685 struct Base1 {
You can’t perform that action at this time.
0 commit comments