ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
enum_property.h
Go to the documentation of this file.
1 
2 #ifndef BDWY_ENUM_PROPERTY_H
3 #define BDWY_ENUM_PROPERTY_H
4 
5 #include <list>
6 #include <map>
7 #include <string>
8 #include <iostream>
9 #include <bitset>
10 
11 typedef std::list< enumValueAnn * > enumvalue_list;
12 typedef enumvalue_list::iterator enumvalue_list_p;
13 typedef enumvalue_list::const_iterator enumvalue_list_cp;
14 
15 typedef std::map< std::string, enumPropertyAnn *> enum_property_map;
16 typedef enum_property_map::iterator enum_property_map_p;
17 typedef enum_property_map::const_iterator enum_property_map_cp;
18 
23 class enumValueAnn : public Ann
24 {
25 private:
26 
29  std::string _name;
30 
34 
38 
41  int _height;
42 
45  int _id;
46 
51  bool _is_leaf;
52 
53 public:
54 
57  enumValueAnn(const parserID * name,
59 
60  // Fields
61 
62  inline std::string & name() { return _name; }
63  inline const std::string & name() const { return _name; }
64 
65  inline enumValueAnn * more_general() const { return _more_general; }
66 
68  inline const enumvalue_list & more_specific() const { return _more_specific; }
69 
70  inline int height() const { return _height; }
71  inline void height(int new_height) { _height = new_height; }
72 
73  inline int id() const { return _id; }
74  inline void id(int new_id) { _id = new_id; }
75 
76  inline bool is_leaf() const { return _is_leaf; }
77 
83  void collect_atleast_values(enumvalue_set & collect);
84 };
85 
86 // ----------------------------------------------------------------------
87 // Enum Value Set
88 // ----------------------------------------------------------------------
89 
90 #define MAX_ENUMVALUES 32
91 
92 typedef std::bitset< MAX_ENUMVALUES > bitset32;
93 
94 class enumvalue_set : public bitset32
95 {
96 public:
97 
101  : bitset32()
102  {}
103 
109  : bitset32()
110  {
111  set(val->id());
112  }
113 
117  inline void insert(enumValueAnn * val) { set(val->id()); }
118 
125  inline bool includes(enumvalue_set & other) {
126  enumvalue_set temp(*this);
127  temp &= other;
128  return (temp != other);
129  }
130 
133  inline void set_union(const enumvalue_set & other) { (*this) |= other; }
134 
137  inline void set_intersection(const enumvalue_set & other) { (*this) &= other; }
138 };
139 
140 // ----------------------------------------------------------------------
141 // Dataflow analysis property
142 // ----------------------------------------------------------------------
143 
144 class Diagnostic; // TB new
145 
151 {
152 public:
153 
154  typedef std::vector< enumValueAnn *> enumvalue_vec;
155  typedef enumvalue_vec::iterator enumvalue_vec_p;
156  typedef enumvalue_vec::const_iterator enumvalue_vec_cp;
157 
158 #ifdef __MEMORYACCESS
159  typedef std::map< memoryAccess *, enumvalue_set> defuse_property_map;
160  typedef defuse_property_map::iterator defuse_property_map_p;
161 #endif
162 
163 #ifdef __MEMORYBLOCK
164  typedef std::map< memoryBlock *, enumvalue_set > block_propertyset_map;
165  typedef block_propertyset_map::iterator block_propertyset_map_p;
166 #endif
167 
168 #ifdef __PROCLOCATION
169  typedef std::pair< int, double > count_accuracy_pair;
170  typedef map< procLocation *, count_accuracy_pair > accuracy_map;
171  typedef accuracy_map::iterator accuracy_map_p;
172 #endif
173 
174 #ifdef __MEMORYBLOCK
175  typedef std::map< Location *, memoryblock_set > tested_objects_map;
176  typedef tested_objects_map::iterator tested_objects_map_p;
177 #endif
178 
179 #ifdef __STMTNODE
180  typedef std::map< stmtNode *, count_accuracy_pair > stmt_accuracy_map;
181  typedef stmt_accuracy_map::iterator stmt_accuracy_map_p;
182 #endif
183 
184  // TB
185 #ifdef __MEMORYBLOCK
186  typedef std::pair< memoryBlock*, Location* > block_loc_pair;
187  typedef std::set< block_loc_pair > block_loc_set;
188 
189  typedef std::pair< memoryBlock*, procNode* > block_proc_pair;
190  typedef std::set< block_proc_pair > block_proc_set;
191 #endif
192 
193 private:
194 
202 
209 
216 
220 
228 
232 
235 #ifdef __MEMORYACCESS
236  defuse_property_map _now_values;
237 #endif
238 
241 #ifdef __MEMORYBLOCK
242  block_propertyset_map _ever_values;
243 #endif
244 
245  // TB_unify
247 #ifdef __MEMORYBLOCK
248  typedef std::pair<procedureInfo*,memoryBlock*> Input_to_pair;
249  std::map<Input_to_pair,enumvalue_set> _input_to_values;
250 #endif
251 
257 #ifdef __FLOW_SENSITIVE_SET
258  flow_sensitive_set _flow_sensitive_objects;
259 #endif
260 
266 #ifdef __TESTED_OBJECTS
267  tested_objects_map _tested_objects;
268 #endif
269 
276 #ifdef __PROCLOCATION
277  accuracy_map _accuracy;
278 #endif
279 
285 #ifdef __FOO
286  stmt_set _error_statements;
287 
288 #endif
289 
293 
294 #ifdef __FOO
295 
299  procedureinfo_set _error_procedures;
300 
301 // begin TB new
302 
308  Diagnostic *_diagnostic;
309 #endif
310 // end TB new
311 
312 public:
313 
316  enumPropertyAnn(const parserID * name,
319  const parserID * default_name,
320  enumvalue_list * lowest_values,
321  parserid_list * diagnostic_values=NULL);
322 
328  void clear();
329 
332  inline bool enforce_weak_updates() const { return _enforce_weak_updates; }
333 
336  inline enumValueAnn * values() const { return _values; }
337 
340  enumValueAnn * lookup(const std::string & name);
341 
344  inline enumValueAnn * bottom() const { return _values; }
345 
348  inline enumValueAnn * top() const { return _top; }
349 
352  inline enumValueAnn * default_val() const { return _default; }
353 
359  enumValueAnn * two);
360 
366  void meet_with(enumvalue_set & first,
367  const enumvalue_set & second);
368 
374  bool at_least(enumValueAnn * left,
375  enumValueAnn * right);
376 
381  bool at_most(enumValueAnn * left,
382  enumValueAnn * right);
383 
389 #ifdef __MEMORYBLOCK
390  memoryBlock * lookup_property_block(memoryBlock * real_block);
391 #endif
392 
398 #ifdef __MEMORYBLOCK
399  void add_property_block(memoryBlock * real_block, memoryBlock * property_block);
400 #endif
401 
405 #ifdef __TEST
406  bool test(Broadway::Operator op, Broadway::FlowSensitivity flow_sensitivity,
407  Location * where,
408  pointerValue & lhs, std::string & lhs_name,
409  pointerValue & rhs, std::string & rhs_name);
410 
416  bool test(Broadway::Operator op, Broadway::FlowSensitivity flow_sensitivity,
417  Location * where,
418  pointerValue & lhs, std::string & lhs_name,
419  enumvalue_set rhs_value_set);
420 
425  bool test(Broadway::Operator op,
426  enumvalue_set lhs_value_set, enumvalue_set rhs_value_set);
427 
432 #ifdef __MEMORYACCESS
433  enumvalue_set lookup_now_value(memoryBlock * property_block,
434  memoryAccess * def_or_use);
435 #endif
436 
442 #ifdef __MEMORYACCESS
443  bool update_now_value(Location * where,
444  memoryBlock * property_block,
445  memoryAccess * def_or_use,
446  enumvalue_set value,
447  bool & lost_information);
448 #endif
449 
455 #ifdef __MEMORYBLOCK
456  bool update_ever_value(memoryBlock * property_block, enumvalue_set values);
457 #endif
458 
459  // TB_unify
461 #ifdef __MEMORYBLOCK
462  enumvalue_set lookup_input_to_value(procedureInfo *info,
463  memoryBlock * property_block);
464 #endif
465  // TB_unify
467 #ifdef __MEMORYBLOCK
468  void update_input_to_value(procedureInfo *info, memoryBlock * property_block,
469  enumvalue_set values, stmtLocation *callsite);
470 #endif
471 
474 
482 #ifdef __MEMORYBLOCK
483  enumvalue_set construct_now_value(Location * where,
484  pointerValue & variable,
485  std::string & variable_name,
486  bool & lost_information,
487  memoryblock_set & complicit_property_blocks);
488 #endif
489 
496 #ifdef __MEMORYBLOCK
497  enumvalue_set construct_now_value(Location * where,
498  memoryBlock * property_block,
499  bool default_to_top);
500 #endif
501 
508  enumvalue_set construct_after_value(pointerValue & variable, std::string & name);
509 
515 #ifdef __MEMORYBLOCK
516  enumvalue_set construct_after_value(memoryBlock * real_block);
517 #endif
518 
524  enumvalue_set construct_ever_value(pointerValue & variable, std::string & name);
525 
534  enumvalue_set construct_weak_now_value(Location * where,
535  pointerValue & variable, std::string & name);
536 
538 
545 #ifdef __MEMORYBLOCK
546  enumvalue_set compute_next(Location * where,
547  ruleAnn * rule,
548  exprAnn * expr,
549  pointerValue & right,
550  std::string & right_name,
551  bool & rhs_lost_information,
552  memoryblock_set & complicit_property_blocks,
553  enumvalue_set & save_ever_values);
554 #endif
555 
563 #ifdef __MEMORYBLOCK
564  void apply_next(Location * where,
565  stmtLocation * parameter_callsite,
566  ruleAnn * rule,
567  enumPropertyExprAnn * expr,
568  pointerValue & left,
569  std::string & left_name,
570  pointerValue & right,
571  enumvalue_set new_value,
572  bool rhs_lost_information,
573  bool rhs_changed, // TB_unify
574  memoryblock_set & complicit_property_blocks,
575  enumvalue_set ever_values,
576  memoryblock_set & changes);
577 #endif
578 
584 #ifdef __MEMORYBLOCK
585  void apply_merge(Location * where,
586  memoryBlock * property_block, memoryuse_list & phi_uses,
587  memoryblock_set & changes);
588 #endif
589 
596 #ifdef __MEMORYBLOCK
597  void apply_assignment(Location * where,
598  stmtLocation * parameter_callsite,
599  pointerValue & left, pointerValue & right,
600  bool is_parameter,
601  memoryblock_set & changes);
602 #endif
603 
609 #ifdef __MEMORYBLOCK
610  void self_assignment(Location * source,
611  Location * target,
612  memoryBlock * property_block,
613  memoryblock_set & changes,
614  bool is_input);
615 #endif
616 
622 #ifdef __MEMORYBLOCK
623  void conservative_procedure_call(stmtLocation * current,
624  pointerValue & reachable,
625  memoryblock_set & changes);
626 #endif
627 
633  void report(std::ostream & out,
634  bool is_error,
635  procLocation * where,
636  Broadway::FlowSensitivity flow_sensitivity,
637  pointerValue & lhs, std::string & lhs_name);
638 
639 #endif /* __TEST */
640 
642  friend std::ostream& operator<<(std::ostream & o, const enumPropertyAnn & anns) {
643  anns.print(o);
644  return o;
645  }
646 
652 #ifdef __MEMORYBLOCK
653  void precision_analysis(memoryModel * memory_model,
654  memoryblock_set & flow_sensitive);
655 #endif
656 
660  void precision_analysis(Analyzer * analyzer, int analyzed_properties);
661 
666  double compute_accuracy(Analyzer * analyzer);
667 
673 #ifdef __MEMORYBLOCK
674  void add_flow_sensitive_object(memoryBlock * property_block);
675 #endif
676 
682 #ifdef __MEMORYBLOCK
683  void set_flow_sensitivity(memoryBlock * real_block);
684 #endif
685 
689 #ifdef __FLOW_SENSITIVE_SET
690  inline int count_flow_sensitive_objects() { return _flow_sensitive_objects.size(); }
691 #endif
692 
694  void print(std::ostream & o) const;
695 
702 
705  std::string to_string(enumvalue_set value_set);
706 
707 // begin TB new
710  void reset_diagnostic();
711 
722 #ifdef __PROCLOCATION
723  void diagnostic(std::ostream &out, procLocation *where, pointerValue &pv,
724  enumvalue_set values) const;
725 #endif
726 // end TB new
727 
729  // TB_unify
730 #ifdef __MEMORYBLOCK
731  bool compare_now_value(Location *where, memoryBlock *property_block,
732  enumvalue_set compare_to);
733 #endif
734 private:
735 
738  void print(std::ostream & o, enumValueAnn * prop, int depth) const;
739 
742  void number_values(enumValueAnn * prop,
743  int & cur_index, int height, int & max_height);
744 
745 
749 #ifdef __MEMORYBLOCK
750  void track_destructive_assignments(Analyzer * analyzer,
751  Location * where,
752  memoryBlock * block,
753  bool disallow_context_sensitivity,
754  block_loc_set & already_seen,
755  block_loc_set seen_stack,
756  memoryblock_set & made_flow_sensitive,
757  memoryblock_set & made_fs_destructive,
758  block_loc_set & made_context_sensitive,
759  block_proc_set & eval_cs_seen_destructive,
760  block_proc_set & eval_cs_seen_complicit,
761  block_proc_set & eval_made_cs,
762  bool & make_chain_flow_sensitive,
763  bool & make_chain_context_sensitive,
764  memoryblock_vector & chain,
765  std::string & indent);
766 #endif
767 
773 #ifdef __MEMORYBLOCK
774  void record_tested_objects(Location * where,
775  pointerValue & ptr,
776  enumvalue_set & value_set,
777  memoryblock_set & complicit_property_blocks);
778 #endif
779 
783 #ifdef __MEMORYBLOCK
784  void trace_object(std::ostream & out,
785  memoryBlock * property_block,
786  memoryblock_set & already_seen,
787  std::string & indent);
788 #endif
789 
794 #ifdef __MEMORYBLOCK
795  bool evaluate_context_sensitivity(Analyzer * analyzer,
796  Location * target,
797  memoryBlock * block,
798  procLocation * procloc,
799  bool destructive,
800  block_proc_set & eval_cs_seen_destructive,
801  block_proc_set & eval_cs_seen_complicit,
802  block_proc_set & evaled_cs,
803  std::string & indent);
804 #endif
805 
809 #ifdef __MEMORYBLOCK
810  bool validate_property_cs(memoryBlock * block,
811  const callsite_objects_map & assignments,
812  procedureInfo *procedure, // TB
813  std::string & indent);
814 #endif
815 
819 #ifdef __MEMORYBLOCK
820  bool validate_multiplicity_cs(memoryBlock * block,
821  const callsite_objects_map & assignments,
822  procedureInfo *procedure, // TB
823  std::string & indent);
824 #endif
825 
829 #ifdef __MEMORYBLOCK
830  bool validate_pointer_cs(memoryBlock * block,
831  const callsite_objects_map & assignments,
832  procedureInfo *procedure, // TB
833  std::string & indent);
834 #endif
835 
840 #ifdef __MEMORYBLOCK
841  bool validate_pointer_fs(memoryBlock * block,
842  stmtLocation * where,
843  std::string & indent);
844 #endif
845 
850 #ifdef __MEMORYBLOCK
851  bool is_location_reachable(Location * source, Location * target, memoryBlock * block);
852 #endif
853 
858 #ifdef __MEMORYBLOCK
859  enumvalue_set reachable_values(stmtLocation * where,
860  const memoryblock_set & blocks,
861  procedureInfo *callee=NULL);
862 #endif
863 
867 #ifdef __PROCEDUREINFO
868  bool add_context_sensitive_proc(procedureInfo * info,
869  procedureinfo_set & already_seen,
870  procedureinfo_set & make_cs);
871 #endif
872 };
873 
874 #endif /* BDWY_ENUM_PROPERTY_H */