1 /* Finding reachable regions and values.
2    Copyright (C) 2020-2022 Free Software Foundation, Inc.
3    Contributed by David Malcolm <dmalcolm@redhat.com>.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #ifndef GCC_ANALYZER_REGION_MODEL_REACHABILITY_H
22 #define GCC_ANALYZER_REGION_MODEL_REACHABILITY_H
23 
24 namespace ana {
25 
26 /* A class for determining which regions and svalues are reachable.
27 
28    Used by region_model::handle_unrecognized_call for keeping
29    track of all regions that are reachable, and, of those, which are
30    mutable.
31 
32    Used by program_state::detect_leaks
33    (via region_model::get_reachable_svalues) for detecting leaks.  */
34 
35 class reachable_regions
36 {
37 public:
38   reachable_regions (region_model *model);
39 
40   /* Callback called for each cluster when initializing this object.  */
41   static void init_cluster_cb (const region *base_reg,
42 			       reachable_regions *this_ptr);
43 
44   /* Called for each cluster when initializing this object.  */
45   void init_cluster (const region *base_reg);
46 
47   /* Lazily mark the cluster containing REG as being reachable, recursively
48      adding clusters reachable from REG's cluster.  */
49   void add (const region *reg, bool is_mutable);
50 
51   static void handle_sval_cb (const svalue *sval,
52 			      reachable_regions *this_ptr);
53 
54   /* Add SVAL.  If it is a pointer, add the pointed-to region.  */
55   void handle_sval (const svalue *sval);
56 
57   /* Add SVAL.  If it is a pointer, add the pointed-to region.
58      Use PARAM_TYPE for determining mutability.  */
59   void handle_parm (const svalue *sval, tree param_type);
60 
61   /* Update the store to mark the clusters that were found to be mutable
62      as having escaped.
63      Notify CTXT about escaping function_decls.  */
64   void mark_escaped_clusters (region_model_context *ctxt);
65 
66   /* Iteration over reachable base regions.  */
begin()67   hash_set<const region *>::iterator begin ()
68   {
69     return m_reachable_base_regs.begin ();
70   }
end()71   hash_set<const region *>::iterator end ()
72   {
73     return m_reachable_base_regs.end ();
74   }
75 
begin_reachable_svals()76   svalue_set::iterator begin_reachable_svals ()
77   {
78     return m_reachable_svals.begin ();
79   }
end_reachable_svals()80   svalue_set::iterator end_reachable_svals ()
81   {
82     return m_reachable_svals.end ();
83   }
begin_mutable_svals()84   svalue_set::iterator begin_mutable_svals ()
85   {
86     return m_mutable_svals.begin ();
87   }
end_mutable_svals()88   svalue_set::iterator end_mutable_svals ()
89   {
90     return m_mutable_svals.end ();
91   }
begin_mutable_base_regs()92   hash_set<const region *>::iterator begin_mutable_base_regs ()
93   {
94     return m_mutable_base_regs.begin ();
95   }
end_mutable_base_regs()96   hash_set<const region *>::iterator end_mutable_base_regs ()
97   {
98     return m_mutable_base_regs.end ();
99   }
100 
101   void dump_to_pp (pretty_printer *pp) const;
102 
103   DEBUG_FUNCTION void dump () const;
104 
105 private:
106   region_model *m_model;
107   store *m_store;
108 
109   /* The base regions already seen.  */
110   hash_set<const region *> m_reachable_base_regs;
111 
112   /* The base regions that can be changed (accessed via non-const pointers).  */
113   hash_set<const region *> m_mutable_base_regs;
114 
115   /* svalues that were passed as const pointers, so e.g. couldn't have
116      been freed (but could have e.g. had "close" called on them if an
117      int file-descriptor).  */
118   svalue_set m_reachable_svals;
119   /* svalues that were passed as non-const pointers, so e.g. could have
120      been freed.  */
121   svalue_set m_mutable_svals;
122 };
123 
124 } // namespace ana
125 
126 #endif /* GCC_ANALYZER_REGION_MODEL_REACHABILITY_H */
127