analyzer: start adding support for errno
[platform/upstream/gcc.git] / gcc / analyzer / region-model.cc
1 /* Classes for modeling the state of memory.
2    Copyright (C) 2019-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 #include "config.h"
22 #define INCLUDE_MEMORY
23 #include "system.h"
24 #include "coretypes.h"
25 #include "make-unique.h"
26 #include "tree.h"
27 #include "function.h"
28 #include "basic-block.h"
29 #include "gimple.h"
30 #include "gimple-iterator.h"
31 #include "diagnostic-core.h"
32 #include "graphviz.h"
33 #include "options.h"
34 #include "cgraph.h"
35 #include "tree-dfa.h"
36 #include "stringpool.h"
37 #include "convert.h"
38 #include "target.h"
39 #include "fold-const.h"
40 #include "tree-pretty-print.h"
41 #include "diagnostic-color.h"
42 #include "diagnostic-metadata.h"
43 #include "bitmap.h"
44 #include "selftest.h"
45 #include "analyzer/analyzer.h"
46 #include "analyzer/analyzer-logging.h"
47 #include "ordered-hash-map.h"
48 #include "options.h"
49 #include "cgraph.h"
50 #include "cfg.h"
51 #include "analyzer/supergraph.h"
52 #include "sbitmap.h"
53 #include "analyzer/call-string.h"
54 #include "analyzer/program-point.h"
55 #include "analyzer/store.h"
56 #include "analyzer/region-model.h"
57 #include "analyzer/constraint-manager.h"
58 #include "diagnostic-event-id.h"
59 #include "analyzer/sm.h"
60 #include "diagnostic-event-id.h"
61 #include "analyzer/sm.h"
62 #include "analyzer/pending-diagnostic.h"
63 #include "analyzer/region-model-reachability.h"
64 #include "analyzer/analyzer-selftests.h"
65 #include "analyzer/program-state.h"
66 #include "analyzer/call-summary.h"
67 #include "stor-layout.h"
68 #include "attribs.h"
69 #include "tree-object-size.h"
70 #include "gimple-ssa.h"
71 #include "tree-phinodes.h"
72 #include "tree-ssa-operands.h"
73 #include "ssa-iterators.h"
74 #include "calls.h"
75 #include "is-a.h"
76 #include "gcc-rich-location.h"
77
78 #if ENABLE_ANALYZER
79
80 namespace ana {
81
82 /* Dump T to PP in language-independent form, for debugging/logging/dumping
83    purposes.  */
84
85 void
86 dump_tree (pretty_printer *pp, tree t)
87 {
88   dump_generic_node (pp, t, 0, TDF_SLIM, 0);
89 }
90
91 /* Dump T to PP in language-independent form in quotes, for
92    debugging/logging/dumping purposes.  */
93
94 void
95 dump_quoted_tree (pretty_printer *pp, tree t)
96 {
97   pp_begin_quote (pp, pp_show_color (pp));
98   dump_tree (pp, t);
99   pp_end_quote (pp, pp_show_color (pp));
100 }
101
102 /* Equivalent to pp_printf (pp, "%qT", t), to avoid nesting pp_printf
103    calls within other pp_printf calls.
104
105    default_tree_printer handles 'T' and some other codes by calling
106      dump_generic_node (pp, t, 0, TDF_SLIM, 0);
107    dump_generic_node calls pp_printf in various places, leading to
108    garbled output.
109
110    Ideally pp_printf could be made to be reentrant, but in the meantime
111    this function provides a workaround.  */
112
113 void
114 print_quoted_type (pretty_printer *pp, tree t)
115 {
116   pp_begin_quote (pp, pp_show_color (pp));
117   dump_generic_node (pp, t, 0, TDF_SLIM, 0);
118   pp_end_quote (pp, pp_show_color (pp));
119 }
120
121 /* class region_to_value_map.  */
122
123 /* Assignment operator for region_to_value_map.  */
124
125 region_to_value_map &
126 region_to_value_map::operator= (const region_to_value_map &other)
127 {
128   m_hash_map.empty ();
129   for (auto iter : other.m_hash_map)
130     {
131       const region *reg = iter.first;
132       const svalue *sval = iter.second;
133       m_hash_map.put (reg, sval);
134     }
135   return *this;
136 }
137
138 /* Equality operator for region_to_value_map.  */
139
140 bool
141 region_to_value_map::operator== (const region_to_value_map &other) const
142 {
143   if (m_hash_map.elements () != other.m_hash_map.elements ())
144     return false;
145
146   for (auto iter : *this)
147     {
148       const region *reg = iter.first;
149       const svalue *sval = iter.second;
150       const svalue * const *other_slot = other.get (reg);
151       if (other_slot == NULL)
152         return false;
153       if (sval != *other_slot)
154         return false;
155     }
156
157   return true;
158 }
159
160 /* Dump this object to PP.  */
161
162 void
163 region_to_value_map::dump_to_pp (pretty_printer *pp, bool simple,
164                                  bool multiline) const
165 {
166   auto_vec<const region *> regs;
167   for (iterator iter = begin (); iter != end (); ++iter)
168     regs.safe_push ((*iter).first);
169   regs.qsort (region::cmp_ptr_ptr);
170   if (multiline)
171     pp_newline (pp);
172   else
173     pp_string (pp, " {");
174   unsigned i;
175   const region *reg;
176   FOR_EACH_VEC_ELT (regs, i, reg)
177     {
178       if (multiline)
179         pp_string (pp, "  ");
180       else if (i > 0)
181         pp_string (pp, ", ");
182       reg->dump_to_pp (pp, simple);
183       pp_string (pp, ": ");
184       const svalue *sval = *get (reg);
185       sval->dump_to_pp (pp, true);
186       if (multiline)
187         pp_newline (pp);
188     }
189   if (!multiline)
190     pp_string (pp, "}");
191 }
192
193 /* Dump this object to stderr.  */
194
195 DEBUG_FUNCTION void
196 region_to_value_map::dump (bool simple) const
197 {
198   pretty_printer pp;
199   pp_format_decoder (&pp) = default_tree_printer;
200   pp_show_color (&pp) = pp_show_color (global_dc->printer);
201   pp.buffer->stream = stderr;
202   dump_to_pp (&pp, simple, true);
203   pp_newline (&pp);
204   pp_flush (&pp);
205 }
206
207
208 /* Attempt to merge THIS with OTHER, writing the result
209    to OUT.
210
211    For now, write (region, value) mappings that are in common between THIS
212    and OTHER to OUT, effectively taking the intersection, rather than
213    rejecting differences.  */
214
215 bool
216 region_to_value_map::can_merge_with_p (const region_to_value_map &other,
217                                        region_to_value_map *out) const
218 {
219   for (auto iter : *this)
220     {
221       const region *iter_reg = iter.first;
222       const svalue *iter_sval = iter.second;
223       const svalue * const * other_slot = other.get (iter_reg);
224       if (other_slot)
225         if (iter_sval == *other_slot)
226           out->put (iter_reg, iter_sval);
227     }
228   return true;
229 }
230
231 /* Purge any state involving SVAL.  */
232
233 void
234 region_to_value_map::purge_state_involving (const svalue *sval)
235 {
236   auto_vec<const region *> to_purge;
237   for (auto iter : *this)
238     {
239       const region *iter_reg = iter.first;
240       const svalue *iter_sval = iter.second;
241       if (iter_reg->involves_p (sval) || iter_sval->involves_p (sval))
242         to_purge.safe_push (iter_reg);
243     }
244   for (auto iter : to_purge)
245     m_hash_map.remove (iter);
246 }
247
248 /* class region_model.  */
249
250 /* Ctor for region_model: construct an "empty" model.  */
251
252 region_model::region_model (region_model_manager *mgr)
253 : m_mgr (mgr), m_store (), m_current_frame (NULL),
254   m_dynamic_extents ()
255 {
256   m_constraints = new constraint_manager (mgr);
257 }
258
259 /* region_model's copy ctor.  */
260
261 region_model::region_model (const region_model &other)
262 : m_mgr (other.m_mgr), m_store (other.m_store),
263   m_constraints (new constraint_manager (*other.m_constraints)),
264   m_current_frame (other.m_current_frame),
265   m_dynamic_extents (other.m_dynamic_extents)
266 {
267 }
268
269 /* region_model's dtor.  */
270
271 region_model::~region_model ()
272 {
273   delete m_constraints;
274 }
275
276 /* region_model's assignment operator.  */
277
278 region_model &
279 region_model::operator= (const region_model &other)
280 {
281   /* m_mgr is const.  */
282   gcc_assert (m_mgr == other.m_mgr);
283
284   m_store = other.m_store;
285
286   delete m_constraints;
287   m_constraints = new constraint_manager (*other.m_constraints);
288
289   m_current_frame = other.m_current_frame;
290
291   m_dynamic_extents = other.m_dynamic_extents;
292
293   return *this;
294 }
295
296 /* Equality operator for region_model.
297
298    Amongst other things this directly compares the stores and the constraint
299    managers, so for this to be meaningful both this and OTHER should
300    have been canonicalized.  */
301
302 bool
303 region_model::operator== (const region_model &other) const
304 {
305   /* We can only compare instances that use the same manager.  */
306   gcc_assert (m_mgr == other.m_mgr);
307
308   if (m_store != other.m_store)
309     return false;
310
311   if (*m_constraints != *other.m_constraints)
312     return false;
313
314   if (m_current_frame != other.m_current_frame)
315     return false;
316
317   if (m_dynamic_extents != other.m_dynamic_extents)
318     return false;
319
320   gcc_checking_assert (hash () == other.hash ());
321
322   return true;
323 }
324
325 /* Generate a hash value for this region_model.  */
326
327 hashval_t
328 region_model::hash () const
329 {
330   hashval_t result = m_store.hash ();
331   result ^= m_constraints->hash ();
332   return result;
333 }
334
335 /* Dump a representation of this model to PP, showing the
336    stack, the store, and any constraints.
337    Use SIMPLE to control how svalues and regions are printed.  */
338
339 void
340 region_model::dump_to_pp (pretty_printer *pp, bool simple,
341                           bool multiline) const
342 {
343   /* Dump stack.  */
344   pp_printf (pp, "stack depth: %i", get_stack_depth ());
345   if (multiline)
346     pp_newline (pp);
347   else
348     pp_string (pp, " {");
349   for (const frame_region *iter_frame = m_current_frame; iter_frame;
350        iter_frame = iter_frame->get_calling_frame ())
351     {
352       if (multiline)
353         pp_string (pp, "  ");
354       else if (iter_frame != m_current_frame)
355         pp_string (pp, ", ");
356       pp_printf (pp, "frame (index %i): ", iter_frame->get_index ());
357       iter_frame->dump_to_pp (pp, simple);
358       if (multiline)
359         pp_newline (pp);
360     }
361   if (!multiline)
362     pp_string (pp, "}");
363
364   /* Dump store.  */
365   if (!multiline)
366     pp_string (pp, ", {");
367   m_store.dump_to_pp (pp, simple, multiline,
368                       m_mgr->get_store_manager ());
369   if (!multiline)
370     pp_string (pp, "}");
371
372   /* Dump constraints.  */
373   pp_string (pp, "constraint_manager:");
374   if (multiline)
375     pp_newline (pp);
376   else
377     pp_string (pp, " {");
378   m_constraints->dump_to_pp (pp, multiline);
379   if (!multiline)
380     pp_string (pp, "}");
381
382   /* Dump sizes of dynamic regions, if any are known.  */
383   if (!m_dynamic_extents.is_empty ())
384     {
385       pp_string (pp, "dynamic_extents:");
386       m_dynamic_extents.dump_to_pp (pp, simple, multiline);
387     }
388 }
389
390 /* Dump a representation of this model to FILE.  */
391
392 void
393 region_model::dump (FILE *fp, bool simple, bool multiline) const
394 {
395   pretty_printer pp;
396   pp_format_decoder (&pp) = default_tree_printer;
397   pp_show_color (&pp) = pp_show_color (global_dc->printer);
398   pp.buffer->stream = fp;
399   dump_to_pp (&pp, simple, multiline);
400   pp_newline (&pp);
401   pp_flush (&pp);
402 }
403
404 /* Dump a multiline representation of this model to stderr.  */
405
406 DEBUG_FUNCTION void
407 region_model::dump (bool simple) const
408 {
409   dump (stderr, simple, true);
410 }
411
412 /* Dump a multiline representation of this model to stderr.  */
413
414 DEBUG_FUNCTION void
415 region_model::debug () const
416 {
417   dump (true);
418 }
419
420 /* Assert that this object is valid.  */
421
422 void
423 region_model::validate () const
424 {
425   m_store.validate ();
426 }
427
428 /* Canonicalize the store and constraints, to maximize the chance of
429    equality between region_model instances.  */
430
431 void
432 region_model::canonicalize ()
433 {
434   m_store.canonicalize (m_mgr->get_store_manager ());
435   m_constraints->canonicalize ();
436 }
437
438 /* Return true if this region_model is in canonical form.  */
439
440 bool
441 region_model::canonicalized_p () const
442 {
443   region_model copy (*this);
444   copy.canonicalize ();
445   return *this == copy;
446 }
447
448 /* See the comment for store::loop_replay_fixup.  */
449
450 void
451 region_model::loop_replay_fixup (const region_model *dst_state)
452 {
453   m_store.loop_replay_fixup (dst_state->get_store (), m_mgr);
454 }
455
456 /* A subclass of pending_diagnostic for complaining about uses of
457    poisoned values.  */
458
459 class poisoned_value_diagnostic
460 : public pending_diagnostic_subclass<poisoned_value_diagnostic>
461 {
462 public:
463   poisoned_value_diagnostic (tree expr, enum poison_kind pkind,
464                              const region *src_region)
465   : m_expr (expr), m_pkind (pkind),
466     m_src_region (src_region)
467   {}
468
469   const char *get_kind () const final override { return "poisoned_value_diagnostic"; }
470
471   bool use_of_uninit_p () const final override
472   {
473     return m_pkind == POISON_KIND_UNINIT;
474   }
475
476   bool operator== (const poisoned_value_diagnostic &other) const
477   {
478     return (m_expr == other.m_expr
479             && m_pkind == other.m_pkind
480             && m_src_region == other.m_src_region);
481   }
482
483   int get_controlling_option () const final override
484   {
485     switch (m_pkind)
486       {
487       default:
488         gcc_unreachable ();
489       case POISON_KIND_UNINIT:
490         return OPT_Wanalyzer_use_of_uninitialized_value;
491       case POISON_KIND_FREED:
492         return OPT_Wanalyzer_use_after_free;
493       case POISON_KIND_POPPED_STACK:
494         return OPT_Wanalyzer_use_of_pointer_in_stale_stack_frame;
495       }
496   }
497
498   bool emit (rich_location *rich_loc) final override
499   {
500     switch (m_pkind)
501       {
502       default:
503         gcc_unreachable ();
504       case POISON_KIND_UNINIT:
505         {
506           diagnostic_metadata m;
507           m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable".  */
508           return warning_meta (rich_loc, m, get_controlling_option (),
509                                "use of uninitialized value %qE",
510                                m_expr);
511         }
512         break;
513       case POISON_KIND_FREED:
514         {
515           diagnostic_metadata m;
516           m.add_cwe (416); /* "CWE-416: Use After Free".  */
517           return warning_meta (rich_loc, m, get_controlling_option (),
518                                "use after %<free%> of %qE",
519                                m_expr);
520         }
521         break;
522       case POISON_KIND_POPPED_STACK:
523         {
524           /* TODO: which CWE?  */
525           return warning_at
526             (rich_loc, get_controlling_option (),
527              "dereferencing pointer %qE to within stale stack frame",
528              m_expr);
529         }
530         break;
531       }
532   }
533
534   label_text describe_final_event (const evdesc::final_event &ev) final override
535   {
536     switch (m_pkind)
537       {
538       default:
539         gcc_unreachable ();
540       case POISON_KIND_UNINIT:
541         return ev.formatted_print ("use of uninitialized value %qE here",
542                                    m_expr);
543       case POISON_KIND_FREED:
544         return ev.formatted_print ("use after %<free%> of %qE here",
545                                    m_expr);
546       case POISON_KIND_POPPED_STACK:
547         return ev.formatted_print
548           ("dereferencing pointer %qE to within stale stack frame",
549            m_expr);
550       }
551   }
552
553   void mark_interesting_stuff (interesting_t *interest) final override
554   {
555     if (m_src_region)
556       interest->add_region_creation (m_src_region);
557   }
558
559 private:
560   tree m_expr;
561   enum poison_kind m_pkind;
562   const region *m_src_region;
563 };
564
565 /* A subclass of pending_diagnostic for complaining about shifts
566    by negative counts.  */
567
568 class shift_count_negative_diagnostic
569 : public pending_diagnostic_subclass<shift_count_negative_diagnostic>
570 {
571 public:
572   shift_count_negative_diagnostic (const gassign *assign, tree count_cst)
573   : m_assign (assign), m_count_cst (count_cst)
574   {}
575
576   const char *get_kind () const final override
577   {
578     return "shift_count_negative_diagnostic";
579   }
580
581   bool operator== (const shift_count_negative_diagnostic &other) const
582   {
583     return (m_assign == other.m_assign
584             && same_tree_p (m_count_cst, other.m_count_cst));
585   }
586
587   int get_controlling_option () const final override
588   {
589     return OPT_Wanalyzer_shift_count_negative;
590   }
591
592   bool emit (rich_location *rich_loc) final override
593   {
594     return warning_at (rich_loc, get_controlling_option (),
595                        "shift by negative count (%qE)", m_count_cst);
596   }
597
598   label_text describe_final_event (const evdesc::final_event &ev) final override
599   {
600     return ev.formatted_print ("shift by negative amount here (%qE)", m_count_cst);
601   }
602
603 private:
604   const gassign *m_assign;
605   tree m_count_cst;
606 };
607
608 /* A subclass of pending_diagnostic for complaining about shifts
609    by counts >= the width of the operand type.  */
610
611 class shift_count_overflow_diagnostic
612 : public pending_diagnostic_subclass<shift_count_overflow_diagnostic>
613 {
614 public:
615   shift_count_overflow_diagnostic (const gassign *assign,
616                                    int operand_precision,
617                                    tree count_cst)
618   : m_assign (assign), m_operand_precision (operand_precision),
619     m_count_cst (count_cst)
620   {}
621
622   const char *get_kind () const final override
623   {
624     return "shift_count_overflow_diagnostic";
625   }
626
627   bool operator== (const shift_count_overflow_diagnostic &other) const
628   {
629     return (m_assign == other.m_assign
630             && m_operand_precision == other.m_operand_precision
631             && same_tree_p (m_count_cst, other.m_count_cst));
632   }
633
634   int get_controlling_option () const final override
635   {
636     return OPT_Wanalyzer_shift_count_overflow;
637   }
638
639   bool emit (rich_location *rich_loc) final override
640   {
641     return warning_at (rich_loc, get_controlling_option (),
642                        "shift by count (%qE) >= precision of type (%qi)",
643                        m_count_cst, m_operand_precision);
644   }
645
646   label_text describe_final_event (const evdesc::final_event &ev) final override
647   {
648     return ev.formatted_print ("shift by count %qE here", m_count_cst);
649   }
650
651 private:
652   const gassign *m_assign;
653   int m_operand_precision;
654   tree m_count_cst;
655 };
656
657 /* If ASSIGN is a stmt that can be modelled via
658      set_value (lhs_reg, SVALUE, CTXT)
659    for some SVALUE, get the SVALUE.
660    Otherwise return NULL.  */
661
662 const svalue *
663 region_model::get_gassign_result (const gassign *assign,
664                                    region_model_context *ctxt)
665 {
666   tree lhs = gimple_assign_lhs (assign);
667   tree rhs1 = gimple_assign_rhs1 (assign);
668   enum tree_code op = gimple_assign_rhs_code (assign);
669   switch (op)
670     {
671     default:
672       return NULL;
673
674     case POINTER_PLUS_EXPR:
675       {
676         /* e.g. "_1 = a_10(D) + 12;" */
677         tree ptr = rhs1;
678         tree offset = gimple_assign_rhs2 (assign);
679
680         const svalue *ptr_sval = get_rvalue (ptr, ctxt);
681         const svalue *offset_sval = get_rvalue (offset, ctxt);
682         /* Quoting tree.def, "the second operand [of a POINTER_PLUS_EXPR]
683            is an integer of type sizetype".  */
684         offset_sval = m_mgr->get_or_create_cast (size_type_node, offset_sval);
685
686         const svalue *sval_binop
687           = m_mgr->get_or_create_binop (TREE_TYPE (lhs), op,
688                                         ptr_sval, offset_sval);
689         return sval_binop;
690       }
691       break;
692
693     case POINTER_DIFF_EXPR:
694       {
695         /* e.g. "_1 = p_2(D) - q_3(D);".  */
696         tree rhs2 = gimple_assign_rhs2 (assign);
697         const svalue *rhs1_sval = get_rvalue (rhs1, ctxt);
698         const svalue *rhs2_sval = get_rvalue (rhs2, ctxt);
699
700         // TODO: perhaps fold to zero if they're known to be equal?
701
702         const svalue *sval_binop
703           = m_mgr->get_or_create_binop (TREE_TYPE (lhs), op,
704                                         rhs1_sval, rhs2_sval);
705         return sval_binop;
706       }
707       break;
708
709     /* Assignments of the form
710         set_value (lvalue (LHS), rvalue (EXPR))
711        for various EXPR.
712        We already have the lvalue for the LHS above, as "lhs_reg".  */
713     case ADDR_EXPR: /* LHS = &RHS;  */
714     case BIT_FIELD_REF:
715     case COMPONENT_REF: /* LHS = op0.op1;  */
716     case MEM_REF:
717     case REAL_CST:
718     case COMPLEX_CST:
719     case VECTOR_CST:
720     case INTEGER_CST:
721     case ARRAY_REF:
722     case SSA_NAME: /* LHS = VAR; */
723     case VAR_DECL: /* LHS = VAR; */
724     case PARM_DECL:/* LHS = VAR; */
725     case REALPART_EXPR:
726     case IMAGPART_EXPR:
727       return get_rvalue (rhs1, ctxt);
728
729     case ABS_EXPR:
730     case ABSU_EXPR:
731     case CONJ_EXPR:
732     case BIT_NOT_EXPR:
733     case FIX_TRUNC_EXPR:
734     case FLOAT_EXPR:
735     case NEGATE_EXPR:
736     case NOP_EXPR:
737     case VIEW_CONVERT_EXPR:
738       {
739         /* Unary ops.  */
740         const svalue *rhs_sval = get_rvalue (rhs1, ctxt);
741         const svalue *sval_unaryop
742           = m_mgr->get_or_create_unaryop (TREE_TYPE (lhs), op, rhs_sval);
743         return sval_unaryop;
744       }
745
746     case EQ_EXPR:
747     case GE_EXPR:
748     case LE_EXPR:
749     case NE_EXPR:
750     case GT_EXPR:
751     case LT_EXPR:
752     case UNORDERED_EXPR:
753     case ORDERED_EXPR:
754       {
755         tree rhs2 = gimple_assign_rhs2 (assign);
756
757         const svalue *rhs1_sval = get_rvalue (rhs1, ctxt);
758         const svalue *rhs2_sval = get_rvalue (rhs2, ctxt);
759
760         if (TREE_TYPE (lhs) == boolean_type_node)
761           {
762             /* Consider constraints between svalues.  */
763             tristate t = eval_condition (rhs1_sval, op, rhs2_sval);
764             if (t.is_known ())
765               return m_mgr->get_or_create_constant_svalue
766                 (t.is_true () ? boolean_true_node : boolean_false_node);
767           }
768
769         /* Otherwise, generate a symbolic binary op.  */
770         const svalue *sval_binop
771           = m_mgr->get_or_create_binop (TREE_TYPE (lhs), op,
772                                         rhs1_sval, rhs2_sval);
773         return sval_binop;
774       }
775       break;
776
777     case PLUS_EXPR:
778     case MINUS_EXPR:
779     case MULT_EXPR:
780     case MULT_HIGHPART_EXPR:
781     case TRUNC_DIV_EXPR:
782     case CEIL_DIV_EXPR:
783     case FLOOR_DIV_EXPR:
784     case ROUND_DIV_EXPR:
785     case TRUNC_MOD_EXPR:
786     case CEIL_MOD_EXPR:
787     case FLOOR_MOD_EXPR:
788     case ROUND_MOD_EXPR:
789     case RDIV_EXPR:
790     case EXACT_DIV_EXPR:
791     case LSHIFT_EXPR:
792     case RSHIFT_EXPR:
793     case LROTATE_EXPR:
794     case RROTATE_EXPR:
795     case BIT_IOR_EXPR:
796     case BIT_XOR_EXPR:
797     case BIT_AND_EXPR:
798     case MIN_EXPR:
799     case MAX_EXPR:
800     case COMPLEX_EXPR:
801       {
802         /* Binary ops.  */
803         tree rhs2 = gimple_assign_rhs2 (assign);
804
805         const svalue *rhs1_sval = get_rvalue (rhs1, ctxt);
806         const svalue *rhs2_sval = get_rvalue (rhs2, ctxt);
807
808         if (ctxt && (op == LSHIFT_EXPR || op == RSHIFT_EXPR))
809           {
810             /* "INT34-C. Do not shift an expression by a negative number of bits
811                or by greater than or equal to the number of bits that exist in
812                the operand."  */
813             if (const tree rhs2_cst = rhs2_sval->maybe_get_constant ())
814               if (TREE_CODE (rhs2_cst) == INTEGER_CST)
815                 {
816                   if (tree_int_cst_sgn (rhs2_cst) < 0)
817                     ctxt->warn
818                       (make_unique<shift_count_negative_diagnostic>
819                          (assign, rhs2_cst));
820                   else if (compare_tree_int (rhs2_cst,
821                                              TYPE_PRECISION (TREE_TYPE (rhs1)))
822                            >= 0)
823                     ctxt->warn
824                       (make_unique<shift_count_overflow_diagnostic>
825                          (assign,
826                           int (TYPE_PRECISION (TREE_TYPE (rhs1))),
827                           rhs2_cst));
828                 }
829           }
830
831         const svalue *sval_binop
832           = m_mgr->get_or_create_binop (TREE_TYPE (lhs), op,
833                                         rhs1_sval, rhs2_sval);
834         return sval_binop;
835       }
836
837     /* Vector expressions.  In theory we could implement these elementwise,
838        but for now, simply return unknown values.  */
839     case VEC_DUPLICATE_EXPR:
840     case VEC_SERIES_EXPR:
841     case VEC_COND_EXPR:
842     case VEC_PERM_EXPR:
843     case VEC_WIDEN_MULT_HI_EXPR:
844     case VEC_WIDEN_MULT_LO_EXPR:
845     case VEC_WIDEN_MULT_EVEN_EXPR:
846     case VEC_WIDEN_MULT_ODD_EXPR:
847     case VEC_UNPACK_HI_EXPR:
848     case VEC_UNPACK_LO_EXPR:
849     case VEC_UNPACK_FLOAT_HI_EXPR:
850     case VEC_UNPACK_FLOAT_LO_EXPR:
851     case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
852     case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
853     case VEC_PACK_TRUNC_EXPR:
854     case VEC_PACK_SAT_EXPR:
855     case VEC_PACK_FIX_TRUNC_EXPR:
856     case VEC_PACK_FLOAT_EXPR:
857     case VEC_WIDEN_LSHIFT_HI_EXPR:
858     case VEC_WIDEN_LSHIFT_LO_EXPR:
859       return m_mgr->get_or_create_unknown_svalue (TREE_TYPE (lhs));
860     }
861 }
862
863 /* Workaround for discarding certain false positives from
864    -Wanalyzer-use-of-uninitialized-value
865    of the form:
866      ((A OR-IF B) OR-IF C)
867    and:
868      ((A AND-IF B) AND-IF C)
869    where evaluating B is redundant, but could involve simple accesses of
870    uninitialized locals.
871
872    When optimization is turned on the FE can immediately fold compound
873    conditionals.  Specifically, c_parser_condition parses this condition:
874      ((A OR-IF B) OR-IF C)
875    and calls c_fully_fold on the condition.
876    Within c_fully_fold, fold_truth_andor is called, which bails when
877    optimization is off, but if any optimization is turned on can convert the
878      ((A OR-IF B) OR-IF C)
879    into:
880      ((A OR B) OR_IF C)
881    for sufficiently simple B
882    i.e. the inner OR-IF becomes an OR.
883    At gimplification time the inner OR becomes BIT_IOR_EXPR (in gimplify_expr),
884    giving this for the inner condition:
885       tmp = A | B;
886       if (tmp)
887    thus effectively synthesizing a redundant access of B when optimization
888    is turned on, when compared to:
889       if (A) goto L1; else goto L4;
890   L1: if (B) goto L2; else goto L4;
891   L2: if (C) goto L3; else goto L4;
892    for the unoptimized case.
893
894    Return true if CTXT appears to be  handling such a short-circuitable stmt,
895    such as the def-stmt for B for the:
896       tmp = A | B;
897    case above, for the case where A is true and thus B would have been
898    short-circuited without optimization, using MODEL for the value of A.  */
899
900 static bool
901 within_short_circuited_stmt_p (const region_model *model,
902                                const gassign *assign_stmt)
903 {
904   /* We must have an assignment to a temporary of _Bool type.  */
905   tree lhs = gimple_assign_lhs (assign_stmt);
906   if (TREE_TYPE (lhs) != boolean_type_node)
907     return false;
908   if (TREE_CODE (lhs) != SSA_NAME)
909     return false;
910   if (SSA_NAME_VAR (lhs) != NULL_TREE)
911     return false;
912
913   /* The temporary bool must be used exactly once: as the second arg of
914      a BIT_IOR_EXPR or BIT_AND_EXPR.  */
915   use_operand_p use_op;
916   gimple *use_stmt;
917   if (!single_imm_use (lhs, &use_op, &use_stmt))
918     return false;
919   const gassign *use_assign = dyn_cast <const gassign *> (use_stmt);
920   if (!use_assign)
921     return false;
922   enum tree_code op = gimple_assign_rhs_code (use_assign);
923   if (!(op == BIT_IOR_EXPR ||op == BIT_AND_EXPR))
924     return false;
925   if (!(gimple_assign_rhs1 (use_assign) != lhs
926         && gimple_assign_rhs2 (use_assign) == lhs))
927     return false;
928
929   /* The first arg of the bitwise stmt must have a known value in MODEL
930      that implies that the value of the second arg doesn't matter, i.e.
931      1 for bitwise or, 0 for bitwise and.  */
932   tree other_arg = gimple_assign_rhs1 (use_assign);
933   /* Use a NULL ctxt here to avoid generating warnings.  */
934   const svalue *other_arg_sval = model->get_rvalue (other_arg, NULL);
935   tree other_arg_cst = other_arg_sval->maybe_get_constant ();
936   if (!other_arg_cst)
937     return false;
938   switch (op)
939     {
940     default:
941       gcc_unreachable ();
942     case BIT_IOR_EXPR:
943       if (zerop (other_arg_cst))
944         return false;
945       break;
946     case BIT_AND_EXPR:
947       if (!zerop (other_arg_cst))
948         return false;
949       break;
950     }
951
952   /* All tests passed.  We appear to be in a stmt that generates a boolean
953      temporary with a value that won't matter.  */
954   return true;
955 }
956
957 /* Workaround for discarding certain false positives from
958    -Wanalyzer-use-of-uninitialized-value
959    seen with -ftrivial-auto-var-init=.
960
961    -ftrivial-auto-var-init= will generate calls to IFN_DEFERRED_INIT.
962
963    If the address of the var is taken, gimplification will give us
964    something like:
965
966      _1 = .DEFERRED_INIT (4, 2, &"len"[0]);
967      len = _1;
968
969    The result of DEFERRED_INIT will be an uninit value; we don't
970    want to emit a false positive for "len = _1;"
971
972    Return true if ASSIGN_STMT is such a stmt.  */
973
974 static bool
975 due_to_ifn_deferred_init_p (const gassign *assign_stmt)
976
977 {
978   /* We must have an assignment to a decl from an SSA name that's the
979      result of a IFN_DEFERRED_INIT call.  */
980   if (gimple_assign_rhs_code (assign_stmt) != SSA_NAME)
981     return false;
982   tree lhs = gimple_assign_lhs (assign_stmt);
983   if (TREE_CODE (lhs) != VAR_DECL)
984     return false;
985   tree rhs = gimple_assign_rhs1 (assign_stmt);
986   if (TREE_CODE (rhs) != SSA_NAME)
987     return false;
988   const gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
989   const gcall *call = dyn_cast <const gcall *> (def_stmt);
990   if (!call)
991     return false;
992   if (gimple_call_internal_p (call)
993       && gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
994     return true;
995   return false;
996 }
997
998 /* Check for SVAL being poisoned, adding a warning to CTXT.
999    Return SVAL, or, if a warning is added, another value, to avoid
1000    repeatedly complaining about the same poisoned value in followup code.  */
1001
1002 const svalue *
1003 region_model::check_for_poison (const svalue *sval,
1004                                 tree expr,
1005                                 region_model_context *ctxt) const
1006 {
1007   if (!ctxt)
1008     return sval;
1009
1010   if (const poisoned_svalue *poisoned_sval = sval->dyn_cast_poisoned_svalue ())
1011     {
1012       enum poison_kind pkind = poisoned_sval->get_poison_kind ();
1013
1014       /* Ignore uninitialized uses of empty types; there's nothing
1015          to initialize.  */
1016       if (pkind == POISON_KIND_UNINIT
1017           && sval->get_type ()
1018           && is_empty_type (sval->get_type ()))
1019         return sval;
1020
1021       if (pkind == POISON_KIND_UNINIT)
1022         if (const gimple *curr_stmt = ctxt->get_stmt ())
1023           if (const gassign *assign_stmt
1024                 = dyn_cast <const gassign *> (curr_stmt))
1025             {
1026               /* Special case to avoid certain false positives.  */
1027               if (within_short_circuited_stmt_p (this, assign_stmt))
1028                 return sval;
1029
1030               /* Special case to avoid false positive on
1031                  -ftrivial-auto-var-init=.  */
1032               if (due_to_ifn_deferred_init_p (assign_stmt))
1033                 return sval;
1034           }
1035
1036       /* If we have an SSA name for a temporary, we don't want to print
1037          '<unknown>'.
1038          Poisoned values are shared by type, and so we can't reconstruct
1039          the tree other than via the def stmts, using
1040          fixup_tree_for_diagnostic.  */
1041       tree diag_arg = fixup_tree_for_diagnostic (expr);
1042       const region *src_region = NULL;
1043       if (pkind == POISON_KIND_UNINIT)
1044         src_region = get_region_for_poisoned_expr (expr);
1045       if (ctxt->warn (make_unique<poisoned_value_diagnostic> (diag_arg,
1046                                                               pkind,
1047                                                               src_region)))
1048         {
1049           /* We only want to report use of a poisoned value at the first
1050              place it gets used; return an unknown value to avoid generating
1051              a chain of followup warnings.  */
1052           sval = m_mgr->get_or_create_unknown_svalue (sval->get_type ());
1053         }
1054
1055       return sval;
1056     }
1057
1058   return sval;
1059 }
1060
1061 /* Attempt to get a region for describing EXPR, the source of region of
1062    a poisoned_svalue for use in a poisoned_value_diagnostic.
1063    Return NULL if there is no good region to use.  */
1064
1065 const region *
1066 region_model::get_region_for_poisoned_expr (tree expr) const
1067 {
1068   if (TREE_CODE (expr) == SSA_NAME)
1069     {
1070       tree decl = SSA_NAME_VAR (expr);
1071       if (decl && DECL_P (decl))
1072         expr = decl;
1073       else
1074         return NULL;
1075     }
1076   return get_lvalue (expr, NULL);
1077 }
1078
1079 /* Update this model for the ASSIGN stmt, using CTXT to report any
1080    diagnostics.  */
1081
1082 void
1083 region_model::on_assignment (const gassign *assign, region_model_context *ctxt)
1084 {
1085   tree lhs = gimple_assign_lhs (assign);
1086   tree rhs1 = gimple_assign_rhs1 (assign);
1087
1088   const region *lhs_reg = get_lvalue (lhs, ctxt);
1089
1090   /* Most assignments are handled by:
1091        set_value (lhs_reg, SVALUE, CTXT)
1092      for some SVALUE.  */
1093   if (const svalue *sval = get_gassign_result (assign, ctxt))
1094     {
1095       tree expr = get_diagnostic_tree_for_gassign (assign);
1096       check_for_poison (sval, expr, ctxt);
1097       set_value (lhs_reg, sval, ctxt);
1098       return;
1099     }
1100
1101   enum tree_code op = gimple_assign_rhs_code (assign);
1102   switch (op)
1103     {
1104     default:
1105       {
1106         if (0)
1107           sorry_at (assign->location, "unhandled assignment op: %qs",
1108                     get_tree_code_name (op));
1109         const svalue *unknown_sval
1110           = m_mgr->get_or_create_unknown_svalue (TREE_TYPE (lhs));
1111         set_value (lhs_reg, unknown_sval, ctxt);
1112       }
1113       break;
1114
1115     case CONSTRUCTOR:
1116       {
1117         if (TREE_CLOBBER_P (rhs1))
1118           {
1119             /* e.g. "x ={v} {CLOBBER};"  */
1120             clobber_region (lhs_reg);
1121           }
1122         else
1123           {
1124             /* Any CONSTRUCTOR that survives to this point is either
1125                just a zero-init of everything, or a vector.  */
1126             if (!CONSTRUCTOR_NO_CLEARING (rhs1))
1127               zero_fill_region (lhs_reg);
1128             unsigned ix;
1129             tree index;
1130             tree val;
1131             FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs1), ix, index, val)
1132               {
1133                 gcc_assert (TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE);
1134                 if (!index)
1135                   index = build_int_cst (integer_type_node, ix);
1136                 gcc_assert (TREE_CODE (index) == INTEGER_CST);
1137                 const svalue *index_sval
1138                   = m_mgr->get_or_create_constant_svalue (index);
1139                 gcc_assert (index_sval);
1140                 const region *sub_reg
1141                   = m_mgr->get_element_region (lhs_reg,
1142                                                TREE_TYPE (val),
1143                                                index_sval);
1144                 const svalue *val_sval = get_rvalue (val, ctxt);
1145                 set_value (sub_reg, val_sval, ctxt);
1146               }
1147           }
1148       }
1149       break;
1150
1151     case STRING_CST:
1152       {
1153         /* e.g. "struct s2 x = {{'A', 'B', 'C', 'D'}};".  */
1154         const svalue *rhs_sval = get_rvalue (rhs1, ctxt);
1155         m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
1156                            ctxt ? ctxt->get_uncertainty () : NULL);
1157       }
1158       break;
1159     }
1160 }
1161
1162 /* A pending_diagnostic subclass for implementing "__analyzer_dump_path".  */
1163
1164 class dump_path_diagnostic
1165   : public pending_diagnostic_subclass<dump_path_diagnostic>
1166 {
1167 public:
1168   int get_controlling_option () const final override
1169   {
1170     return 0;
1171   }
1172
1173   bool emit (rich_location *richloc) final override
1174   {
1175     inform (richloc, "path");
1176     return true;
1177   }
1178
1179   const char *get_kind () const final override { return "dump_path_diagnostic"; }
1180
1181   bool operator== (const dump_path_diagnostic &) const
1182   {
1183     return true;
1184   }
1185 };
1186
1187 /* Handle the pre-sm-state part of STMT, modifying this object in-place.
1188    Write true to *OUT_TERMINATE_PATH if the path should be terminated.
1189    Write true to *OUT_UNKNOWN_SIDE_EFFECTS if the stmt has unknown
1190    side effects.  */
1191
1192 void
1193 region_model::on_stmt_pre (const gimple *stmt,
1194                            bool *out_terminate_path,
1195                            bool *out_unknown_side_effects,
1196                            region_model_context *ctxt)
1197 {
1198   switch (gimple_code (stmt))
1199     {
1200     default:
1201       /* No-op for now.  */
1202       break;
1203
1204     case GIMPLE_ASSIGN:
1205       {
1206         const gassign *assign = as_a <const gassign *> (stmt);
1207         on_assignment (assign, ctxt);
1208       }
1209       break;
1210
1211     case GIMPLE_ASM:
1212       {
1213         const gasm *asm_stmt = as_a <const gasm *> (stmt);
1214         on_asm_stmt (asm_stmt, ctxt);
1215       }
1216       break;
1217
1218     case GIMPLE_CALL:
1219       {
1220         /* Track whether we have a gcall to a function that's not recognized by
1221            anything, for which we don't have a function body, or for which we
1222            don't know the fndecl.  */
1223         const gcall *call = as_a <const gcall *> (stmt);
1224
1225         /* Debugging/test support.  */
1226         if (is_special_named_call_p (call, "__analyzer_describe", 2))
1227           impl_call_analyzer_describe (call, ctxt);
1228         else if (is_special_named_call_p (call, "__analyzer_dump_capacity", 1))
1229           impl_call_analyzer_dump_capacity (call, ctxt);
1230         else if (is_special_named_call_p (call, "__analyzer_dump_escaped", 0))
1231           impl_call_analyzer_dump_escaped (call);
1232         else if (is_special_named_call_p (call, "__analyzer_dump_path", 0))
1233           {
1234             /* Handle the builtin "__analyzer_dump_path" by queuing a
1235                diagnostic at this exploded_node.  */
1236             ctxt->warn (make_unique<dump_path_diagnostic> ());
1237           }
1238         else if (is_special_named_call_p (call, "__analyzer_dump_region_model",
1239                                           0))
1240           {
1241             /* Handle the builtin "__analyzer_dump_region_model" by dumping
1242                the region model's state to stderr.  */
1243             dump (false);
1244           }
1245         else if (is_special_named_call_p (call, "__analyzer_eval", 1))
1246           impl_call_analyzer_eval (call, ctxt);
1247         else if (is_special_named_call_p (call, "__analyzer_break", 0))
1248           {
1249             /* Handle the builtin "__analyzer_break" by triggering a
1250                breakpoint.  */
1251             /* TODO: is there a good cross-platform way to do this?  */
1252             raise (SIGINT);
1253           }
1254         else if (is_special_named_call_p (call,
1255                                           "__analyzer_dump_exploded_nodes",
1256                                           1))
1257           {
1258             /* This is handled elsewhere.  */
1259           }
1260         else if (is_special_named_call_p (call, "__analyzer_get_unknown_ptr",
1261                                           0))
1262           {
1263             call_details cd (call, this, ctxt);
1264             impl_call_analyzer_get_unknown_ptr (cd);
1265           }
1266         else
1267           *out_unknown_side_effects = on_call_pre (call, ctxt,
1268                                                    out_terminate_path);
1269       }
1270       break;
1271
1272     case GIMPLE_RETURN:
1273       {
1274         const greturn *return_ = as_a <const greturn *> (stmt);
1275         on_return (return_, ctxt);
1276       }
1277       break;
1278     }
1279 }
1280
1281 /* Abstract base class for all out-of-bounds warnings with concrete values.  */
1282
1283 class out_of_bounds : public pending_diagnostic_subclass<out_of_bounds>
1284 {
1285 public:
1286   out_of_bounds (const region *reg, tree diag_arg,
1287                  byte_range out_of_bounds_range)
1288   : m_reg (reg), m_diag_arg (diag_arg),
1289     m_out_of_bounds_range (out_of_bounds_range)
1290   {}
1291
1292   const char *get_kind () const final override
1293   {
1294     return "out_of_bounds_diagnostic";
1295   }
1296
1297   bool operator== (const out_of_bounds &other) const
1298   {
1299     return m_reg == other.m_reg
1300            && m_out_of_bounds_range == other.m_out_of_bounds_range
1301            && pending_diagnostic::same_tree_p (m_diag_arg, other.m_diag_arg);
1302   }
1303
1304   int get_controlling_option () const final override
1305   {
1306     return OPT_Wanalyzer_out_of_bounds;
1307   }
1308
1309   void mark_interesting_stuff (interesting_t *interest) final override
1310   {
1311     interest->add_region_creation (m_reg);
1312   }
1313
1314 protected:
1315   const region *m_reg;
1316   tree m_diag_arg;
1317   byte_range m_out_of_bounds_range;
1318 };
1319
1320 /* Abstract subclass to complaing about out-of-bounds
1321    past the end of the buffer.  */
1322
1323 class past_the_end : public out_of_bounds
1324 {
1325 public:
1326   past_the_end (const region *reg, tree diag_arg, byte_range range,
1327                 tree byte_bound)
1328   : out_of_bounds (reg, diag_arg, range), m_byte_bound (byte_bound)
1329   {}
1330
1331   bool operator== (const past_the_end &other) const
1332   {
1333     return out_of_bounds::operator== (other)
1334            && pending_diagnostic::same_tree_p (m_byte_bound,
1335                                                other.m_byte_bound);
1336   }
1337
1338   label_text
1339   describe_region_creation_event (const evdesc::region_creation &ev) final
1340   override
1341   {
1342     if (m_byte_bound && TREE_CODE (m_byte_bound) == INTEGER_CST)
1343       return ev.formatted_print ("capacity is %E bytes", m_byte_bound);
1344
1345     return label_text ();
1346   }
1347
1348 protected:
1349   tree m_byte_bound;
1350 };
1351
1352 /* Concrete subclass to complain about buffer overflows.  */
1353
1354 class buffer_overflow : public past_the_end
1355 {
1356 public:
1357   buffer_overflow (const region *reg, tree diag_arg,
1358                    byte_range range, tree byte_bound)
1359   : past_the_end (reg, diag_arg, range, byte_bound)
1360   {}
1361
1362   bool emit (rich_location *rich_loc) final override
1363   {
1364     diagnostic_metadata m;
1365     bool warned;
1366     switch (m_reg->get_memory_space ())
1367       {
1368       default:
1369         m.add_cwe (787);
1370         warned = warning_meta (rich_loc, m, get_controlling_option (),
1371                                "buffer overflow");
1372         break;
1373       case MEMSPACE_STACK:
1374         m.add_cwe (121);
1375         warned = warning_meta (rich_loc, m, get_controlling_option (),
1376                                "stack-based buffer overflow");
1377         break;
1378       case MEMSPACE_HEAP:
1379         m.add_cwe (122);
1380         warned = warning_meta (rich_loc, m, get_controlling_option (),
1381                                "heap-based buffer overflow");
1382         break;
1383       }
1384
1385     if (warned)
1386       {
1387         char num_bytes_past_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1388         print_dec (m_out_of_bounds_range.m_size_in_bytes,
1389                    num_bytes_past_buf, UNSIGNED);
1390         if (m_diag_arg)
1391           inform (rich_loc->get_loc (), "write is %s bytes past the end"
1392                                         " of %qE", num_bytes_past_buf,
1393                                                    m_diag_arg);
1394         else
1395           inform (rich_loc->get_loc (), "write is %s bytes past the end"
1396                                         "of the region",
1397                                         num_bytes_past_buf);
1398       }
1399
1400     return warned;
1401   }
1402
1403   label_text describe_final_event (const evdesc::final_event &ev)
1404   final override
1405   {
1406     byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
1407     byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
1408     char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1409     print_dec (start, start_buf, SIGNED);
1410     char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1411     print_dec (end, end_buf, SIGNED);
1412
1413     if (start == end)
1414       {
1415         if (m_diag_arg)
1416           return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
1417                                      " ends at byte %E", start_buf, m_diag_arg,
1418                                                          m_byte_bound);
1419         return ev.formatted_print ("out-of-bounds write at byte %s but region"
1420                                    " ends at byte %E", start_buf,
1421                                                        m_byte_bound);
1422       }
1423     else
1424       {
1425         if (m_diag_arg)
1426           return ev.formatted_print ("out-of-bounds write from byte %s till"
1427                                      " byte %s but %qE ends at byte %E",
1428                                      start_buf, end_buf, m_diag_arg,
1429                                      m_byte_bound);
1430         return ev.formatted_print ("out-of-bounds write from byte %s till"
1431                                    " byte %s but region ends at byte %E",
1432                                    start_buf, end_buf, m_byte_bound);
1433       }
1434   }
1435 };
1436
1437 /* Concrete subclass to complain about buffer overreads.  */
1438
1439 class buffer_overread : public past_the_end
1440 {
1441 public:
1442   buffer_overread (const region *reg, tree diag_arg,
1443                    byte_range range, tree byte_bound)
1444   : past_the_end (reg, diag_arg, range, byte_bound)
1445   {}
1446
1447   bool emit (rich_location *rich_loc) final override
1448   {
1449     diagnostic_metadata m;
1450     m.add_cwe (126);
1451     bool warned = warning_meta (rich_loc, m, get_controlling_option (),
1452                                 "buffer overread");
1453
1454     if (warned)
1455       {
1456         char num_bytes_past_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1457         print_dec (m_out_of_bounds_range.m_size_in_bytes,
1458                    num_bytes_past_buf, UNSIGNED);
1459         if (m_diag_arg)
1460           inform (rich_loc->get_loc (), "read is %s bytes past the end"
1461                                         " of %qE", num_bytes_past_buf,
1462                                                     m_diag_arg);
1463         else
1464           inform (rich_loc->get_loc (), "read is %s bytes past the end"
1465                                         "of the region",
1466                                         num_bytes_past_buf);
1467       }
1468
1469     return warned;
1470   }
1471
1472   label_text describe_final_event (const evdesc::final_event &ev)
1473   final override
1474   {
1475     byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
1476     byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
1477     char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1478     print_dec (start, start_buf, SIGNED);
1479     char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1480     print_dec (end, end_buf, SIGNED);
1481
1482     if (start == end)
1483       {
1484         if (m_diag_arg)
1485           return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
1486                                      " ends at byte %E", start_buf, m_diag_arg,
1487                                                          m_byte_bound);
1488         return ev.formatted_print ("out-of-bounds read at byte %s but region"
1489                                    " ends at byte %E", start_buf,
1490                                                        m_byte_bound);
1491       }
1492     else
1493       {
1494         if (m_diag_arg)
1495           return ev.formatted_print ("out-of-bounds read from byte %s till"
1496                                      " byte %s but %qE ends at byte %E",
1497                                      start_buf, end_buf, m_diag_arg,
1498                                      m_byte_bound);
1499         return ev.formatted_print ("out-of-bounds read from byte %s till"
1500                                    " byte %s but region ends at byte %E",
1501                                    start_buf, end_buf, m_byte_bound);
1502       }
1503   }
1504 };
1505
1506 /* Concrete subclass to complain about buffer underflows.  */
1507
1508 class buffer_underflow : public out_of_bounds
1509 {
1510 public:
1511   buffer_underflow (const region *reg, tree diag_arg, byte_range range)
1512   : out_of_bounds (reg, diag_arg, range)
1513   {}
1514
1515   bool emit (rich_location *rich_loc) final override
1516   {
1517     diagnostic_metadata m;
1518     m.add_cwe (124);
1519     return warning_meta (rich_loc, m, get_controlling_option (),
1520                          "buffer underflow");
1521   }
1522
1523   label_text describe_final_event (const evdesc::final_event &ev)
1524   final override
1525   {
1526     byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
1527     byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
1528     char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1529     print_dec (start, start_buf, SIGNED);
1530     char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1531     print_dec (end, end_buf, SIGNED);
1532
1533     if (start == end)
1534       {
1535         if (m_diag_arg)
1536           return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
1537                                      " starts at byte 0", start_buf,
1538                                                           m_diag_arg);
1539         return ev.formatted_print ("out-of-bounds write at byte %s but region"
1540                                    " starts at byte 0", start_buf);
1541       }
1542     else
1543       {
1544         if (m_diag_arg)
1545           return ev.formatted_print ("out-of-bounds write from byte %s till"
1546                                      " byte %s but %qE starts at byte 0",
1547                                      start_buf, end_buf, m_diag_arg);
1548         return ev.formatted_print ("out-of-bounds write from byte %s till"
1549                                    " byte %s but region starts at byte 0",
1550                                    start_buf, end_buf);;
1551       }
1552   }
1553 };
1554
1555 /* Concrete subclass to complain about buffer underreads.  */
1556
1557 class buffer_underread : public out_of_bounds
1558 {
1559 public:
1560   buffer_underread (const region *reg, tree diag_arg, byte_range range)
1561   : out_of_bounds (reg, diag_arg, range)
1562   {}
1563
1564   bool emit (rich_location *rich_loc) final override
1565   {
1566     diagnostic_metadata m;
1567     m.add_cwe (127);
1568     return warning_meta (rich_loc, m, get_controlling_option (),
1569                          "buffer underread");
1570   }
1571
1572   label_text describe_final_event (const evdesc::final_event &ev)
1573   final override
1574   {
1575     byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
1576     byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
1577     char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1578     print_dec (start, start_buf, SIGNED);
1579     char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
1580     print_dec (end, end_buf, SIGNED);
1581
1582     if (start == end)
1583       {
1584         if (m_diag_arg)
1585           return ev.formatted_print ("out-of-bounds read at byte %s but %qE"
1586                                      " starts at byte 0", start_buf,
1587                                                           m_diag_arg);
1588         return ev.formatted_print ("out-of-bounds read at byte %s but region"
1589                                   " starts at byte 0", start_buf);
1590       }
1591     else
1592       {
1593         if (m_diag_arg)
1594           return ev.formatted_print ("out-of-bounds read from byte %s till"
1595                                      " byte %s but %qE starts at byte 0",
1596                                      start_buf, end_buf, m_diag_arg);
1597         return ev.formatted_print ("out-of-bounds read from byte %s till"
1598                                    " byte %s but region starts at byte 0",
1599                                    start_buf, end_buf);;
1600       }
1601   }
1602 };
1603
1604 /* Abstract class to complain about out-of-bounds read/writes where
1605    the values are symbolic.  */
1606
1607 class symbolic_past_the_end
1608   : public pending_diagnostic_subclass<symbolic_past_the_end>
1609 {
1610 public:
1611   symbolic_past_the_end (const region *reg, tree diag_arg, tree offset,
1612                          tree num_bytes, tree capacity)
1613   : m_reg (reg), m_diag_arg (diag_arg), m_offset (offset),
1614     m_num_bytes (num_bytes), m_capacity (capacity)
1615   {}
1616
1617   const char *get_kind () const final override
1618   {
1619     return "symbolic_past_the_end";
1620   }
1621
1622   bool operator== (const symbolic_past_the_end &other) const
1623   {
1624     return m_reg == other.m_reg
1625            && pending_diagnostic::same_tree_p (m_diag_arg, other.m_diag_arg)
1626            && pending_diagnostic::same_tree_p (m_offset, other.m_offset)
1627            && pending_diagnostic::same_tree_p (m_num_bytes, other.m_num_bytes)
1628            && pending_diagnostic::same_tree_p (m_capacity, other.m_capacity);
1629   }
1630
1631   int get_controlling_option () const final override
1632   {
1633     return OPT_Wanalyzer_out_of_bounds;
1634   }
1635
1636   void mark_interesting_stuff (interesting_t *interest) final override
1637   {
1638     interest->add_region_creation (m_reg);
1639   }
1640
1641   label_text
1642   describe_region_creation_event (const evdesc::region_creation &ev) final
1643   override
1644   {
1645     if (m_capacity)
1646       return ev.formatted_print ("capacity is %qE bytes", m_capacity);
1647
1648     return label_text ();
1649   }
1650
1651   label_text
1652   describe_final_event (const evdesc::final_event &ev) final override
1653   {
1654     const char *byte_str;
1655     if (pending_diagnostic::same_tree_p (m_num_bytes, integer_one_node))
1656       byte_str = "byte";
1657     else
1658       byte_str = "bytes";
1659
1660     if (m_offset)
1661       {
1662         if (m_num_bytes && TREE_CODE (m_num_bytes) == INTEGER_CST)
1663           {
1664             if (m_diag_arg)
1665               return ev.formatted_print ("%s of %E %s at offset %qE"
1666                                          " exceeds %qE", m_dir_str,
1667                                          m_num_bytes, byte_str,
1668                                          m_offset, m_diag_arg);
1669             else
1670               return ev.formatted_print ("%s of %E %s at offset %qE"
1671                                          " exceeds the buffer", m_dir_str,
1672                                          m_num_bytes, byte_str, m_offset);
1673           }
1674         else if (m_num_bytes)
1675           {
1676             if (m_diag_arg)
1677               return ev.formatted_print ("%s of %qE %s at offset %qE"
1678                                          " exceeds %qE", m_dir_str,
1679                                          m_num_bytes, byte_str,
1680                                          m_offset, m_diag_arg);
1681             else
1682               return ev.formatted_print ("%s of %qE %s at offset %qE"
1683                                          " exceeds the buffer", m_dir_str,
1684                                          m_num_bytes, byte_str, m_offset);
1685           }
1686         else
1687           {
1688             if (m_diag_arg)
1689               return ev.formatted_print ("%s at offset %qE exceeds %qE",
1690                                          m_dir_str, m_offset, m_diag_arg);
1691             else
1692               return ev.formatted_print ("%s at offset %qE exceeds the"
1693                                          " buffer", m_dir_str, m_offset);
1694           }
1695       }
1696     if (m_diag_arg)
1697       return ev.formatted_print ("out-of-bounds %s on %qE",
1698                                  m_dir_str, m_diag_arg);
1699     return ev.formatted_print ("out-of-bounds %s", m_dir_str);
1700   }
1701
1702 protected:
1703   const region *m_reg;
1704   tree m_diag_arg;
1705   tree m_offset;
1706   tree m_num_bytes;
1707   tree m_capacity;
1708   const char *m_dir_str;
1709 };
1710
1711 /* Concrete subclass to complain about overflows with symbolic values.  */
1712
1713 class symbolic_buffer_overflow : public symbolic_past_the_end
1714 {
1715 public:
1716   symbolic_buffer_overflow (const region *reg, tree diag_arg, tree offset,
1717                             tree num_bytes, tree capacity)
1718   : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
1719   {
1720     m_dir_str = "write";
1721   }
1722
1723   bool emit (rich_location *rich_loc) final override
1724   {
1725     diagnostic_metadata m;
1726     switch (m_reg->get_memory_space ())
1727       {
1728       default:
1729         m.add_cwe (787);
1730         return warning_meta (rich_loc, m, get_controlling_option (),
1731                              "buffer overflow");
1732       case MEMSPACE_STACK:
1733         m.add_cwe (121);
1734         return warning_meta (rich_loc, m, get_controlling_option (),
1735                              "stack-based buffer overflow");
1736       case MEMSPACE_HEAP:
1737         m.add_cwe (122);
1738         return warning_meta (rich_loc, m, get_controlling_option (),
1739                              "heap-based buffer overflow");
1740       }
1741   }
1742 };
1743
1744 /* Concrete subclass to complain about overreads with symbolic values.  */
1745
1746 class symbolic_buffer_overread : public symbolic_past_the_end
1747 {
1748 public:
1749   symbolic_buffer_overread (const region *reg, tree diag_arg, tree offset,
1750                             tree num_bytes, tree capacity)
1751   : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity)
1752   {
1753     m_dir_str = "read";
1754   }
1755
1756   bool emit (rich_location *rich_loc) final override
1757   {
1758     diagnostic_metadata m;
1759     m.add_cwe (126);
1760     return warning_meta (rich_loc, m, get_controlling_option (),
1761                          "buffer overread");
1762   }
1763 };
1764
1765 /* Check whether an access is past the end of the BASE_REG.  */
1766
1767 void region_model::check_symbolic_bounds (const region *base_reg,
1768                                           const svalue *sym_byte_offset,
1769                                           const svalue *num_bytes_sval,
1770                                           const svalue *capacity,
1771                                           enum access_direction dir,
1772                                           region_model_context *ctxt) const
1773 {
1774   gcc_assert (ctxt);
1775
1776   const svalue *next_byte
1777     = m_mgr->get_or_create_binop (num_bytes_sval->get_type (), PLUS_EXPR,
1778                                   sym_byte_offset, num_bytes_sval);
1779
1780   if (eval_condition_without_cm (next_byte, GT_EXPR, capacity).is_true ())
1781     {
1782       tree diag_arg = get_representative_tree (base_reg);
1783       tree offset_tree = get_representative_tree (sym_byte_offset);
1784       tree num_bytes_tree = get_representative_tree (num_bytes_sval);
1785       tree capacity_tree = get_representative_tree (capacity);
1786       switch (dir)
1787         {
1788         default:
1789           gcc_unreachable ();
1790           break;
1791         case DIR_READ:
1792           ctxt->warn (make_unique<symbolic_buffer_overread> (base_reg,
1793                                                              diag_arg,
1794                                                              offset_tree,
1795                                                              num_bytes_tree,
1796                                                              capacity_tree));
1797           break;
1798         case DIR_WRITE:
1799           ctxt->warn (make_unique<symbolic_buffer_overflow> (base_reg,
1800                                                              diag_arg,
1801                                                              offset_tree,
1802                                                              num_bytes_tree,
1803                                                              capacity_tree));
1804           break;
1805         }
1806     }
1807 }
1808
1809 static tree
1810 maybe_get_integer_cst_tree (const svalue *sval)
1811 {
1812   tree cst_tree = sval->maybe_get_constant ();
1813   if (cst_tree && TREE_CODE (cst_tree) == INTEGER_CST)
1814     return cst_tree;
1815
1816   return NULL_TREE;
1817 }
1818
1819 /* May complain when the access on REG is out-of-bounds.  */
1820
1821 void
1822 region_model::check_region_bounds (const region *reg,
1823                                    enum access_direction dir,
1824                                    region_model_context *ctxt) const
1825 {
1826   gcc_assert (ctxt);
1827
1828   /* Get the offset.  */
1829   region_offset reg_offset = reg->get_offset (m_mgr);
1830   const region *base_reg = reg_offset.get_base_region ();
1831
1832   /* Bail out on symbolic regions.
1833      (e.g. because the analyzer did not see previous offsets on the latter,
1834      it might think that a negative access is before the buffer).  */
1835   if (base_reg->symbolic_p ())
1836     return;
1837
1838   /* Find out how many bytes were accessed.  */
1839   const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
1840   tree num_bytes_tree = maybe_get_integer_cst_tree (num_bytes_sval);
1841   /* Bail out if 0 bytes are accessed.  */
1842   if (num_bytes_tree && zerop (num_bytes_tree))
1843     return;
1844
1845   /* Get the capacity of the buffer.  */
1846   const svalue *capacity = get_capacity (base_reg);
1847   tree cst_capacity_tree = maybe_get_integer_cst_tree (capacity);
1848
1849   /* The constant offset from a pointer is represented internally as a sizetype
1850      but should be interpreted as a signed value here.  The statement below
1851      converts the offset from bits to bytes and then to a signed integer with
1852      the same precision the sizetype has on the target system.
1853
1854      For example, this is needed for out-of-bounds-3.c test1 to pass when
1855      compiled with a 64-bit gcc build targeting 32-bit systems.  */
1856   byte_offset_t offset;
1857   if (!reg_offset.symbolic_p ())
1858     offset = wi::sext (reg_offset.get_bit_offset () >> LOG2_BITS_PER_UNIT,
1859                        TYPE_PRECISION (size_type_node));
1860
1861   /* If either the offset or the number of bytes accessed are symbolic,
1862      we have to reason about symbolic values.  */
1863   if (reg_offset.symbolic_p () || !num_bytes_tree)
1864     {
1865       const svalue* byte_offset_sval;
1866       if (!reg_offset.symbolic_p ())
1867         {
1868           tree offset_tree = wide_int_to_tree (integer_type_node, offset);
1869           byte_offset_sval
1870             = m_mgr->get_or_create_constant_svalue (offset_tree);
1871         }
1872       else
1873         byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
1874       check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
1875                              capacity, dir, ctxt);
1876       return;
1877     }
1878
1879   /* Otherwise continue to check with concrete values.  */
1880   byte_range out (0, 0);
1881   /* NUM_BYTES_TREE should always be interpreted as unsigned.  */
1882   byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree);
1883   byte_range read_bytes (offset, num_bytes_unsigned);
1884   /* If read_bytes has a subset < 0, we do have an underflow.  */
1885   if (read_bytes.falls_short_of_p (0, &out))
1886     {
1887       tree diag_arg = get_representative_tree (base_reg);
1888       switch (dir)
1889         {
1890         default:
1891           gcc_unreachable ();
1892           break;
1893         case DIR_READ:
1894           ctxt->warn (make_unique<buffer_underread> (reg, diag_arg, out));
1895           break;
1896         case DIR_WRITE:
1897           ctxt->warn (make_unique<buffer_underflow> (reg, diag_arg, out));
1898           break;
1899         }
1900     }
1901
1902   /* For accesses past the end, we do need a concrete capacity.  No need to
1903      do a symbolic check here because the inequality check does not reason
1904      whether constants are greater than symbolic values.  */
1905   if (!cst_capacity_tree)
1906     return;
1907
1908   byte_range buffer (0, wi::to_offset (cst_capacity_tree));
1909   /* If READ_BYTES exceeds BUFFER, we do have an overflow.  */
1910   if (read_bytes.exceeds_p (buffer, &out))
1911     {
1912       tree byte_bound = wide_int_to_tree (size_type_node,
1913                                           buffer.get_next_byte_offset ());
1914       tree diag_arg = get_representative_tree (base_reg);
1915
1916       switch (dir)
1917         {
1918         default:
1919           gcc_unreachable ();
1920           break;
1921         case DIR_READ:
1922           ctxt->warn (make_unique<buffer_overread> (reg, diag_arg,
1923                                                     out, byte_bound));
1924           break;
1925         case DIR_WRITE:
1926           ctxt->warn (make_unique<buffer_overflow> (reg, diag_arg,
1927                                                     out, byte_bound));
1928           break;
1929         }
1930     }
1931 }
1932
1933 /* Ensure that all arguments at the call described by CD are checked
1934    for poisoned values, by calling get_rvalue on each argument.  */
1935
1936 void
1937 region_model::check_call_args (const call_details &cd) const
1938 {
1939   for (unsigned arg_idx = 0; arg_idx < cd.num_args (); arg_idx++)
1940     cd.get_arg_svalue (arg_idx);
1941 }
1942
1943 /* Return true if CD is known to be a call to a function with
1944    __attribute__((const)).  */
1945
1946 static bool
1947 const_fn_p (const call_details &cd)
1948 {
1949   tree fndecl = cd.get_fndecl_for_call ();
1950   if (!fndecl)
1951     return false;
1952   gcc_assert (DECL_P (fndecl));
1953   return TREE_READONLY (fndecl);
1954 }
1955
1956 /* If this CD is known to be a call to a function with
1957    __attribute__((const)), attempt to get a const_fn_result_svalue
1958    based on the arguments, or return NULL otherwise.  */
1959
1960 static const svalue *
1961 maybe_get_const_fn_result (const call_details &cd)
1962 {
1963   if (!const_fn_p (cd))
1964     return NULL;
1965
1966   unsigned num_args = cd.num_args ();
1967   if (num_args > const_fn_result_svalue::MAX_INPUTS)
1968     /* Too many arguments.  */
1969     return NULL;
1970
1971   auto_vec<const svalue *> inputs (num_args);
1972   for (unsigned arg_idx = 0; arg_idx < num_args; arg_idx++)
1973     {
1974       const svalue *arg_sval = cd.get_arg_svalue (arg_idx);
1975       if (!arg_sval->can_have_associated_state_p ())
1976         return NULL;
1977       inputs.quick_push (arg_sval);
1978     }
1979
1980   region_model_manager *mgr = cd.get_manager ();
1981   const svalue *sval
1982     = mgr->get_or_create_const_fn_result_svalue (cd.get_lhs_type (),
1983                                                  cd.get_fndecl_for_call (),
1984                                                  inputs);
1985   return sval;
1986 }
1987
1988 /* Update this model for an outcome of a call that returns a specific
1989    integer constant.
1990    If UNMERGEABLE, then make the result unmergeable, e.g. to prevent
1991    the state-merger code from merging success and failure outcomes.  */
1992
1993 void
1994 region_model::update_for_int_cst_return (const call_details &cd,
1995                                          int retval,
1996                                          bool unmergeable)
1997 {
1998   if (!cd.get_lhs_type ())
1999     return;
2000   const svalue *result
2001     = m_mgr->get_or_create_int_cst (cd.get_lhs_type (), retval);
2002   if (unmergeable)
2003     result = m_mgr->get_or_create_unmergeable (result);
2004   set_value (cd.get_lhs_region (), result, cd.get_ctxt ());
2005 }
2006
2007 /* Update this model for an outcome of a call that returns zero.
2008    If UNMERGEABLE, then make the result unmergeable, e.g. to prevent
2009    the state-merger code from merging success and failure outcomes.  */
2010
2011 void
2012 region_model::update_for_zero_return (const call_details &cd,
2013                                       bool unmergeable)
2014 {
2015   update_for_int_cst_return (cd, 0, unmergeable);
2016 }
2017
2018 /* Update this model for an outcome of a call that returns non-zero.  */
2019
2020 void
2021 region_model::update_for_nonzero_return (const call_details &cd)
2022 {
2023   if (!cd.get_lhs_type ())
2024     return;
2025   const svalue *zero
2026     = m_mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
2027   const svalue *result
2028     = get_store_value (cd.get_lhs_region (), cd.get_ctxt ());
2029   add_constraint (result, NE_EXPR, zero, cd.get_ctxt ());
2030 }
2031
2032 /* Subroutine of region_model::maybe_get_copy_bounds.
2033    The Linux kernel commonly uses
2034      min_t([unsigned] long, VAR, sizeof(T));
2035    to set an upper bound on the size of a copy_to_user.
2036    Attempt to simplify such sizes by trying to get the upper bound as a
2037    constant.
2038    Return the simplified svalue if possible, or NULL otherwise.  */
2039
2040 static const svalue *
2041 maybe_simplify_upper_bound (const svalue *num_bytes_sval,
2042                             region_model_manager *mgr)
2043 {
2044   tree type = num_bytes_sval->get_type ();
2045   while (const svalue *raw = num_bytes_sval->maybe_undo_cast ())
2046     num_bytes_sval = raw;
2047   if (const binop_svalue *binop_sval = num_bytes_sval->dyn_cast_binop_svalue ())
2048     if (binop_sval->get_op () == MIN_EXPR)
2049       if (binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT)
2050         {
2051           return mgr->get_or_create_cast (type, binop_sval->get_arg1 ());
2052           /* TODO: we might want to also capture the constraint
2053              when recording the diagnostic, or note that we're using
2054              the upper bound.  */
2055         }
2056   return NULL;
2057 }
2058
2059 /* Attempt to get an upper bound for the size of a copy when simulating a
2060    copy function.
2061
2062    NUM_BYTES_SVAL is the symbolic value for the size of the copy.
2063    Use it if it's constant, otherwise try to simplify it.  Failing
2064    that, use the size of SRC_REG if constant.
2065
2066    Return a symbolic value for an upper limit on the number of bytes
2067    copied, or NULL if no such value could be determined.  */
2068
2069 const svalue *
2070 region_model::maybe_get_copy_bounds (const region *src_reg,
2071                                      const svalue *num_bytes_sval)
2072 {
2073   if (num_bytes_sval->maybe_get_constant ())
2074     return num_bytes_sval;
2075
2076   if (const svalue *simplified
2077       = maybe_simplify_upper_bound (num_bytes_sval, m_mgr))
2078     num_bytes_sval = simplified;
2079
2080   if (num_bytes_sval->maybe_get_constant ())
2081     return num_bytes_sval;
2082
2083   /* For now, try just guessing the size as the capacity of the
2084      base region of the src.
2085      This is a hack; we might get too large a value.  */
2086   const region *src_base_reg = src_reg->get_base_region ();
2087   num_bytes_sval = get_capacity (src_base_reg);
2088
2089   if (num_bytes_sval->maybe_get_constant ())
2090     return num_bytes_sval;
2091
2092   /* Non-constant: give up. */
2093   return NULL;
2094 }
2095
2096 /* Get any known_function for FNDECL, or NULL if there is none.  */
2097
2098 const known_function *
2099 region_model::get_known_function (tree fndecl) const
2100 {
2101   known_function_manager *known_fn_mgr = m_mgr->get_known_function_manager ();
2102   return known_fn_mgr->get_by_fndecl (fndecl);
2103 }
2104
2105 /* Update this model for the CALL stmt, using CTXT to report any
2106    diagnostics - the first half.
2107
2108    Updates to the region_model that should be made *before* sm-states
2109    are updated are done here; other updates to the region_model are done
2110    in region_model::on_call_post.
2111
2112    Return true if the function call has unknown side effects (it wasn't
2113    recognized and we don't have a body for it, or are unable to tell which
2114    fndecl it is).
2115
2116    Write true to *OUT_TERMINATE_PATH if this execution path should be
2117    terminated (e.g. the function call terminates the process).  */
2118
2119 bool
2120 region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
2121                            bool *out_terminate_path)
2122 {
2123   call_details cd (call, this, ctxt);
2124
2125   bool unknown_side_effects = false;
2126
2127   /* Special-case for IFN_DEFERRED_INIT.
2128      We want to report uninitialized variables with -fanalyzer (treating
2129      -ftrivial-auto-var-init= as purely a mitigation feature).
2130      Handle IFN_DEFERRED_INIT by treating it as no-op: don't touch the
2131      lhs of the call, so that it is still uninitialized from the point of
2132      view of the analyzer.  */
2133   if (gimple_call_internal_p (call)
2134       && gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
2135     return false;
2136
2137   /* Get svalues for all of the arguments at the callsite, to ensure that we
2138      complain about any uninitialized arguments.  This might lead to
2139      duplicates if any of the handling below also looks up the svalues,
2140      but the deduplication code should deal with that.  */
2141   if (ctxt)
2142     check_call_args (cd);
2143
2144   /* Some of the cases below update the lhs of the call based on the
2145      return value, but not all.  Provide a default value, which may
2146      get overwritten below.  */
2147   if (tree lhs = gimple_call_lhs (call))
2148     {
2149       const region *lhs_region = get_lvalue (lhs, ctxt);
2150       const svalue *sval = maybe_get_const_fn_result (cd);
2151       if (!sval)
2152         {
2153           /* For the common case of functions without __attribute__((const)),
2154              use a conjured value, and purge any prior state involving that
2155              value (in case this is in a loop).  */
2156           sval = m_mgr->get_or_create_conjured_svalue (TREE_TYPE (lhs), call,
2157                                                        lhs_region,
2158                                                        conjured_purge (this,
2159                                                                        ctxt));
2160         }
2161       set_value (lhs_region, sval, ctxt);
2162     }
2163
2164   if (gimple_call_internal_p (call))
2165     {
2166       switch (gimple_call_internal_fn (call))
2167        {
2168        default:
2169          break;
2170        case IFN_BUILTIN_EXPECT:
2171          impl_call_builtin_expect (cd);
2172          return false;
2173        case IFN_UBSAN_BOUNDS:
2174          return false;
2175        case IFN_VA_ARG:
2176          impl_call_va_arg (cd);
2177          return false;
2178        }
2179     }
2180
2181   if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
2182     {
2183       /* The various impl_call_* member functions are implemented
2184          in region-model-impl-calls.cc.
2185          Having them split out into separate functions makes it easier
2186          to put breakpoints on the handling of specific functions.  */
2187       int callee_fndecl_flags = flags_from_decl_or_type (callee_fndecl);
2188
2189       if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
2190           && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
2191         switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
2192           {
2193           default:
2194             if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
2195               unknown_side_effects = true;
2196             break;
2197           case BUILT_IN_ALLOCA:
2198           case BUILT_IN_ALLOCA_WITH_ALIGN:
2199             impl_call_alloca (cd);
2200             return false;
2201           case BUILT_IN_CALLOC:
2202             impl_call_calloc (cd);
2203             return false;
2204           case BUILT_IN_EXPECT:
2205           case BUILT_IN_EXPECT_WITH_PROBABILITY:
2206             impl_call_builtin_expect (cd);
2207             return false;
2208           case BUILT_IN_FREE:
2209             /* Handle in "on_call_post".  */
2210             break;
2211           case BUILT_IN_MALLOC:
2212             impl_call_malloc (cd);
2213             return false;
2214           case BUILT_IN_MEMCPY:
2215           case BUILT_IN_MEMCPY_CHK:
2216             impl_call_memcpy (cd);
2217             return false;
2218           case BUILT_IN_MEMSET:
2219           case BUILT_IN_MEMSET_CHK:
2220             impl_call_memset (cd);
2221             return false;
2222             break;
2223           case BUILT_IN_REALLOC:
2224             return false;
2225           case BUILT_IN_STRCHR:
2226             /* Handle in "on_call_post".  */
2227             return false;
2228           case BUILT_IN_STRCPY:
2229           case BUILT_IN_STRCPY_CHK:
2230             impl_call_strcpy (cd);
2231             return false;
2232           case BUILT_IN_STRLEN:
2233             impl_call_strlen (cd);
2234             return false;
2235
2236           case BUILT_IN_STACK_SAVE:
2237           case BUILT_IN_STACK_RESTORE:
2238             return false;
2239
2240           /* Stdio builtins.  */
2241           case BUILT_IN_FPRINTF:
2242           case BUILT_IN_FPRINTF_UNLOCKED:
2243           case BUILT_IN_PUTC:
2244           case BUILT_IN_PUTC_UNLOCKED:
2245           case BUILT_IN_FPUTC:
2246           case BUILT_IN_FPUTC_UNLOCKED:
2247           case BUILT_IN_FPUTS:
2248           case BUILT_IN_FPUTS_UNLOCKED:
2249           case BUILT_IN_FWRITE:
2250           case BUILT_IN_FWRITE_UNLOCKED:
2251           case BUILT_IN_PRINTF:
2252           case BUILT_IN_PRINTF_UNLOCKED:
2253           case BUILT_IN_PUTCHAR:
2254           case BUILT_IN_PUTCHAR_UNLOCKED:
2255           case BUILT_IN_PUTS:
2256           case BUILT_IN_PUTS_UNLOCKED:
2257           case BUILT_IN_VFPRINTF:
2258           case BUILT_IN_VPRINTF:
2259             /* These stdio builtins have external effects that are out
2260                of scope for the analyzer: we only want to model the effects
2261                on the return value.  */
2262             break;
2263
2264           case BUILT_IN_VA_START:
2265             impl_call_va_start (cd);
2266             return false;
2267           case BUILT_IN_VA_COPY:
2268             impl_call_va_copy (cd);
2269             return false;
2270           }
2271       else if (is_named_call_p (callee_fndecl, "malloc", call, 1))
2272         {
2273           impl_call_malloc (cd);
2274           return false;
2275         }
2276       else if (is_named_call_p (callee_fndecl, "calloc", call, 2))
2277         {
2278           impl_call_calloc (cd);
2279           return false;
2280         }
2281       else if (is_named_call_p (callee_fndecl, "alloca", call, 1))
2282         {
2283           impl_call_alloca (cd);
2284           return false;
2285         }
2286       else if (is_named_call_p (callee_fndecl, "realloc", call, 2))
2287         {
2288           impl_call_realloc (cd);
2289           return false;
2290         }
2291       else if (is_named_call_p (callee_fndecl, "__errno_location", call, 0))
2292         {
2293           impl_call_errno_location (cd);
2294           return false;
2295         }
2296       else if (is_named_call_p (callee_fndecl, "error"))
2297         {
2298           if (impl_call_error (cd, 3, out_terminate_path))
2299             return false;
2300           else
2301             unknown_side_effects = true;
2302         }
2303       else if (is_named_call_p (callee_fndecl, "error_at_line"))
2304         {
2305           if (impl_call_error (cd, 5, out_terminate_path))
2306             return false;
2307           else
2308             unknown_side_effects = true;
2309         }
2310       else if (is_named_call_p (callee_fndecl, "fgets", call, 3)
2311                || is_named_call_p (callee_fndecl, "fgets_unlocked", call, 3))
2312         {
2313           impl_call_fgets (cd);
2314           return false;
2315         }
2316       else if (is_named_call_p (callee_fndecl, "fread", call, 4))
2317         {
2318           impl_call_fread (cd);
2319           return false;
2320         }
2321       else if (is_named_call_p (callee_fndecl, "getchar", call, 0))
2322         {
2323           /* No side-effects (tracking stream state is out-of-scope
2324              for the analyzer).  */
2325         }
2326       else if (is_named_call_p (callee_fndecl, "memset", call, 3)
2327                && POINTER_TYPE_P (cd.get_arg_type (0)))
2328         {
2329           impl_call_memset (cd);
2330           return false;
2331         }
2332       else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1)
2333                || is_pipe_call_p (callee_fndecl, "pipe2", call, 2))
2334         {
2335           /* Handle in "on_call_post"; bail now so that fd array
2336              is left untouched so that we can detect use-of-uninit
2337              for the case where the call fails.  */
2338           return false;
2339         }
2340       else if (is_named_call_p (callee_fndecl, "putenv", call, 1)
2341                && POINTER_TYPE_P (cd.get_arg_type (0)))
2342         {
2343           impl_call_putenv (cd);
2344           return false;
2345         }
2346       else if (is_named_call_p (callee_fndecl, "strchr", call, 2)
2347                && POINTER_TYPE_P (cd.get_arg_type (0)))
2348         {
2349           /* Handle in "on_call_post".  */
2350           return false;
2351         }
2352       else if (is_named_call_p (callee_fndecl, "strlen", call, 1)
2353                && POINTER_TYPE_P (cd.get_arg_type (0)))
2354         {
2355           impl_call_strlen (cd);
2356           return false;
2357         }
2358       else if (is_named_call_p (callee_fndecl, "operator new", call, 1))
2359         {
2360           impl_call_operator_new (cd);
2361           return false;
2362         }
2363       else if (is_named_call_p (callee_fndecl, "operator new []", call, 1))
2364         {
2365           impl_call_operator_new (cd);
2366           return false;
2367         }
2368       else if (is_named_call_p (callee_fndecl, "operator delete", call, 1)
2369                || is_named_call_p (callee_fndecl, "operator delete", call, 2)
2370                || is_named_call_p (callee_fndecl, "operator delete []", call, 1))
2371         {
2372           /* Handle in "on_call_post".  */
2373         }
2374       else if (const known_function *kf = get_known_function (callee_fndecl))
2375         {
2376           kf->impl_call_pre (cd);
2377           return false;
2378         }
2379       else if (!fndecl_has_gimple_body_p (callee_fndecl)
2380                && (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
2381                && !fndecl_built_in_p (callee_fndecl))
2382         unknown_side_effects = true;
2383     }
2384   else
2385     unknown_side_effects = true;
2386
2387   return unknown_side_effects;
2388 }
2389
2390 /* Update this model for the CALL stmt, using CTXT to report any
2391    diagnostics - the second half.
2392
2393    Updates to the region_model that should be made *after* sm-states
2394    are updated are done here; other updates to the region_model are done
2395    in region_model::on_call_pre.
2396
2397    If UNKNOWN_SIDE_EFFECTS is true, also call handle_unrecognized_call
2398    to purge state.  */
2399
2400 void
2401 region_model::on_call_post (const gcall *call,
2402                             bool unknown_side_effects,
2403                             region_model_context *ctxt)
2404 {
2405   if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
2406     {
2407       call_details cd (call, this, ctxt);
2408       if (is_named_call_p (callee_fndecl, "free", call, 1))
2409         {
2410           impl_call_free (cd);
2411           return;
2412         }
2413       if (is_named_call_p (callee_fndecl, "operator delete", call, 1)
2414           || is_named_call_p (callee_fndecl, "operator delete", call, 2)
2415           || is_named_call_p (callee_fndecl, "operator delete []", call, 1))
2416         {
2417           impl_call_operator_delete (cd);
2418           return;
2419         }
2420       else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1)
2421                || is_pipe_call_p (callee_fndecl, "pipe2", call, 2))
2422         {
2423           impl_call_pipe (cd);
2424           return;
2425         }
2426       else if (is_named_call_p (callee_fndecl, "strchr", call, 2)
2427                && POINTER_TYPE_P (cd.get_arg_type (0)))
2428         {
2429           impl_call_strchr (cd);
2430           return;
2431         }
2432       /* Was this fndecl referenced by
2433          __attribute__((malloc(FOO)))?  */
2434       if (lookup_attribute ("*dealloc", DECL_ATTRIBUTES (callee_fndecl)))
2435         {
2436           impl_deallocation_call (cd);
2437           return;
2438         }
2439       if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
2440           && gimple_builtin_call_types_compatible_p (call, callee_fndecl))
2441         switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
2442           {
2443           default:
2444             break;
2445           case BUILT_IN_REALLOC:
2446             impl_call_realloc (cd);
2447             return;
2448
2449           case BUILT_IN_STRCHR:
2450             impl_call_strchr (cd);
2451             return;
2452
2453           case BUILT_IN_VA_END:
2454             impl_call_va_end (cd);
2455             return;
2456           }
2457     }
2458
2459   if (unknown_side_effects)
2460     handle_unrecognized_call (call, ctxt);
2461 }
2462
2463 /* Purge state involving SVAL from this region_model, using CTXT
2464    (if non-NULL) to purge other state in a program_state.
2465
2466    For example, if we're at the def-stmt of an SSA name, then we need to
2467    purge any state for svalues that involve that SSA name.  This avoids
2468    false positives in loops, since a symbolic value referring to the
2469    SSA name will be referring to the previous value of that SSA name.
2470
2471    For example, in:
2472      while ((e = hashmap_iter_next(&iter))) {
2473        struct oid2strbuf *e_strbuf = (struct oid2strbuf *)e;
2474        free (e_strbuf->value);
2475      }
2476    at the def-stmt of e_8:
2477      e_8 = hashmap_iter_next (&iter);
2478    we should purge the "freed" state of:
2479      INIT_VAL(CAST_REG(‘struct oid2strbuf’, (*INIT_VAL(e_8))).value)
2480    which is the "e_strbuf->value" value from the previous iteration,
2481    or we will erroneously report a double-free - the "e_8" within it
2482    refers to the previous value.  */
2483
2484 void
2485 region_model::purge_state_involving (const svalue *sval,
2486                                      region_model_context *ctxt)
2487 {
2488   if (!sval->can_have_associated_state_p ())
2489     return;
2490   m_store.purge_state_involving (sval, m_mgr);
2491   m_constraints->purge_state_involving (sval);
2492   m_dynamic_extents.purge_state_involving (sval);
2493   if (ctxt)
2494     ctxt->purge_state_involving (sval);
2495 }
2496
2497 /* A pending_note subclass for adding a note about an
2498    __attribute__((access, ...)) to a diagnostic.  */
2499
2500 class reason_attr_access : public pending_note_subclass<reason_attr_access>
2501 {
2502 public:
2503   reason_attr_access (tree callee_fndecl, const attr_access &access)
2504   : m_callee_fndecl (callee_fndecl),
2505     m_ptr_argno (access.ptrarg),
2506     m_access_str (TREE_STRING_POINTER (access.to_external_string ()))
2507   {
2508   }
2509
2510   const char *get_kind () const final override { return "reason_attr_access"; }
2511
2512   void emit () const final override
2513   {
2514     inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
2515             "parameter %i of %qD marked with attribute %qs",
2516             m_ptr_argno + 1, m_callee_fndecl, m_access_str);
2517   }
2518
2519   bool operator== (const reason_attr_access &other) const
2520   {
2521     return (m_callee_fndecl == other.m_callee_fndecl
2522             && m_ptr_argno == other.m_ptr_argno
2523             && !strcmp (m_access_str, other.m_access_str));
2524   }
2525
2526 private:
2527   tree m_callee_fndecl;
2528   unsigned m_ptr_argno;
2529   const char *m_access_str;
2530 };
2531
2532 /* Check CALL a call to external function CALLEE_FNDECL based on
2533    any __attribute__ ((access, ....) on the latter, complaining to
2534    CTXT about any issues.
2535
2536    Currently we merely call check_region_for_write on any regions
2537    pointed to by arguments marked with a "write_only" or "read_write"
2538    attribute.  */
2539
2540 void
2541 region_model::
2542 check_external_function_for_access_attr (const gcall *call,
2543                                          tree callee_fndecl,
2544                                          region_model_context *ctxt) const
2545 {
2546   gcc_assert (call);
2547   gcc_assert (callee_fndecl);
2548   gcc_assert (ctxt);
2549
2550   tree fntype = TREE_TYPE (callee_fndecl);
2551   if (!fntype)
2552     return;
2553
2554   if (!TYPE_ATTRIBUTES (fntype))
2555     return;
2556
2557   /* Initialize a map of attribute access specifications for arguments
2558      to the function call.  */
2559   rdwr_map rdwr_idx;
2560   init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
2561
2562   unsigned argno = 0;
2563
2564   for (tree iter = TYPE_ARG_TYPES (fntype); iter;
2565        iter = TREE_CHAIN (iter), ++argno)
2566     {
2567       const attr_access* access = rdwr_idx.get (argno);
2568       if (!access)
2569         continue;
2570
2571       /* Ignore any duplicate entry in the map for the size argument.  */
2572       if (access->ptrarg != argno)
2573         continue;
2574
2575       if (access->mode == access_write_only
2576           || access->mode == access_read_write)
2577         {
2578           /* Subclass of decorated_region_model_context that
2579              adds a note about the attr access to any saved diagnostics.  */
2580           class annotating_ctxt : public note_adding_context
2581           {
2582           public:
2583             annotating_ctxt (tree callee_fndecl,
2584                              const attr_access &access,
2585                              region_model_context *ctxt)
2586             : note_adding_context (ctxt),
2587               m_callee_fndecl (callee_fndecl),
2588               m_access (access)
2589             {
2590             }
2591             std::unique_ptr<pending_note> make_note () final override
2592             {
2593               return make_unique<reason_attr_access>
2594                 (m_callee_fndecl, m_access);
2595             }
2596           private:
2597             tree m_callee_fndecl;
2598             const attr_access &m_access;
2599           };
2600
2601           /* Use this ctxt below so that any diagnostics get the
2602              note added to them.  */
2603           annotating_ctxt my_ctxt (callee_fndecl, *access, ctxt);
2604
2605           tree ptr_tree = gimple_call_arg (call, access->ptrarg);
2606           const svalue *ptr_sval = get_rvalue (ptr_tree, &my_ctxt);
2607           const region *reg = deref_rvalue (ptr_sval, ptr_tree, &my_ctxt);
2608           check_region_for_write (reg, &my_ctxt);
2609           /* We don't use the size arg for now.  */
2610         }
2611     }
2612 }
2613
2614 /* Handle a call CALL to a function with unknown behavior.
2615
2616    Traverse the regions in this model, determining what regions are
2617    reachable from pointer arguments to CALL and from global variables,
2618    recursively.
2619
2620    Set all reachable regions to new unknown values and purge sm-state
2621    from their values, and from values that point to them.  */
2622
2623 void
2624 region_model::handle_unrecognized_call (const gcall *call,
2625                                         region_model_context *ctxt)
2626 {
2627   tree fndecl = get_fndecl_for_call (call, ctxt);
2628
2629   if (fndecl && ctxt)
2630     check_external_function_for_access_attr (call, fndecl, ctxt);
2631
2632   reachable_regions reachable_regs (this);
2633
2634   /* Determine the reachable regions and their mutability.  */
2635   {
2636     /* Add globals and regions that already escaped in previous
2637        unknown calls.  */
2638     m_store.for_each_cluster (reachable_regions::init_cluster_cb,
2639                               &reachable_regs);
2640
2641     /* Params that are pointers.  */
2642     tree iter_param_types = NULL_TREE;
2643     if (fndecl)
2644       iter_param_types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2645     for (unsigned arg_idx = 0; arg_idx < gimple_call_num_args (call); arg_idx++)
2646       {
2647         /* Track expected param type, where available.  */
2648         tree param_type = NULL_TREE;
2649         if (iter_param_types)
2650           {
2651             param_type = TREE_VALUE (iter_param_types);
2652             gcc_assert (param_type);
2653             iter_param_types = TREE_CHAIN (iter_param_types);
2654           }
2655
2656         tree parm = gimple_call_arg (call, arg_idx);
2657         const svalue *parm_sval = get_rvalue (parm, ctxt);
2658         reachable_regs.handle_parm (parm_sval, param_type);
2659       }
2660   }
2661
2662   uncertainty_t *uncertainty = ctxt ? ctxt->get_uncertainty () : NULL;
2663
2664   /* Purge sm-state for the svalues that were reachable,
2665      both in non-mutable and mutable form.  */
2666   for (svalue_set::iterator iter
2667          = reachable_regs.begin_reachable_svals ();
2668        iter != reachable_regs.end_reachable_svals (); ++iter)
2669     {
2670       const svalue *sval = (*iter);
2671       if (ctxt)
2672         ctxt->on_unknown_change (sval, false);
2673     }
2674   for (svalue_set::iterator iter
2675          = reachable_regs.begin_mutable_svals ();
2676        iter != reachable_regs.end_mutable_svals (); ++iter)
2677     {
2678       const svalue *sval = (*iter);
2679       if (ctxt)
2680         ctxt->on_unknown_change (sval, true);
2681       if (uncertainty)
2682         uncertainty->on_mutable_sval_at_unknown_call (sval);
2683     }
2684
2685   /* Mark any clusters that have escaped.  */
2686   reachable_regs.mark_escaped_clusters (ctxt);
2687
2688   /* Update bindings for all clusters that have escaped, whether above,
2689      or previously.  */
2690   m_store.on_unknown_fncall (call, m_mgr->get_store_manager (),
2691                              conjured_purge (this, ctxt));
2692
2693   /* Purge dynamic extents from any regions that have escaped mutably:
2694      realloc could have been called on them.  */
2695   for (hash_set<const region *>::iterator
2696          iter = reachable_regs.begin_mutable_base_regs ();
2697        iter != reachable_regs.end_mutable_base_regs ();
2698        ++iter)
2699     {
2700       const region *base_reg = (*iter);
2701       unset_dynamic_extents (base_reg);
2702     }
2703 }
2704
2705 /* Traverse the regions in this model, determining what regions are
2706    reachable from the store and populating *OUT.
2707
2708    If EXTRA_SVAL is non-NULL, treat it as an additional "root"
2709    for reachability (for handling return values from functions when
2710    analyzing return of the only function on the stack).
2711
2712    If UNCERTAINTY is non-NULL, treat any svalues that were recorded
2713    within it as being maybe-bound as additional "roots" for reachability.
2714
2715    Find svalues that haven't leaked.    */
2716
2717 void
2718 region_model::get_reachable_svalues (svalue_set *out,
2719                                      const svalue *extra_sval,
2720                                      const uncertainty_t *uncertainty)
2721 {
2722   reachable_regions reachable_regs (this);
2723
2724   /* Add globals and regions that already escaped in previous
2725      unknown calls.  */
2726   m_store.for_each_cluster (reachable_regions::init_cluster_cb,
2727                             &reachable_regs);
2728
2729   if (extra_sval)
2730     reachable_regs.handle_sval (extra_sval);
2731
2732   if (uncertainty)
2733     for (uncertainty_t::iterator iter
2734            = uncertainty->begin_maybe_bound_svals ();
2735          iter != uncertainty->end_maybe_bound_svals (); ++iter)
2736       reachable_regs.handle_sval (*iter);
2737
2738   /* Get regions for locals that have explicitly bound values.  */
2739   for (store::cluster_map_t::iterator iter = m_store.begin ();
2740        iter != m_store.end (); ++iter)
2741     {
2742       const region *base_reg = (*iter).first;
2743       if (const region *parent = base_reg->get_parent_region ())
2744         if (parent->get_kind () == RK_FRAME)
2745           reachable_regs.add (base_reg, false);
2746     }
2747
2748   /* Populate *OUT based on the values that were reachable.  */
2749   for (svalue_set::iterator iter
2750          = reachable_regs.begin_reachable_svals ();
2751        iter != reachable_regs.end_reachable_svals (); ++iter)
2752     out->add (*iter);
2753 }
2754
2755 /* Update this model for the RETURN_STMT, using CTXT to report any
2756    diagnostics.  */
2757
2758 void
2759 region_model::on_return (const greturn *return_stmt, region_model_context *ctxt)
2760 {
2761   tree callee = get_current_function ()->decl;
2762   tree lhs = DECL_RESULT (callee);
2763   tree rhs = gimple_return_retval (return_stmt);
2764
2765   if (lhs && rhs)
2766     {
2767       const svalue *sval = get_rvalue (rhs, ctxt);
2768       const region *ret_reg = get_lvalue (lhs, ctxt);
2769       set_value (ret_reg, sval, ctxt);
2770     }
2771 }
2772
2773 /* Update this model for a call and return of setjmp/sigsetjmp at CALL within
2774    ENODE, using CTXT to report any diagnostics.
2775
2776    This is for the initial direct invocation of setjmp/sigsetjmp (which returns
2777    0), as opposed to any second return due to longjmp/sigsetjmp.  */
2778
2779 void
2780 region_model::on_setjmp (const gcall *call, const exploded_node *enode,
2781                          region_model_context *ctxt)
2782 {
2783   const svalue *buf_ptr = get_rvalue (gimple_call_arg (call, 0), ctxt);
2784   const region *buf_reg = deref_rvalue (buf_ptr, gimple_call_arg (call, 0),
2785                                          ctxt);
2786
2787   /* Create a setjmp_svalue for this call and store it in BUF_REG's
2788      region.  */
2789   if (buf_reg)
2790     {
2791       setjmp_record r (enode, call);
2792       const svalue *sval
2793         = m_mgr->get_or_create_setjmp_svalue (r, buf_reg->get_type ());
2794       set_value (buf_reg, sval, ctxt);
2795     }
2796
2797   /* Direct calls to setjmp return 0.  */
2798   if (tree lhs = gimple_call_lhs (call))
2799     {
2800       const svalue *new_sval
2801         = m_mgr->get_or_create_int_cst (TREE_TYPE (lhs), 0);
2802       const region *lhs_reg = get_lvalue (lhs, ctxt);
2803       set_value (lhs_reg, new_sval, ctxt);
2804     }
2805 }
2806
2807 /* Update this region_model for rewinding from a "longjmp" at LONGJMP_CALL
2808    to a "setjmp" at SETJMP_CALL where the final stack depth should be
2809    SETJMP_STACK_DEPTH.  Pop any stack frames.  Leak detection is *not*
2810    done, and should be done by the caller.  */
2811
2812 void
2813 region_model::on_longjmp (const gcall *longjmp_call, const gcall *setjmp_call,
2814                            int setjmp_stack_depth, region_model_context *ctxt)
2815 {
2816   /* Evaluate the val, using the frame of the "longjmp".  */
2817   tree fake_retval = gimple_call_arg (longjmp_call, 1);
2818   const svalue *fake_retval_sval = get_rvalue (fake_retval, ctxt);
2819
2820   /* Pop any frames until we reach the stack depth of the function where
2821      setjmp was called.  */
2822   gcc_assert (get_stack_depth () >= setjmp_stack_depth);
2823   while (get_stack_depth () > setjmp_stack_depth)
2824     pop_frame (NULL, NULL, ctxt);
2825
2826   gcc_assert (get_stack_depth () == setjmp_stack_depth);
2827
2828   /* Assign to LHS of "setjmp" in new_state.  */
2829   if (tree lhs = gimple_call_lhs (setjmp_call))
2830     {
2831       /* Passing 0 as the val to longjmp leads to setjmp returning 1.  */
2832       const svalue *zero_sval
2833         = m_mgr->get_or_create_int_cst (TREE_TYPE (fake_retval), 0);
2834       tristate eq_zero = eval_condition (fake_retval_sval, EQ_EXPR, zero_sval);
2835       /* If we have 0, use 1.  */
2836       if (eq_zero.is_true ())
2837         {
2838           const svalue *one_sval
2839             = m_mgr->get_or_create_int_cst (TREE_TYPE (fake_retval), 1);
2840           fake_retval_sval = one_sval;
2841         }
2842       else
2843         {
2844           /* Otherwise note that the value is nonzero.  */
2845           m_constraints->add_constraint (fake_retval_sval, NE_EXPR, zero_sval);
2846         }
2847
2848       /* Decorate the return value from setjmp as being unmergeable,
2849          so that we don't attempt to merge states with it as zero
2850          with states in which it's nonzero, leading to a clean distinction
2851          in the exploded_graph betweeen the first return and the second
2852          return.  */
2853       fake_retval_sval = m_mgr->get_or_create_unmergeable (fake_retval_sval);
2854
2855       const region *lhs_reg = get_lvalue (lhs, ctxt);
2856       set_value (lhs_reg, fake_retval_sval, ctxt);
2857     }
2858 }
2859
2860 /* Update this region_model for a phi stmt of the form
2861      LHS = PHI <...RHS...>.
2862    where RHS is for the appropriate edge.
2863    Get state from OLD_STATE so that all of the phi stmts for a basic block
2864    are effectively handled simultaneously.  */
2865
2866 void
2867 region_model::handle_phi (const gphi *phi,
2868                           tree lhs, tree rhs,
2869                           const region_model &old_state,
2870                           region_model_context *ctxt)
2871 {
2872   /* For now, don't bother tracking the .MEM SSA names.  */
2873   if (tree var = SSA_NAME_VAR (lhs))
2874     if (TREE_CODE (var) == VAR_DECL)
2875       if (VAR_DECL_IS_VIRTUAL_OPERAND (var))
2876         return;
2877
2878   const svalue *src_sval = old_state.get_rvalue (rhs, ctxt);
2879   const region *dst_reg = old_state.get_lvalue (lhs, ctxt);
2880
2881   set_value (dst_reg, src_sval, ctxt);
2882
2883   if (ctxt)
2884     ctxt->on_phi (phi, rhs);
2885 }
2886
2887 /* Implementation of region_model::get_lvalue; the latter adds type-checking.
2888
2889    Get the id of the region for PV within this region_model,
2890    emitting any diagnostics to CTXT.  */
2891
2892 const region *
2893 region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) const
2894 {
2895   tree expr = pv.m_tree;
2896
2897   gcc_assert (expr);
2898
2899   switch (TREE_CODE (expr))
2900     {
2901     default:
2902       return m_mgr->get_region_for_unexpected_tree_code (ctxt, expr,
2903                                                          dump_location_t ());
2904
2905     case ARRAY_REF:
2906       {
2907         tree array = TREE_OPERAND (expr, 0);
2908         tree index = TREE_OPERAND (expr, 1);
2909
2910         const region *array_reg = get_lvalue (array, ctxt);
2911         const svalue *index_sval = get_rvalue (index, ctxt);
2912         return m_mgr->get_element_region (array_reg,
2913                                           TREE_TYPE (TREE_TYPE (array)),
2914                                           index_sval);
2915       }
2916       break;
2917
2918     case BIT_FIELD_REF:
2919       {
2920         tree inner_expr = TREE_OPERAND (expr, 0);
2921         const region *inner_reg = get_lvalue (inner_expr, ctxt);
2922         tree num_bits = TREE_OPERAND (expr, 1);
2923         tree first_bit_offset = TREE_OPERAND (expr, 2);
2924         gcc_assert (TREE_CODE (num_bits) == INTEGER_CST);
2925         gcc_assert (TREE_CODE (first_bit_offset) == INTEGER_CST);
2926         bit_range bits (TREE_INT_CST_LOW (first_bit_offset),
2927                         TREE_INT_CST_LOW (num_bits));
2928         return m_mgr->get_bit_range (inner_reg, TREE_TYPE (expr), bits);
2929       }
2930       break;
2931
2932     case MEM_REF:
2933       {
2934         tree ptr = TREE_OPERAND (expr, 0);
2935         tree offset = TREE_OPERAND (expr, 1);
2936         const svalue *ptr_sval = get_rvalue (ptr, ctxt);
2937         const svalue *offset_sval = get_rvalue (offset, ctxt);
2938         const region *star_ptr = deref_rvalue (ptr_sval, ptr, ctxt);
2939         return m_mgr->get_offset_region (star_ptr,
2940                                          TREE_TYPE (expr),
2941                                          offset_sval);
2942       }
2943       break;
2944
2945     case FUNCTION_DECL:
2946       return m_mgr->get_region_for_fndecl (expr);
2947
2948     case LABEL_DECL:
2949       return m_mgr->get_region_for_label (expr);
2950
2951     case VAR_DECL:
2952       /* Handle globals.  */
2953       if (is_global_var (expr))
2954         return m_mgr->get_region_for_global (expr);
2955
2956       /* Fall through.  */
2957
2958     case SSA_NAME:
2959     case PARM_DECL:
2960     case RESULT_DECL:
2961       {
2962         gcc_assert (TREE_CODE (expr) == SSA_NAME
2963                     || TREE_CODE (expr) == PARM_DECL
2964                     || TREE_CODE (expr) == VAR_DECL
2965                     || TREE_CODE (expr) == RESULT_DECL);
2966
2967         int stack_index = pv.m_stack_depth;
2968         const frame_region *frame = get_frame_at_index (stack_index);
2969         gcc_assert (frame);
2970         return frame->get_region_for_local (m_mgr, expr, ctxt);
2971       }
2972
2973     case COMPONENT_REF:
2974       {
2975         /* obj.field  */
2976         tree obj = TREE_OPERAND (expr, 0);
2977         tree field = TREE_OPERAND (expr, 1);
2978         const region *obj_reg = get_lvalue (obj, ctxt);
2979         return m_mgr->get_field_region (obj_reg, field);
2980       }
2981       break;
2982
2983     case STRING_CST:
2984       return m_mgr->get_region_for_string (expr);
2985     }
2986 }
2987
2988 /* Assert that SRC_TYPE can be converted to DST_TYPE as a no-op.  */
2989
2990 static void
2991 assert_compat_types (tree src_type, tree dst_type)
2992 {
2993   if (src_type && dst_type && !VOID_TYPE_P (dst_type))
2994     {
2995 #if CHECKING_P
2996       if (!(useless_type_conversion_p (src_type, dst_type)))
2997         internal_error ("incompatible types: %qT and %qT", src_type, dst_type);
2998 #endif
2999     }
3000 }
3001
3002 /* Return true if SRC_TYPE can be converted to DST_TYPE as a no-op.  */
3003
3004 bool
3005 compat_types_p (tree src_type, tree dst_type)
3006 {
3007   if (src_type && dst_type && !VOID_TYPE_P (dst_type))
3008     if (!(useless_type_conversion_p (src_type, dst_type)))
3009       return false;
3010   return true;
3011 }
3012
3013 /* Get the region for PV within this region_model,
3014    emitting any diagnostics to CTXT.  */
3015
3016 const region *
3017 region_model::get_lvalue (path_var pv, region_model_context *ctxt) const
3018 {
3019   if (pv.m_tree == NULL_TREE)
3020     return NULL;
3021
3022   const region *result_reg = get_lvalue_1 (pv, ctxt);
3023   assert_compat_types (result_reg->get_type (), TREE_TYPE (pv.m_tree));
3024   return result_reg;
3025 }
3026
3027 /* Get the region for EXPR within this region_model (assuming the most
3028    recent stack frame if it's a local).  */
3029
3030 const region *
3031 region_model::get_lvalue (tree expr, region_model_context *ctxt) const
3032 {
3033   return get_lvalue (path_var (expr, get_stack_depth () - 1), ctxt);
3034 }
3035
3036 /* Implementation of region_model::get_rvalue; the latter adds type-checking.
3037
3038    Get the value of PV within this region_model,
3039    emitting any diagnostics to CTXT.  */
3040
3041 const svalue *
3042 region_model::get_rvalue_1 (path_var pv, region_model_context *ctxt) const
3043 {
3044   gcc_assert (pv.m_tree);
3045
3046   switch (TREE_CODE (pv.m_tree))
3047     {
3048     default:
3049       return m_mgr->get_or_create_unknown_svalue (TREE_TYPE (pv.m_tree));
3050
3051     case ADDR_EXPR:
3052       {
3053         /* "&EXPR".  */
3054         tree expr = pv.m_tree;
3055         tree op0 = TREE_OPERAND (expr, 0);
3056         const region *expr_reg = get_lvalue (op0, ctxt);
3057         return m_mgr->get_ptr_svalue (TREE_TYPE (expr), expr_reg);
3058       }
3059       break;
3060
3061     case BIT_FIELD_REF:
3062       {
3063         tree expr = pv.m_tree;
3064         tree op0 = TREE_OPERAND (expr, 0);
3065         const region *reg = get_lvalue (op0, ctxt);
3066         tree num_bits = TREE_OPERAND (expr, 1);
3067         tree first_bit_offset = TREE_OPERAND (expr, 2);
3068         gcc_assert (TREE_CODE (num_bits) == INTEGER_CST);
3069         gcc_assert (TREE_CODE (first_bit_offset) == INTEGER_CST);
3070         bit_range bits (TREE_INT_CST_LOW (first_bit_offset),
3071                         TREE_INT_CST_LOW (num_bits));
3072         return get_rvalue_for_bits (TREE_TYPE (expr), reg, bits, ctxt);
3073       }
3074
3075     case SSA_NAME:
3076     case VAR_DECL:
3077     case PARM_DECL:
3078     case RESULT_DECL:
3079     case ARRAY_REF:
3080       {
3081         const region *reg = get_lvalue (pv, ctxt);
3082         return get_store_value (reg, ctxt);
3083       }
3084
3085     case REALPART_EXPR:
3086     case IMAGPART_EXPR:
3087     case VIEW_CONVERT_EXPR:
3088       {
3089         tree expr = pv.m_tree;
3090         tree arg = TREE_OPERAND (expr, 0);
3091         const svalue *arg_sval = get_rvalue (arg, ctxt);
3092         const svalue *sval_unaryop
3093           = m_mgr->get_or_create_unaryop (TREE_TYPE (expr), TREE_CODE (expr),
3094                                           arg_sval);
3095         return sval_unaryop;
3096       };
3097
3098     case INTEGER_CST:
3099     case REAL_CST:
3100     case COMPLEX_CST:
3101     case VECTOR_CST:
3102     case STRING_CST:
3103       return m_mgr->get_or_create_constant_svalue (pv.m_tree);
3104
3105     case POINTER_PLUS_EXPR:
3106         {
3107           tree expr = pv.m_tree;
3108           tree ptr = TREE_OPERAND (expr, 0);
3109           tree offset = TREE_OPERAND (expr, 1);
3110           const svalue *ptr_sval = get_rvalue (ptr, ctxt);
3111           const svalue *offset_sval = get_rvalue (offset, ctxt);
3112           const svalue *sval_binop
3113             = m_mgr->get_or_create_binop (TREE_TYPE (expr), POINTER_PLUS_EXPR,
3114                                           ptr_sval, offset_sval);
3115           return sval_binop;
3116         }
3117
3118     /* Binary ops.  */
3119     case PLUS_EXPR:
3120     case MULT_EXPR:
3121         {
3122           tree expr = pv.m_tree;
3123           tree arg0 = TREE_OPERAND (expr, 0);
3124           tree arg1 = TREE_OPERAND (expr, 1);
3125           const svalue *arg0_sval = get_rvalue (arg0, ctxt);
3126           const svalue *arg1_sval = get_rvalue (arg1, ctxt);
3127           const svalue *sval_binop
3128             = m_mgr->get_or_create_binop (TREE_TYPE (expr), TREE_CODE (expr),
3129                                           arg0_sval, arg1_sval);
3130           return sval_binop;
3131         }
3132
3133     case COMPONENT_REF:
3134     case MEM_REF:
3135       {
3136         const region *ref_reg = get_lvalue (pv, ctxt);
3137         return get_store_value (ref_reg, ctxt);
3138       }
3139     case OBJ_TYPE_REF:
3140       {
3141         tree expr = OBJ_TYPE_REF_EXPR (pv.m_tree);
3142         return get_rvalue (expr, ctxt);
3143       }
3144     }
3145 }
3146
3147 /* Get the value of PV within this region_model,
3148    emitting any diagnostics to CTXT.  */
3149
3150 const svalue *
3151 region_model::get_rvalue (path_var pv, region_model_context *ctxt) const
3152 {
3153   if (pv.m_tree == NULL_TREE)
3154     return NULL;
3155
3156   const svalue *result_sval = get_rvalue_1 (pv, ctxt);
3157
3158   assert_compat_types (result_sval->get_type (), TREE_TYPE (pv.m_tree));
3159
3160   result_sval = check_for_poison (result_sval, pv.m_tree, ctxt);
3161
3162   return result_sval;
3163 }
3164
3165 /* Get the value of EXPR within this region_model (assuming the most
3166    recent stack frame if it's a local).  */
3167
3168 const svalue *
3169 region_model::get_rvalue (tree expr, region_model_context *ctxt) const
3170 {
3171   return get_rvalue (path_var (expr, get_stack_depth () - 1), ctxt);
3172 }
3173
3174 /* Return true if this model is on a path with "main" as the entrypoint
3175    (as opposed to one in which we're merely analyzing a subset of the
3176    path through the code).  */
3177
3178 bool
3179 region_model::called_from_main_p () const
3180 {
3181   if (!m_current_frame)
3182     return false;
3183   /* Determine if the oldest stack frame in this model is for "main".  */
3184   const frame_region *frame0 = get_frame_at_index (0);
3185   gcc_assert (frame0);
3186   return id_equal (DECL_NAME (frame0->get_function ()->decl), "main");
3187 }
3188
3189 /* Subroutine of region_model::get_store_value for when REG is (or is within)
3190    a global variable that hasn't been touched since the start of this path
3191    (or was implicitly touched due to a call to an unknown function).  */
3192
3193 const svalue *
3194 region_model::get_initial_value_for_global (const region *reg) const
3195 {
3196   /* Get the decl that REG is for (or is within).  */
3197   const decl_region *base_reg
3198     = reg->get_base_region ()->dyn_cast_decl_region ();
3199   gcc_assert (base_reg);
3200   tree decl = base_reg->get_decl ();
3201
3202   /* Special-case: to avoid having to explicitly update all previously
3203      untracked globals when calling an unknown fn, they implicitly have
3204      an unknown value if an unknown call has occurred, unless this is
3205      static to-this-TU and hasn't escaped.  Globals that have escaped
3206      are explicitly tracked, so we shouldn't hit this case for them.  */
3207   if (m_store.called_unknown_fn_p ()
3208       && TREE_PUBLIC (decl)
3209       && !TREE_READONLY (decl))
3210     return m_mgr->get_or_create_unknown_svalue (reg->get_type ());
3211
3212   /* If we are on a path from the entrypoint from "main" and we have a
3213      global decl defined in this TU that hasn't been touched yet, then
3214      the initial value of REG can be taken from the initialization value
3215      of the decl.  */
3216   if (called_from_main_p () || TREE_READONLY (decl))
3217     {
3218       /* Attempt to get the initializer value for base_reg.  */
3219       if (const svalue *base_reg_init
3220             = base_reg->get_svalue_for_initializer (m_mgr))
3221         {
3222           if (reg == base_reg)
3223             return base_reg_init;
3224           else
3225             {
3226               /* Get the value for REG within base_reg_init.  */
3227               binding_cluster c (base_reg);
3228               c.bind (m_mgr->get_store_manager (), base_reg, base_reg_init);
3229               const svalue *sval
3230                 = c.get_any_binding (m_mgr->get_store_manager (), reg);
3231               if (sval)
3232                 {
3233                   if (reg->get_type ())
3234                     sval = m_mgr->get_or_create_cast (reg->get_type (),
3235                                                       sval);
3236                   return sval;
3237                 }
3238             }
3239         }
3240     }
3241
3242   /* Otherwise, return INIT_VAL(REG).  */
3243   return m_mgr->get_or_create_initial_value (reg);
3244 }
3245
3246 /* Get a value for REG, looking it up in the store, or otherwise falling
3247    back to "initial" or "unknown" values.
3248    Use CTXT to report any warnings associated with reading from REG. */
3249
3250 const svalue *
3251 region_model::get_store_value (const region *reg,
3252                                region_model_context *ctxt) const
3253 {
3254   check_region_for_read (reg, ctxt);
3255
3256   /* Special-case: handle var_decls in the constant pool.  */
3257   if (const decl_region *decl_reg = reg->dyn_cast_decl_region ())
3258     if (const svalue *sval = decl_reg->maybe_get_constant_value (m_mgr))
3259       return sval;
3260
3261   const svalue *sval
3262     = m_store.get_any_binding (m_mgr->get_store_manager (), reg);
3263   if (sval)
3264     {
3265       if (reg->get_type ())
3266         sval = m_mgr->get_or_create_cast (reg->get_type (), sval);
3267       return sval;
3268     }
3269
3270   /* Special-case: read at a constant index within a STRING_CST.  */
3271   if (const offset_region *offset_reg = reg->dyn_cast_offset_region ())
3272     if (tree byte_offset_cst
3273           = offset_reg->get_byte_offset ()->maybe_get_constant ())
3274       if (const string_region *str_reg
3275           = reg->get_parent_region ()->dyn_cast_string_region ())
3276         {
3277           tree string_cst = str_reg->get_string_cst ();
3278           if (const svalue *char_sval
3279                 = m_mgr->maybe_get_char_from_string_cst (string_cst,
3280                                                          byte_offset_cst))
3281             return m_mgr->get_or_create_cast (reg->get_type (), char_sval);
3282         }
3283
3284   /* Special-case: read the initial char of a STRING_CST.  */
3285   if (const cast_region *cast_reg = reg->dyn_cast_cast_region ())
3286     if (const string_region *str_reg
3287         = cast_reg->get_original_region ()->dyn_cast_string_region ())
3288       {
3289         tree string_cst = str_reg->get_string_cst ();
3290         tree byte_offset_cst = build_int_cst (integer_type_node, 0);
3291         if (const svalue *char_sval
3292             = m_mgr->maybe_get_char_from_string_cst (string_cst,
3293                                                      byte_offset_cst))
3294           return m_mgr->get_or_create_cast (reg->get_type (), char_sval);
3295       }
3296
3297   /* Otherwise we implicitly have the initial value of the region
3298      (if the cluster had been touched, binding_cluster::get_any_binding,
3299      would have returned UNKNOWN, and we would already have returned
3300      that above).  */
3301
3302   /* Handle globals.  */
3303   if (reg->get_base_region ()->get_parent_region ()->get_kind ()
3304       == RK_GLOBALS)
3305     return get_initial_value_for_global (reg);
3306
3307   return m_mgr->get_or_create_initial_value (reg);
3308 }
3309
3310 /* Return false if REG does not exist, true if it may do.
3311    This is for detecting regions within the stack that don't exist anymore
3312    after frames are popped.  */
3313
3314 bool
3315 region_model::region_exists_p (const region *reg) const
3316 {
3317   /* If within a stack frame, check that the stack frame is live.  */
3318   if (const frame_region *enclosing_frame = reg->maybe_get_frame_region ())
3319     {
3320       /* Check that the current frame is the enclosing frame, or is called
3321          by it.  */
3322       for (const frame_region *iter_frame = get_current_frame (); iter_frame;
3323            iter_frame = iter_frame->get_calling_frame ())
3324         if (iter_frame == enclosing_frame)
3325           return true;
3326       return false;
3327     }
3328
3329   return true;
3330 }
3331
3332 /* Get a region for referencing PTR_SVAL, creating a region if need be, and
3333    potentially generating warnings via CTXT.
3334    PTR_SVAL must be of pointer type.
3335    PTR_TREE if non-NULL can be used when emitting diagnostics.  */
3336
3337 const region *
3338 region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree,
3339                             region_model_context *ctxt) const
3340 {
3341   gcc_assert (ptr_sval);
3342   gcc_assert (POINTER_TYPE_P (ptr_sval->get_type ()));
3343
3344   /* If we're dereferencing PTR_SVAL, assume that it is non-NULL; add this
3345      as a constraint.  This suppresses false positives from
3346      -Wanalyzer-null-dereference for the case where we later have an
3347      if (PTR_SVAL) that would occur if we considered the false branch
3348      and transitioned the malloc state machine from start->null.  */
3349   tree null_ptr_cst = build_int_cst (ptr_sval->get_type (), 0);
3350   const svalue *null_ptr = m_mgr->get_or_create_constant_svalue (null_ptr_cst);
3351   m_constraints->add_constraint (ptr_sval, NE_EXPR, null_ptr);
3352
3353   switch (ptr_sval->get_kind ())
3354     {
3355     default:
3356       break;
3357
3358     case SK_REGION:
3359       {
3360         const region_svalue *region_sval
3361           = as_a <const region_svalue *> (ptr_sval);
3362         return region_sval->get_pointee ();
3363       }
3364
3365     case SK_BINOP:
3366       {
3367         const binop_svalue *binop_sval
3368           = as_a <const binop_svalue *> (ptr_sval);
3369         switch (binop_sval->get_op ())
3370           {
3371           case POINTER_PLUS_EXPR:
3372             {
3373               /* If we have a symbolic value expressing pointer arithmentic,
3374                  try to convert it to a suitable region.  */
3375               const region *parent_region
3376                 = deref_rvalue (binop_sval->get_arg0 (), NULL_TREE, ctxt);
3377               const svalue *offset = binop_sval->get_arg1 ();
3378               tree type= TREE_TYPE (ptr_sval->get_type ());
3379               return m_mgr->get_offset_region (parent_region, type, offset);
3380             }
3381           default:
3382             break;
3383           }
3384       }
3385       break;
3386
3387     case SK_POISONED:
3388       {
3389         if (ctxt)
3390           {
3391             tree ptr = get_representative_tree (ptr_sval);
3392             /* If we can't get a representative tree for PTR_SVAL
3393                (e.g. if it hasn't been bound into the store), then
3394                fall back on PTR_TREE, if non-NULL.  */
3395             if (!ptr)
3396               ptr = ptr_tree;
3397             if (ptr)
3398               {
3399                 const poisoned_svalue *poisoned_sval
3400                   = as_a <const poisoned_svalue *> (ptr_sval);
3401                 enum poison_kind pkind = poisoned_sval->get_poison_kind ();
3402                 ctxt->warn (make_unique<poisoned_value_diagnostic>
3403                               (ptr, pkind, NULL));
3404               }
3405           }
3406       }
3407       break;
3408     }
3409
3410   return m_mgr->get_symbolic_region (ptr_sval);
3411 }
3412
3413 /* Attempt to get BITS within any value of REG, as TYPE.
3414    In particular, extract values from compound_svalues for the case
3415    where there's a concrete binding at BITS.
3416    Return an unknown svalue if we can't handle the given case.
3417    Use CTXT to report any warnings associated with reading from REG.  */
3418
3419 const svalue *
3420 region_model::get_rvalue_for_bits (tree type,
3421                                    const region *reg,
3422                                    const bit_range &bits,
3423                                    region_model_context *ctxt) const
3424 {
3425   const svalue *sval = get_store_value (reg, ctxt);
3426   return m_mgr->get_or_create_bits_within (type, bits, sval);
3427 }
3428
3429 /* A subclass of pending_diagnostic for complaining about writes to
3430    constant regions of memory.  */
3431
3432 class write_to_const_diagnostic
3433 : public pending_diagnostic_subclass<write_to_const_diagnostic>
3434 {
3435 public:
3436   write_to_const_diagnostic (const region *reg, tree decl)
3437   : m_reg (reg), m_decl (decl)
3438   {}
3439
3440   const char *get_kind () const final override
3441   {
3442     return "write_to_const_diagnostic";
3443   }
3444
3445   bool operator== (const write_to_const_diagnostic &other) const
3446   {
3447     return (m_reg == other.m_reg
3448             && m_decl == other.m_decl);
3449   }
3450
3451   int get_controlling_option () const final override
3452   {
3453     return OPT_Wanalyzer_write_to_const;
3454   }
3455
3456   bool emit (rich_location *rich_loc) final override
3457   {
3458     auto_diagnostic_group d;
3459     bool warned;
3460     switch (m_reg->get_kind ())
3461       {
3462       default:
3463         warned = warning_at (rich_loc, get_controlling_option (),
3464                              "write to %<const%> object %qE", m_decl);
3465         break;
3466       case RK_FUNCTION:
3467         warned = warning_at (rich_loc, get_controlling_option (),
3468                              "write to function %qE", m_decl);
3469         break;
3470       case RK_LABEL:
3471         warned = warning_at (rich_loc, get_controlling_option (),
3472                              "write to label %qE", m_decl);
3473         break;
3474       }
3475     if (warned)
3476       inform (DECL_SOURCE_LOCATION (m_decl), "declared here");
3477     return warned;
3478   }
3479
3480   label_text describe_final_event (const evdesc::final_event &ev) final override
3481   {
3482     switch (m_reg->get_kind ())
3483       {
3484       default:
3485         return ev.formatted_print ("write to %<const%> object %qE here", m_decl);
3486       case RK_FUNCTION:
3487         return ev.formatted_print ("write to function %qE here", m_decl);
3488       case RK_LABEL:
3489         return ev.formatted_print ("write to label %qE here", m_decl);
3490       }
3491   }
3492
3493 private:
3494   const region *m_reg;
3495   tree m_decl;
3496 };
3497
3498 /* A subclass of pending_diagnostic for complaining about writes to
3499    string literals.  */
3500
3501 class write_to_string_literal_diagnostic
3502 : public pending_diagnostic_subclass<write_to_string_literal_diagnostic>
3503 {
3504 public:
3505   write_to_string_literal_diagnostic (const region *reg)
3506   : m_reg (reg)
3507   {}
3508
3509   const char *get_kind () const final override
3510   {
3511     return "write_to_string_literal_diagnostic";
3512   }
3513
3514   bool operator== (const write_to_string_literal_diagnostic &other) const
3515   {
3516     return m_reg == other.m_reg;
3517   }
3518
3519   int get_controlling_option () const final override
3520   {
3521     return OPT_Wanalyzer_write_to_string_literal;
3522   }
3523
3524   bool emit (rich_location *rich_loc) final override
3525   {
3526     return warning_at (rich_loc, get_controlling_option (),
3527                        "write to string literal");
3528     /* Ideally we would show the location of the STRING_CST as well,
3529        but it is not available at this point.  */
3530   }
3531
3532   label_text describe_final_event (const evdesc::final_event &ev) final override
3533   {
3534     return ev.formatted_print ("write to string literal here");
3535   }
3536
3537 private:
3538   const region *m_reg;
3539 };
3540
3541 /* Use CTXT to warn If DEST_REG is a region that shouldn't be written to.  */
3542
3543 void
3544 region_model::check_for_writable_region (const region* dest_reg,
3545                                          region_model_context *ctxt) const
3546 {
3547   /* Fail gracefully if CTXT is NULL.  */
3548   if (!ctxt)
3549     return;
3550
3551   const region *base_reg = dest_reg->get_base_region ();
3552   switch (base_reg->get_kind ())
3553     {
3554     default:
3555       break;
3556     case RK_FUNCTION:
3557       {
3558         const function_region *func_reg = as_a <const function_region *> (base_reg);
3559         tree fndecl = func_reg->get_fndecl ();
3560         ctxt->warn (make_unique<write_to_const_diagnostic>
3561                       (func_reg, fndecl));
3562       }
3563       break;
3564     case RK_LABEL:
3565       {
3566         const label_region *label_reg = as_a <const label_region *> (base_reg);
3567         tree label = label_reg->get_label ();
3568         ctxt->warn (make_unique<write_to_const_diagnostic>
3569                       (label_reg, label));
3570       }
3571       break;
3572     case RK_DECL:
3573       {
3574         const decl_region *decl_reg = as_a <const decl_region *> (base_reg);
3575         tree decl = decl_reg->get_decl ();
3576         /* Warn about writes to const globals.
3577            Don't warn for writes to const locals, and params in particular,
3578            since we would warn in push_frame when setting them up (e.g the
3579            "this" param is "T* const").  */
3580         if (TREE_READONLY (decl)
3581             && is_global_var (decl))
3582           ctxt->warn (make_unique<write_to_const_diagnostic> (dest_reg, decl));
3583       }
3584       break;
3585     case RK_STRING:
3586       ctxt->warn (make_unique<write_to_string_literal_diagnostic> (dest_reg));
3587       break;
3588     }
3589 }
3590
3591 /* Get the capacity of REG in bytes.  */
3592
3593 const svalue *
3594 region_model::get_capacity (const region *reg) const
3595 {
3596   switch (reg->get_kind ())
3597     {
3598     default:
3599       break;
3600     case RK_DECL:
3601       {
3602         const decl_region *decl_reg = as_a <const decl_region *> (reg);
3603         tree decl = decl_reg->get_decl ();
3604         if (TREE_CODE (decl) == SSA_NAME)
3605           {
3606             tree type = TREE_TYPE (decl);
3607             tree size = TYPE_SIZE (type);
3608             return get_rvalue (size, NULL);
3609           }
3610         else
3611           {
3612             tree size = decl_init_size (decl, false);
3613             if (size)
3614               return get_rvalue (size, NULL);
3615           }
3616       }
3617       break;
3618     case RK_SIZED:
3619       /* Look through sized regions to get at the capacity
3620          of the underlying regions.  */
3621       return get_capacity (reg->get_parent_region ());
3622     }
3623
3624   if (const svalue *recorded = get_dynamic_extents (reg))
3625     return recorded;
3626
3627   return m_mgr->get_or_create_unknown_svalue (sizetype);
3628 }
3629
3630 /* Return the string size, including the 0-terminator, if SVAL is a
3631    constant_svalue holding a string.  Otherwise, return an unknown_svalue.  */
3632
3633 const svalue *
3634 region_model::get_string_size (const svalue *sval) const
3635 {
3636   tree cst = sval->maybe_get_constant ();
3637   if (!cst || TREE_CODE (cst) != STRING_CST)
3638     return m_mgr->get_or_create_unknown_svalue (size_type_node);
3639
3640   tree out = build_int_cst (size_type_node, TREE_STRING_LENGTH (cst));
3641   return m_mgr->get_or_create_constant_svalue (out);
3642 }
3643
3644 /* Return the string size, including the 0-terminator, if REG is a
3645    string_region.  Otherwise, return an unknown_svalue.  */
3646
3647 const svalue *
3648 region_model::get_string_size (const region *reg) const
3649 {
3650   const string_region *str_reg = dyn_cast <const string_region *> (reg);
3651   if (!str_reg)
3652     return m_mgr->get_or_create_unknown_svalue (size_type_node);
3653
3654   tree cst = str_reg->get_string_cst ();
3655   tree out = build_int_cst (size_type_node, TREE_STRING_LENGTH (cst));
3656   return m_mgr->get_or_create_constant_svalue (out);
3657 }
3658
3659 /* If CTXT is non-NULL, use it to warn about any problems accessing REG,
3660    using DIR to determine if this access is a read or write.  */
3661
3662 void
3663 region_model::check_region_access (const region *reg,
3664                                    enum access_direction dir,
3665                                    region_model_context *ctxt) const
3666 {
3667   /* Fail gracefully if CTXT is NULL.  */
3668   if (!ctxt)
3669     return;
3670
3671   check_region_for_taint (reg, dir, ctxt);
3672   check_region_bounds (reg, dir, ctxt);
3673
3674   switch (dir)
3675     {
3676     default:
3677       gcc_unreachable ();
3678     case DIR_READ:
3679       /* Currently a no-op.  */
3680       break;
3681     case DIR_WRITE:
3682       check_for_writable_region (reg, ctxt);
3683       break;
3684     }
3685 }
3686
3687 /* If CTXT is non-NULL, use it to warn about any problems writing to REG.  */
3688
3689 void
3690 region_model::check_region_for_write (const region *dest_reg,
3691                                       region_model_context *ctxt) const
3692 {
3693   check_region_access (dest_reg, DIR_WRITE, ctxt);
3694 }
3695
3696 /* If CTXT is non-NULL, use it to warn about any problems reading from REG.  */
3697
3698 void
3699 region_model::check_region_for_read (const region *src_reg,
3700                                      region_model_context *ctxt) const
3701 {
3702   check_region_access (src_reg, DIR_READ, ctxt);
3703 }
3704
3705 /* Concrete subclass for casts of pointers that lead to trailing bytes.  */
3706
3707 class dubious_allocation_size
3708 : public pending_diagnostic_subclass<dubious_allocation_size>
3709 {
3710 public:
3711   dubious_allocation_size (const region *lhs, const region *rhs)
3712   : m_lhs (lhs), m_rhs (rhs), m_expr (NULL_TREE)
3713   {}
3714
3715   dubious_allocation_size (const region *lhs, const region *rhs,
3716                            tree expr)
3717   : m_lhs (lhs), m_rhs (rhs), m_expr (expr)
3718   {}
3719
3720   const char *get_kind () const final override
3721   {
3722     return "dubious_allocation_size";
3723   }
3724
3725   bool operator== (const dubious_allocation_size &other) const
3726   {
3727     return m_lhs == other.m_lhs && m_rhs == other.m_rhs
3728            && pending_diagnostic::same_tree_p (m_expr, other.m_expr);
3729   }
3730
3731   int get_controlling_option () const final override
3732   {
3733     return OPT_Wanalyzer_allocation_size;
3734   }
3735
3736   bool emit (rich_location *rich_loc) final override
3737   {
3738     diagnostic_metadata m;
3739     m.add_cwe (131);
3740
3741     return warning_meta (rich_loc, m, get_controlling_option (),
3742                          "allocated buffer size is not a multiple"
3743                          " of the pointee's size");
3744   }
3745
3746   label_text
3747   describe_region_creation_event (const evdesc::region_creation &ev) final
3748   override
3749   {
3750     m_allocation_event = &ev;
3751     if (m_expr)
3752       {
3753         if (TREE_CODE (m_expr) == INTEGER_CST)
3754           return ev.formatted_print ("allocated %E bytes here", m_expr);
3755         else
3756           return ev.formatted_print ("allocated %qE bytes here", m_expr);
3757       }
3758
3759     return ev.formatted_print ("allocated here");
3760   }
3761
3762   label_text describe_final_event (const evdesc::final_event &ev) final
3763   override
3764   {
3765     tree pointee_type = TREE_TYPE (m_lhs->get_type ());
3766     if (m_allocation_event)
3767       /* Fallback: Typically, we should always
3768          see an m_allocation_event before.  */
3769       return ev.formatted_print ("assigned to %qT here;"
3770                                  " %<sizeof (%T)%> is %qE",
3771                                  m_lhs->get_type (), pointee_type,
3772                                  size_in_bytes (pointee_type));
3773
3774     if (m_expr)
3775       {
3776         if (TREE_CODE (m_expr) == INTEGER_CST)
3777           return ev.formatted_print ("allocated %E bytes and assigned to"
3778                                     " %qT here; %<sizeof (%T)%> is %qE",
3779                                     m_expr, m_lhs->get_type (), pointee_type,
3780                                     size_in_bytes (pointee_type));
3781         else
3782           return ev.formatted_print ("allocated %qE bytes and assigned to"
3783                                     " %qT here; %<sizeof (%T)%> is %qE",
3784                                     m_expr, m_lhs->get_type (), pointee_type,
3785                                     size_in_bytes (pointee_type));
3786       }
3787
3788     return ev.formatted_print ("allocated and assigned to %qT here;"
3789                                " %<sizeof (%T)%> is %qE",
3790                                m_lhs->get_type (), pointee_type,
3791                                size_in_bytes (pointee_type));
3792   }
3793
3794   void mark_interesting_stuff (interesting_t *interest) final override
3795   {
3796     interest->add_region_creation (m_rhs);
3797   }
3798
3799 private:
3800   const region *m_lhs;
3801   const region *m_rhs;
3802   const tree m_expr;
3803   const evdesc::region_creation *m_allocation_event;
3804 };
3805
3806 /* Return true on dubious allocation sizes for constant sizes.  */
3807
3808 static bool
3809 capacity_compatible_with_type (tree cst, tree pointee_size_tree,
3810                                bool is_struct)
3811 {
3812   gcc_assert (TREE_CODE (cst) == INTEGER_CST);
3813   gcc_assert (TREE_CODE (pointee_size_tree) == INTEGER_CST);
3814
3815   unsigned HOST_WIDE_INT pointee_size = TREE_INT_CST_LOW (pointee_size_tree);
3816   unsigned HOST_WIDE_INT alloc_size = TREE_INT_CST_LOW (cst);
3817
3818   if (is_struct)
3819     return alloc_size == 0 || alloc_size >= pointee_size;
3820   return alloc_size % pointee_size == 0;
3821 }
3822
3823 static bool
3824 capacity_compatible_with_type (tree cst, tree pointee_size_tree)
3825 {
3826   return capacity_compatible_with_type (cst, pointee_size_tree, false);
3827 }
3828
3829 /* Checks whether SVAL could be a multiple of SIZE_CST.
3830
3831    It works by visiting all svalues inside SVAL until it reaches
3832    atomic nodes.  From those, it goes back up again and adds each
3833    node that might be a multiple of SIZE_CST to the RESULT_SET.  */
3834
3835 class size_visitor : public visitor
3836 {
3837 public:
3838   size_visitor (tree size_cst, const svalue *root_sval, constraint_manager *cm)
3839   : m_size_cst (size_cst), m_root_sval (root_sval), m_cm (cm)
3840   {
3841     m_root_sval->accept (this);
3842   }
3843
3844   bool get_result ()
3845   {
3846     return result_set.contains (m_root_sval);
3847   }
3848
3849   void visit_constant_svalue (const constant_svalue *sval) final override
3850   {
3851     check_constant (sval->get_constant (), sval);
3852   }
3853
3854   void visit_unknown_svalue (const unknown_svalue *sval ATTRIBUTE_UNUSED)
3855     final override
3856   {
3857     result_set.add (sval);
3858   }
3859
3860   void visit_poisoned_svalue (const poisoned_svalue *sval ATTRIBUTE_UNUSED)
3861     final override
3862   {
3863     result_set.add (sval);
3864   }
3865
3866   void visit_unaryop_svalue (const unaryop_svalue *sval) final override
3867   {
3868     const svalue *arg = sval->get_arg ();
3869     if (result_set.contains (arg))
3870       result_set.add (sval);
3871   }
3872
3873   void visit_binop_svalue (const binop_svalue *sval) final override
3874   {
3875     const svalue *arg0 = sval->get_arg0 ();
3876     const svalue *arg1 = sval->get_arg1 ();
3877
3878     if (sval->get_op () == MULT_EXPR)
3879       {
3880         if (result_set.contains (arg0) || result_set.contains (arg1))
3881           result_set.add (sval);
3882       }
3883     else
3884       {
3885         if (result_set.contains (arg0) && result_set.contains (arg1))
3886           result_set.add (sval);
3887       }
3888   }
3889
3890   void visit_repeated_svalue (const repeated_svalue *sval) final override
3891   {
3892     sval->get_inner_svalue ()->accept (this);
3893     if (result_set.contains (sval->get_inner_svalue ()))
3894       result_set.add (sval);
3895   }
3896
3897   void visit_unmergeable_svalue (const unmergeable_svalue *sval) final override
3898   {
3899     sval->get_arg ()->accept (this);
3900     if (result_set.contains (sval->get_arg ()))
3901       result_set.add (sval);
3902   }
3903
3904   void visit_widening_svalue (const widening_svalue *sval) final override
3905   {
3906     const svalue *base = sval->get_base_svalue ();
3907     const svalue *iter = sval->get_iter_svalue ();
3908
3909     if (result_set.contains (base) && result_set.contains (iter))
3910       result_set.add (sval);
3911   }
3912
3913   void visit_conjured_svalue (const conjured_svalue *sval ATTRIBUTE_UNUSED)
3914     final override
3915   {
3916     equiv_class_id id (-1);
3917     if (m_cm->get_equiv_class_by_svalue (sval, &id))
3918       {
3919         if (tree cst = id.get_obj (*m_cm).get_any_constant ())
3920           check_constant (cst, sval);
3921         else
3922           result_set.add (sval);
3923       }
3924   }
3925
3926   void visit_asm_output_svalue (const asm_output_svalue *sval ATTRIBUTE_UNUSED)
3927     final override
3928   {
3929     result_set.add (sval);
3930   }
3931
3932   void visit_const_fn_result_svalue (const const_fn_result_svalue
3933                                       *sval ATTRIBUTE_UNUSED) final override
3934   {
3935     result_set.add (sval);
3936   }
3937
3938 private:
3939   void check_constant (tree cst, const svalue *sval)
3940   {
3941     switch (TREE_CODE (cst))
3942       {
3943       default:
3944         /* Assume all unhandled operands are compatible.  */
3945         result_set.add (sval);
3946         break;
3947       case INTEGER_CST:
3948         if (capacity_compatible_with_type (cst, m_size_cst))
3949           result_set.add (sval);
3950         break;
3951       }
3952   }
3953
3954   tree m_size_cst;
3955   const svalue *m_root_sval;
3956   constraint_manager *m_cm;
3957   svalue_set result_set; /* Used as a mapping of svalue*->bool.  */
3958 };
3959
3960 /* Return true if a struct or union either uses the inheritance pattern,
3961    where the first field is a base struct, or the flexible array member
3962    pattern, where the last field is an array without a specified size.  */
3963
3964 static bool
3965 struct_or_union_with_inheritance_p (tree struc)
3966 {
3967   tree iter = TYPE_FIELDS (struc);
3968   if (iter == NULL_TREE)
3969           return false;
3970   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (iter)))
3971           return true;
3972
3973   tree last_field;
3974   while (iter != NULL_TREE)
3975     {
3976       last_field = iter;
3977       iter = DECL_CHAIN (iter);
3978     }
3979
3980   if (last_field != NULL_TREE
3981       && TREE_CODE (TREE_TYPE (last_field)) == ARRAY_TYPE)
3982           return true;
3983
3984   return false;
3985 }
3986
3987 /* Return true if the lhs and rhs of an assignment have different types.  */
3988
3989 static bool
3990 is_any_cast_p (const gimple *stmt)
3991 {
3992   if (const gassign *assign = dyn_cast <const gassign *> (stmt))
3993     return gimple_assign_cast_p (assign)
3994            || !pending_diagnostic::same_tree_p (
3995                   TREE_TYPE (gimple_assign_lhs (assign)),
3996                   TREE_TYPE (gimple_assign_rhs1 (assign)));
3997   else if (const gcall *call = dyn_cast <const gcall *> (stmt))
3998     {
3999       tree lhs = gimple_call_lhs (call);
4000       return lhs != NULL_TREE && !pending_diagnostic::same_tree_p (
4001                                     TREE_TYPE (gimple_call_lhs (call)),
4002                                     gimple_call_return_type (call));
4003     }
4004
4005   return false;
4006 }
4007
4008 /* On pointer assignments, check whether the buffer size of
4009    RHS_SVAL is compatible with the type of the LHS_REG.
4010    Use a non-null CTXT to report allocation size warnings.  */
4011
4012 void
4013 region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval,
4014                                  region_model_context *ctxt) const
4015 {
4016   if (!ctxt || ctxt->get_stmt () == NULL)
4017     return;
4018   /* Only report warnings on assignments that actually change the type.  */
4019   if (!is_any_cast_p (ctxt->get_stmt ()))
4020     return;
4021
4022   const region_svalue *reg_sval = dyn_cast <const region_svalue *> (rhs_sval);
4023   if (!reg_sval)
4024     return;
4025
4026   tree pointer_type = lhs_reg->get_type ();
4027   if (pointer_type == NULL_TREE || !POINTER_TYPE_P (pointer_type))
4028     return;
4029
4030   tree pointee_type = TREE_TYPE (pointer_type);
4031   /* Make sure that the type on the left-hand size actually has a size.  */
4032   if (pointee_type == NULL_TREE || VOID_TYPE_P (pointee_type)
4033       || TYPE_SIZE_UNIT (pointee_type) == NULL_TREE)
4034     return;
4035
4036   /* Bail out early on pointers to structs where we can
4037      not deduce whether the buffer size is compatible.  */
4038   bool is_struct = RECORD_OR_UNION_TYPE_P (pointee_type);
4039   if (is_struct && struct_or_union_with_inheritance_p (pointee_type))
4040     return;
4041
4042   tree pointee_size_tree = size_in_bytes (pointee_type);
4043   /* We give up if the type size is not known at compile-time or the
4044      type size is always compatible regardless of the buffer size.  */
4045   if (TREE_CODE (pointee_size_tree) != INTEGER_CST
4046       || integer_zerop (pointee_size_tree)
4047       || integer_onep (pointee_size_tree))
4048     return;
4049
4050   const region *rhs_reg = reg_sval->get_pointee ();
4051   const svalue *capacity = get_capacity (rhs_reg);
4052   switch (capacity->get_kind ())
4053     {
4054     case svalue_kind::SK_CONSTANT:
4055       {
4056         const constant_svalue *cst_cap_sval
4057           = as_a <const constant_svalue *> (capacity);
4058         tree cst_cap = cst_cap_sval->get_constant ();
4059         if (TREE_CODE (cst_cap) == INTEGER_CST
4060             && !capacity_compatible_with_type (cst_cap, pointee_size_tree,
4061                                                is_struct))
4062           ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg, rhs_reg,
4063                                                              cst_cap));
4064       }
4065       break;
4066     default:
4067       {
4068         if (!is_struct)
4069           {
4070             size_visitor v (pointee_size_tree, capacity, m_constraints);
4071             if (!v.get_result ())
4072               {
4073                 tree expr = get_representative_tree (capacity);
4074                 ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg,
4075                                                                    rhs_reg,
4076                                                                    expr));
4077               }
4078           }
4079       break;
4080       }
4081     }
4082 }
4083
4084 /* Set the value of the region given by LHS_REG to the value given
4085    by RHS_SVAL.
4086    Use CTXT to report any warnings associated with writing to LHS_REG.  */
4087
4088 void
4089 region_model::set_value (const region *lhs_reg, const svalue *rhs_sval,
4090                          region_model_context *ctxt)
4091 {
4092   gcc_assert (lhs_reg);
4093   gcc_assert (rhs_sval);
4094
4095   check_region_size (lhs_reg, rhs_sval, ctxt);
4096
4097   check_region_for_write (lhs_reg, ctxt);
4098
4099   m_store.set_value (m_mgr->get_store_manager(), lhs_reg, rhs_sval,
4100                      ctxt ? ctxt->get_uncertainty () : NULL);
4101 }
4102
4103 /* Set the value of the region given by LHS to the value given by RHS.  */
4104
4105 void
4106 region_model::set_value (tree lhs, tree rhs, region_model_context *ctxt)
4107 {
4108   const region *lhs_reg = get_lvalue (lhs, ctxt);
4109   const svalue *rhs_sval = get_rvalue (rhs, ctxt);
4110   gcc_assert (lhs_reg);
4111   gcc_assert (rhs_sval);
4112   set_value (lhs_reg, rhs_sval, ctxt);
4113 }
4114
4115 /* Remove all bindings overlapping REG within the store.  */
4116
4117 void
4118 region_model::clobber_region (const region *reg)
4119 {
4120   m_store.clobber_region (m_mgr->get_store_manager(), reg);
4121 }
4122
4123 /* Remove any bindings for REG within the store.  */
4124
4125 void
4126 region_model::purge_region (const region *reg)
4127 {
4128   m_store.purge_region (m_mgr->get_store_manager(), reg);
4129 }
4130
4131 /* Fill REG with SVAL.  */
4132
4133 void
4134 region_model::fill_region (const region *reg, const svalue *sval)
4135 {
4136   m_store.fill_region (m_mgr->get_store_manager(), reg, sval);
4137 }
4138
4139 /* Zero-fill REG.  */
4140
4141 void
4142 region_model::zero_fill_region (const region *reg)
4143 {
4144   m_store.zero_fill_region (m_mgr->get_store_manager(), reg);
4145 }
4146
4147 /* Mark REG as having unknown content.  */
4148
4149 void
4150 region_model::mark_region_as_unknown (const region *reg,
4151                                       uncertainty_t *uncertainty)
4152 {
4153   m_store.mark_region_as_unknown (m_mgr->get_store_manager(), reg,
4154                                   uncertainty);
4155 }
4156
4157 /* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within
4158    this model.  */
4159
4160 tristate
4161 region_model::eval_condition (const svalue *lhs,
4162                                enum tree_code op,
4163                                const svalue *rhs) const
4164 {
4165   /* For now, make no attempt to capture constraints on floating-point
4166      values.  */
4167   if ((lhs->get_type () && FLOAT_TYPE_P (lhs->get_type ()))
4168       || (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ())))
4169     return tristate::unknown ();
4170
4171   tristate ts = eval_condition_without_cm (lhs, op, rhs);
4172   if (ts.is_known ())
4173     return ts;
4174
4175   /* Otherwise, try constraints.  */
4176   return m_constraints->eval_condition (lhs, op, rhs);
4177 }
4178
4179 /* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within
4180    this model, without resorting to the constraint_manager.
4181
4182    This is exposed so that impl_region_model_context::on_state_leak can
4183    check for equality part-way through region_model::purge_unused_svalues
4184    without risking creating new ECs.  */
4185
4186 tristate
4187 region_model::eval_condition_without_cm (const svalue *lhs,
4188                                           enum tree_code op,
4189                                           const svalue *rhs) const
4190 {
4191   gcc_assert (lhs);
4192   gcc_assert (rhs);
4193
4194   /* See what we know based on the values.  */
4195
4196   /* For now, make no attempt to capture constraints on floating-point
4197      values.  */
4198   if ((lhs->get_type () && FLOAT_TYPE_P (lhs->get_type ()))
4199       || (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ())))
4200     return tristate::unknown ();
4201
4202   /* Unwrap any unmergeable values.  */
4203   lhs = lhs->unwrap_any_unmergeable ();
4204   rhs = rhs->unwrap_any_unmergeable ();
4205
4206   if (lhs == rhs)
4207     {
4208       /* If we have the same svalue, then we have equality
4209          (apart from NaN-handling).
4210          TODO: should this definitely be the case for poisoned values?  */
4211       /* Poisoned and unknown values are "unknowable".  */
4212       if (lhs->get_kind () == SK_POISONED
4213           || lhs->get_kind () == SK_UNKNOWN)
4214         return tristate::TS_UNKNOWN;
4215
4216       switch (op)
4217         {
4218         case EQ_EXPR:
4219         case GE_EXPR:
4220         case LE_EXPR:
4221           return tristate::TS_TRUE;
4222
4223         case NE_EXPR:
4224         case GT_EXPR:
4225         case LT_EXPR:
4226           return tristate::TS_FALSE;
4227
4228         default:
4229           /* For other ops, use the logic below.  */
4230           break;
4231         }
4232     }
4233
4234   /* If we have a pair of region_svalues, compare them.  */
4235   if (const region_svalue *lhs_ptr = lhs->dyn_cast_region_svalue ())
4236     if (const region_svalue *rhs_ptr = rhs->dyn_cast_region_svalue ())
4237       {
4238         tristate res = region_svalue::eval_condition (lhs_ptr, op, rhs_ptr);
4239         if (res.is_known ())
4240           return res;
4241         /* Otherwise, only known through constraints.  */
4242       }
4243
4244   if (const constant_svalue *cst_lhs = lhs->dyn_cast_constant_svalue ())
4245     {
4246       /* If we have a pair of constants, compare them.  */
4247       if (const constant_svalue *cst_rhs = rhs->dyn_cast_constant_svalue ())
4248         return constant_svalue::eval_condition (cst_lhs, op, cst_rhs);
4249       else
4250         {
4251           /* When we have one constant, put it on the RHS.  */
4252           std::swap (lhs, rhs);
4253           op = swap_tree_comparison (op);
4254         }
4255     }
4256   gcc_assert (lhs->get_kind () != SK_CONSTANT);
4257
4258   /* Handle comparison against zero.  */
4259   if (const constant_svalue *cst_rhs = rhs->dyn_cast_constant_svalue ())
4260     if (zerop (cst_rhs->get_constant ()))
4261       {
4262         if (const region_svalue *ptr = lhs->dyn_cast_region_svalue ())
4263           {
4264             /* A region_svalue is a non-NULL pointer, except in certain
4265                special cases (see the comment for region::non_null_p).  */
4266             const region *pointee = ptr->get_pointee ();
4267             if (pointee->non_null_p ())
4268               {
4269                 switch (op)
4270                   {
4271                   default:
4272                     gcc_unreachable ();
4273
4274                   case EQ_EXPR:
4275                   case GE_EXPR:
4276                   case LE_EXPR:
4277                     return tristate::TS_FALSE;
4278
4279                   case NE_EXPR:
4280                   case GT_EXPR:
4281                   case LT_EXPR:
4282                     return tristate::TS_TRUE;
4283                   }
4284               }
4285           }
4286         else if (const binop_svalue *binop = lhs->dyn_cast_binop_svalue ())
4287           {
4288             /* Treat offsets from a non-NULL pointer as being non-NULL.  This
4289                isn't strictly true, in that eventually ptr++ will wrap
4290                around and be NULL, but it won't occur in practise and thus
4291                can be used to suppress effectively false positives that we
4292                shouldn't warn for.  */
4293             if (binop->get_op () == POINTER_PLUS_EXPR)
4294               {
4295                 tristate lhs_ts
4296                   = eval_condition_without_cm (binop->get_arg0 (),
4297                                                op, rhs);
4298                 if (lhs_ts.is_known ())
4299                   return lhs_ts;
4300               }
4301           }
4302       }
4303
4304   /* Handle rejection of equality for comparisons of the initial values of
4305      "external" values (such as params) with the address of locals.  */
4306   if (const initial_svalue *init_lhs = lhs->dyn_cast_initial_svalue ())
4307     if (const region_svalue *rhs_ptr = rhs->dyn_cast_region_svalue ())
4308       {
4309         tristate res = compare_initial_and_pointer (init_lhs, rhs_ptr);
4310         if (res.is_known ())
4311           return res;
4312       }
4313   if (const initial_svalue *init_rhs = rhs->dyn_cast_initial_svalue ())
4314     if (const region_svalue *lhs_ptr = lhs->dyn_cast_region_svalue ())
4315       {
4316         tristate res = compare_initial_and_pointer (init_rhs, lhs_ptr);
4317         if (res.is_known ())
4318           return res;
4319       }
4320
4321   if (const widening_svalue *widen_lhs = lhs->dyn_cast_widening_svalue ())
4322     if (tree rhs_cst = rhs->maybe_get_constant ())
4323       {
4324         tristate res = widen_lhs->eval_condition_without_cm (op, rhs_cst);
4325         if (res.is_known ())
4326           return res;
4327       }
4328
4329   /* Handle comparisons between two svalues with more than one operand.  */
4330         if (const binop_svalue *binop = lhs->dyn_cast_binop_svalue ())
4331     {
4332       switch (op)
4333         {
4334         default:
4335           break;
4336         case EQ_EXPR:
4337           {
4338             /* TODO: binops can be equal even if they are not structurally
4339                      equal in case of commutative operators.  */
4340             tristate res = structural_equality (lhs, rhs);
4341             if (res.is_true ())
4342               return res;
4343           }
4344           break;
4345         case LE_EXPR:
4346           {
4347             tristate res = structural_equality (lhs, rhs);
4348             if (res.is_true ())
4349               return res;
4350           }
4351           break;
4352         case GE_EXPR:
4353           {
4354             tristate res = structural_equality (lhs, rhs);
4355             if (res.is_true ())
4356               return res;
4357             res = symbolic_greater_than (binop, rhs);
4358             if (res.is_true ())
4359               return res;
4360           }
4361           break;
4362         case GT_EXPR:
4363           {
4364             tristate res = symbolic_greater_than (binop, rhs);
4365             if (res.is_true ())
4366               return res;
4367           }
4368           break;
4369         }
4370     }
4371
4372   return tristate::TS_UNKNOWN;
4373 }
4374
4375 /* Subroutine of region_model::eval_condition_without_cm, for rejecting
4376    equality of INIT_VAL(PARM) with &LOCAL.  */
4377
4378 tristate
4379 region_model::compare_initial_and_pointer (const initial_svalue *init,
4380                                             const region_svalue *ptr) const
4381 {
4382   const region *pointee = ptr->get_pointee ();
4383
4384   /* If we have a pointer to something within a stack frame, it can't be the
4385      initial value of a param.  */
4386   if (pointee->maybe_get_frame_region ())
4387     if (init->initial_value_of_param_p ())
4388       return tristate::TS_FALSE;
4389
4390   return tristate::TS_UNKNOWN;
4391 }
4392
4393 /* Return true if SVAL is definitely positive.  */
4394
4395 static bool
4396 is_positive_svalue (const svalue *sval)
4397 {
4398   if (tree cst = sval->maybe_get_constant ())
4399     return !zerop (cst) && get_range_pos_neg (cst) == 1;
4400   tree type = sval->get_type ();
4401   if (!type)
4402     return false;
4403   /* Consider a binary operation size_t + int.  The analyzer wraps the int in
4404      an unaryop_svalue, converting it to a size_t, but in the dynamic execution
4405      the result is smaller than the first operand.  Thus, we have to look if
4406      the argument of the unaryop_svalue is also positive.  */
4407   if (const unaryop_svalue *un_op = dyn_cast <const unaryop_svalue *> (sval))
4408     return CONVERT_EXPR_CODE_P (un_op->get_op ()) && TYPE_UNSIGNED (type)
4409            && is_positive_svalue (un_op->get_arg ());
4410   return TYPE_UNSIGNED (type);
4411 }
4412
4413 /* Return true if A is definitely larger than B.
4414
4415    Limitation: does not account for integer overflows and does not try to
4416                return false, so it can not be used negated.  */
4417
4418 tristate
4419 region_model::symbolic_greater_than (const binop_svalue *bin_a,
4420                                      const svalue *b) const
4421 {
4422   if (bin_a->get_op () == PLUS_EXPR || bin_a->get_op () == MULT_EXPR)
4423     {
4424       /* Eliminate the right-hand side of both svalues.  */
4425       if (const binop_svalue *bin_b = dyn_cast <const binop_svalue *> (b))
4426         if (bin_a->get_op () == bin_b->get_op ()
4427             && eval_condition_without_cm (bin_a->get_arg1 (),
4428                                           GT_EXPR,
4429                                           bin_b->get_arg1 ()).is_true ()
4430             && eval_condition_without_cm (bin_a->get_arg0 (),
4431                                           GE_EXPR,
4432                                           bin_b->get_arg0 ()).is_true ())
4433           return tristate (tristate::TS_TRUE);
4434
4435       /* Otherwise, try to remove a positive offset or factor from BIN_A.  */
4436       if (is_positive_svalue (bin_a->get_arg1 ())
4437           && eval_condition_without_cm (bin_a->get_arg0 (),
4438                                         GE_EXPR, b).is_true ())
4439           return tristate (tristate::TS_TRUE);
4440     }
4441   return tristate::unknown ();
4442 }
4443
4444 /* Return true if A and B are equal structurally.
4445
4446    Structural equality means that A and B are equal if the svalues A and B have
4447    the same nodes at the same positions in the tree and the leafs are equal.
4448    Equality for conjured_svalues and initial_svalues is determined by comparing
4449    the pointers while constants are compared by value.  That behavior is useful
4450    to check for binaryop_svlaues that evaluate to the same concrete value but
4451    might use one operand with a different type but the same constant value.
4452
4453    For example,
4454      binop_svalue (mult_expr,
4455        initial_svalue (‘size_t’, decl_region (..., 'some_var')),
4456        constant_svalue (‘size_t’, 4))
4457    and
4458      binop_svalue (mult_expr,
4459        initial_svalue (‘size_t’, decl_region (..., 'some_var'),
4460        constant_svalue (‘sizetype’, 4))
4461    are structurally equal.  A concrete C code example, where this occurs, can
4462    be found in test7 of out-of-bounds-5.c.  */
4463
4464 tristate
4465 region_model::structural_equality (const svalue *a, const svalue *b) const
4466 {
4467   /* If A and B are referentially equal, they are also structurally equal.  */
4468   if (a == b)
4469     return tristate (tristate::TS_TRUE);
4470
4471   switch (a->get_kind ())
4472     {
4473     default:
4474       return tristate::unknown ();
4475     /* SK_CONJURED and SK_INITIAL are already handled
4476        by the referential equality above.  */
4477     case SK_CONSTANT:
4478       {
4479         tree a_cst = a->maybe_get_constant ();
4480         tree b_cst = b->maybe_get_constant ();
4481         if (a_cst && b_cst)
4482           return tristate (tree_int_cst_equal (a_cst, b_cst));
4483       }
4484       return tristate (tristate::TS_FALSE);
4485     case SK_UNARYOP:
4486       {
4487         const unaryop_svalue *un_a = as_a <const unaryop_svalue *> (a);
4488         if (const unaryop_svalue *un_b = dyn_cast <const unaryop_svalue *> (b))
4489           return tristate (pending_diagnostic::same_tree_p (un_a->get_type (),
4490                                                             un_b->get_type ())
4491                            && un_a->get_op () == un_b->get_op ()
4492                            && structural_equality (un_a->get_arg (),
4493                                                    un_b->get_arg ()));
4494       }
4495       return tristate (tristate::TS_FALSE);
4496     case SK_BINOP:
4497       {
4498         const binop_svalue *bin_a = as_a <const binop_svalue *> (a);
4499         if (const binop_svalue *bin_b = dyn_cast <const binop_svalue *> (b))
4500           return tristate (bin_a->get_op () == bin_b->get_op ()
4501                            && structural_equality (bin_a->get_arg0 (),
4502                                                    bin_b->get_arg0 ())
4503                            && structural_equality (bin_a->get_arg1 (),
4504                                                    bin_b->get_arg1 ()));
4505       }
4506       return tristate (tristate::TS_FALSE);
4507     }
4508 }
4509
4510 /* Handle various constraints of the form:
4511      LHS: ((bool)INNER_LHS INNER_OP INNER_RHS))
4512      OP : == or !=
4513      RHS: zero
4514    and (with a cast):
4515      LHS: CAST([long]int, ((bool)INNER_LHS INNER_OP INNER_RHS))
4516      OP : == or !=
4517      RHS: zero
4518    by adding constraints for INNER_LHS INNEROP INNER_RHS.
4519
4520    Return true if this function can fully handle the constraint; if
4521    so, add the implied constraint(s) and write true to *OUT if they
4522    are consistent with existing constraints, or write false to *OUT
4523    if they contradicts existing constraints.
4524
4525    Return false for cases that this function doeesn't know how to handle.
4526
4527    For example, if we're checking a stored conditional, we'll have
4528    something like:
4529      LHS: CAST(long int, (&HEAP_ALLOCATED_REGION(8)!=(int *)0B))
4530      OP : NE_EXPR
4531      RHS: zero
4532    which this function can turn into an add_constraint of:
4533      (&HEAP_ALLOCATED_REGION(8) != (int *)0B)
4534
4535    Similarly, optimized && and || conditionals lead to e.g.
4536      if (p && q)
4537    becoming gimple like this:
4538      _1 = p_6 == 0B;
4539      _2 = q_8 == 0B
4540      _3 = _1 | _2
4541    On the "_3 is false" branch we can have constraints of the form:
4542      ((&HEAP_ALLOCATED_REGION(8)!=(int *)0B)
4543       | (&HEAP_ALLOCATED_REGION(10)!=(int *)0B))
4544      == 0
4545    which implies that both _1 and _2 are false,
4546    which this function can turn into a pair of add_constraints of
4547      (&HEAP_ALLOCATED_REGION(8)!=(int *)0B)
4548    and:
4549      (&HEAP_ALLOCATED_REGION(10)!=(int *)0B).  */
4550
4551 bool
4552 region_model::add_constraints_from_binop (const svalue *outer_lhs,
4553                                           enum tree_code outer_op,
4554                                           const svalue *outer_rhs,
4555                                           bool *out,
4556                                           region_model_context *ctxt)
4557 {
4558   while (const svalue *cast = outer_lhs->maybe_undo_cast ())
4559     outer_lhs = cast;
4560   const binop_svalue *binop_sval = outer_lhs->dyn_cast_binop_svalue ();
4561   if (!binop_sval)
4562     return false;
4563   if (!outer_rhs->all_zeroes_p ())
4564     return false;
4565
4566   const svalue *inner_lhs = binop_sval->get_arg0 ();
4567   enum tree_code inner_op = binop_sval->get_op ();
4568   const svalue *inner_rhs = binop_sval->get_arg1 ();
4569
4570   if (outer_op != NE_EXPR && outer_op != EQ_EXPR)
4571     return false;
4572
4573   /* We have either
4574      - "OUTER_LHS != false" (i.e. OUTER is true), or
4575      - "OUTER_LHS == false" (i.e. OUTER is false).  */
4576   bool is_true = outer_op == NE_EXPR;
4577
4578   switch (inner_op)
4579     {
4580     default:
4581       return false;
4582
4583     case EQ_EXPR:
4584     case NE_EXPR:
4585       {
4586         /* ...and "(inner_lhs OP inner_rhs) == 0"
4587            then (inner_lhs OP inner_rhs) must have the same
4588            logical value as LHS.  */
4589         if (!is_true)
4590           inner_op = invert_tree_comparison (inner_op, false /* honor_nans */);
4591         *out = add_constraint (inner_lhs, inner_op, inner_rhs, ctxt);
4592         return true;
4593       }
4594       break;
4595
4596     case BIT_AND_EXPR:
4597       if (is_true)
4598         {
4599           /* ...and "(inner_lhs & inner_rhs) != 0"
4600              then both inner_lhs and inner_rhs must be true.  */
4601           const svalue *false_sval
4602             = m_mgr->get_or_create_constant_svalue (boolean_false_node);
4603           bool sat1 = add_constraint (inner_lhs, NE_EXPR, false_sval, ctxt);
4604           bool sat2 = add_constraint (inner_rhs, NE_EXPR, false_sval, ctxt);
4605           *out = sat1 && sat2;
4606           return true;
4607         }
4608       return false;
4609
4610     case BIT_IOR_EXPR:
4611       if (!is_true)
4612         {
4613           /* ...and "(inner_lhs | inner_rhs) == 0"
4614              i.e. "(inner_lhs | inner_rhs)" is false
4615              then both inner_lhs and inner_rhs must be false.  */
4616           const svalue *false_sval
4617             = m_mgr->get_or_create_constant_svalue (boolean_false_node);
4618           bool sat1 = add_constraint (inner_lhs, EQ_EXPR, false_sval, ctxt);
4619           bool sat2 = add_constraint (inner_rhs, EQ_EXPR, false_sval, ctxt);
4620           *out = sat1 && sat2;
4621           return true;
4622         }
4623       return false;
4624     }
4625 }
4626
4627 /* Attempt to add the constraint "LHS OP RHS" to this region_model.
4628    If it is consistent with existing constraints, add it, and return true.
4629    Return false if it contradicts existing constraints.
4630    Use CTXT for reporting any diagnostics associated with the accesses.  */
4631
4632 bool
4633 region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
4634                               region_model_context *ctxt)
4635 {
4636   /* For now, make no attempt to capture constraints on floating-point
4637      values.  */
4638   if (FLOAT_TYPE_P (TREE_TYPE (lhs)) || FLOAT_TYPE_P (TREE_TYPE (rhs)))
4639     return true;
4640
4641   const svalue *lhs_sval = get_rvalue (lhs, ctxt);
4642   const svalue *rhs_sval = get_rvalue (rhs, ctxt);
4643
4644   return add_constraint (lhs_sval, op, rhs_sval, ctxt);
4645 }
4646
4647 /* Attempt to add the constraint "LHS OP RHS" to this region_model.
4648    If it is consistent with existing constraints, add it, and return true.
4649    Return false if it contradicts existing constraints.
4650    Use CTXT for reporting any diagnostics associated with the accesses.  */
4651
4652 bool
4653 region_model::add_constraint (const svalue *lhs,
4654                               enum tree_code op,
4655                               const svalue *rhs,
4656                               region_model_context *ctxt)
4657 {
4658   tristate t_cond = eval_condition (lhs, op, rhs);
4659
4660   /* If we already have the condition, do nothing.  */
4661   if (t_cond.is_true ())
4662     return true;
4663
4664   /* Reject a constraint that would contradict existing knowledge, as
4665      unsatisfiable.  */
4666   if (t_cond.is_false ())
4667     return false;
4668
4669   bool out;
4670   if (add_constraints_from_binop (lhs, op, rhs, &out, ctxt))
4671     return out;
4672
4673   /* Attempt to store the constraint.  */
4674   if (!m_constraints->add_constraint (lhs, op, rhs))
4675     return false;
4676
4677   /* Notify the context, if any.  This exists so that the state machines
4678      in a program_state can be notified about the condition, and so can
4679      set sm-state for e.g. unchecked->checked, both for cfg-edges, and
4680      when synthesizing constraints as above.  */
4681   if (ctxt)
4682     ctxt->on_condition (lhs, op, rhs);
4683
4684   /* If we have &REGION == NULL, then drop dynamic extents for REGION (for
4685      the case where REGION is heap-allocated and thus could be NULL).  */
4686   if (tree rhs_cst = rhs->maybe_get_constant ())
4687     if (op == EQ_EXPR && zerop (rhs_cst))
4688       if (const region_svalue *region_sval = lhs->dyn_cast_region_svalue ())
4689         unset_dynamic_extents (region_sval->get_pointee ());
4690
4691   return true;
4692 }
4693
4694 /* As above, but when returning false, if OUT is non-NULL, write a
4695    new rejected_constraint to *OUT.  */
4696
4697 bool
4698 region_model::add_constraint (tree lhs, enum tree_code op, tree rhs,
4699                               region_model_context *ctxt,
4700                               rejected_constraint **out)
4701 {
4702   bool sat = add_constraint (lhs, op, rhs, ctxt);
4703   if (!sat && out)
4704     *out = new rejected_op_constraint (*this, lhs, op, rhs);
4705   return sat;
4706 }
4707
4708 /* Determine what is known about the condition "LHS OP RHS" within
4709    this model.
4710    Use CTXT for reporting any diagnostics associated with the accesses.  */
4711
4712 tristate
4713 region_model::eval_condition (tree lhs,
4714                               enum tree_code op,
4715                               tree rhs,
4716                               region_model_context *ctxt)
4717 {
4718   /* For now, make no attempt to model constraints on floating-point
4719      values.  */
4720   if (FLOAT_TYPE_P (TREE_TYPE (lhs)) || FLOAT_TYPE_P (TREE_TYPE (rhs)))
4721     return tristate::unknown ();
4722
4723   return eval_condition (get_rvalue (lhs, ctxt), op, get_rvalue (rhs, ctxt));
4724 }
4725
4726 /* Implementation of region_model::get_representative_path_var.
4727    Attempt to return a path_var that represents SVAL, or return NULL_TREE.
4728    Use VISITED to prevent infinite mutual recursion with the overload for
4729    regions.  */
4730
4731 path_var
4732 region_model::get_representative_path_var_1 (const svalue *sval,
4733                                              svalue_set *visited) const
4734 {
4735   gcc_assert (sval);
4736
4737   /* Prevent infinite recursion.  */
4738   if (visited->contains (sval))
4739     return path_var (NULL_TREE, 0);
4740   visited->add (sval);
4741
4742   /* Handle casts by recursion into get_representative_path_var.  */
4743   if (const svalue *cast_sval = sval->maybe_undo_cast ())
4744     {
4745       path_var result = get_representative_path_var (cast_sval, visited);
4746       tree orig_type = sval->get_type ();
4747       /* If necessary, wrap the result in a cast.  */
4748       if (result.m_tree && orig_type)
4749         result.m_tree = build1 (NOP_EXPR, orig_type, result.m_tree);
4750       return result;
4751     }
4752
4753   auto_vec<path_var> pvs;
4754   m_store.get_representative_path_vars (this, visited, sval, &pvs);
4755
4756   if (tree cst = sval->maybe_get_constant ())
4757     pvs.safe_push (path_var (cst, 0));
4758
4759   /* Handle string literals and various other pointers.  */
4760   if (const region_svalue *ptr_sval = sval->dyn_cast_region_svalue ())
4761     {
4762       const region *reg = ptr_sval->get_pointee ();
4763       if (path_var pv = get_representative_path_var (reg, visited))
4764         return path_var (build1 (ADDR_EXPR,
4765                                  sval->get_type (),
4766                                  pv.m_tree),
4767                          pv.m_stack_depth);
4768     }
4769
4770   /* If we have a sub_svalue, look for ways to represent the parent.  */
4771   if (const sub_svalue *sub_sval = sval->dyn_cast_sub_svalue ())
4772     {
4773       const svalue *parent_sval = sub_sval->get_parent ();
4774       const region *subreg = sub_sval->get_subregion ();
4775       if (path_var parent_pv
4776             = get_representative_path_var (parent_sval, visited))
4777         if (const field_region *field_reg = subreg->dyn_cast_field_region ())
4778           return path_var (build3 (COMPONENT_REF,
4779                                    sval->get_type (),
4780                                    parent_pv.m_tree,
4781                                    field_reg->get_field (),
4782                                    NULL_TREE),
4783                            parent_pv.m_stack_depth);
4784     }
4785
4786   /* Handle binops.  */
4787   if (const binop_svalue *binop_sval = sval->dyn_cast_binop_svalue ())
4788     if (path_var lhs_pv
4789         = get_representative_path_var (binop_sval->get_arg0 (), visited))
4790       if (path_var rhs_pv
4791           = get_representative_path_var (binop_sval->get_arg1 (), visited))
4792         return path_var (build2 (binop_sval->get_op (),
4793                                  sval->get_type (),
4794                                  lhs_pv.m_tree, rhs_pv.m_tree),
4795                          lhs_pv.m_stack_depth);
4796
4797   if (pvs.length () < 1)
4798     return path_var (NULL_TREE, 0);
4799
4800   pvs.qsort (readability_comparator);
4801   return pvs[0];
4802 }
4803
4804 /* Attempt to return a path_var that represents SVAL, or return NULL_TREE.
4805    Use VISITED to prevent infinite mutual recursion with the overload for
4806    regions
4807
4808    This function defers to get_representative_path_var_1 to do the work;
4809    it adds verification that get_representative_path_var_1 returned a tree
4810    of the correct type.  */
4811
4812 path_var
4813 region_model::get_representative_path_var (const svalue *sval,
4814                                            svalue_set *visited) const
4815 {
4816   if (sval == NULL)
4817     return path_var (NULL_TREE, 0);
4818
4819   tree orig_type = sval->get_type ();
4820
4821   path_var result = get_representative_path_var_1 (sval, visited);
4822
4823   /* Verify that the result has the same type as SVAL, if any.  */
4824   if (result.m_tree && orig_type)
4825     gcc_assert (TREE_TYPE (result.m_tree) == orig_type);
4826
4827   return result;
4828 }
4829
4830 /* Attempt to return a tree that represents SVAL, or return NULL_TREE.
4831
4832    Strip off any top-level cast, to avoid messages like
4833      double-free of '(void *)ptr'
4834    from analyzer diagnostics.  */
4835
4836 tree
4837 region_model::get_representative_tree (const svalue *sval) const
4838 {
4839   svalue_set visited;
4840   tree expr = get_representative_path_var (sval, &visited).m_tree;
4841
4842   /* Strip off any top-level cast.  */
4843   if (expr && TREE_CODE (expr) == NOP_EXPR)
4844     expr = TREE_OPERAND (expr, 0);
4845
4846   return fixup_tree_for_diagnostic (expr);
4847 }
4848
4849 tree
4850 region_model::get_representative_tree (const region *reg) const
4851 {
4852   svalue_set visited;
4853   tree expr = get_representative_path_var (reg, &visited).m_tree;
4854
4855   /* Strip off any top-level cast.  */
4856   if (expr && TREE_CODE (expr) == NOP_EXPR)
4857     expr = TREE_OPERAND (expr, 0);
4858
4859   return fixup_tree_for_diagnostic (expr);
4860 }
4861
4862 /* Implementation of region_model::get_representative_path_var.
4863
4864    Attempt to return a path_var that represents REG, or return
4865    the NULL path_var.
4866    For example, a region for a field of a local would be a path_var
4867    wrapping a COMPONENT_REF.
4868    Use VISITED to prevent infinite mutual recursion with the overload for
4869    svalues.  */
4870
4871 path_var
4872 region_model::get_representative_path_var_1 (const region *reg,
4873                                              svalue_set *visited) const
4874 {
4875   switch (reg->get_kind ())
4876     {
4877     default:
4878       gcc_unreachable ();
4879
4880     case RK_FRAME:
4881     case RK_GLOBALS:
4882     case RK_CODE:
4883     case RK_HEAP:
4884     case RK_STACK:
4885     case RK_ROOT:
4886        /* Regions that represent memory spaces are not expressible as trees.  */
4887       return path_var (NULL_TREE, 0);
4888
4889     case RK_FUNCTION:
4890       {
4891         const function_region *function_reg
4892           = as_a <const function_region *> (reg);
4893         return path_var (function_reg->get_fndecl (), 0);
4894       }
4895     case RK_LABEL:
4896       {
4897         const label_region *label_reg = as_a <const label_region *> (reg);
4898         return path_var (label_reg->get_label (), 0);
4899       }
4900
4901     case RK_SYMBOLIC:
4902       {
4903         const symbolic_region *symbolic_reg
4904           = as_a <const symbolic_region *> (reg);
4905         const svalue *pointer = symbolic_reg->get_pointer ();
4906         path_var pointer_pv = get_representative_path_var (pointer, visited);
4907         if (!pointer_pv)
4908           return path_var (NULL_TREE, 0);
4909         tree offset = build_int_cst (pointer->get_type (), 0);
4910         return path_var (build2 (MEM_REF,
4911                                  reg->get_type (),
4912                                  pointer_pv.m_tree,
4913                                  offset),
4914                          pointer_pv.m_stack_depth);
4915       }
4916     case RK_DECL:
4917       {
4918         const decl_region *decl_reg = as_a <const decl_region *> (reg);
4919         return path_var (decl_reg->get_decl (), decl_reg->get_stack_depth ());
4920       }
4921     case RK_FIELD:
4922       {
4923         const field_region *field_reg = as_a <const field_region *> (reg);
4924         path_var parent_pv
4925           = get_representative_path_var (reg->get_parent_region (), visited);
4926         if (!parent_pv)
4927           return path_var (NULL_TREE, 0);
4928         return path_var (build3 (COMPONENT_REF,
4929                                  reg->get_type (),
4930                                  parent_pv.m_tree,
4931                                  field_reg->get_field (),
4932                                  NULL_TREE),
4933                          parent_pv.m_stack_depth);
4934       }
4935
4936     case RK_ELEMENT:
4937       {
4938         const element_region *element_reg
4939           = as_a <const element_region *> (reg);
4940         path_var parent_pv
4941           = get_representative_path_var (reg->get_parent_region (), visited);
4942         if (!parent_pv)
4943           return path_var (NULL_TREE, 0);
4944         path_var index_pv
4945           = get_representative_path_var (element_reg->get_index (), visited);
4946         if (!index_pv)
4947           return path_var (NULL_TREE, 0);
4948         return path_var (build4 (ARRAY_REF,
4949                                  reg->get_type (),
4950                                  parent_pv.m_tree, index_pv.m_tree,
4951                                  NULL_TREE, NULL_TREE),
4952                          parent_pv.m_stack_depth);
4953       }
4954
4955     case RK_OFFSET:
4956       {
4957         const offset_region *offset_reg
4958           = as_a <const offset_region *> (reg);
4959         path_var parent_pv
4960           = get_representative_path_var (reg->get_parent_region (), visited);
4961         if (!parent_pv)
4962           return path_var (NULL_TREE, 0);
4963         path_var offset_pv
4964           = get_representative_path_var (offset_reg->get_byte_offset (),
4965                                          visited);
4966         if (!offset_pv || TREE_CODE (offset_pv.m_tree) != INTEGER_CST)
4967           return path_var (NULL_TREE, 0);
4968         tree addr_parent = build1 (ADDR_EXPR,
4969                                    build_pointer_type (reg->get_type ()),
4970                                    parent_pv.m_tree);
4971         return path_var (build2 (MEM_REF,
4972                                  reg->get_type (),
4973                                  addr_parent, offset_pv.m_tree),
4974                          parent_pv.m_stack_depth);
4975       }
4976
4977     case RK_SIZED:
4978       return path_var (NULL_TREE, 0);
4979
4980     case RK_CAST:
4981       {
4982         path_var parent_pv
4983           = get_representative_path_var (reg->get_parent_region (), visited);
4984         if (!parent_pv)
4985           return path_var (NULL_TREE, 0);
4986         return path_var (build1 (NOP_EXPR,
4987                                  reg->get_type (),
4988                                  parent_pv.m_tree),
4989                          parent_pv.m_stack_depth);
4990       }
4991
4992     case RK_HEAP_ALLOCATED:
4993     case RK_ALLOCA:
4994       /* No good way to express heap-allocated/alloca regions as trees.  */
4995       return path_var (NULL_TREE, 0);
4996
4997     case RK_STRING:
4998       {
4999         const string_region *string_reg = as_a <const string_region *> (reg);
5000         return path_var (string_reg->get_string_cst (), 0);
5001       }
5002
5003     case RK_VAR_ARG:
5004     case RK_UNKNOWN:
5005       return path_var (NULL_TREE, 0);
5006     }
5007 }
5008
5009 /* Attempt to return a path_var that represents REG, or return
5010    the NULL path_var.
5011    For example, a region for a field of a local would be a path_var
5012    wrapping a COMPONENT_REF.
5013    Use VISITED to prevent infinite mutual recursion with the overload for
5014    svalues.
5015
5016    This function defers to get_representative_path_var_1 to do the work;
5017    it adds verification that get_representative_path_var_1 returned a tree
5018    of the correct type.  */
5019
5020 path_var
5021 region_model::get_representative_path_var (const region *reg,
5022                                            svalue_set *visited) const
5023 {
5024   path_var result = get_representative_path_var_1 (reg, visited);
5025
5026   /* Verify that the result has the same type as REG, if any.  */
5027   if (result.m_tree && reg->get_type ())
5028     gcc_assert (TREE_TYPE (result.m_tree) == reg->get_type ());
5029
5030   return result;
5031 }
5032
5033 /* Update this model for any phis in SNODE, assuming we came from
5034    LAST_CFG_SUPEREDGE.  */
5035
5036 void
5037 region_model::update_for_phis (const supernode *snode,
5038                                const cfg_superedge *last_cfg_superedge,
5039                                region_model_context *ctxt)
5040 {
5041   gcc_assert (last_cfg_superedge);
5042
5043   /* Copy this state and pass it to handle_phi so that all of the phi stmts
5044      are effectively handled simultaneously.  */
5045   const region_model old_state (*this);
5046
5047   for (gphi_iterator gpi = const_cast<supernode *>(snode)->start_phis ();
5048        !gsi_end_p (gpi); gsi_next (&gpi))
5049     {
5050       gphi *phi = gpi.phi ();
5051
5052       tree src = last_cfg_superedge->get_phi_arg (phi);
5053       tree lhs = gimple_phi_result (phi);
5054
5055       /* Update next_state based on phi and old_state.  */
5056       handle_phi (phi, lhs, src, old_state, ctxt);
5057     }
5058 }
5059
5060 /* Attempt to update this model for taking EDGE (where the last statement
5061    was LAST_STMT), returning true if the edge can be taken, false
5062    otherwise.
5063    When returning false, if OUT is non-NULL, write a new rejected_constraint
5064    to it.
5065
5066    For CFG superedges where LAST_STMT is a conditional or a switch
5067    statement, attempt to add the relevant conditions for EDGE to this
5068    model, returning true if they are feasible, or false if they are
5069    impossible.
5070
5071    For call superedges, push frame information and store arguments
5072    into parameters.
5073
5074    For return superedges, pop frame information and store return
5075    values into any lhs.
5076
5077    Rejection of call/return superedges happens elsewhere, in
5078    program_point::on_edge (i.e. based on program point, rather
5079    than program state).  */
5080
5081 bool
5082 region_model::maybe_update_for_edge (const superedge &edge,
5083                                      const gimple *last_stmt,
5084                                      region_model_context *ctxt,
5085                                      rejected_constraint **out)
5086 {
5087   /* Handle frame updates for interprocedural edges.  */
5088   switch (edge.m_kind)
5089     {
5090     default:
5091       break;
5092
5093     case SUPEREDGE_CALL:
5094       {
5095         const call_superedge *call_edge = as_a <const call_superedge *> (&edge);
5096         update_for_call_superedge (*call_edge, ctxt);
5097       }
5098       break;
5099
5100     case SUPEREDGE_RETURN:
5101       {
5102         const return_superedge *return_edge
5103           = as_a <const return_superedge *> (&edge);
5104         update_for_return_superedge (*return_edge, ctxt);
5105       }
5106       break;
5107
5108     case SUPEREDGE_INTRAPROCEDURAL_CALL:
5109       /* This is a no-op for call summaries; we should already
5110          have handled the effect of the call summary at the call stmt.  */
5111       break;
5112     }
5113
5114   if (last_stmt == NULL)
5115     return true;
5116
5117   /* Apply any constraints for conditionals/switch statements.  */
5118
5119   if (const gcond *cond_stmt = dyn_cast <const gcond *> (last_stmt))
5120     {
5121       const cfg_superedge *cfg_sedge = as_a <const cfg_superedge *> (&edge);
5122       return apply_constraints_for_gcond (*cfg_sedge, cond_stmt, ctxt, out);
5123     }
5124
5125   if (const gswitch *switch_stmt = dyn_cast <const gswitch *> (last_stmt))
5126     {
5127       const switch_cfg_superedge *switch_sedge
5128         = as_a <const switch_cfg_superedge *> (&edge);
5129       return apply_constraints_for_gswitch (*switch_sedge, switch_stmt,
5130                                             ctxt, out);
5131     }
5132
5133   /* Apply any constraints due to an exception being thrown.  */
5134   if (const cfg_superedge *cfg_sedge = dyn_cast <const cfg_superedge *> (&edge))
5135     if (cfg_sedge->get_flags () & EDGE_EH)
5136       return apply_constraints_for_exception (last_stmt, ctxt, out);
5137
5138   return true;
5139 }
5140
5141 /* Push a new frame_region on to the stack region.
5142    Populate the frame_region with child regions for the function call's
5143    parameters, using values from the arguments at the callsite in the
5144    caller's frame.  */
5145
5146 void
5147 region_model::update_for_gcall (const gcall *call_stmt,
5148                                 region_model_context *ctxt,
5149                                 function *callee)
5150 {
5151   /* Build a vec of argument svalues, using the current top
5152      frame for resolving tree expressions.  */
5153   auto_vec<const svalue *> arg_svals (gimple_call_num_args (call_stmt));
5154
5155   for (unsigned i = 0; i < gimple_call_num_args (call_stmt); i++)
5156     {
5157       tree arg = gimple_call_arg (call_stmt, i);
5158       arg_svals.quick_push (get_rvalue (arg, ctxt));
5159     }
5160
5161   if(!callee)
5162   {
5163     /* Get the function * from the gcall.  */
5164     tree fn_decl = get_fndecl_for_call (call_stmt,ctxt);
5165     callee = DECL_STRUCT_FUNCTION (fn_decl);
5166   }
5167
5168   push_frame (callee, &arg_svals, ctxt);
5169 }
5170
5171 /* Pop the top-most frame_region from the stack, and copy the return
5172    region's values (if any) into the region for the lvalue of the LHS of
5173    the call (if any).  */
5174
5175 void
5176 region_model::update_for_return_gcall (const gcall *call_stmt,
5177                                        region_model_context *ctxt)
5178 {
5179   /* Get the lvalue for the result of the call, passing it to pop_frame,
5180      so that pop_frame can determine the region with respect to the
5181      *caller* frame.  */
5182   tree lhs = gimple_call_lhs (call_stmt);
5183   pop_frame (lhs, NULL, ctxt);
5184 }
5185
5186 /* Extract calling information from the superedge and update the model for the 
5187    call  */
5188
5189 void
5190 region_model::update_for_call_superedge (const call_superedge &call_edge,
5191                                          region_model_context *ctxt)
5192 {
5193   const gcall *call_stmt = call_edge.get_call_stmt ();
5194   update_for_gcall (call_stmt, ctxt, call_edge.get_callee_function ());
5195 }
5196
5197 /* Extract calling information from the return superedge and update the model 
5198    for the returning call */
5199
5200 void
5201 region_model::update_for_return_superedge (const return_superedge &return_edge,
5202                                            region_model_context *ctxt)
5203 {
5204   const gcall *call_stmt = return_edge.get_call_stmt ();
5205   update_for_return_gcall (call_stmt, ctxt);
5206 }
5207
5208 /* Attempt to to use R to replay SUMMARY into this object.
5209    Return true if it is possible.  */
5210
5211 bool
5212 region_model::replay_call_summary (call_summary_replay &r,
5213                                    const region_model &summary)
5214 {
5215   gcc_assert (summary.get_stack_depth () == 1);
5216
5217   m_store.replay_call_summary (r, summary.m_store);
5218
5219   if (!m_constraints->replay_call_summary (r, *summary.m_constraints))
5220     return false;
5221
5222   for (auto kv : summary.m_dynamic_extents)
5223     {
5224       const region *summary_reg = kv.first;
5225       const region *caller_reg = r.convert_region_from_summary (summary_reg);
5226       if (!caller_reg)
5227         continue;
5228       const svalue *summary_sval = kv.second;
5229       const svalue *caller_sval = r.convert_svalue_from_summary (summary_sval);
5230       if (!caller_sval)
5231         continue;
5232       m_dynamic_extents.put (caller_reg, caller_sval);
5233     }
5234
5235   return true;
5236 }
5237
5238 /* Given a true or false edge guarded by conditional statement COND_STMT,
5239    determine appropriate constraints for the edge to be taken.
5240
5241    If they are feasible, add the constraints and return true.
5242
5243    Return false if the constraints contradict existing knowledge
5244    (and so the edge should not be taken).
5245    When returning false, if OUT is non-NULL, write a new rejected_constraint
5246    to it.  */
5247
5248 bool
5249 region_model::apply_constraints_for_gcond (const cfg_superedge &sedge,
5250                                            const gcond *cond_stmt,
5251                                            region_model_context *ctxt,
5252                                            rejected_constraint **out)
5253 {
5254   ::edge cfg_edge = sedge.get_cfg_edge ();
5255   gcc_assert (cfg_edge != NULL);
5256   gcc_assert (cfg_edge->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE));
5257
5258   enum tree_code op = gimple_cond_code (cond_stmt);
5259   tree lhs = gimple_cond_lhs (cond_stmt);
5260   tree rhs = gimple_cond_rhs (cond_stmt);
5261   if (cfg_edge->flags & EDGE_FALSE_VALUE)
5262     op = invert_tree_comparison (op, false /* honor_nans */);
5263   return add_constraint (lhs, op, rhs, ctxt, out);
5264 }
5265
5266 /* Given an EDGE guarded by SWITCH_STMT, determine appropriate constraints
5267    for the edge to be taken.
5268
5269    If they are feasible, add the constraints and return true.
5270
5271    Return false if the constraints contradict existing knowledge
5272    (and so the edge should not be taken).
5273    When returning false, if OUT is non-NULL, write a new rejected_constraint
5274    to it.  */
5275
5276 bool
5277 region_model::apply_constraints_for_gswitch (const switch_cfg_superedge &edge,
5278                                              const gswitch *switch_stmt,
5279                                              region_model_context *ctxt,
5280                                              rejected_constraint **out)
5281 {
5282   bounded_ranges_manager *ranges_mgr = get_range_manager ();
5283   const bounded_ranges *all_cases_ranges
5284     = ranges_mgr->get_or_create_ranges_for_switch (&edge, switch_stmt);
5285   tree index  = gimple_switch_index (switch_stmt);
5286   const svalue *index_sval = get_rvalue (index, ctxt);
5287   bool sat = m_constraints->add_bounded_ranges (index_sval, all_cases_ranges);
5288   if (!sat && out)
5289     *out = new rejected_ranges_constraint (*this, index, all_cases_ranges);
5290   if (sat && ctxt && !all_cases_ranges->empty_p ())
5291     ctxt->on_bounded_ranges (*index_sval, *all_cases_ranges);
5292   return sat;
5293 }
5294
5295 /* Apply any constraints due to an exception being thrown at LAST_STMT.
5296
5297    If they are feasible, add the constraints and return true.
5298
5299    Return false if the constraints contradict existing knowledge
5300    (and so the edge should not be taken).
5301    When returning false, if OUT is non-NULL, write a new rejected_constraint
5302    to it.  */
5303
5304 bool
5305 region_model::apply_constraints_for_exception (const gimple *last_stmt,
5306                                                region_model_context *ctxt,
5307                                                rejected_constraint **out)
5308 {
5309   gcc_assert (last_stmt);
5310   if (const gcall *call = dyn_cast <const gcall *> (last_stmt))
5311     if (tree callee_fndecl = get_fndecl_for_call (call, ctxt))
5312       if (is_named_call_p (callee_fndecl, "operator new", call, 1)
5313           || is_named_call_p (callee_fndecl, "operator new []", call, 1))
5314         {
5315           /* We have an exception thrown from operator new.
5316              Add a constraint that the result was NULL, to avoid a false
5317              leak report due to the result being lost when following
5318              the EH edge.  */
5319           if (tree lhs = gimple_call_lhs (call))
5320             return add_constraint (lhs, EQ_EXPR, null_pointer_node, ctxt, out);
5321           return true;
5322         }
5323   return true;
5324 }
5325
5326 /* For use with push_frame when handling a top-level call within the analysis.
5327    PARAM has a defined but unknown initial value.
5328    Anything it points to has escaped, since the calling context "knows"
5329    the pointer, and thus calls to unknown functions could read/write into
5330    the region.  */
5331
5332 void
5333 region_model::on_top_level_param (tree param,
5334                                    region_model_context *ctxt)
5335 {
5336   if (POINTER_TYPE_P (TREE_TYPE (param)))
5337     {
5338       const region *param_reg = get_lvalue (param, ctxt);
5339       const svalue *init_ptr_sval
5340         = m_mgr->get_or_create_initial_value (param_reg);
5341       const region *pointee_reg = m_mgr->get_symbolic_region (init_ptr_sval);
5342       m_store.mark_as_escaped (pointee_reg);
5343     }
5344 }
5345
5346 /* Update this region_model to reflect pushing a frame onto the stack
5347    for a call to FUN.
5348
5349    If ARG_SVALS is non-NULL, use it to populate the parameters
5350    in the new frame.
5351    Otherwise, the params have their initial_svalues.
5352
5353    Return the frame_region for the new frame.  */
5354
5355 const region *
5356 region_model::push_frame (function *fun, const vec<const svalue *> *arg_svals,
5357                           region_model_context *ctxt)
5358 {
5359   m_current_frame = m_mgr->get_frame_region (m_current_frame, fun);
5360   if (arg_svals)
5361     {
5362       /* Arguments supplied from a caller frame.  */
5363       tree fndecl = fun->decl;
5364       unsigned idx = 0;
5365       for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm;
5366            iter_parm = DECL_CHAIN (iter_parm), ++idx)
5367         {
5368           /* If there's a mismatching declaration, the call stmt might
5369              not have enough args.  Handle this case by leaving the
5370              rest of the params as uninitialized.  */
5371           if (idx >= arg_svals->length ())
5372             break;
5373           tree parm_lval = iter_parm;
5374           if (tree parm_default_ssa = ssa_default_def (fun, iter_parm))
5375             parm_lval = parm_default_ssa;
5376           const region *parm_reg = get_lvalue (parm_lval, ctxt);
5377           const svalue *arg_sval = (*arg_svals)[idx];
5378           set_value (parm_reg, arg_sval, ctxt);
5379         }
5380
5381       /* Handle any variadic args.  */
5382       unsigned va_arg_idx = 0;
5383       for (; idx < arg_svals->length (); idx++, va_arg_idx++)
5384         {
5385           const svalue *arg_sval = (*arg_svals)[idx];
5386           const region *var_arg_reg
5387             = m_mgr->get_var_arg_region (m_current_frame,
5388                                          va_arg_idx);
5389           set_value (var_arg_reg, arg_sval, ctxt);
5390         }
5391     }
5392   else
5393     {
5394       /* Otherwise we have a top-level call within the analysis.  The params
5395          have defined but unknown initial values.
5396          Anything they point to has escaped.  */
5397       tree fndecl = fun->decl;
5398       for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm;
5399            iter_parm = DECL_CHAIN (iter_parm))
5400         {
5401           if (tree parm_default_ssa = ssa_default_def (fun, iter_parm))
5402             on_top_level_param (parm_default_ssa, ctxt);
5403           else
5404             on_top_level_param (iter_parm, ctxt);
5405         }
5406     }
5407
5408   return m_current_frame;
5409 }
5410
5411 /* Get the function of the top-most frame in this region_model's stack.
5412    There must be such a frame.  */
5413
5414 function *
5415 region_model::get_current_function () const
5416 {
5417   const frame_region *frame = get_current_frame ();
5418   gcc_assert (frame);
5419   return frame->get_function ();
5420 }
5421
5422 /* Pop the topmost frame_region from this region_model's stack;
5423
5424    If RESULT_LVALUE is non-null, copy any return value from the frame
5425    into the corresponding region (evaluated with respect to the *caller*
5426    frame, rather than the called frame).
5427    If OUT_RESULT is non-null, copy any return value from the frame
5428    into *OUT_RESULT.
5429
5430    Purge the frame region and all its descendent regions.
5431    Convert any pointers that point into such regions into
5432    POISON_KIND_POPPED_STACK svalues.  */
5433
5434 void
5435 region_model::pop_frame (tree result_lvalue,
5436                          const svalue **out_result,
5437                          region_model_context *ctxt)
5438 {
5439   gcc_assert (m_current_frame);
5440
5441   /* Evaluate the result, within the callee frame.  */
5442   const frame_region *frame_reg = m_current_frame;
5443   tree fndecl = m_current_frame->get_function ()->decl;
5444   tree result = DECL_RESULT (fndecl);
5445   const svalue *retval = NULL;
5446   if (result && TREE_TYPE (result) != void_type_node)
5447     {
5448       retval = get_rvalue (result, ctxt);
5449       if (out_result)
5450         *out_result = retval;
5451     }
5452
5453   /* Pop the frame.  */
5454   m_current_frame = m_current_frame->get_calling_frame ();
5455
5456   if (result_lvalue && retval)
5457     {
5458       /* Compute result_dst_reg using RESULT_LVALUE *after* popping
5459          the frame, but before poisoning pointers into the old frame.  */
5460       const region *result_dst_reg = get_lvalue (result_lvalue, ctxt);
5461       set_value (result_dst_reg, retval, ctxt);
5462     }
5463
5464   unbind_region_and_descendents (frame_reg,POISON_KIND_POPPED_STACK);
5465 }
5466
5467 /* Get the number of frames in this region_model's stack.  */
5468
5469 int
5470 region_model::get_stack_depth () const
5471 {
5472   const frame_region *frame = get_current_frame ();
5473   if (frame)
5474     return frame->get_stack_depth ();
5475   else
5476     return 0;
5477 }
5478
5479 /* Get the frame_region with the given index within the stack.
5480    The frame_region must exist.  */
5481
5482 const frame_region *
5483 region_model::get_frame_at_index (int index) const
5484 {
5485   const frame_region *frame = get_current_frame ();
5486   gcc_assert (frame);
5487   gcc_assert (index >= 0);
5488   gcc_assert (index <= frame->get_index ());
5489   while (index != frame->get_index ())
5490     {
5491       frame = frame->get_calling_frame ();
5492       gcc_assert (frame);
5493     }
5494   return frame;
5495 }
5496
5497 /* Unbind svalues for any regions in REG and below.
5498    Find any pointers to such regions; convert them to
5499    poisoned values of kind PKIND.
5500    Also purge any dynamic extents.  */
5501
5502 void
5503 region_model::unbind_region_and_descendents (const region *reg,
5504                                              enum poison_kind pkind)
5505 {
5506   /* Gather a set of base regions to be unbound.  */
5507   hash_set<const region *> base_regs;
5508   for (store::cluster_map_t::iterator iter = m_store.begin ();
5509        iter != m_store.end (); ++iter)
5510     {
5511       const region *iter_base_reg = (*iter).first;
5512       if (iter_base_reg->descendent_of_p (reg))
5513         base_regs.add (iter_base_reg);
5514     }
5515   for (hash_set<const region *>::iterator iter = base_regs.begin ();
5516        iter != base_regs.end (); ++iter)
5517     m_store.purge_cluster (*iter);
5518
5519   /* Find any pointers to REG or its descendents; convert to poisoned.  */
5520   poison_any_pointers_to_descendents (reg, pkind);
5521
5522   /* Purge dynamic extents of any base regions in REG and below
5523      (e.g. VLAs and alloca stack regions).  */
5524   for (auto iter : m_dynamic_extents)
5525     {
5526       const region *iter_reg = iter.first;
5527       if (iter_reg->descendent_of_p (reg))
5528         unset_dynamic_extents (iter_reg);
5529     }
5530 }
5531
5532 /* Implementation of BindingVisitor.
5533    Update the bound svalues for regions below REG to use poisoned
5534    values instead.  */
5535
5536 struct bad_pointer_finder
5537 {
5538   bad_pointer_finder (const region *reg, enum poison_kind pkind,
5539                       region_model_manager *mgr)
5540   : m_reg (reg), m_pkind (pkind), m_mgr (mgr), m_count (0)
5541   {}
5542
5543   void on_binding (const binding_key *, const svalue *&sval)
5544   {
5545     if (const region_svalue *ptr_sval = sval->dyn_cast_region_svalue ())
5546       {
5547         const region *ptr_dst = ptr_sval->get_pointee ();
5548         /* Poison ptrs to descendents of REG, but not to REG itself,
5549            otherwise double-free detection doesn't work (since sm-state
5550            for "free" is stored on the original ptr svalue).  */
5551         if (ptr_dst->descendent_of_p (m_reg)
5552             && ptr_dst != m_reg)
5553           {
5554             sval = m_mgr->get_or_create_poisoned_svalue (m_pkind,
5555                                                          sval->get_type ());
5556             ++m_count;
5557           }
5558       }
5559   }
5560
5561   const region *m_reg;
5562   enum poison_kind m_pkind;
5563   region_model_manager *const m_mgr;
5564   int m_count;
5565 };
5566
5567 /* Find any pointers to REG or its descendents; convert them to
5568    poisoned values of kind PKIND.
5569    Return the number of pointers that were poisoned.  */
5570
5571 int
5572 region_model::poison_any_pointers_to_descendents (const region *reg,
5573                                                    enum poison_kind pkind)
5574 {
5575   bad_pointer_finder bv (reg, pkind, m_mgr);
5576   m_store.for_each_binding (bv);
5577   return bv.m_count;
5578 }
5579
5580 /* Attempt to merge THIS with OTHER_MODEL, writing the result
5581    to OUT_MODEL.  Use POINT to distinguish values created as a
5582    result of merging.  */
5583
5584 bool
5585 region_model::can_merge_with_p (const region_model &other_model,
5586                                 const program_point &point,
5587                                 region_model *out_model,
5588                                 const extrinsic_state *ext_state,
5589                                 const program_state *state_a,
5590                                 const program_state *state_b) const
5591 {
5592   gcc_assert (out_model);
5593   gcc_assert (m_mgr == other_model.m_mgr);
5594   gcc_assert (m_mgr == out_model->m_mgr);
5595
5596   if (m_current_frame != other_model.m_current_frame)
5597     return false;
5598   out_model->m_current_frame = m_current_frame;
5599
5600   model_merger m (this, &other_model, point, out_model,
5601                   ext_state, state_a, state_b);
5602
5603   if (!store::can_merge_p (&m_store, &other_model.m_store,
5604                            &out_model->m_store, m_mgr->get_store_manager (),
5605                            &m))
5606     return false;
5607
5608   if (!m_dynamic_extents.can_merge_with_p (other_model.m_dynamic_extents,
5609                                            &out_model->m_dynamic_extents))
5610     return false;
5611
5612   /* Merge constraints.  */
5613   constraint_manager::merge (*m_constraints,
5614                               *other_model.m_constraints,
5615                               out_model->m_constraints);
5616
5617   return true;
5618 }
5619
5620 /* Attempt to get the fndecl used at CALL, if known, or NULL_TREE
5621    otherwise.  */
5622
5623 tree
5624 region_model::get_fndecl_for_call (const gcall *call,
5625                                    region_model_context *ctxt)
5626 {
5627   tree fn_ptr = gimple_call_fn (call);
5628   if (fn_ptr == NULL_TREE)
5629     return NULL_TREE;
5630   const svalue *fn_ptr_sval = get_rvalue (fn_ptr, ctxt);
5631   if (const region_svalue *fn_ptr_ptr
5632         = fn_ptr_sval->dyn_cast_region_svalue ())
5633     {
5634       const region *reg = fn_ptr_ptr->get_pointee ();
5635       if (const function_region *fn_reg = reg->dyn_cast_function_region ())
5636         {
5637           tree fn_decl = fn_reg->get_fndecl ();
5638           cgraph_node *node = cgraph_node::get (fn_decl);
5639           if (!node)
5640             return NULL_TREE;
5641           const cgraph_node *ultimate_node = node->ultimate_alias_target ();
5642           if (ultimate_node)
5643             return ultimate_node->decl;
5644         }
5645     }
5646
5647   return NULL_TREE;
5648 }
5649
5650 /* Would be much simpler to use a lambda here, if it were supported.  */
5651
5652 struct append_regions_cb_data
5653 {
5654   const region_model *model;
5655   auto_vec<const decl_region *> *out;
5656 };
5657
5658 /* Populate *OUT with all decl_regions in the current
5659    frame that have clusters within the store.  */
5660
5661 void
5662 region_model::
5663 get_regions_for_current_frame (auto_vec<const decl_region *> *out) const
5664 {
5665   append_regions_cb_data data;
5666   data.model = this;
5667   data.out = out;
5668   m_store.for_each_cluster (append_regions_cb, &data);
5669 }
5670
5671 /* Implementation detail of get_regions_for_current_frame.  */
5672
5673 void
5674 region_model::append_regions_cb (const region *base_reg,
5675                                  append_regions_cb_data *cb_data)
5676 {
5677   if (base_reg->get_parent_region () != cb_data->model->m_current_frame)
5678     return;
5679   if (const decl_region *decl_reg = base_reg->dyn_cast_decl_region ())
5680     cb_data->out->safe_push (decl_reg);
5681 }
5682
5683
5684 /* Abstract class for diagnostics related to the use of
5685    floating-point arithmetic where precision is needed.  */
5686
5687 class imprecise_floating_point_arithmetic : public pending_diagnostic
5688 {
5689 public:
5690   int get_controlling_option () const final override
5691   {
5692     return OPT_Wanalyzer_imprecise_fp_arithmetic;
5693   }
5694 };
5695
5696 /* Concrete diagnostic to complain about uses of floating-point arithmetic
5697    in the size argument of malloc etc.  */
5698
5699 class float_as_size_arg : public imprecise_floating_point_arithmetic
5700 {
5701 public:
5702   float_as_size_arg (tree arg) : m_arg (arg)
5703   {}
5704
5705   const char *get_kind () const final override
5706   {
5707     return "float_as_size_arg_diagnostic";
5708   }
5709
5710   bool subclass_equal_p (const pending_diagnostic &other) const final override
5711   {
5712     return same_tree_p (m_arg, ((const float_as_size_arg &) other).m_arg);
5713   }
5714
5715   bool emit (rich_location *rich_loc) final override
5716   {
5717     diagnostic_metadata m;
5718     bool warned = warning_meta (rich_loc, m, get_controlling_option (),
5719                                 "use of floating-point arithmetic here might"
5720                                 " yield unexpected results");
5721     if (warned)
5722       inform (rich_loc->get_loc (), "only use operands of an integer type"
5723                                     " inside the size argument");
5724     return warned;
5725   }
5726
5727   label_text describe_final_event (const evdesc::final_event &ev) final
5728   override
5729   {
5730     if (m_arg)
5731       return ev.formatted_print ("operand %qE is of type %qT",
5732                                  m_arg, TREE_TYPE (m_arg));
5733     return ev.formatted_print ("at least one operand of the size argument is"
5734                                " of a floating-point type");
5735   }
5736
5737 private:
5738   tree m_arg;
5739 };
5740
5741 /* Visitor to find uses of floating-point variables/constants in an svalue.  */
5742
5743 class contains_floating_point_visitor : public visitor
5744 {
5745 public:
5746   contains_floating_point_visitor (const svalue *root_sval) : m_result (NULL)
5747   {
5748     root_sval->accept (this);
5749   }
5750
5751   const svalue *get_svalue_to_report ()
5752   {
5753     return m_result;
5754   }
5755
5756   void visit_constant_svalue (const constant_svalue *sval) final override
5757   {
5758     /* At the point the analyzer runs, constant integer operands in a floating
5759        point expression are already implictly converted to floating-points.
5760        Thus, we do prefer to report non-constants such that the diagnostic
5761        always reports a floating-point operand.  */
5762     tree type = sval->get_type ();
5763     if (type && FLOAT_TYPE_P (type) && !m_result)
5764       m_result = sval;
5765   }
5766
5767   void visit_conjured_svalue (const conjured_svalue *sval) final override
5768   {
5769     tree type = sval->get_type ();
5770     if (type && FLOAT_TYPE_P (type))
5771       m_result = sval;
5772   }
5773
5774   void visit_initial_svalue (const initial_svalue *sval) final override
5775   {
5776     tree type = sval->get_type ();
5777     if (type && FLOAT_TYPE_P (type))
5778       m_result = sval;
5779   }
5780
5781 private:
5782   /* Non-null if at least one floating-point operand was found.  */
5783   const svalue *m_result;
5784 };
5785
5786 /* May complain about uses of floating-point operands in SIZE_IN_BYTES.  */
5787
5788 void
5789 region_model::check_dynamic_size_for_floats (const svalue *size_in_bytes,
5790                                              region_model_context *ctxt) const
5791 {
5792   gcc_assert (ctxt);
5793
5794   contains_floating_point_visitor v (size_in_bytes);
5795   if (const svalue *float_sval = v.get_svalue_to_report ())
5796         {
5797           tree diag_arg = get_representative_tree (float_sval);
5798           ctxt->warn (make_unique<float_as_size_arg> (diag_arg));
5799         }
5800 }
5801
5802 /* Return a new region describing a heap-allocated block of memory.
5803    Use CTXT to complain about tainted sizes.  */
5804
5805 const region *
5806 region_model::create_region_for_heap_alloc (const svalue *size_in_bytes,
5807                                             region_model_context *ctxt)
5808 {
5809   const region *reg = m_mgr->create_region_for_heap_alloc ();
5810   if (compat_types_p (size_in_bytes->get_type (), size_type_node))
5811     set_dynamic_extents (reg, size_in_bytes, ctxt);
5812   return reg;
5813 }
5814
5815 /* Return a new region describing a block of memory allocated within the
5816    current frame.
5817    Use CTXT to complain about tainted sizes.  */
5818
5819 const region *
5820 region_model::create_region_for_alloca (const svalue *size_in_bytes,
5821                                         region_model_context *ctxt)
5822 {
5823   const region *reg = m_mgr->create_region_for_alloca (m_current_frame);
5824   if (compat_types_p (size_in_bytes->get_type (), size_type_node))
5825     set_dynamic_extents (reg, size_in_bytes, ctxt);
5826   return reg;
5827 }
5828
5829 /* Record that the size of REG is SIZE_IN_BYTES.
5830    Use CTXT to complain about tainted sizes.  */
5831
5832 void
5833 region_model::set_dynamic_extents (const region *reg,
5834                                    const svalue *size_in_bytes,
5835                                    region_model_context *ctxt)
5836 {
5837   assert_compat_types (size_in_bytes->get_type (), size_type_node);
5838   if (ctxt)
5839     {
5840       check_dynamic_size_for_taint (reg->get_memory_space (), size_in_bytes,
5841                                     ctxt);
5842       check_dynamic_size_for_floats (size_in_bytes, ctxt);
5843     }
5844   m_dynamic_extents.put (reg, size_in_bytes);
5845 }
5846
5847 /* Get the recording of REG in bytes, or NULL if no dynamic size was
5848    recorded.  */
5849
5850 const svalue *
5851 region_model::get_dynamic_extents (const region *reg) const
5852 {
5853   if (const svalue * const *slot = m_dynamic_extents.get (reg))
5854     return *slot;
5855   return NULL;
5856 }
5857
5858 /* Unset any recorded dynamic size of REG.  */
5859
5860 void
5861 region_model::unset_dynamic_extents (const region *reg)
5862 {
5863   m_dynamic_extents.remove (reg);
5864 }
5865
5866 /* Information of the layout of a RECORD_TYPE, capturing it as a vector
5867    of items, where each item is either a field or padding.  */
5868
5869 class record_layout
5870 {
5871 public:
5872   /* An item within a record; either a field, or padding after a field.  */
5873   struct item
5874   {
5875   public:
5876     item (const bit_range &br,
5877           tree field,
5878           bool is_padding)
5879     : m_bit_range (br),
5880       m_field (field),
5881       m_is_padding (is_padding)
5882     {
5883     }
5884
5885     bit_offset_t get_start_bit_offset () const
5886     {
5887       return m_bit_range.get_start_bit_offset ();
5888     }
5889     bit_offset_t get_next_bit_offset () const
5890     {
5891       return m_bit_range.get_next_bit_offset ();
5892     }
5893
5894     bool contains_p (bit_offset_t offset) const
5895     {
5896       return m_bit_range.contains_p (offset);
5897     }
5898
5899     void dump_to_pp (pretty_printer *pp) const
5900     {
5901       if (m_is_padding)
5902         pp_printf (pp, "padding after %qD", m_field);
5903       else
5904         pp_printf (pp, "%qD", m_field);
5905       pp_string (pp, ", ");
5906       m_bit_range.dump_to_pp (pp);
5907     }
5908
5909     bit_range m_bit_range;
5910     tree m_field;
5911     bool m_is_padding;
5912   };
5913
5914   record_layout (tree record_type)
5915   {
5916     gcc_assert (TREE_CODE (record_type) == RECORD_TYPE);
5917
5918     for (tree iter = TYPE_FIELDS (record_type); iter != NULL_TREE;
5919          iter = DECL_CHAIN (iter))
5920       {
5921         if (TREE_CODE (iter) == FIELD_DECL)
5922           {
5923             int iter_field_offset = int_bit_position (iter);
5924             bit_size_t size_in_bits;
5925             if (!int_size_in_bits (TREE_TYPE (iter), &size_in_bits))
5926               size_in_bits = 0;
5927
5928             maybe_pad_to (iter_field_offset);
5929
5930             /* Add field.  */
5931             m_items.safe_push (item (bit_range (iter_field_offset,
5932                                                 size_in_bits),
5933                                      iter, false));
5934           }
5935       }
5936
5937     /* Add any trailing padding.  */
5938     bit_size_t size_in_bits;
5939     if (int_size_in_bits (record_type, &size_in_bits))
5940       maybe_pad_to (size_in_bits);
5941   }
5942
5943   void dump_to_pp (pretty_printer *pp) const
5944   {
5945     unsigned i;
5946     item *it;
5947     FOR_EACH_VEC_ELT (m_items, i, it)
5948       {
5949         it->dump_to_pp (pp);
5950         pp_newline (pp);
5951       }
5952   }
5953
5954   DEBUG_FUNCTION void dump () const
5955   {
5956     pretty_printer pp;
5957     pp_format_decoder (&pp) = default_tree_printer;
5958     pp.buffer->stream = stderr;
5959     dump_to_pp (&pp);
5960     pp_flush (&pp);
5961   }
5962
5963   const record_layout::item *get_item_at (bit_offset_t offset) const
5964   {
5965     unsigned i;
5966     item *it;
5967     FOR_EACH_VEC_ELT (m_items, i, it)
5968       if (it->contains_p (offset))
5969         return it;
5970     return NULL;
5971   }
5972
5973 private:
5974   /* Subroutine of ctor.  Add padding item to NEXT_OFFSET if necessary.  */
5975
5976   void maybe_pad_to (bit_offset_t next_offset)
5977   {
5978     if (m_items.length () > 0)
5979       {
5980         const item &last_item = m_items[m_items.length () - 1];
5981         bit_offset_t offset_after_last_item
5982           = last_item.get_next_bit_offset ();
5983         if (next_offset > offset_after_last_item)
5984           {
5985             bit_size_t padding_size
5986               = next_offset - offset_after_last_item;
5987             m_items.safe_push (item (bit_range (offset_after_last_item,
5988                                                 padding_size),
5989                                      last_item.m_field, true));
5990           }
5991       }
5992   }
5993
5994   auto_vec<item> m_items;
5995 };
5996
5997 /* A subclass of pending_diagnostic for complaining about uninitialized data
5998    being copied across a trust boundary to an untrusted output
5999    (e.g. copy_to_user infoleaks in the Linux kernel).  */
6000
6001 class exposure_through_uninit_copy
6002   : public pending_diagnostic_subclass<exposure_through_uninit_copy>
6003 {
6004 public:
6005   exposure_through_uninit_copy (const region *src_region,
6006                                 const region *dest_region,
6007                                 const svalue *copied_sval)
6008   : m_src_region (src_region),
6009     m_dest_region (dest_region),
6010     m_copied_sval (copied_sval)
6011   {
6012     gcc_assert (m_copied_sval->get_kind () == SK_POISONED
6013                 || m_copied_sval->get_kind () == SK_COMPOUND);
6014   }
6015
6016   const char *get_kind () const final override
6017   {
6018     return "exposure_through_uninit_copy";
6019   }
6020
6021   bool operator== (const exposure_through_uninit_copy &other) const
6022   {
6023     return (m_src_region == other.m_src_region
6024             && m_dest_region == other.m_dest_region
6025             && m_copied_sval == other.m_copied_sval);
6026   }
6027
6028   int get_controlling_option () const final override
6029   {
6030     return OPT_Wanalyzer_exposure_through_uninit_copy;
6031   }
6032
6033   bool emit (rich_location *rich_loc) final override
6034   {
6035     diagnostic_metadata m;
6036     /* CWE-200: Exposure of Sensitive Information to an Unauthorized Actor.  */
6037     m.add_cwe (200);
6038     enum memory_space mem_space = get_src_memory_space ();
6039     bool warned;
6040     switch (mem_space)
6041       {
6042       default:
6043         warned = warning_meta
6044           (rich_loc, m, get_controlling_option (),
6045            "potential exposure of sensitive information"
6046            " by copying uninitialized data across trust boundary");
6047         break;
6048       case MEMSPACE_STACK:
6049         warned = warning_meta
6050           (rich_loc, m, get_controlling_option (),
6051            "potential exposure of sensitive information"
6052            " by copying uninitialized data from stack across trust boundary");
6053         break;
6054       case MEMSPACE_HEAP:
6055         warned = warning_meta
6056           (rich_loc, m, get_controlling_option (),
6057            "potential exposure of sensitive information"
6058            " by copying uninitialized data from heap across trust boundary");
6059         break;
6060       }
6061     if (warned)
6062       {
6063         location_t loc = rich_loc->get_loc ();
6064         inform_number_of_uninit_bits (loc);
6065         complain_about_uninit_ranges (loc);
6066
6067         if (mem_space == MEMSPACE_STACK)
6068           maybe_emit_fixit_hint ();
6069       }
6070     return warned;
6071   }
6072
6073   label_text describe_final_event (const evdesc::final_event &) final override
6074   {
6075     enum memory_space mem_space = get_src_memory_space ();
6076     switch (mem_space)
6077       {
6078       default:
6079         return label_text::borrow ("uninitialized data copied here");
6080
6081       case MEMSPACE_STACK:
6082         return label_text::borrow ("uninitialized data copied from stack here");
6083
6084       case MEMSPACE_HEAP:
6085         return label_text::borrow ("uninitialized data copied from heap here");
6086       }
6087   }
6088
6089   void mark_interesting_stuff (interesting_t *interest) final override
6090   {
6091     if (m_src_region)
6092       interest->add_region_creation (m_src_region);
6093   }
6094
6095 private:
6096   enum memory_space get_src_memory_space () const
6097   {
6098     return m_src_region ? m_src_region->get_memory_space () : MEMSPACE_UNKNOWN;
6099   }
6100
6101   bit_size_t calc_num_uninit_bits () const
6102   {
6103     switch (m_copied_sval->get_kind ())
6104       {
6105       default:
6106         gcc_unreachable ();
6107         break;
6108       case SK_POISONED:
6109         {
6110           const poisoned_svalue *poisoned_sval
6111             = as_a <const poisoned_svalue *> (m_copied_sval);
6112           gcc_assert (poisoned_sval->get_poison_kind () == POISON_KIND_UNINIT);
6113
6114           /* Give up if don't have type information.  */
6115           if (m_copied_sval->get_type () == NULL_TREE)
6116             return 0;
6117
6118           bit_size_t size_in_bits;
6119           if (int_size_in_bits (m_copied_sval->get_type (), &size_in_bits))
6120             return size_in_bits;
6121
6122           /* Give up if we can't get the size of the type.  */
6123           return 0;
6124         }
6125         break;
6126       case SK_COMPOUND:
6127         {
6128           const compound_svalue *compound_sval
6129             = as_a <const compound_svalue *> (m_copied_sval);
6130           bit_size_t result = 0;
6131           /* Find keys for uninit svals.  */
6132           for (auto iter : *compound_sval)
6133             {
6134               const svalue *sval = iter.second;
6135               if (const poisoned_svalue *psval
6136                   = sval->dyn_cast_poisoned_svalue ())
6137                 if (psval->get_poison_kind () == POISON_KIND_UNINIT)
6138                   {
6139                     const binding_key *key = iter.first;
6140                     const concrete_binding *ckey
6141                       = key->dyn_cast_concrete_binding ();
6142                     gcc_assert (ckey);
6143                     result += ckey->get_size_in_bits ();
6144                   }
6145             }
6146           return result;
6147         }
6148       }
6149   }
6150
6151   void inform_number_of_uninit_bits (location_t loc) const
6152   {
6153     bit_size_t num_uninit_bits = calc_num_uninit_bits ();
6154     if (num_uninit_bits <= 0)
6155       return;
6156     if (num_uninit_bits % BITS_PER_UNIT == 0)
6157       {
6158         /* Express in bytes.  */
6159         byte_size_t num_uninit_bytes = num_uninit_bits / BITS_PER_UNIT;
6160         if (num_uninit_bytes == 1)
6161           inform (loc, "1 byte is uninitialized");
6162         else
6163           inform (loc,
6164                   "%wu bytes are uninitialized", num_uninit_bytes.to_uhwi ());
6165       }
6166     else
6167       {
6168         /* Express in bits.  */
6169         if (num_uninit_bits == 1)
6170           inform (loc, "1 bit is uninitialized");
6171         else
6172           inform (loc,
6173                   "%wu bits are uninitialized", num_uninit_bits.to_uhwi ());
6174       }
6175   }
6176
6177   void complain_about_uninit_ranges (location_t loc) const
6178   {
6179     if (const compound_svalue *compound_sval
6180         = m_copied_sval->dyn_cast_compound_svalue ())
6181       {
6182         /* Find keys for uninit svals.  */
6183         auto_vec<const concrete_binding *> uninit_keys;
6184         for (auto iter : *compound_sval)
6185           {
6186             const svalue *sval = iter.second;
6187             if (const poisoned_svalue *psval
6188                 = sval->dyn_cast_poisoned_svalue ())
6189               if (psval->get_poison_kind () == POISON_KIND_UNINIT)
6190                 {
6191                   const binding_key *key = iter.first;
6192                   const concrete_binding *ckey
6193                     = key->dyn_cast_concrete_binding ();
6194                   gcc_assert (ckey);
6195                   uninit_keys.safe_push (ckey);
6196                 }
6197           }
6198         /* Complain about them in sorted order.  */
6199         uninit_keys.qsort (concrete_binding::cmp_ptr_ptr);
6200
6201         std::unique_ptr<record_layout> layout;
6202
6203         tree type = m_copied_sval->get_type ();
6204         if (type && TREE_CODE (type) == RECORD_TYPE)
6205           {
6206             // (std::make_unique is C++14)
6207             layout = std::unique_ptr<record_layout> (new record_layout (type));
6208
6209             if (0)
6210               layout->dump ();
6211           }
6212
6213         unsigned i;
6214         const concrete_binding *ckey;
6215         FOR_EACH_VEC_ELT (uninit_keys, i, ckey)
6216           {
6217             bit_offset_t start_bit = ckey->get_start_bit_offset ();
6218             bit_offset_t next_bit = ckey->get_next_bit_offset ();
6219             complain_about_uninit_range (loc, start_bit, next_bit,
6220                                          layout.get ());
6221           }
6222       }
6223   }
6224
6225   void complain_about_uninit_range (location_t loc,
6226                                     bit_offset_t start_bit,
6227                                     bit_offset_t next_bit,
6228                                     const record_layout *layout) const
6229   {
6230     if (layout)
6231       {
6232         while (start_bit < next_bit)
6233           {
6234             if (const record_layout::item *item
6235                   = layout->get_item_at (start_bit))
6236               {
6237                 gcc_assert (start_bit >= item->get_start_bit_offset ());
6238                 gcc_assert (start_bit < item->get_next_bit_offset ());
6239                 if (item->get_start_bit_offset () == start_bit
6240                     && item->get_next_bit_offset () <= next_bit)
6241                   complain_about_fully_uninit_item (*item);
6242                 else
6243                   complain_about_partially_uninit_item (*item);
6244                 start_bit = item->get_next_bit_offset ();
6245                 continue;
6246               }
6247             else
6248               break;
6249           }
6250       }
6251
6252     if (start_bit >= next_bit)
6253       return;
6254
6255     if (start_bit % 8 == 0 && next_bit % 8 == 0)
6256       {
6257         /* Express in bytes.  */
6258         byte_offset_t start_byte = start_bit / 8;
6259         byte_offset_t last_byte = (next_bit / 8) - 1;
6260         if (last_byte == start_byte)
6261           inform (loc,
6262                   "byte %wu is uninitialized",
6263                   start_byte.to_uhwi ());
6264         else
6265           inform (loc,
6266                   "bytes %wu - %wu are uninitialized",
6267                   start_byte.to_uhwi (),
6268                   last_byte.to_uhwi ());
6269       }
6270     else
6271       {
6272         /* Express in bits.  */
6273         bit_offset_t last_bit = next_bit - 1;
6274         if (last_bit == start_bit)
6275           inform (loc,
6276                   "bit %wu is uninitialized",
6277                   start_bit.to_uhwi ());
6278         else
6279           inform (loc,
6280                   "bits %wu - %wu are uninitialized",
6281                   start_bit.to_uhwi (),
6282                   last_bit.to_uhwi ());
6283       }
6284   }
6285
6286   static void
6287   complain_about_fully_uninit_item (const record_layout::item &item)
6288   {
6289     tree field = item.m_field;
6290     bit_size_t num_bits = item.m_bit_range.m_size_in_bits;
6291     if (item.m_is_padding)
6292       {
6293         if (num_bits % 8 == 0)
6294           {
6295             /* Express in bytes.  */
6296             byte_size_t num_bytes = num_bits / BITS_PER_UNIT;
6297             if (num_bytes == 1)
6298               inform (DECL_SOURCE_LOCATION (field),
6299                       "padding after field %qD is uninitialized (1 byte)",
6300                       field);
6301             else
6302               inform (DECL_SOURCE_LOCATION (field),
6303                       "padding after field %qD is uninitialized (%wu bytes)",
6304                       field, num_bytes.to_uhwi ());
6305           }
6306         else
6307           {
6308             /* Express in bits.  */
6309             if (num_bits == 1)
6310               inform (DECL_SOURCE_LOCATION (field),
6311                       "padding after field %qD is uninitialized (1 bit)",
6312                       field);
6313             else
6314               inform (DECL_SOURCE_LOCATION (field),
6315                       "padding after field %qD is uninitialized (%wu bits)",
6316                       field, num_bits.to_uhwi ());
6317           }
6318       }
6319     else
6320       {
6321         if (num_bits % 8 == 0)
6322           {
6323             /* Express in bytes.  */
6324             byte_size_t num_bytes = num_bits / BITS_PER_UNIT;
6325             if (num_bytes == 1)
6326               inform (DECL_SOURCE_LOCATION (field),
6327                       "field %qD is uninitialized (1 byte)", field);
6328             else
6329               inform (DECL_SOURCE_LOCATION (field),
6330                       "field %qD is uninitialized (%wu bytes)",
6331                       field, num_bytes.to_uhwi ());
6332           }
6333         else
6334           {
6335             /* Express in bits.  */
6336             if (num_bits == 1)
6337               inform (DECL_SOURCE_LOCATION (field),
6338                       "field %qD is uninitialized (1 bit)", field);
6339             else
6340               inform (DECL_SOURCE_LOCATION (field),
6341                       "field %qD is uninitialized (%wu bits)",
6342                       field, num_bits.to_uhwi ());
6343           }
6344       }
6345   }
6346
6347   static void
6348   complain_about_partially_uninit_item (const record_layout::item &item)
6349   {
6350     tree field = item.m_field;
6351     if (item.m_is_padding)
6352       inform (DECL_SOURCE_LOCATION (field),
6353               "padding after field %qD is partially uninitialized",
6354               field);
6355     else
6356       inform (DECL_SOURCE_LOCATION (field),
6357               "field %qD is partially uninitialized",
6358               field);
6359     /* TODO: ideally we'd describe what parts are uninitialized.  */
6360   }
6361
6362   void maybe_emit_fixit_hint () const
6363   {
6364     if (tree decl = m_src_region->maybe_get_decl ())
6365       {
6366         gcc_rich_location hint_richloc (DECL_SOURCE_LOCATION (decl));
6367         hint_richloc.add_fixit_insert_after (" = {0}");
6368         inform (&hint_richloc,
6369                 "suggest forcing zero-initialization by"
6370                 " providing a %<{0}%> initializer");
6371       }
6372   }
6373
6374 private:
6375   const region *m_src_region;
6376   const region *m_dest_region;
6377   const svalue *m_copied_sval;
6378 };
6379
6380 /* Return true if any part of SVAL is uninitialized.  */
6381
6382 static bool
6383 contains_uninit_p (const svalue *sval)
6384 {
6385   struct uninit_finder : public visitor
6386   {
6387   public:
6388     uninit_finder () : m_found_uninit (false) {}
6389     void visit_poisoned_svalue (const poisoned_svalue *sval)
6390     {
6391       if (sval->get_poison_kind () == POISON_KIND_UNINIT)
6392         m_found_uninit = true;
6393     }
6394     bool m_found_uninit;
6395   };
6396
6397   uninit_finder v;
6398   sval->accept (&v);
6399
6400   return v.m_found_uninit;
6401 }
6402
6403 /* Function for use by plugins when simulating writing data through a
6404    pointer to an "untrusted" region DST_REG (and thus crossing a security
6405    boundary), such as copying data to user space in an OS kernel.
6406
6407    Check that COPIED_SVAL is fully initialized.  If not, complain about
6408    an infoleak to CTXT.
6409
6410    SRC_REG can be NULL; if non-NULL it is used as a hint in the diagnostic
6411    as to where COPIED_SVAL came from.  */
6412
6413 void
6414 region_model::maybe_complain_about_infoleak (const region *dst_reg,
6415                                              const svalue *copied_sval,
6416                                              const region *src_reg,
6417                                              region_model_context *ctxt)
6418 {
6419   /* Check for exposure.  */
6420   if (contains_uninit_p (copied_sval))
6421     ctxt->warn (make_unique<exposure_through_uninit_copy> (src_reg,
6422                                                            dst_reg,
6423                                                            copied_sval));
6424 }
6425
6426 /* Set errno to a positive symbolic int, as if some error has occurred.  */
6427
6428 void
6429 region_model::set_errno (const call_details &cd)
6430 {
6431   const region *errno_reg = m_mgr->get_errno_region ();
6432   conjured_purge p (this, cd.get_ctxt ());
6433   const svalue *new_errno_sval
6434     = m_mgr->get_or_create_conjured_svalue (integer_type_node,
6435                                             cd.get_call_stmt (),
6436                                             errno_reg, p);
6437   const svalue *zero
6438     = m_mgr->get_or_create_int_cst (integer_type_node, 0);
6439   add_constraint (new_errno_sval, GT_EXPR, zero, cd.get_ctxt ());
6440   set_value (errno_reg, new_errno_sval, cd.get_ctxt ());
6441 }
6442
6443 /* class noop_region_model_context : public region_model_context.  */
6444
6445 void
6446 noop_region_model_context::add_note (std::unique_ptr<pending_note>)
6447 {
6448 }
6449
6450 void
6451 noop_region_model_context::bifurcate (std::unique_ptr<custom_edge_info>)
6452 {
6453 }
6454
6455 void
6456 noop_region_model_context::terminate_path ()
6457 {
6458 }
6459
6460 /* struct model_merger.  */
6461
6462 /* Dump a multiline representation of this merger to PP.  */
6463
6464 void
6465 model_merger::dump_to_pp (pretty_printer *pp, bool simple) const
6466 {
6467   pp_string (pp, "model A:");
6468   pp_newline (pp);
6469   m_model_a->dump_to_pp (pp, simple, true);
6470   pp_newline (pp);
6471
6472   pp_string (pp, "model B:");
6473   pp_newline (pp);
6474   m_model_b->dump_to_pp (pp, simple, true);
6475   pp_newline (pp);
6476
6477   pp_string (pp, "merged model:");
6478   pp_newline (pp);
6479   m_merged_model->dump_to_pp (pp, simple, true);
6480   pp_newline (pp);
6481 }
6482
6483 /* Dump a multiline representation of this merger to FILE.  */
6484
6485 void
6486 model_merger::dump (FILE *fp, bool simple) const
6487 {
6488   pretty_printer pp;
6489   pp_format_decoder (&pp) = default_tree_printer;
6490   pp_show_color (&pp) = pp_show_color (global_dc->printer);
6491   pp.buffer->stream = fp;
6492   dump_to_pp (&pp, simple);
6493   pp_flush (&pp);
6494 }
6495
6496 /* Dump a multiline representation of this merger to stderr.  */
6497
6498 DEBUG_FUNCTION void
6499 model_merger::dump (bool simple) const
6500 {
6501   dump (stderr, simple);
6502 }
6503
6504 /* Return true if it's OK to merge SVAL with other svalues.  */
6505
6506 bool
6507 model_merger::mergeable_svalue_p (const svalue *sval) const
6508 {
6509   if (m_ext_state)
6510     {
6511       /* Reject merging svalues that have non-purgable sm-state,
6512          to avoid falsely reporting memory leaks by merging them
6513          with something else.  For example, given a local var "p",
6514          reject the merger of a:
6515            store_a mapping "p" to a malloc-ed ptr
6516          with:
6517            store_b mapping "p" to a NULL ptr.  */
6518       if (m_state_a)
6519         if (!m_state_a->can_purge_p (*m_ext_state, sval))
6520           return false;
6521       if (m_state_b)
6522         if (!m_state_b->can_purge_p (*m_ext_state, sval))
6523           return false;
6524     }
6525   return true;
6526 }
6527
6528 } // namespace ana
6529
6530 /* Dump RMODEL fully to stderr (i.e. without summarization).  */
6531
6532 DEBUG_FUNCTION void
6533 debug (const region_model &rmodel)
6534 {
6535   rmodel.dump (false);
6536 }
6537
6538 /* class rejected_op_constraint : public rejected_constraint.  */
6539
6540 void
6541 rejected_op_constraint::dump_to_pp (pretty_printer *pp) const
6542 {
6543   region_model m (m_model);
6544   const svalue *lhs_sval = m.get_rvalue (m_lhs, NULL);
6545   const svalue *rhs_sval = m.get_rvalue (m_rhs, NULL);
6546   lhs_sval->dump_to_pp (pp, true);
6547   pp_printf (pp, " %s ", op_symbol_code (m_op));
6548   rhs_sval->dump_to_pp (pp, true);
6549 }
6550
6551 /* class rejected_ranges_constraint : public rejected_constraint.  */
6552
6553 void
6554 rejected_ranges_constraint::dump_to_pp (pretty_printer *pp) const
6555 {
6556   region_model m (m_model);
6557   const svalue *sval = m.get_rvalue (m_expr, NULL);
6558   sval->dump_to_pp (pp, true);
6559   pp_string (pp, " in ");
6560   m_ranges->dump_to_pp (pp, true);
6561 }
6562
6563 /* class engine.  */
6564
6565 /* engine's ctor.  */
6566
6567 engine::engine (const supergraph *sg, logger *logger)
6568 : m_sg (sg), m_mgr (logger)
6569 {
6570 }
6571
6572 /* Dump the managed objects by class to LOGGER, and the per-class totals.  */
6573
6574 void
6575 engine::log_stats (logger *logger) const
6576 {
6577   m_mgr.log_stats (logger, true);
6578 }
6579
6580 namespace ana {
6581
6582 #if CHECKING_P
6583
6584 namespace selftest {
6585
6586 /* Build a constant tree of the given type from STR.  */
6587
6588 static tree
6589 build_real_cst_from_string (tree type, const char *str)
6590 {
6591   REAL_VALUE_TYPE real;
6592   real_from_string (&real, str);
6593   return build_real (type, real);
6594 }
6595
6596 /* Append various "interesting" constants to OUT (e.g. NaN).  */
6597
6598 static void
6599 append_interesting_constants (auto_vec<tree> *out)
6600 {
6601   out->safe_push (build_int_cst (integer_type_node, 0));
6602   out->safe_push (build_int_cst (integer_type_node, 42));
6603   out->safe_push (build_int_cst (unsigned_type_node, 0));
6604   out->safe_push (build_int_cst (unsigned_type_node, 42));
6605   out->safe_push (build_real_cst_from_string (float_type_node, "QNaN"));
6606   out->safe_push (build_real_cst_from_string (float_type_node, "-QNaN"));
6607   out->safe_push (build_real_cst_from_string (float_type_node, "SNaN"));
6608   out->safe_push (build_real_cst_from_string (float_type_node, "-SNaN"));
6609   out->safe_push (build_real_cst_from_string (float_type_node, "0.0"));
6610   out->safe_push (build_real_cst_from_string (float_type_node, "-0.0"));
6611   out->safe_push (build_real_cst_from_string (float_type_node, "Inf"));
6612   out->safe_push (build_real_cst_from_string (float_type_node, "-Inf"));
6613 }
6614
6615 /* Verify that tree_cmp is a well-behaved comparator for qsort, even
6616    if the underlying constants aren't comparable.  */
6617
6618 static void
6619 test_tree_cmp_on_constants ()
6620 {
6621   auto_vec<tree> csts;
6622   append_interesting_constants (&csts);
6623
6624   /* Try sorting every triple. */
6625   const unsigned num = csts.length ();
6626   for (unsigned i = 0; i < num; i++)
6627     for (unsigned j = 0; j < num; j++)
6628       for (unsigned k = 0; k < num; k++)
6629         {
6630           auto_vec<tree> v (3);
6631           v.quick_push (csts[i]);
6632           v.quick_push (csts[j]);
6633           v.quick_push (csts[k]);
6634           v.qsort (tree_cmp);
6635         }
6636 }
6637
6638 /* Implementation detail of the ASSERT_CONDITION_* macros.  */
6639
6640 void
6641 assert_condition (const location &loc,
6642                   region_model &model,
6643                   const svalue *lhs, tree_code op, const svalue *rhs,
6644                   tristate expected)
6645 {
6646   tristate actual = model.eval_condition (lhs, op, rhs);
6647   ASSERT_EQ_AT (loc, actual, expected);
6648 }
6649
6650 /* Implementation detail of the ASSERT_CONDITION_* macros.  */
6651
6652 void
6653 assert_condition (const location &loc,
6654                   region_model &model,
6655                   tree lhs, tree_code op, tree rhs,
6656                   tristate expected)
6657 {
6658   tristate actual = model.eval_condition (lhs, op, rhs, NULL);
6659   ASSERT_EQ_AT (loc, actual, expected);
6660 }
6661
6662 /* Implementation detail of ASSERT_DUMP_TREE_EQ.  */
6663
6664 static void
6665 assert_dump_tree_eq (const location &loc, tree t, const char *expected)
6666 {
6667   auto_fix_quotes sentinel;
6668   pretty_printer pp;
6669   pp_format_decoder (&pp) = default_tree_printer;
6670   dump_tree (&pp, t);
6671   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected);
6672 }
6673
6674 /* Assert that dump_tree (T) is EXPECTED.  */
6675
6676 #define ASSERT_DUMP_TREE_EQ(T, EXPECTED) \
6677   SELFTEST_BEGIN_STMT                                                   \
6678   assert_dump_tree_eq ((SELFTEST_LOCATION), (T), (EXPECTED)); \
6679   SELFTEST_END_STMT
6680
6681 /* Implementation detail of ASSERT_DUMP_EQ.  */
6682
6683 static void
6684 assert_dump_eq (const location &loc,
6685                 const region_model &model,
6686                 bool summarize,
6687                 const char *expected)
6688 {
6689   auto_fix_quotes sentinel;
6690   pretty_printer pp;
6691   pp_format_decoder (&pp) = default_tree_printer;
6692
6693   model.dump_to_pp (&pp, summarize, true);
6694   ASSERT_STREQ_AT (loc, pp_formatted_text (&pp), expected);
6695 }
6696
6697 /* Assert that MODEL.dump_to_pp (SUMMARIZE) is EXPECTED.  */
6698
6699 #define ASSERT_DUMP_EQ(MODEL, SUMMARIZE, EXPECTED) \
6700   SELFTEST_BEGIN_STMT                                                   \
6701   assert_dump_eq ((SELFTEST_LOCATION), (MODEL), (SUMMARIZE), (EXPECTED)); \
6702   SELFTEST_END_STMT
6703
6704 /* Smoketest for region_model::dump_to_pp.  */
6705
6706 static void
6707 test_dump ()
6708 {
6709   region_model_manager mgr;
6710   region_model model (&mgr);
6711
6712   ASSERT_DUMP_EQ (model, false,
6713                   "stack depth: 0\n"
6714                   "m_called_unknown_fn: FALSE\n"
6715                   "constraint_manager:\n"
6716                   "  equiv classes:\n"
6717                   "  constraints:\n");
6718   ASSERT_DUMP_EQ (model, true,
6719                   "stack depth: 0\n"
6720                   "m_called_unknown_fn: FALSE\n"
6721                   "constraint_manager:\n"
6722                   "  equiv classes:\n"
6723                   "  constraints:\n");
6724 }
6725
6726 /* Helper function for selftests.  Create a struct or union type named NAME,
6727    with the fields given by the FIELD_DECLS in FIELDS.
6728    If IS_STRUCT is true create a RECORD_TYPE (aka a struct), otherwise
6729    create a UNION_TYPE.  */
6730
6731 static tree
6732 make_test_compound_type (const char *name, bool is_struct,
6733                          const auto_vec<tree> *fields)
6734 {
6735   tree t = make_node (is_struct ? RECORD_TYPE : UNION_TYPE);
6736   TYPE_NAME (t) = get_identifier (name);
6737   TYPE_SIZE (t) = 0;
6738
6739   tree fieldlist = NULL;
6740   int i;
6741   tree field;
6742   FOR_EACH_VEC_ELT (*fields, i, field)
6743     {
6744       gcc_assert (TREE_CODE (field) == FIELD_DECL);
6745       DECL_CONTEXT (field) = t;
6746       fieldlist = chainon (field, fieldlist);
6747     }
6748   fieldlist = nreverse (fieldlist);
6749   TYPE_FIELDS (t) = fieldlist;
6750
6751   layout_type (t);
6752   return t;
6753 }
6754
6755 /* Selftest fixture for creating the type "struct coord {int x; int y; };".  */
6756
6757 struct coord_test
6758 {
6759   coord_test ()
6760   {
6761     auto_vec<tree> fields;
6762     m_x_field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
6763                                get_identifier ("x"), integer_type_node);
6764     fields.safe_push (m_x_field);
6765     m_y_field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
6766                                get_identifier ("y"), integer_type_node);
6767     fields.safe_push (m_y_field);
6768     m_coord_type = make_test_compound_type ("coord", true, &fields);
6769   }
6770
6771   tree m_x_field;
6772   tree m_y_field;
6773   tree m_coord_type;
6774 };
6775
6776 /* Verify usage of a struct.  */
6777
6778 static void
6779 test_struct ()
6780 {
6781   coord_test ct;
6782
6783   tree c = build_global_decl ("c", ct.m_coord_type);
6784   tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
6785                      c, ct.m_x_field, NULL_TREE);
6786   tree c_y = build3 (COMPONENT_REF, TREE_TYPE (ct.m_y_field),
6787                      c, ct.m_y_field, NULL_TREE);
6788
6789   tree int_17 = build_int_cst (integer_type_node, 17);
6790   tree int_m3 = build_int_cst (integer_type_node, -3);
6791
6792   region_model_manager mgr;
6793   region_model model (&mgr);
6794   model.set_value (c_x, int_17, NULL);
6795   model.set_value (c_y, int_m3, NULL);
6796
6797   /* Verify get_offset for "c.x".  */
6798   {
6799     const region *c_x_reg = model.get_lvalue (c_x, NULL);
6800     region_offset offset = c_x_reg->get_offset (&mgr);
6801     ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, NULL));
6802     ASSERT_EQ (offset.get_bit_offset (), 0);
6803   }
6804
6805   /* Verify get_offset for "c.y".  */
6806   {
6807     const region *c_y_reg = model.get_lvalue (c_y, NULL);
6808     region_offset offset = c_y_reg->get_offset (&mgr);
6809     ASSERT_EQ (offset.get_base_region (), model.get_lvalue (c, NULL));
6810     ASSERT_EQ (offset.get_bit_offset (), INT_TYPE_SIZE);
6811   }
6812 }
6813
6814 /* Verify usage of an array element.  */
6815
6816 static void
6817 test_array_1 ()
6818 {
6819   tree tlen = size_int (10);
6820   tree arr_type = build_array_type (char_type_node, build_index_type (tlen));
6821
6822   tree a = build_global_decl ("a", arr_type);
6823
6824   region_model_manager mgr;
6825   region_model model (&mgr);
6826   tree int_0 = build_int_cst (integer_type_node, 0);
6827   tree a_0 = build4 (ARRAY_REF, char_type_node,
6828                      a, int_0, NULL_TREE, NULL_TREE);
6829   tree char_A = build_int_cst (char_type_node, 'A');
6830   model.set_value (a_0, char_A, NULL);
6831 }
6832
6833 /* Verify that region_model::get_representative_tree works as expected.  */
6834
6835 static void
6836 test_get_representative_tree ()
6837 {
6838   region_model_manager mgr;
6839
6840   /* STRING_CST.  */
6841   {
6842     tree string_cst = build_string (4, "foo");
6843     region_model m (&mgr);
6844     const svalue *str_sval = m.get_rvalue (string_cst, NULL);
6845     tree rep = m.get_representative_tree (str_sval);
6846     ASSERT_EQ (rep, string_cst);
6847   }
6848
6849   /* String literal.  */
6850   {
6851     tree string_cst_ptr = build_string_literal (4, "foo");
6852     region_model m (&mgr);
6853     const svalue *str_sval = m.get_rvalue (string_cst_ptr, NULL);
6854     tree rep = m.get_representative_tree (str_sval);
6855     ASSERT_DUMP_TREE_EQ (rep, "&\"foo\"[0]");
6856   }
6857
6858   /* Value of an element within an array.  */
6859   {
6860     tree tlen = size_int (10);
6861     tree arr_type = build_array_type (char_type_node, build_index_type (tlen));
6862     tree a = build_global_decl ("a", arr_type);
6863     placeholder_svalue test_sval (char_type_node, "test value");
6864
6865     /* Value of a[3].  */
6866     {
6867       test_region_model_context ctxt;
6868       region_model model (&mgr);
6869       tree int_3 = build_int_cst (integer_type_node, 3);
6870       tree a_3 = build4 (ARRAY_REF, char_type_node,
6871                          a, int_3, NULL_TREE, NULL_TREE);
6872       const region *a_3_reg = model.get_lvalue (a_3, &ctxt);
6873       model.set_value (a_3_reg, &test_sval, &ctxt);
6874       tree rep = model.get_representative_tree (&test_sval);
6875       ASSERT_DUMP_TREE_EQ (rep, "a[3]");
6876     }
6877
6878     /* Value of a[0].  */
6879     {
6880       test_region_model_context ctxt;
6881       region_model model (&mgr);
6882       tree idx = build_int_cst (integer_type_node, 0);
6883       tree a_0 = build4 (ARRAY_REF, char_type_node,
6884                          a, idx, NULL_TREE, NULL_TREE);
6885       const region *a_0_reg = model.get_lvalue (a_0, &ctxt);
6886       model.set_value (a_0_reg, &test_sval, &ctxt);
6887       tree rep = model.get_representative_tree (&test_sval);
6888       ASSERT_DUMP_TREE_EQ (rep, "a[0]");
6889     }
6890   }
6891
6892   /* Value of a field within a struct.  */
6893   {
6894     coord_test ct;
6895
6896     tree c = build_global_decl ("c", ct.m_coord_type);
6897     tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
6898                        c, ct.m_x_field, NULL_TREE);
6899     tree c_y = build3 (COMPONENT_REF, TREE_TYPE (ct.m_y_field),
6900                        c, ct.m_y_field, NULL_TREE);
6901
6902     test_region_model_context ctxt;
6903
6904     /* Value of initial field.  */
6905     {
6906       region_model m (&mgr);
6907       const region *c_x_reg = m.get_lvalue (c_x, &ctxt);
6908       placeholder_svalue test_sval_x (integer_type_node, "test x val");
6909       m.set_value (c_x_reg, &test_sval_x, &ctxt);
6910       tree rep = m.get_representative_tree (&test_sval_x);
6911       ASSERT_DUMP_TREE_EQ (rep, "c.x");
6912     }
6913
6914     /* Value of non-initial field.  */
6915     {
6916       region_model m (&mgr);
6917       const region *c_y_reg = m.get_lvalue (c_y, &ctxt);
6918       placeholder_svalue test_sval_y (integer_type_node, "test y val");
6919       m.set_value (c_y_reg, &test_sval_y, &ctxt);
6920       tree rep = m.get_representative_tree (&test_sval_y);
6921       ASSERT_DUMP_TREE_EQ (rep, "c.y");
6922     }
6923   }
6924 }
6925
6926 /* Verify that calling region_model::get_rvalue repeatedly on the same
6927    tree constant retrieves the same svalue *.  */
6928
6929 static void
6930 test_unique_constants ()
6931 {
6932   tree int_0 = build_int_cst (integer_type_node, 0);
6933   tree int_42 = build_int_cst (integer_type_node, 42);
6934
6935   test_region_model_context ctxt;
6936   region_model_manager mgr;
6937   region_model model (&mgr);
6938   ASSERT_EQ (model.get_rvalue (int_0, &ctxt), model.get_rvalue (int_0, &ctxt));
6939   ASSERT_EQ (model.get_rvalue (int_42, &ctxt),
6940              model.get_rvalue (int_42, &ctxt));
6941   ASSERT_NE (model.get_rvalue (int_0, &ctxt), model.get_rvalue (int_42, &ctxt));
6942   ASSERT_EQ (ctxt.get_num_diagnostics (), 0);
6943
6944   /* A "(const int)42" will be a different tree from "(int)42)"...  */
6945   tree const_int_type_node
6946     = build_qualified_type (integer_type_node, TYPE_QUAL_CONST);
6947   tree const_int_42 = build_int_cst (const_int_type_node, 42);
6948   ASSERT_NE (int_42, const_int_42);
6949   /* It should have a different const_svalue.  */
6950   const svalue *int_42_sval = model.get_rvalue (int_42, &ctxt);
6951   const svalue *const_int_42_sval = model.get_rvalue (const_int_42, &ctxt);
6952   ASSERT_NE (int_42_sval, const_int_42_sval);
6953   /* But they should compare as equal.  */
6954   ASSERT_CONDITION_TRUE (model, int_42_sval, EQ_EXPR, const_int_42_sval);
6955   ASSERT_CONDITION_FALSE (model, int_42_sval, NE_EXPR, const_int_42_sval);
6956 }
6957
6958 /* Verify that each type gets its own singleton unknown_svalue within a
6959    region_model_manager, and that NULL_TREE gets its own singleton.  */
6960
6961 static void
6962 test_unique_unknowns ()
6963 {
6964   region_model_manager mgr;
6965   const svalue *unknown_int
6966     = mgr.get_or_create_unknown_svalue (integer_type_node);
6967   /* Repeated calls with the same type should get the same "unknown"
6968      svalue.  */
6969   const svalue *unknown_int_2
6970     = mgr.get_or_create_unknown_svalue (integer_type_node);
6971   ASSERT_EQ (unknown_int, unknown_int_2);
6972
6973   /* Different types (or the NULL type) should have different
6974      unknown_svalues.  */
6975   const svalue *unknown_NULL_type = mgr.get_or_create_unknown_svalue (NULL);
6976   ASSERT_NE (unknown_NULL_type, unknown_int);
6977
6978   /* Repeated calls with NULL for the type should get the same "unknown"
6979      svalue.  */
6980   const svalue *unknown_NULL_type_2 = mgr.get_or_create_unknown_svalue (NULL);
6981   ASSERT_EQ (unknown_NULL_type, unknown_NULL_type_2);
6982 }
6983
6984 /* Verify that initial_svalue are handled as expected.  */
6985
6986 static void
6987 test_initial_svalue_folding ()
6988 {
6989   region_model_manager mgr;
6990   tree x = build_global_decl ("x", integer_type_node);
6991   tree y = build_global_decl ("y", integer_type_node);
6992
6993   test_region_model_context ctxt;
6994   region_model model (&mgr);
6995   const svalue *x_init = model.get_rvalue (x, &ctxt);
6996   const svalue *y_init = model.get_rvalue (y, &ctxt);
6997   ASSERT_NE (x_init, y_init);
6998   const region *x_reg = model.get_lvalue (x, &ctxt);
6999   ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg));
7000
7001 }
7002
7003 /* Verify that unary ops are folded as expected.  */
7004
7005 static void
7006 test_unaryop_svalue_folding ()
7007 {
7008   region_model_manager mgr;
7009   tree x = build_global_decl ("x", integer_type_node);
7010   tree y = build_global_decl ("y", integer_type_node);
7011
7012   test_region_model_context ctxt;
7013   region_model model (&mgr);
7014   const svalue *x_init = model.get_rvalue (x, &ctxt);
7015   const svalue *y_init = model.get_rvalue (y, &ctxt);
7016   const region *x_reg = model.get_lvalue (x, &ctxt);
7017   ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg));
7018
7019   /* "(int)x" -> "x".  */
7020   ASSERT_EQ (x_init, mgr.get_or_create_cast (integer_type_node, x_init));
7021
7022   /* "(void *)x" -> something other than "x".  */
7023   ASSERT_NE (x_init, mgr.get_or_create_cast (ptr_type_node, x_init));
7024
7025   /* "!(x == y)" -> "x != y".  */
7026   ASSERT_EQ (mgr.get_or_create_unaryop
7027                (boolean_type_node, TRUTH_NOT_EXPR,
7028                 mgr.get_or_create_binop (boolean_type_node, EQ_EXPR,
7029                                          x_init, y_init)),
7030              mgr.get_or_create_binop (boolean_type_node, NE_EXPR,
7031                                       x_init, y_init));
7032   /* "!(x > y)" -> "x <= y".  */
7033   ASSERT_EQ (mgr.get_or_create_unaryop
7034                (boolean_type_node, TRUTH_NOT_EXPR,
7035                 mgr.get_or_create_binop (boolean_type_node, GT_EXPR,
7036                                          x_init, y_init)),
7037              mgr.get_or_create_binop (boolean_type_node, LE_EXPR,
7038                                       x_init, y_init));
7039 }
7040
7041 /* Verify that binops on constant svalues are folded.  */
7042
7043 static void
7044 test_binop_svalue_folding ()
7045 {
7046 #define NUM_CSTS 10
7047   tree cst_int[NUM_CSTS];
7048   region_model_manager mgr;
7049   const svalue *cst_sval[NUM_CSTS];
7050   for (int i = 0; i < NUM_CSTS; i++)
7051     {
7052       cst_int[i] = build_int_cst (integer_type_node, i);
7053       cst_sval[i] = mgr.get_or_create_constant_svalue (cst_int[i]);
7054       ASSERT_EQ (cst_sval[i]->get_kind (), SK_CONSTANT);
7055       ASSERT_EQ (cst_sval[i]->maybe_get_constant (), cst_int[i]);
7056     }
7057
7058   for (int i = 0; i < NUM_CSTS; i++)
7059     for (int j = 0; j < NUM_CSTS; j++)
7060       {
7061         if (i != j)
7062           ASSERT_NE (cst_sval[i], cst_sval[j]);
7063         if (i + j < NUM_CSTS)
7064           {
7065             const svalue *sum
7066               = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7067                                          cst_sval[i], cst_sval[j]);
7068             ASSERT_EQ (sum, cst_sval[i + j]);
7069           }
7070         if (i - j >= 0)
7071           {
7072             const svalue *difference
7073               = mgr.get_or_create_binop (integer_type_node, MINUS_EXPR,
7074                                          cst_sval[i], cst_sval[j]);
7075             ASSERT_EQ (difference, cst_sval[i - j]);
7076           }
7077         if (i * j < NUM_CSTS)
7078           {
7079             const svalue *product
7080               = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7081                                          cst_sval[i], cst_sval[j]);
7082             ASSERT_EQ (product, cst_sval[i * j]);
7083           }
7084         const svalue *eq = mgr.get_or_create_binop (integer_type_node, EQ_EXPR,
7085                                                cst_sval[i], cst_sval[j]);
7086         ASSERT_EQ (eq, i == j ? cst_sval[1] : cst_sval [0]);
7087         const svalue *neq = mgr.get_or_create_binop (integer_type_node, NE_EXPR,
7088                                                 cst_sval[i], cst_sval[j]);
7089         ASSERT_EQ (neq, i != j ? cst_sval[1] : cst_sval [0]);
7090         // etc
7091       }
7092
7093   tree x = build_global_decl ("x", integer_type_node);
7094
7095   test_region_model_context ctxt;
7096   region_model model (&mgr);
7097   const svalue *x_init = model.get_rvalue (x, &ctxt);
7098
7099   /* PLUS_EXPR folding.  */
7100   const svalue *x_init_plus_zero
7101     = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7102                                x_init, cst_sval[0]);
7103   ASSERT_EQ (x_init_plus_zero, x_init);
7104   const svalue *zero_plus_x_init
7105     = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7106                                cst_sval[0], x_init);
7107   ASSERT_EQ (zero_plus_x_init, x_init);
7108
7109   /* MULT_EXPR folding.  */
7110   const svalue *x_init_times_zero
7111     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7112                                x_init, cst_sval[0]);
7113   ASSERT_EQ (x_init_times_zero, cst_sval[0]);
7114   const svalue *zero_times_x_init
7115     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7116                                cst_sval[0], x_init);
7117   ASSERT_EQ (zero_times_x_init, cst_sval[0]);
7118
7119   const svalue *x_init_times_one
7120     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7121                                x_init, cst_sval[1]);
7122   ASSERT_EQ (x_init_times_one, x_init);
7123   const svalue *one_times_x_init
7124     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7125                                cst_sval[1], x_init);
7126   ASSERT_EQ (one_times_x_init, x_init);
7127
7128   // etc
7129   // TODO: do we want to use the match-and-simplify DSL for this?
7130
7131   /* Verify that binops put any constants on the RHS.  */
7132   const svalue *four_times_x_init
7133     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7134                                cst_sval[4], x_init);
7135   const svalue *x_init_times_four
7136     = mgr.get_or_create_binop (integer_type_node, MULT_EXPR,
7137                                x_init, cst_sval[4]);
7138   ASSERT_EQ (four_times_x_init, x_init_times_four);
7139   const binop_svalue *binop = four_times_x_init->dyn_cast_binop_svalue ();
7140   ASSERT_EQ (binop->get_op (), MULT_EXPR);
7141   ASSERT_EQ (binop->get_arg0 (), x_init);
7142   ASSERT_EQ (binop->get_arg1 (), cst_sval[4]);
7143
7144   /* Verify that ((x + 1) + 1) == (x + 2).  */
7145   const svalue *x_init_plus_one
7146     = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7147                                x_init, cst_sval[1]);
7148   const svalue *x_init_plus_two
7149     = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7150                                x_init, cst_sval[2]);
7151   const svalue *x_init_plus_one_plus_one
7152     = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR,
7153                                x_init_plus_one, cst_sval[1]);
7154   ASSERT_EQ (x_init_plus_one_plus_one, x_init_plus_two);
7155
7156   /* Verify various binops on booleans.  */
7157   {
7158     const svalue *sval_true = mgr.get_or_create_int_cst (boolean_type_node, 1);
7159     const svalue *sval_false = mgr.get_or_create_int_cst (boolean_type_node, 0);
7160     const svalue *sval_unknown
7161       = mgr.get_or_create_unknown_svalue (boolean_type_node);
7162     const placeholder_svalue sval_placeholder (boolean_type_node, "v");
7163     for (auto op : {BIT_IOR_EXPR, TRUTH_OR_EXPR})
7164       {
7165         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7166                                             sval_true, sval_unknown),
7167                    sval_true);
7168         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7169                                             sval_false, sval_unknown),
7170                    sval_unknown);
7171         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7172                                             sval_false, &sval_placeholder),
7173                    &sval_placeholder);
7174       }
7175     for (auto op : {BIT_AND_EXPR, TRUTH_AND_EXPR})
7176       {
7177         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7178                                             sval_false, sval_unknown),
7179                    sval_false);
7180         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7181                                             sval_true, sval_unknown),
7182                    sval_unknown);
7183         ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
7184                                             sval_true, &sval_placeholder),
7185                    &sval_placeholder);
7186       }
7187   }
7188 }
7189
7190 /* Verify that sub_svalues are folded as expected.  */
7191
7192 static void
7193 test_sub_svalue_folding ()
7194 {
7195   coord_test ct;
7196   tree c = build_global_decl ("c", ct.m_coord_type);
7197   tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
7198                      c, ct.m_x_field, NULL_TREE);
7199
7200   region_model_manager mgr;
7201   region_model model (&mgr);
7202   test_region_model_context ctxt;
7203   const region *c_x_reg = model.get_lvalue (c_x, &ctxt);
7204
7205   /* Verify that sub_svalue of "unknown" simply
7206      yields an unknown.  */
7207
7208   const svalue *unknown = mgr.get_or_create_unknown_svalue (ct.m_coord_type);
7209   const svalue *sub = mgr.get_or_create_sub_svalue (TREE_TYPE (ct.m_x_field),
7210                                                       unknown, c_x_reg);
7211   ASSERT_EQ (sub->get_kind (), SK_UNKNOWN);
7212   ASSERT_EQ (sub->get_type (), TREE_TYPE (ct.m_x_field));
7213 }
7214
7215 /* Get BIT within VAL as a symbolic value within MGR.  */
7216
7217 static const svalue *
7218 get_bit (region_model_manager *mgr,
7219          bit_offset_t bit,
7220          unsigned HOST_WIDE_INT val)
7221 {
7222   const svalue *inner_svalue
7223     = mgr->get_or_create_int_cst (unsigned_type_node, val);
7224   return mgr->get_or_create_bits_within (boolean_type_node,
7225                                          bit_range (bit, 1),
7226                                          inner_svalue);
7227 }
7228
7229 /* Verify that bits_within_svalues are folded as expected.  */
7230
7231 static void
7232 test_bits_within_svalue_folding ()
7233 {
7234   region_model_manager mgr;
7235
7236   const svalue *zero = mgr.get_or_create_int_cst (boolean_type_node, 0);
7237   const svalue *one = mgr.get_or_create_int_cst (boolean_type_node, 1);
7238
7239   {
7240     const unsigned val = 0x0000;
7241     for (unsigned bit = 0; bit < 16; bit++)
7242       ASSERT_EQ (get_bit (&mgr, bit, val), zero);
7243   }
7244
7245   {
7246     const unsigned val = 0x0001;
7247     ASSERT_EQ (get_bit (&mgr, 0, val), one);
7248     for (unsigned bit = 1; bit < 16; bit++)
7249       ASSERT_EQ (get_bit (&mgr, bit, val), zero);
7250   }
7251
7252   {
7253     const unsigned val = 0x8000;
7254     for (unsigned bit = 0; bit < 15; bit++)
7255       ASSERT_EQ (get_bit (&mgr, bit, val), zero);
7256     ASSERT_EQ (get_bit (&mgr, 15, val), one);
7257   }
7258
7259   {
7260     const unsigned val = 0xFFFF;
7261     for (unsigned bit = 0; bit < 16; bit++)
7262       ASSERT_EQ (get_bit (&mgr, bit, val), one);
7263   }
7264 }
7265
7266 /* Test that region::descendent_of_p works as expected.  */
7267
7268 static void
7269 test_descendent_of_p ()
7270 {
7271   region_model_manager mgr;
7272   const region *stack = mgr.get_stack_region ();
7273   const region *heap = mgr.get_heap_region ();
7274   const region *code = mgr.get_code_region ();
7275   const region *globals = mgr.get_globals_region ();
7276
7277   /* descendent_of_p should return true when used on the region itself.  */
7278   ASSERT_TRUE (stack->descendent_of_p (stack));
7279   ASSERT_FALSE (stack->descendent_of_p (heap));
7280   ASSERT_FALSE (stack->descendent_of_p (code));
7281   ASSERT_FALSE (stack->descendent_of_p (globals));
7282
7283   tree x = build_global_decl ("x", integer_type_node);
7284   const region *x_reg = mgr.get_region_for_global (x);
7285   ASSERT_TRUE (x_reg->descendent_of_p (globals));
7286
7287   /* A cast_region should be a descendent of the original region.  */
7288   const region *cast_reg = mgr.get_cast_region (x_reg, ptr_type_node);
7289   ASSERT_TRUE (cast_reg->descendent_of_p (x_reg));
7290 }
7291
7292 /* Verify that bit_range_region works as expected.  */
7293
7294 static void
7295 test_bit_range_regions ()
7296 {
7297   tree x = build_global_decl ("x", integer_type_node);
7298   region_model_manager mgr;
7299   const region *x_reg = mgr.get_region_for_global (x);
7300   const region *byte0
7301     = mgr.get_bit_range (x_reg, char_type_node, bit_range (0, 8));
7302   const region *byte1
7303     = mgr.get_bit_range (x_reg, char_type_node, bit_range (8, 8));
7304   ASSERT_TRUE (byte0->descendent_of_p (x_reg));
7305   ASSERT_TRUE (byte1->descendent_of_p (x_reg));
7306   ASSERT_NE (byte0, byte1);
7307 }
7308
7309 /* Verify that simple assignments work as expected.  */
7310
7311 static void
7312 test_assignment ()
7313 {
7314   tree int_0 = build_int_cst (integer_type_node, 0);
7315   tree x = build_global_decl ("x", integer_type_node);
7316   tree y = build_global_decl ("y", integer_type_node);
7317
7318   /* "x == 0", then use of y, then "y = 0;".  */
7319   region_model_manager mgr;
7320   region_model model (&mgr);
7321   ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
7322   ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, int_0);
7323   model.set_value (model.get_lvalue (y, NULL),
7324                    model.get_rvalue (int_0, NULL),
7325                    NULL);
7326   ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, int_0);
7327   ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, x);
7328 }
7329
7330 /* Verify that compound assignments work as expected.  */
7331
7332 static void
7333 test_compound_assignment ()
7334 {
7335   coord_test ct;
7336
7337   tree c = build_global_decl ("c", ct.m_coord_type);
7338   tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
7339                      c, ct.m_x_field, NULL_TREE);
7340   tree c_y = build3 (COMPONENT_REF, TREE_TYPE (ct.m_y_field),
7341                      c, ct.m_y_field, NULL_TREE);
7342   tree d = build_global_decl ("d", ct.m_coord_type);
7343   tree d_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
7344                      d, ct.m_x_field, NULL_TREE);
7345   tree d_y = build3 (COMPONENT_REF, TREE_TYPE (ct.m_y_field),
7346                      d, ct.m_y_field, NULL_TREE);
7347
7348   tree int_17 = build_int_cst (integer_type_node, 17);
7349   tree int_m3 = build_int_cst (integer_type_node, -3);
7350
7351   region_model_manager mgr;
7352   region_model model (&mgr);
7353   model.set_value (c_x, int_17, NULL);
7354   model.set_value (c_y, int_m3, NULL);
7355
7356   /* Copy c to d.  */
7357   const svalue *sval = model.get_rvalue (c, NULL);
7358   model.set_value (model.get_lvalue (d, NULL), sval, NULL);
7359
7360   /* Check that the fields have the same svalues.  */
7361   ASSERT_EQ (model.get_rvalue (c_x, NULL), model.get_rvalue (d_x, NULL));
7362   ASSERT_EQ (model.get_rvalue (c_y, NULL), model.get_rvalue (d_y, NULL));
7363 }
7364
7365 /* Verify the details of pushing and popping stack frames.  */
7366
7367 static void
7368 test_stack_frames ()
7369 {
7370   tree int_42 = build_int_cst (integer_type_node, 42);
7371   tree int_10 = build_int_cst (integer_type_node, 10);
7372   tree int_5 = build_int_cst (integer_type_node, 5);
7373   tree int_0 = build_int_cst (integer_type_node, 0);
7374
7375   auto_vec <tree> param_types;
7376   tree parent_fndecl = make_fndecl (integer_type_node,
7377                                     "parent_fn",
7378                                     param_types);
7379   allocate_struct_function (parent_fndecl, true);
7380
7381   tree child_fndecl = make_fndecl (integer_type_node,
7382                                    "child_fn",
7383                                    param_types);
7384   allocate_struct_function (child_fndecl, true);
7385
7386   /* "a" and "b" in the parent frame.  */
7387   tree a = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7388                        get_identifier ("a"),
7389                        integer_type_node);
7390   DECL_CONTEXT (a) = parent_fndecl;
7391   tree b = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7392                        get_identifier ("b"),
7393                        integer_type_node);
7394   DECL_CONTEXT (b) = parent_fndecl;
7395   /* "x" and "y" in a child frame.  */
7396   tree x = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7397                        get_identifier ("x"),
7398                        integer_type_node);
7399   DECL_CONTEXT (x) = child_fndecl;
7400   tree y = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7401                        get_identifier ("y"),
7402                        integer_type_node);
7403   DECL_CONTEXT (y) = child_fndecl;
7404
7405   /* "p" global.  */
7406   tree p = build_global_decl ("p", ptr_type_node);
7407
7408   /* "q" global.  */
7409   tree q = build_global_decl ("q", ptr_type_node);
7410
7411   region_model_manager mgr;
7412   test_region_model_context ctxt;
7413   region_model model (&mgr);
7414
7415   /* Push stack frame for "parent_fn".  */
7416   const region *parent_frame_reg
7417     = model.push_frame (DECL_STRUCT_FUNCTION (parent_fndecl),
7418                         NULL, &ctxt);
7419   ASSERT_EQ (model.get_current_frame (), parent_frame_reg);
7420   ASSERT_TRUE (model.region_exists_p (parent_frame_reg));
7421   const region *a_in_parent_reg = model.get_lvalue (a, &ctxt);
7422   model.set_value (a_in_parent_reg,
7423                    model.get_rvalue (int_42, &ctxt),
7424                    &ctxt);
7425   ASSERT_EQ (a_in_parent_reg->maybe_get_frame_region (), parent_frame_reg);
7426
7427   model.add_constraint (b, LT_EXPR, int_10, &ctxt);
7428   ASSERT_EQ (model.eval_condition (b, LT_EXPR, int_10, &ctxt),
7429              tristate (tristate::TS_TRUE));
7430
7431   /* Push stack frame for "child_fn".  */
7432   const region *child_frame_reg
7433     = model.push_frame (DECL_STRUCT_FUNCTION (child_fndecl), NULL, &ctxt);
7434   ASSERT_EQ (model.get_current_frame (), child_frame_reg);
7435   ASSERT_TRUE (model.region_exists_p (child_frame_reg));
7436   const region *x_in_child_reg = model.get_lvalue (x, &ctxt);
7437   model.set_value (x_in_child_reg,
7438                    model.get_rvalue (int_0, &ctxt),
7439                    &ctxt);
7440   ASSERT_EQ (x_in_child_reg->maybe_get_frame_region (), child_frame_reg);
7441
7442   model.add_constraint (y, NE_EXPR, int_5, &ctxt);
7443   ASSERT_EQ (model.eval_condition (y, NE_EXPR, int_5, &ctxt),
7444              tristate (tristate::TS_TRUE));
7445
7446   /* Point a global pointer at a local in the child frame:  p = &x.  */
7447   const region *p_in_globals_reg = model.get_lvalue (p, &ctxt);
7448   model.set_value (p_in_globals_reg,
7449                    mgr.get_ptr_svalue (ptr_type_node, x_in_child_reg),
7450                    &ctxt);
7451   ASSERT_EQ (p_in_globals_reg->maybe_get_frame_region (), NULL);
7452
7453   /* Point another global pointer at p: q = &p.  */
7454   const region *q_in_globals_reg = model.get_lvalue (q, &ctxt);
7455   model.set_value (q_in_globals_reg,
7456                    mgr.get_ptr_svalue (ptr_type_node, p_in_globals_reg),
7457                    &ctxt);
7458
7459   /* Test region::descendent_of_p.  */
7460   ASSERT_TRUE (child_frame_reg->descendent_of_p (child_frame_reg));
7461   ASSERT_TRUE (x_in_child_reg->descendent_of_p (child_frame_reg));
7462   ASSERT_FALSE (a_in_parent_reg->descendent_of_p (child_frame_reg));
7463
7464   /* Pop the "child_fn" frame from the stack.  */
7465   model.pop_frame (NULL, NULL, &ctxt);
7466   ASSERT_FALSE (model.region_exists_p (child_frame_reg));
7467   ASSERT_TRUE (model.region_exists_p (parent_frame_reg));
7468
7469   /* Verify that p (which was pointing at the local "x" in the popped
7470      frame) has been poisoned.  */
7471   const svalue *new_p_sval = model.get_rvalue (p, NULL);
7472   ASSERT_EQ (new_p_sval->get_kind (), SK_POISONED);
7473   ASSERT_EQ (new_p_sval->dyn_cast_poisoned_svalue ()->get_poison_kind (),
7474              POISON_KIND_POPPED_STACK);
7475
7476   /* Verify that q still points to p, in spite of the region
7477      renumbering.  */
7478   const svalue *new_q_sval = model.get_rvalue (q, &ctxt);
7479   ASSERT_EQ (new_q_sval->get_kind (), SK_REGION);
7480   ASSERT_EQ (new_q_sval->maybe_get_region (),
7481              model.get_lvalue (p, &ctxt));
7482
7483   /* Verify that top of stack has been updated.  */
7484   ASSERT_EQ (model.get_current_frame (), parent_frame_reg);
7485
7486   /* Verify locals in parent frame.  */
7487   /* Verify "a" still has its value.  */
7488   const svalue *new_a_sval = model.get_rvalue (a, &ctxt);
7489   ASSERT_EQ (new_a_sval->get_kind (), SK_CONSTANT);
7490   ASSERT_EQ (new_a_sval->dyn_cast_constant_svalue ()->get_constant (),
7491              int_42);
7492   /* Verify "b" still has its constraint.  */
7493   ASSERT_EQ (model.eval_condition (b, LT_EXPR, int_10, &ctxt),
7494              tristate (tristate::TS_TRUE));
7495 }
7496
7497 /* Verify that get_representative_path_var works as expected, that
7498    we can map from regions to parms and back within a recursive call
7499    stack.  */
7500
7501 static void
7502 test_get_representative_path_var ()
7503 {
7504   auto_vec <tree> param_types;
7505   tree fndecl = make_fndecl (integer_type_node,
7506                              "factorial",
7507                              param_types);
7508   allocate_struct_function (fndecl, true);
7509
7510   /* Parm "n".  */
7511   tree n = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7512                        get_identifier ("n"),
7513                        integer_type_node);
7514   DECL_CONTEXT (n) = fndecl;
7515
7516   region_model_manager mgr;
7517   test_region_model_context ctxt;
7518   region_model model (&mgr);
7519
7520   /* Push 5 stack frames for "factorial", each with a param  */
7521   auto_vec<const region *> parm_regs;
7522   auto_vec<const svalue *> parm_svals;
7523   for (int depth = 0; depth < 5; depth++)
7524     {
7525       const region *frame_n_reg
7526         = model.push_frame (DECL_STRUCT_FUNCTION (fndecl), NULL, &ctxt);
7527       const region *parm_n_reg = model.get_lvalue (path_var (n, depth), &ctxt);
7528       parm_regs.safe_push (parm_n_reg);
7529
7530       ASSERT_EQ (parm_n_reg->get_parent_region (), frame_n_reg);
7531       const svalue *sval_n = mgr.get_or_create_initial_value (parm_n_reg);
7532       parm_svals.safe_push (sval_n);
7533     }
7534
7535   /* Verify that we can recognize that the regions are the parms,
7536      at every depth.  */
7537   for (int depth = 0; depth < 5; depth++)
7538     {
7539       {
7540         svalue_set visited;
7541         ASSERT_EQ (model.get_representative_path_var (parm_regs[depth],
7542                                                       &visited),
7543                    path_var (n, depth + 1));
7544       }
7545       /* ...and that we can lookup lvalues for locals for all frames,
7546          not just the top.  */
7547       ASSERT_EQ (model.get_lvalue (path_var (n, depth), NULL),
7548                  parm_regs[depth]);
7549       /* ...and that we can locate the svalues.  */
7550       {
7551         svalue_set visited;
7552         ASSERT_EQ (model.get_representative_path_var (parm_svals[depth],
7553                                                       &visited),
7554                    path_var (n, depth + 1));
7555       }
7556     }
7557 }
7558
7559 /* Ensure that region_model::operator== works as expected.  */
7560
7561 static void
7562 test_equality_1 ()
7563 {
7564   tree int_42 = build_int_cst (integer_type_node, 42);
7565   tree int_17 = build_int_cst (integer_type_node, 17);
7566
7567 /* Verify that "empty" region_model instances are equal to each other.  */
7568   region_model_manager mgr;
7569   region_model model0 (&mgr);
7570   region_model model1 (&mgr);
7571   ASSERT_EQ (model0, model1);
7572
7573   /* Verify that setting state in model1 makes the models non-equal.  */
7574   tree x = build_global_decl ("x", integer_type_node);
7575   model0.set_value (x, int_42, NULL);
7576   ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
7577   ASSERT_NE (model0, model1);
7578
7579   /* Verify the copy-ctor.  */
7580   region_model model2 (model0);
7581   ASSERT_EQ (model0, model2);
7582   ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
7583   ASSERT_NE (model1, model2);
7584
7585   /* Verify that models obtained from copy-ctor are independently editable
7586      w/o affecting the original model.  */
7587   model2.set_value (x, int_17, NULL);
7588   ASSERT_NE (model0, model2);
7589   ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_17);
7590   ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
7591 }
7592
7593 /* Verify that region models for
7594       x = 42; y = 113;
7595    and
7596       y = 113; x = 42;
7597    are equal.  */
7598
7599 static void
7600 test_canonicalization_2 ()
7601 {
7602   tree int_42 = build_int_cst (integer_type_node, 42);
7603   tree int_113 = build_int_cst (integer_type_node, 113);
7604   tree x = build_global_decl ("x", integer_type_node);
7605   tree y = build_global_decl ("y", integer_type_node);
7606
7607   region_model_manager mgr;
7608   region_model model0 (&mgr);
7609   model0.set_value (model0.get_lvalue (x, NULL),
7610                     model0.get_rvalue (int_42, NULL),
7611                     NULL);
7612   model0.set_value (model0.get_lvalue (y, NULL),
7613                     model0.get_rvalue (int_113, NULL),
7614                     NULL);
7615
7616   region_model model1 (&mgr);
7617   model1.set_value (model1.get_lvalue (y, NULL),
7618                     model1.get_rvalue (int_113, NULL),
7619                     NULL);
7620   model1.set_value (model1.get_lvalue (x, NULL),
7621                     model1.get_rvalue (int_42, NULL),
7622                     NULL);
7623
7624   ASSERT_EQ (model0, model1);
7625 }
7626
7627 /* Verify that constraints for
7628      x > 3 && y > 42
7629    and
7630      y > 42 && x > 3
7631    are equal after canonicalization.  */
7632
7633 static void
7634 test_canonicalization_3 ()
7635 {
7636   tree int_3 = build_int_cst (integer_type_node, 3);
7637   tree int_42 = build_int_cst (integer_type_node, 42);
7638   tree x = build_global_decl ("x", integer_type_node);
7639   tree y = build_global_decl ("y", integer_type_node);
7640
7641   region_model_manager mgr;
7642   region_model model0 (&mgr);
7643   model0.add_constraint (x, GT_EXPR, int_3, NULL);
7644   model0.add_constraint (y, GT_EXPR, int_42, NULL);
7645
7646   region_model model1 (&mgr);
7647   model1.add_constraint (y, GT_EXPR, int_42, NULL);
7648   model1.add_constraint (x, GT_EXPR, int_3, NULL);
7649
7650   model0.canonicalize ();
7651   model1.canonicalize ();
7652   ASSERT_EQ (model0, model1);
7653 }
7654
7655 /* Verify that we can canonicalize a model containing NaN and other real
7656    constants.  */
7657
7658 static void
7659 test_canonicalization_4 ()
7660 {
7661   auto_vec<tree> csts;
7662   append_interesting_constants (&csts);
7663
7664   region_model_manager mgr;
7665   region_model model (&mgr);
7666
7667   for (tree cst : csts)
7668     model.get_rvalue (cst, NULL);
7669
7670   model.canonicalize ();
7671 }
7672
7673 /* Assert that if we have two region_model instances
7674    with values VAL_A and VAL_B for EXPR that they are
7675    mergable.  Write the merged model to *OUT_MERGED_MODEL,
7676    and the merged svalue ptr to *OUT_MERGED_SVALUE.
7677    If VAL_A or VAL_B are NULL_TREE, don't populate EXPR
7678    for that region_model.  */
7679
7680 static void
7681 assert_region_models_merge (tree expr, tree val_a, tree val_b,
7682                              region_model *out_merged_model,
7683                              const svalue **out_merged_svalue)
7684 {
7685   region_model_manager *mgr = out_merged_model->get_manager ();
7686   program_point point (program_point::origin (*mgr));
7687   test_region_model_context ctxt;
7688   region_model model0 (mgr);
7689   region_model model1 (mgr);
7690   if (val_a)
7691     model0.set_value (model0.get_lvalue (expr, &ctxt),
7692                       model0.get_rvalue (val_a, &ctxt),
7693                       &ctxt);
7694   if (val_b)
7695     model1.set_value (model1.get_lvalue (expr, &ctxt),
7696                       model1.get_rvalue (val_b, &ctxt),
7697                       &ctxt);
7698
7699   /* They should be mergeable.  */
7700   ASSERT_TRUE (model0.can_merge_with_p (model1, point, out_merged_model));
7701   *out_merged_svalue = out_merged_model->get_rvalue (expr, &ctxt);
7702 }
7703
7704 /* Verify that we can merge region_model instances.  */
7705
7706 static void
7707 test_state_merging ()
7708 {
7709   tree int_42 = build_int_cst (integer_type_node, 42);
7710   tree int_113 = build_int_cst (integer_type_node, 113);
7711   tree x = build_global_decl ("x", integer_type_node);
7712   tree y = build_global_decl ("y", integer_type_node);
7713   tree z = build_global_decl ("z", integer_type_node);
7714   tree p = build_global_decl ("p", ptr_type_node);
7715
7716   tree addr_of_y = build1 (ADDR_EXPR, ptr_type_node, y);
7717   tree addr_of_z = build1 (ADDR_EXPR, ptr_type_node, z);
7718
7719   auto_vec <tree> param_types;
7720   tree test_fndecl = make_fndecl (integer_type_node, "test_fn", param_types);
7721   allocate_struct_function (test_fndecl, true);
7722
7723   /* Param "a".  */
7724   tree a = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7725                        get_identifier ("a"),
7726                        integer_type_node);
7727   DECL_CONTEXT (a) = test_fndecl;
7728   tree addr_of_a = build1 (ADDR_EXPR, ptr_type_node, a);
7729
7730   /* Param "q", a pointer.  */
7731   tree q = build_decl (UNKNOWN_LOCATION, PARM_DECL,
7732                        get_identifier ("q"),
7733                        ptr_type_node);
7734   DECL_CONTEXT (q) = test_fndecl;
7735
7736   region_model_manager mgr;
7737   program_point point (program_point::origin (mgr));
7738
7739   {
7740     region_model model0 (&mgr);
7741     region_model model1 (&mgr);
7742     region_model merged (&mgr);
7743     /* Verify empty models can be merged.  */
7744     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7745     ASSERT_EQ (model0, merged);
7746   }
7747
7748   /* Verify that we can merge two contradictory constraints on the
7749      value for a global.  */
7750   /* TODO: verify that the merged model doesn't have a value for
7751      the global  */
7752   {
7753     region_model model0 (&mgr);
7754     region_model model1 (&mgr);
7755     region_model merged (&mgr);
7756     test_region_model_context ctxt;
7757     model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
7758     model1.add_constraint (x, EQ_EXPR, int_113, &ctxt);
7759     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7760     ASSERT_NE (model0, merged);
7761     ASSERT_NE (model1, merged);
7762   }
7763
7764   /* Verify handling of a PARM_DECL.  */
7765   {
7766     test_region_model_context ctxt;
7767     region_model model0 (&mgr);
7768     region_model model1 (&mgr);
7769     ASSERT_EQ (model0.get_stack_depth (), 0);
7770     model0.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, &ctxt);
7771     ASSERT_EQ (model0.get_stack_depth (), 1);
7772     model1.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, &ctxt);
7773
7774     placeholder_svalue test_sval (integer_type_node, "test sval");
7775     model0.set_value (model0.get_lvalue (a, &ctxt), &test_sval, &ctxt);
7776     model1.set_value (model1.get_lvalue (a, &ctxt), &test_sval, &ctxt);
7777     ASSERT_EQ (model0, model1);
7778
7779     /* They should be mergeable, and the result should be the same.  */
7780     region_model merged (&mgr);
7781     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7782     ASSERT_EQ (model0, merged);
7783     /* In particular, "a" should have the placeholder value.  */
7784     ASSERT_EQ (merged.get_rvalue (a, &ctxt), &test_sval);
7785   }
7786
7787   /* Verify handling of a global.  */
7788   {
7789     test_region_model_context ctxt;
7790     region_model model0 (&mgr);
7791     region_model model1 (&mgr);
7792
7793     placeholder_svalue test_sval (integer_type_node, "test sval");
7794     model0.set_value (model0.get_lvalue (x, &ctxt), &test_sval, &ctxt);
7795     model1.set_value (model1.get_lvalue (x, &ctxt), &test_sval, &ctxt);
7796     ASSERT_EQ (model0, model1);
7797
7798     /* They should be mergeable, and the result should be the same.  */
7799     region_model merged (&mgr);
7800     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7801     ASSERT_EQ (model0, merged);
7802     /* In particular, "x" should have the placeholder value.  */
7803     ASSERT_EQ (merged.get_rvalue (x, &ctxt), &test_sval);
7804   }
7805
7806   /* Use global-handling to verify various combinations of values.  */
7807
7808   /* Two equal constant values.  */
7809   {
7810     region_model merged (&mgr);
7811     const svalue *merged_x_sval;
7812     assert_region_models_merge (x, int_42, int_42, &merged, &merged_x_sval);
7813
7814     /* In particular, there should be a constant value for "x".  */
7815     ASSERT_EQ (merged_x_sval->get_kind (), SK_CONSTANT);
7816     ASSERT_EQ (merged_x_sval->dyn_cast_constant_svalue ()->get_constant (),
7817                int_42);
7818   }
7819
7820   /* Two non-equal constant values.  */
7821   {
7822     region_model merged (&mgr);
7823     const svalue *merged_x_sval;
7824     assert_region_models_merge (x, int_42, int_113, &merged, &merged_x_sval);
7825
7826     /* In particular, there should be a "widening" value for "x".  */
7827     ASSERT_EQ (merged_x_sval->get_kind (), SK_WIDENING);
7828   }
7829
7830   /* Initial and constant.  */
7831   {
7832     region_model merged (&mgr);
7833     const svalue *merged_x_sval;
7834     assert_region_models_merge (x, NULL_TREE, int_113, &merged, &merged_x_sval);
7835
7836     /* In particular, there should be an unknown value for "x".  */
7837     ASSERT_EQ (merged_x_sval->get_kind (), SK_UNKNOWN);
7838   }
7839
7840   /* Constant and initial.  */
7841   {
7842     region_model merged (&mgr);
7843     const svalue *merged_x_sval;
7844     assert_region_models_merge (x, int_42, NULL_TREE, &merged, &merged_x_sval);
7845
7846     /* In particular, there should be an unknown value for "x".  */
7847     ASSERT_EQ (merged_x_sval->get_kind (), SK_UNKNOWN);
7848   }
7849
7850   /* Unknown and constant.  */
7851   // TODO
7852
7853   /* Pointers: NULL and NULL.  */
7854   // TODO
7855
7856   /* Pointers: NULL and non-NULL.  */
7857   // TODO
7858
7859   /* Pointers: non-NULL and non-NULL: ptr to a local.  */
7860   {
7861     region_model model0 (&mgr);
7862     model0.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, NULL);
7863     model0.set_value (model0.get_lvalue (p, NULL),
7864                       model0.get_rvalue (addr_of_a, NULL), NULL);
7865
7866     region_model model1 (model0);
7867     ASSERT_EQ (model0, model1);
7868
7869     /* They should be mergeable, and the result should be the same.  */
7870     region_model merged (&mgr);
7871     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7872     ASSERT_EQ (model0, merged);
7873   }
7874
7875   /* Pointers: non-NULL and non-NULL: ptr to a global.  */
7876   {
7877     region_model merged (&mgr);
7878     /* p == &y in both input models.  */
7879     const svalue *merged_p_sval;
7880     assert_region_models_merge (p, addr_of_y, addr_of_y, &merged,
7881                                 &merged_p_sval);
7882
7883     /* We should get p == &y in the merged model.  */
7884     ASSERT_EQ (merged_p_sval->get_kind (), SK_REGION);
7885     const region_svalue *merged_p_ptr
7886       = merged_p_sval->dyn_cast_region_svalue ();
7887     const region *merged_p_star_reg = merged_p_ptr->get_pointee ();
7888     ASSERT_EQ (merged_p_star_reg, merged.get_lvalue (y, NULL));
7889   }
7890
7891   /* Pointers: non-NULL ptrs to different globals: should be unknown.  */
7892   {
7893     region_model merged (&mgr);
7894     /* x == &y vs x == &z in the input models; these are actually casts
7895        of the ptrs to "int".  */
7896     const svalue *merged_x_sval;
7897     // TODO:
7898     assert_region_models_merge (x, addr_of_y, addr_of_z, &merged,
7899                                 &merged_x_sval);
7900
7901     /* We should get x == unknown in the merged model.  */
7902     ASSERT_EQ (merged_x_sval->get_kind (), SK_UNKNOWN);
7903   }
7904
7905   /* Pointers: non-NULL and non-NULL: ptr to a heap region.  */
7906   {
7907     test_region_model_context ctxt;
7908     region_model model0 (&mgr);
7909     tree size = build_int_cst (size_type_node, 1024);
7910     const svalue *size_sval = mgr.get_or_create_constant_svalue (size);
7911     const region *new_reg
7912       = model0.create_region_for_heap_alloc (size_sval, &ctxt);
7913     const svalue *ptr_sval = mgr.get_ptr_svalue (ptr_type_node, new_reg);
7914     model0.set_value (model0.get_lvalue (p, &ctxt),
7915                       ptr_sval, &ctxt);
7916
7917     region_model model1 (model0);
7918
7919     ASSERT_EQ (model0, model1);
7920
7921     region_model merged (&mgr);
7922     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7923
7924     /* The merged model ought to be identical.  */
7925     ASSERT_EQ (model0, merged);
7926   }
7927
7928   /* Two regions sharing the same placeholder svalue should continue sharing
7929      it after self-merger.  */
7930   {
7931     test_region_model_context ctxt;
7932     region_model model0 (&mgr);
7933     placeholder_svalue placeholder_sval (integer_type_node, "test");
7934     model0.set_value (model0.get_lvalue (x, &ctxt),
7935                       &placeholder_sval, &ctxt);
7936     model0.set_value (model0.get_lvalue (y, &ctxt), &placeholder_sval, &ctxt);
7937     region_model model1 (model0);
7938
7939     /* They should be mergeable, and the result should be the same.  */
7940     region_model merged (&mgr);
7941     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7942     ASSERT_EQ (model0, merged);
7943
7944     /* In particular, we should have x == y.  */
7945     ASSERT_EQ (merged.eval_condition (x, EQ_EXPR, y, &ctxt),
7946                tristate (tristate::TS_TRUE));
7947   }
7948
7949   {
7950     region_model model0 (&mgr);
7951     region_model model1 (&mgr);
7952     test_region_model_context ctxt;
7953     model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
7954     model1.add_constraint (x, NE_EXPR, int_42, &ctxt);
7955     region_model merged (&mgr);
7956     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7957   }
7958
7959   {
7960     region_model model0 (&mgr);
7961     region_model model1 (&mgr);
7962     test_region_model_context ctxt;
7963     model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
7964     model1.add_constraint (x, NE_EXPR, int_42, &ctxt);
7965     model1.add_constraint (x, EQ_EXPR, int_113, &ctxt);
7966     region_model merged (&mgr);
7967     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7968   }
7969
7970   // TODO: what can't we merge? need at least one such test
7971
7972   /* TODO: various things
7973      - heap regions
7974      - value merging:
7975        - every combination, but in particular
7976            - pairs of regions
7977    */
7978
7979   /* Views.  */
7980   {
7981     test_region_model_context ctxt;
7982     region_model model0 (&mgr);
7983
7984     const region *x_reg = model0.get_lvalue (x, &ctxt);
7985     const region *x_as_ptr = mgr.get_cast_region (x_reg, ptr_type_node);
7986     model0.set_value (x_as_ptr, model0.get_rvalue (addr_of_y, &ctxt), &ctxt);
7987
7988     region_model model1 (model0);
7989     ASSERT_EQ (model1, model0);
7990
7991     /* They should be mergeable, and the result should be the same.  */
7992     region_model merged (&mgr);
7993     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
7994   }
7995
7996   /* Verify that we can merge a model in which a local in an older stack
7997      frame points to a local in a more recent stack frame.  */
7998   {
7999     region_model model0 (&mgr);
8000     model0.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, NULL);
8001     const region *q_in_first_frame = model0.get_lvalue (q, NULL);
8002
8003     /* Push a second frame.  */
8004     const region *reg_2nd_frame
8005       = model0.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, NULL);
8006
8007     /* Have a pointer in the older frame point to a local in the
8008        more recent frame.  */
8009     const svalue *sval_ptr = model0.get_rvalue (addr_of_a, NULL);
8010     model0.set_value (q_in_first_frame, sval_ptr, NULL);
8011
8012     /* Verify that it's pointing at the newer frame.  */
8013     const region *reg_pointee = sval_ptr->maybe_get_region ();
8014     ASSERT_EQ (reg_pointee->get_parent_region (), reg_2nd_frame);
8015
8016     model0.canonicalize ();
8017
8018     region_model model1 (model0);
8019     ASSERT_EQ (model0, model1);
8020
8021     /* They should be mergeable, and the result should be the same
8022        (after canonicalization, at least).  */
8023     region_model merged (&mgr);
8024     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
8025     merged.canonicalize ();
8026     ASSERT_EQ (model0, merged);
8027   }
8028
8029   /* Verify that we can merge a model in which a local points to a global.  */
8030   {
8031     region_model model0 (&mgr);
8032     model0.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, NULL);
8033     model0.set_value (model0.get_lvalue (q, NULL),
8034                       model0.get_rvalue (addr_of_y, NULL), NULL);
8035
8036     region_model model1 (model0);
8037     ASSERT_EQ (model0, model1);
8038
8039     /* They should be mergeable, and the result should be the same
8040        (after canonicalization, at least).  */
8041     region_model merged (&mgr);
8042     ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
8043     ASSERT_EQ (model0, merged);
8044   }
8045 }
8046
8047 /* Verify that constraints are correctly merged when merging region_model
8048    instances.  */
8049
8050 static void
8051 test_constraint_merging ()
8052 {
8053   tree int_0 = build_int_cst (integer_type_node, 0);
8054   tree int_5 = build_int_cst (integer_type_node, 5);
8055   tree x = build_global_decl ("x", integer_type_node);
8056   tree y = build_global_decl ("y", integer_type_node);
8057   tree z = build_global_decl ("z", integer_type_node);
8058   tree n = build_global_decl ("n", integer_type_node);
8059
8060   region_model_manager mgr;
8061   test_region_model_context ctxt;
8062
8063   /* model0: 0 <= (x == y) < n.  */
8064   region_model model0 (&mgr);
8065   model0.add_constraint (x, EQ_EXPR, y, &ctxt);
8066   model0.add_constraint (x, GE_EXPR, int_0, NULL);
8067   model0.add_constraint (x, LT_EXPR, n, NULL);
8068
8069   /* model1: z != 5 && (0 <= x < n).  */
8070   region_model model1 (&mgr);
8071   model1.add_constraint (z, NE_EXPR, int_5, NULL);
8072   model1.add_constraint (x, GE_EXPR, int_0, NULL);
8073   model1.add_constraint (x, LT_EXPR, n, NULL);
8074
8075   /* They should be mergeable; the merged constraints should
8076      be: (0 <= x < n).  */
8077   program_point point (program_point::origin (mgr));
8078   region_model merged (&mgr);
8079   ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
8080
8081   ASSERT_EQ (merged.eval_condition (x, GE_EXPR, int_0, &ctxt),
8082              tristate (tristate::TS_TRUE));
8083   ASSERT_EQ (merged.eval_condition (x, LT_EXPR, n, &ctxt),
8084              tristate (tristate::TS_TRUE));
8085
8086   ASSERT_EQ (merged.eval_condition (z, NE_EXPR, int_5, &ctxt),
8087              tristate (tristate::TS_UNKNOWN));
8088   ASSERT_EQ (merged.eval_condition (x, LT_EXPR, y, &ctxt),
8089              tristate (tristate::TS_UNKNOWN));
8090 }
8091
8092 /* Verify that widening_svalue::eval_condition_without_cm works as
8093    expected.  */
8094
8095 static void
8096 test_widening_constraints ()
8097 {
8098   region_model_manager mgr;
8099   function_point point (program_point::origin (mgr).get_function_point ());
8100   tree int_0 = build_int_cst (integer_type_node, 0);
8101   tree int_m1 = build_int_cst (integer_type_node, -1);
8102   tree int_1 = build_int_cst (integer_type_node, 1);
8103   tree int_256 = build_int_cst (integer_type_node, 256);
8104   test_region_model_context ctxt;
8105   const svalue *int_0_sval = mgr.get_or_create_constant_svalue (int_0);
8106   const svalue *int_1_sval = mgr.get_or_create_constant_svalue (int_1);
8107   const svalue *w_zero_then_one_sval
8108     = mgr.get_or_create_widening_svalue (integer_type_node, point,
8109                                           int_0_sval, int_1_sval);
8110   const widening_svalue *w_zero_then_one
8111     = w_zero_then_one_sval->dyn_cast_widening_svalue ();
8112   ASSERT_EQ (w_zero_then_one->get_direction (),
8113              widening_svalue::DIR_ASCENDING);
8114   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LT_EXPR, int_m1),
8115              tristate::TS_FALSE);
8116   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LT_EXPR, int_0),
8117              tristate::TS_FALSE);
8118   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LT_EXPR, int_1),
8119              tristate::TS_UNKNOWN);
8120   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LT_EXPR, int_256),
8121              tristate::TS_UNKNOWN);
8122
8123   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LE_EXPR, int_m1),
8124              tristate::TS_FALSE);
8125   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LE_EXPR, int_0),
8126              tristate::TS_UNKNOWN);
8127   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LE_EXPR, int_1),
8128              tristate::TS_UNKNOWN);
8129   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (LE_EXPR, int_256),
8130              tristate::TS_UNKNOWN);
8131
8132   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GT_EXPR, int_m1),
8133              tristate::TS_TRUE);
8134   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GT_EXPR, int_0),
8135              tristate::TS_UNKNOWN);
8136   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GT_EXPR, int_1),
8137              tristate::TS_UNKNOWN);
8138   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GT_EXPR, int_256),
8139              tristate::TS_UNKNOWN);
8140
8141   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GE_EXPR, int_m1),
8142              tristate::TS_TRUE);
8143   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GE_EXPR, int_0),
8144              tristate::TS_TRUE);
8145   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GE_EXPR, int_1),
8146              tristate::TS_UNKNOWN);
8147   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (GE_EXPR, int_256),
8148              tristate::TS_UNKNOWN);
8149
8150   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (EQ_EXPR, int_m1),
8151              tristate::TS_FALSE);
8152   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (EQ_EXPR, int_0),
8153              tristate::TS_UNKNOWN);
8154   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (EQ_EXPR, int_1),
8155              tristate::TS_UNKNOWN);
8156   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (EQ_EXPR, int_256),
8157              tristate::TS_UNKNOWN);
8158
8159   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (NE_EXPR, int_m1),
8160              tristate::TS_TRUE);
8161   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (NE_EXPR, int_0),
8162              tristate::TS_UNKNOWN);
8163   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (NE_EXPR, int_1),
8164              tristate::TS_UNKNOWN);
8165   ASSERT_EQ (w_zero_then_one->eval_condition_without_cm (NE_EXPR, int_256),
8166              tristate::TS_UNKNOWN);
8167 }
8168
8169 /* Verify merging constraints for states simulating successive iterations
8170    of a loop.
8171    Simulate:
8172      for (i = 0; i < 256; i++)
8173        [...body...]
8174    i.e. this gimple:.
8175      i_15 = 0;
8176      goto <bb 4>;
8177
8178    <bb 4> :
8179      i_11 = PHI <i_15(2), i_23(3)>
8180      if (i_11 <= 255)
8181        goto <bb 3>;
8182      else
8183        goto [AFTER LOOP]
8184
8185    <bb 3> :
8186      [LOOP BODY]
8187      i_23 = i_11 + 1;
8188
8189    and thus these ops (and resultant states):
8190      i_11 = PHI()
8191        {i_11: 0}
8192      add_constraint (i_11 <= 255) [for the true edge]
8193        {i_11: 0}  [constraint was a no-op]
8194      i_23 = i_11 + 1;
8195        {i_22: 1}
8196      i_11 = PHI()
8197        {i_11: WIDENED (at phi, 0, 1)}
8198      add_constraint (i_11 <= 255) [for the true edge]
8199        {i_11: WIDENED (at phi, 0, 1); WIDENED <= 255}
8200      i_23 = i_11 + 1;
8201        {i_23: (WIDENED (at phi, 0, 1) + 1); WIDENED <= 255}
8202      i_11 = PHI(); merge with state at phi above
8203        {i_11: WIDENED (at phi, 0, 1); WIDENED <= 256}
8204          [changing meaning of "WIDENED" here]
8205      if (i_11 <= 255)
8206         T: {i_11: WIDENED (at phi, 0, 1); WIDENED <= 255}; cache hit
8207         F: {i_11: 256}
8208  */
8209
8210 static void
8211 test_iteration_1 ()
8212 {
8213   region_model_manager mgr;
8214   program_point point (program_point::origin (mgr));
8215
8216   tree int_0 = build_int_cst (integer_type_node, 0);
8217   tree int_1 = build_int_cst (integer_type_node, 1);
8218   tree int_256 = build_int_cst (integer_type_node, 256);
8219   tree int_257 = build_int_cst (integer_type_node, 257);
8220   tree i = build_global_decl ("i", integer_type_node);
8221
8222   test_region_model_context ctxt;
8223
8224   /* model0: i: 0.  */
8225   region_model model0 (&mgr);
8226   model0.set_value (i, int_0, &ctxt);
8227
8228   /* model1: i: 1.  */
8229   region_model model1 (&mgr);
8230   model1.set_value (i, int_1, &ctxt);
8231
8232   /* Should merge "i" to a widened value.  */
8233   region_model model2 (&mgr);
8234   ASSERT_TRUE (model1.can_merge_with_p (model0, point, &model2));
8235   const svalue *merged_i = model2.get_rvalue (i, &ctxt);
8236   ASSERT_EQ (merged_i->get_kind (), SK_WIDENING);
8237   const widening_svalue *w = merged_i->dyn_cast_widening_svalue ();
8238   ASSERT_EQ (w->get_direction (), widening_svalue::DIR_ASCENDING);
8239
8240   /* Add constraint: i < 256  */
8241   model2.add_constraint (i, LT_EXPR, int_256, &ctxt);
8242   ASSERT_EQ (model2.eval_condition (i, LT_EXPR, int_256, &ctxt),
8243              tristate (tristate::TS_TRUE));
8244   ASSERT_EQ (model2.eval_condition (i, GE_EXPR, int_0, &ctxt),
8245              tristate (tristate::TS_TRUE));
8246
8247   /* Try merging with the initial state.  */
8248   region_model model3 (&mgr);
8249   ASSERT_TRUE (model2.can_merge_with_p (model0, point, &model3));
8250   /* Merging the merged value with the initial value should be idempotent,
8251      so that the analysis converges.  */
8252   ASSERT_EQ (model3.get_rvalue (i, &ctxt), merged_i);
8253   /* Merger of 0 and a widening value with constraint < CST
8254      should retain the constraint, even though it was implicit
8255      for the 0 case.  */
8256   ASSERT_EQ (model3.eval_condition (i, LT_EXPR, int_256, &ctxt),
8257              tristate (tristate::TS_TRUE));
8258   /* ...and we should have equality: the analysis should have converged.  */
8259   ASSERT_EQ (model3, model2);
8260
8261   /* "i_23 = i_11 + 1;"  */
8262   region_model model4 (model3);
8263   ASSERT_EQ (model4, model2);
8264   model4.set_value (i, build2 (PLUS_EXPR, integer_type_node, i, int_1), &ctxt);
8265   const svalue *plus_one = model4.get_rvalue (i, &ctxt);
8266   ASSERT_EQ (plus_one->get_kind (), SK_BINOP);
8267
8268   /* Try merging with the "i: 1" state.  */
8269   region_model model5 (&mgr);
8270   ASSERT_TRUE (model4.can_merge_with_p (model1, point, &model5));
8271   ASSERT_EQ (model5.get_rvalue (i, &ctxt), plus_one);
8272   ASSERT_EQ (model5, model4);
8273
8274   /* "i_11 = PHI();" merge with state at phi above.
8275      For i, we should have a merger of WIDENING with WIDENING + 1,
8276      and this should be WIDENING again.  */
8277   region_model model6 (&mgr);
8278   ASSERT_TRUE (model5.can_merge_with_p (model2, point, &model6));
8279   const svalue *merged_widening = model6.get_rvalue (i, &ctxt);
8280   ASSERT_EQ (merged_widening->get_kind (), SK_WIDENING);
8281
8282   ASSERT_CONDITION_TRUE (model6, i, LT_EXPR, int_257);
8283 }
8284
8285 /* Verify that if we mark a pointer to a malloc-ed region as non-NULL,
8286    all cast pointers to that region are also known to be non-NULL.  */
8287
8288 static void
8289 test_malloc_constraints ()
8290 {
8291   region_model_manager mgr;
8292   region_model model (&mgr);
8293   tree p = build_global_decl ("p", ptr_type_node);
8294   tree char_star = build_pointer_type (char_type_node);
8295   tree q = build_global_decl ("q", char_star);
8296   tree null_ptr = build_int_cst (ptr_type_node, 0);
8297
8298   const svalue *size_in_bytes
8299     = mgr.get_or_create_unknown_svalue (size_type_node);
8300   const region *reg = model.create_region_for_heap_alloc (size_in_bytes, NULL);
8301   const svalue *sval = mgr.get_ptr_svalue (ptr_type_node, reg);
8302   model.set_value (model.get_lvalue (p, NULL), sval, NULL);
8303   model.set_value (q, p, NULL);
8304
8305   ASSERT_CONDITION_UNKNOWN (model, p, NE_EXPR, null_ptr);
8306   ASSERT_CONDITION_UNKNOWN (model, p, EQ_EXPR, null_ptr);
8307   ASSERT_CONDITION_UNKNOWN (model, q, NE_EXPR, null_ptr);
8308   ASSERT_CONDITION_UNKNOWN (model, q, EQ_EXPR, null_ptr);
8309
8310   model.add_constraint (p, NE_EXPR, null_ptr, NULL);
8311
8312   ASSERT_CONDITION_TRUE (model, p, NE_EXPR, null_ptr);
8313   ASSERT_CONDITION_FALSE (model, p, EQ_EXPR, null_ptr);
8314   ASSERT_CONDITION_TRUE (model, q, NE_EXPR, null_ptr);
8315   ASSERT_CONDITION_FALSE (model, q, EQ_EXPR, null_ptr);
8316 }
8317
8318 /* Smoketest of getting and setting the value of a variable.  */
8319
8320 static void
8321 test_var ()
8322 {
8323   /* "int i;"  */
8324   tree i = build_global_decl ("i", integer_type_node);
8325
8326   tree int_17 = build_int_cst (integer_type_node, 17);
8327   tree int_m3 = build_int_cst (integer_type_node, -3);
8328
8329   region_model_manager mgr;
8330   region_model model (&mgr);
8331
8332   const region *i_reg = model.get_lvalue (i, NULL);
8333   ASSERT_EQ (i_reg->get_kind (), RK_DECL);
8334
8335   /* Reading "i" should give a symbolic "initial value".  */
8336   const svalue *sval_init = model.get_rvalue (i, NULL);
8337   ASSERT_EQ (sval_init->get_kind (), SK_INITIAL);
8338   ASSERT_EQ (sval_init->dyn_cast_initial_svalue ()->get_region (), i_reg);
8339   /* ..and doing it again should give the same "initial value".  */
8340   ASSERT_EQ (model.get_rvalue (i, NULL), sval_init);
8341
8342   /* "i = 17;".  */
8343   model.set_value (i, int_17, NULL);
8344   ASSERT_EQ (model.get_rvalue (i, NULL),
8345              model.get_rvalue (int_17, NULL));
8346
8347   /* "i = -3;".  */
8348   model.set_value (i, int_m3, NULL);
8349   ASSERT_EQ (model.get_rvalue (i, NULL),
8350              model.get_rvalue (int_m3, NULL));
8351
8352   /* Verify get_offset for "i".  */
8353   {
8354     region_offset offset = i_reg->get_offset (&mgr);
8355     ASSERT_EQ (offset.get_base_region (), i_reg);
8356     ASSERT_EQ (offset.get_bit_offset (), 0);
8357   }
8358 }
8359
8360 static void
8361 test_array_2 ()
8362 {
8363   /* "int arr[10];"  */
8364   tree tlen = size_int (10);
8365   tree arr_type
8366     = build_array_type (integer_type_node, build_index_type (tlen));
8367   tree arr = build_global_decl ("arr", arr_type);
8368
8369   /* "int i;"  */
8370   tree i = build_global_decl ("i", integer_type_node);
8371
8372   tree int_0 = build_int_cst (integer_type_node, 0);
8373   tree int_1 = build_int_cst (integer_type_node, 1);
8374
8375   tree arr_0 = build4 (ARRAY_REF, integer_type_node,
8376                        arr, int_0, NULL_TREE, NULL_TREE);
8377   tree arr_1 = build4 (ARRAY_REF, integer_type_node,
8378                        arr, int_1, NULL_TREE, NULL_TREE);
8379   tree arr_i = build4 (ARRAY_REF, integer_type_node,
8380                        arr, i, NULL_TREE, NULL_TREE);
8381
8382   tree int_17 = build_int_cst (integer_type_node, 17);
8383   tree int_42 = build_int_cst (integer_type_node, 42);
8384   tree int_m3 = build_int_cst (integer_type_node, -3);
8385
8386   region_model_manager mgr;
8387   region_model model (&mgr);
8388   /* "arr[0] = 17;".  */
8389   model.set_value (arr_0, int_17, NULL);
8390   /* "arr[1] = -3;".  */
8391   model.set_value (arr_1, int_m3, NULL);
8392
8393   ASSERT_EQ (model.get_rvalue (arr_0, NULL), model.get_rvalue (int_17, NULL));
8394   ASSERT_EQ (model.get_rvalue (arr_1, NULL), model.get_rvalue (int_m3, NULL));
8395
8396   /* Overwrite a pre-existing binding: "arr[1] = 42;".  */
8397   model.set_value (arr_1, int_42, NULL);
8398   ASSERT_EQ (model.get_rvalue (arr_1, NULL), model.get_rvalue (int_42, NULL));
8399
8400   /* Verify get_offset for "arr[0]".  */
8401   {
8402     const region *arr_0_reg = model.get_lvalue (arr_0, NULL);
8403     region_offset offset = arr_0_reg->get_offset (&mgr);
8404     ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL));
8405     ASSERT_EQ (offset.get_bit_offset (), 0);
8406   }
8407
8408   /* Verify get_offset for "arr[1]".  */
8409   {
8410     const region *arr_1_reg = model.get_lvalue (arr_1, NULL);
8411     region_offset offset = arr_1_reg->get_offset (&mgr);
8412     ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL));
8413     ASSERT_EQ (offset.get_bit_offset (), INT_TYPE_SIZE);
8414   }
8415
8416   /* Verify get_offset for "arr[i]".  */
8417   {
8418     const region *arr_i_reg = model.get_lvalue (arr_i, NULL);
8419     region_offset offset = arr_i_reg->get_offset (&mgr);
8420     ASSERT_EQ (offset.get_base_region (), model.get_lvalue (arr, NULL));
8421     ASSERT_EQ (offset.get_symbolic_byte_offset ()->get_kind (), SK_BINOP);
8422   }
8423
8424   /* "arr[i] = i;" - this should remove the earlier bindings.  */
8425   model.set_value (arr_i, i, NULL);
8426   ASSERT_EQ (model.get_rvalue (arr_i, NULL), model.get_rvalue (i, NULL));
8427   ASSERT_EQ (model.get_rvalue (arr_0, NULL)->get_kind (), SK_UNKNOWN);
8428
8429   /* "arr[0] = 17;" - this should remove the arr[i] binding.  */
8430   model.set_value (arr_0, int_17, NULL);
8431   ASSERT_EQ (model.get_rvalue (arr_0, NULL), model.get_rvalue (int_17, NULL));
8432   ASSERT_EQ (model.get_rvalue (arr_i, NULL)->get_kind (), SK_UNKNOWN);
8433 }
8434
8435 /* Smoketest of dereferencing a pointer via MEM_REF.  */
8436
8437 static void
8438 test_mem_ref ()
8439 {
8440   /*
8441     x = 17;
8442     p = &x;
8443     *p;
8444    */
8445   tree x = build_global_decl ("x", integer_type_node);
8446   tree int_star = build_pointer_type (integer_type_node);
8447   tree p = build_global_decl ("p", int_star);
8448
8449   tree int_17 = build_int_cst (integer_type_node, 17);
8450   tree addr_of_x = build1 (ADDR_EXPR, int_star, x);
8451   tree offset_0 = build_int_cst (integer_type_node, 0);
8452   tree star_p = build2 (MEM_REF, integer_type_node, p, offset_0);
8453
8454   region_model_manager mgr;
8455   region_model model (&mgr);
8456
8457   /* "x = 17;".  */
8458   model.set_value (x, int_17, NULL);
8459
8460   /* "p = &x;".  */
8461   model.set_value (p, addr_of_x, NULL);
8462
8463   const svalue *sval = model.get_rvalue (star_p, NULL);
8464   ASSERT_EQ (sval->maybe_get_constant (), int_17);
8465 }
8466
8467 /* Test for a POINTER_PLUS_EXPR followed by a MEM_REF.
8468    Analogous to this code:
8469      void test_6 (int a[10])
8470      {
8471        __analyzer_eval (a[3] == 42); [should be UNKNOWN]
8472        a[3] = 42;
8473        __analyzer_eval (a[3] == 42); [should be TRUE]
8474      }
8475    from data-model-1.c, which looks like this at the gimple level:
8476        # __analyzer_eval (a[3] == 42); [should be UNKNOWN]
8477        int *_1 = a_10(D) + 12;   # POINTER_PLUS_EXPR
8478        int _2 = *_1;             # MEM_REF
8479        _Bool _3 = _2 == 42;
8480        int _4 = (int) _3;
8481        __analyzer_eval (_4);
8482
8483        # a[3] = 42;
8484        int *_5 = a_10(D) + 12;   # POINTER_PLUS_EXPR
8485        *_5 = 42;                 # MEM_REF
8486
8487        # __analyzer_eval (a[3] == 42); [should be TRUE]
8488        int *_6 = a_10(D) + 12;   # POINTER_PLUS_EXPR
8489        int _7 = *_6;             # MEM_REF
8490        _Bool _8 = _7 == 42;
8491        int _9 = (int) _8;
8492        __analyzer_eval (_9);  */
8493
8494 static void
8495 test_POINTER_PLUS_EXPR_then_MEM_REF ()
8496 {
8497   tree int_star = build_pointer_type (integer_type_node);
8498   tree a = build_global_decl ("a", int_star);
8499   tree offset_12 = build_int_cst (size_type_node, 12);
8500   tree pointer_plus_expr = build2 (POINTER_PLUS_EXPR, int_star, a, offset_12);
8501   tree offset_0 = build_int_cst (integer_type_node, 0);
8502   tree mem_ref = build2 (MEM_REF, integer_type_node,
8503                          pointer_plus_expr, offset_0);
8504   region_model_manager mgr;
8505   region_model m (&mgr);
8506
8507   tree int_42 = build_int_cst (integer_type_node, 42);
8508   m.set_value (mem_ref, int_42, NULL);
8509   ASSERT_EQ (m.get_rvalue (mem_ref, NULL)->maybe_get_constant (), int_42);
8510 }
8511
8512 /* Verify that malloc works.  */
8513
8514 static void
8515 test_malloc ()
8516 {
8517   tree int_star = build_pointer_type (integer_type_node);
8518   tree p = build_global_decl ("p", int_star);
8519   tree n = build_global_decl ("n", integer_type_node);
8520   tree n_times_4 = build2 (MULT_EXPR, size_type_node,
8521                            n, build_int_cst (size_type_node, 4));
8522
8523   region_model_manager mgr;
8524   test_region_model_context ctxt;
8525   region_model model (&mgr);
8526
8527   /* "p = malloc (n * 4);".  */
8528   const svalue *size_sval = model.get_rvalue (n_times_4, &ctxt);
8529   const region *reg = model.create_region_for_heap_alloc (size_sval, &ctxt);
8530   const svalue *ptr = mgr.get_ptr_svalue (int_star, reg);
8531   model.set_value (model.get_lvalue (p, &ctxt), ptr, &ctxt);
8532   ASSERT_EQ (model.get_capacity (reg), size_sval);
8533 }
8534
8535 /* Verify that alloca works.  */
8536
8537 static void
8538 test_alloca ()
8539 {
8540   auto_vec <tree> param_types;
8541   tree fndecl = make_fndecl (integer_type_node,
8542                              "test_fn",
8543                              param_types);
8544   allocate_struct_function (fndecl, true);
8545
8546
8547   tree int_star = build_pointer_type (integer_type_node);
8548   tree p = build_global_decl ("p", int_star);
8549   tree n = build_global_decl ("n", integer_type_node);
8550   tree n_times_4 = build2 (MULT_EXPR, size_type_node,
8551                            n, build_int_cst (size_type_node, 4));
8552
8553   region_model_manager mgr;
8554   test_region_model_context ctxt;
8555   region_model model (&mgr);
8556
8557   /* Push stack frame.  */
8558   const region *frame_reg
8559     = model.push_frame (DECL_STRUCT_FUNCTION (fndecl),
8560                         NULL, &ctxt);
8561   /* "p = alloca (n * 4);".  */
8562   const svalue *size_sval = model.get_rvalue (n_times_4, &ctxt);
8563   const region *reg = model.create_region_for_alloca (size_sval, &ctxt);
8564   ASSERT_EQ (reg->get_parent_region (), frame_reg);
8565   const svalue *ptr = mgr.get_ptr_svalue (int_star, reg);
8566   model.set_value (model.get_lvalue (p, &ctxt), ptr, &ctxt);
8567   ASSERT_EQ (model.get_capacity (reg), size_sval);
8568
8569   /* Verify that the pointers to the alloca region are replaced by
8570      poisoned values when the frame is popped.  */
8571   model.pop_frame (NULL, NULL, &ctxt);
8572   ASSERT_EQ (model.get_rvalue (p, NULL)->get_kind (), SK_POISONED);
8573 }
8574
8575 /* Verify that svalue::involves_p works.  */
8576
8577 static void
8578 test_involves_p ()
8579 {
8580   region_model_manager mgr;
8581   tree int_star = build_pointer_type (integer_type_node);
8582   tree p = build_global_decl ("p", int_star);
8583   tree q = build_global_decl ("q", int_star);
8584
8585   test_region_model_context ctxt;
8586   region_model model (&mgr);
8587   const svalue *p_init = model.get_rvalue (p, &ctxt);
8588   const svalue *q_init = model.get_rvalue (q, &ctxt);
8589
8590   ASSERT_TRUE (p_init->involves_p (p_init));
8591   ASSERT_FALSE (p_init->involves_p (q_init));
8592
8593   const region *star_p_reg = mgr.get_symbolic_region (p_init);
8594   const region *star_q_reg = mgr.get_symbolic_region (q_init);
8595
8596   const svalue *init_star_p = mgr.get_or_create_initial_value (star_p_reg);
8597   const svalue *init_star_q = mgr.get_or_create_initial_value (star_q_reg);
8598
8599   ASSERT_TRUE (init_star_p->involves_p (p_init));
8600   ASSERT_FALSE (p_init->involves_p (init_star_p));
8601   ASSERT_FALSE (init_star_p->involves_p (q_init));
8602   ASSERT_TRUE (init_star_q->involves_p (q_init));
8603   ASSERT_FALSE (init_star_q->involves_p (p_init));
8604 }
8605
8606 /* Run all of the selftests within this file.  */
8607
8608 void
8609 analyzer_region_model_cc_tests ()
8610 {
8611   test_tree_cmp_on_constants ();
8612   test_dump ();
8613   test_struct ();
8614   test_array_1 ();
8615   test_get_representative_tree ();
8616   test_unique_constants ();
8617   test_unique_unknowns ();
8618   test_initial_svalue_folding ();
8619   test_unaryop_svalue_folding ();
8620   test_binop_svalue_folding ();
8621   test_sub_svalue_folding ();
8622   test_bits_within_svalue_folding ();
8623   test_descendent_of_p ();
8624   test_bit_range_regions ();
8625   test_assignment ();
8626   test_compound_assignment ();
8627   test_stack_frames ();
8628   test_get_representative_path_var ();
8629   test_equality_1 ();
8630   test_canonicalization_2 ();
8631   test_canonicalization_3 ();
8632   test_canonicalization_4 ();
8633   test_state_merging ();
8634   test_constraint_merging ();
8635   test_widening_constraints ();
8636   test_iteration_1 ();
8637   test_malloc_constraints ();
8638   test_var ();
8639   test_array_2 ();
8640   test_mem_ref ();
8641   test_POINTER_PLUS_EXPR_then_MEM_REF ();
8642   test_malloc ();
8643   test_alloca ();
8644   test_involves_p ();
8645 }
8646
8647 } // namespace selftest
8648
8649 #endif /* CHECKING_P */
8650
8651 } // namespace ana
8652
8653 #endif /* #if ENABLE_ANALYZER */