File tree 2 files changed +48
-1
lines changed
include/clang/Analysis/FlowSensitive
unittests/Analysis/FlowSensitive 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> {
113
113
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
114
114
bool TraverseDecltypeTypeLoc (DecltypeTypeLoc) { return true ; }
115
115
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
+ }
117
121
bool TraverseUnaryExprOrTypeTraitExpr (UnaryExprOrTypeTraitExpr *) {
118
122
return true ;
119
123
}
Original file line number Diff line number Diff line change @@ -1637,6 +1637,49 @@ TEST(TransferTest, StructModeledFieldsWithAccessor) {
1637
1637
});
1638
1638
}
1639
1639
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
+
1640
1683
TEST (TransferTest, StructModeledFieldsWithComplicatedInheritance) {
1641
1684
std::string Code = R"(
1642
1685
struct Base1 {
You can’t perform that action at this time.
0 commit comments