/* Handling for the known behavior of various specific functions.
   Copyright (C) 2020-2025 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "analyzer/common.h"

#include "diagnostic.h"

#include "analyzer/analyzer-logging.h"
#include "analyzer/region-model.h"
#include "analyzer/call-details.h"
#include "analyzer/call-info.h"

#if ENABLE_ANALYZER

namespace ana {

/* Abstract subclass for describing undefined behavior of an API.  */

class undefined_function_behavior
  : public pending_diagnostic_subclass<undefined_function_behavior>
{
public:
  undefined_function_behavior (const call_details &cd)
  : m_call_stmt (cd.get_call_stmt ()),
    m_callee_fndecl (cd.get_fndecl_for_call ())
  {
    gcc_assert (m_callee_fndecl);
  }

  const char *get_kind () const final override
  {
    return "undefined_behavior";
  }

  bool operator== (const undefined_function_behavior &other) const
  {
    return (&m_call_stmt == &other.m_call_stmt
	    && m_callee_fndecl == other.m_callee_fndecl);
  }

  bool terminate_path_p () const final override { return true; }

  tree get_callee_fndecl () const { return m_callee_fndecl; }

private:
  const gimple &m_call_stmt;
  tree m_callee_fndecl;
};

/* class pure_known_function_with_default_return : public known_function.  */

void
pure_known_function_with_default_return::
impl_call_pre (const call_details &cd) const
{
  cd.set_any_lhs_with_defaults ();
}

/* Implementations of specific functions.  */

/* Handler for "alloca".  */

class kf_alloca : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return cd.num_args () == 1;
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_ALLOCA;
  }
  void impl_call_pre (const call_details &cd) const final override;
};

void
kf_alloca::impl_call_pre (const call_details &cd) const
{
  const svalue *size_sval = cd.get_arg_svalue (0);

  region_model *model = cd.get_model ();
  region_model_manager *mgr = cd.get_manager ();

  const region *new_reg
    = model->create_region_for_alloca (size_sval, cd.get_ctxt ());
  const svalue *ptr_sval
    = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
  cd.maybe_set_lhs (ptr_sval);
}

/* Handler for __atomic_exchange.
   Although the user-facing documentation specifies it as having this
   signature:
     void __atomic_exchange (type *ptr, type *val, type *ret, int memorder)

   by the time the C/C++ frontends have acted on it, any calls that
   can't be mapped to a _N variation end up with this signature:

     void
     __atomic_exchange (size_t sz, void *ptr, void *val, void *ret,
			int memorder)

   as seen in the gimple seen by the analyzer, and as specified
   in sync-builtins.def.  */

class kf_atomic_exchange : public internal_known_function
{
public:
  /* This is effectively:
       tmpA = *PTR;
       tmpB = *VAL;
       *PTR = tmpB;
       *RET = tmpA;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *num_bytes_sval = cd.get_arg_svalue (0);
    const svalue *ptr_sval = cd.get_arg_svalue (1);
    tree ptr_tree = cd.get_arg_tree (1);
    const svalue *val_sval = cd.get_arg_svalue (2);
    tree val_tree = cd.get_arg_tree (2);
    const svalue *ret_sval = cd.get_arg_svalue (3);
    tree ret_tree = cd.get_arg_tree (3);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *ptr_reg = model->deref_rvalue (ptr_sval, ptr_tree, ctxt);
    const region *val_reg = model->deref_rvalue (val_sval, val_tree, ctxt);
    const region *ret_reg = model->deref_rvalue (ret_sval, ret_tree, ctxt);

    const svalue *tmp_a_sval
      = model->read_bytes (ptr_reg, ptr_tree, num_bytes_sval, ctxt);
    const svalue *tmp_b_sval
      = model->read_bytes (val_reg, val_tree, num_bytes_sval, ctxt);
    model->write_bytes (ptr_reg, num_bytes_sval, tmp_b_sval, ctxt);
    model->write_bytes (ret_reg, num_bytes_sval, tmp_a_sval, ctxt);
  }
};

/* Handler for:
   __atomic_exchange_n (type *ptr, type val, int memorder).  */

class kf_atomic_exchange_n : public internal_known_function
{
public:
  /* This is effectively:
       RET = *PTR;
       *PTR = VAL;
       return RET;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *ptr_sval = cd.get_arg_svalue (0);
    tree ptr_tree = cd.get_arg_tree (0);
    const svalue *set_sval = cd.get_arg_svalue (1);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *dst_region = model->deref_rvalue (ptr_sval, ptr_tree, ctxt);
    const svalue *ret_sval = model->get_store_value (dst_region, ctxt);
    model->set_value (dst_region, set_sval, ctxt);
    cd.maybe_set_lhs (ret_sval);
  }
};

/* Handler for:
   type __atomic_fetch_add (type *ptr, type val, int memorder);
   type __atomic_fetch_sub (type *ptr, type val, int memorder);
   type __atomic_fetch_and (type *ptr, type val, int memorder);
   type __atomic_fetch_xor (type *ptr, type val, int memorder);
   type __atomic_fetch_or (type *ptr, type val, int memorder);
*/

class kf_atomic_fetch_op : public internal_known_function
{
public:
  kf_atomic_fetch_op (enum tree_code op): m_op (op) {}

  /* This is effectively:
       RET = *PTR;
       *PTR = RET OP VAL;
       return RET;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *ptr_sval = cd.get_arg_svalue (0);
    tree ptr_tree = cd.get_arg_tree (0);
    const svalue *val_sval = cd.get_arg_svalue (1);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_manager *mgr = cd.get_manager ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *star_ptr_region
      = model->deref_rvalue (ptr_sval, ptr_tree, ctxt);
    const svalue *old_sval = model->get_store_value (star_ptr_region, ctxt);
    const svalue *new_sval = mgr->get_or_create_binop (old_sval->get_type (),
						       m_op,
						       old_sval, val_sval);
    model->set_value (star_ptr_region, new_sval, ctxt);
    cd.maybe_set_lhs (old_sval);
  }

private:
  enum tree_code m_op;
};

/* Handler for:
   type __atomic_add_fetch (type *ptr, type val, int memorder);
   type __atomic_sub_fetch (type *ptr, type val, int memorder);
   type __atomic_and_fetch (type *ptr, type val, int memorder);
   type __atomic_xor_fetch (type *ptr, type val, int memorder);
   type __atomic_or_fetch (type *ptr, type val, int memorder);
*/

class kf_atomic_op_fetch : public internal_known_function
{
public:
  kf_atomic_op_fetch (enum tree_code op): m_op (op) {}

  /* This is effectively:
       *PTR = RET OP VAL;
       return *PTR;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *ptr_sval = cd.get_arg_svalue (0);
    tree ptr_tree = cd.get_arg_tree (0);
    const svalue *val_sval = cd.get_arg_svalue (1);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_manager *mgr = cd.get_manager ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *star_ptr_region
      = model->deref_rvalue (ptr_sval, ptr_tree, ctxt);
    const svalue *old_sval = model->get_store_value (star_ptr_region, ctxt);
    const svalue *new_sval = mgr->get_or_create_binop (old_sval->get_type (),
						       m_op,
						       old_sval, val_sval);
    model->set_value (star_ptr_region, new_sval, ctxt);
    cd.maybe_set_lhs (new_sval);
  }

private:
  enum tree_code m_op;
};

/* Handler for __atomic_load.
   Although the user-facing documentation specifies it as having this
   signature:

      void __atomic_load (type *ptr, type *ret, int memorder)

   by the time the C/C++ frontends have acted on it, any calls that
   can't be mapped to a _N variation end up with this signature:

      void __atomic_load (size_t sz, const void *src, void *dst, int memorder);

   as seen in the gimple seen by the analyzer, and as specified
   in sync-builtins.def.  */

class kf_atomic_load : public internal_known_function
{
public:
  /* This is effectively:
       memmove (dst, src, sz);
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *num_bytes_sval = cd.get_arg_svalue (0);
    const svalue *src_sval = cd.get_arg_svalue (1);
    tree src_tree = cd.get_arg_tree (1);
    const svalue *dst_sval = cd.get_arg_svalue (2);
    tree dst_tree = cd.get_arg_tree (2);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *dst_reg = model->deref_rvalue (dst_sval, dst_tree, ctxt);
    const region *src_reg = model->deref_rvalue (src_sval, src_tree, ctxt);

    const svalue *data_sval
      = model->read_bytes (src_reg, src_tree, num_bytes_sval, ctxt);
    model->write_bytes (dst_reg, num_bytes_sval, data_sval, ctxt);
  }
};

/* Handler for __atomic_store.
   Although the user-facing documentation specifies it as having this
   signature:

      void __atomic_store (type *ptr, type *val, int memorder)

   by the time the C/C++ frontends have acted on it, any calls that
   can't be mapped to a _N variation end up with this signature:

      void __atomic_store (size_t sz, type *dst, type *src, int memorder)

   as seen in the gimple seen by the analyzer, and as specified
   in sync-builtins.def.  */

class kf_atomic_store : public internal_known_function
{
public:
  /* This is effectively:
       memmove (dst, src, sz);
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *num_bytes_sval = cd.get_arg_svalue (0);
    const svalue *dst_sval = cd.get_arg_svalue (1);
    tree dst_tree = cd.get_arg_tree (1);
    const svalue *src_sval = cd.get_arg_svalue (2);
    tree src_tree = cd.get_arg_tree (2);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *dst_reg = model->deref_rvalue (dst_sval, dst_tree, ctxt);
    const region *src_reg = model->deref_rvalue (src_sval, src_tree, ctxt);

    const svalue *data_sval
      = model->read_bytes (src_reg, src_tree, num_bytes_sval, ctxt);
    model->write_bytes (dst_reg, num_bytes_sval, data_sval, ctxt);
  }
};

/* Handler for:
   type __atomic_load_n (type *ptr, int memorder) */

class kf_atomic_load_n : public internal_known_function
{
public:
  /* This is effectively:
       RET = *PTR;
       return RET;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *ptr_ptr_sval = cd.get_arg_svalue (0);
    tree ptr_ptr_tree = cd.get_arg_tree (0);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *ptr_region
      = model->deref_rvalue (ptr_ptr_sval, ptr_ptr_tree, ctxt);
    const svalue *star_ptr_sval = model->get_store_value (ptr_region, ctxt);
    cd.maybe_set_lhs (star_ptr_sval);
  }
};

/* Handler for:
   void __atomic_store_n (type *ptr, type val, int memorder) */

class kf_atomic_store_n : public internal_known_function
{
public:
  /* This is effectively:
       *PTR = VAL;
  */
  void impl_call_pre (const call_details &cd) const final override
  {
    const svalue *ptr_sval = cd.get_arg_svalue (0);
    tree ptr_tree = cd.get_arg_tree (0);
    const svalue *new_sval = cd.get_arg_svalue (1);
    /* Ignore the memorder param.  */

    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();

    const region *star_ptr_region
      = model->deref_rvalue (ptr_sval, ptr_tree, ctxt);
    model->set_value (star_ptr_region, new_sval, ctxt);
  }
};

/* Handler for "__builtin_expect" etc.  */

class kf_expect : public internal_known_function
{
public:
  void impl_call_pre (const call_details &cd) const final override
  {
    /* __builtin_expect's return value is its initial argument.  */
    const svalue *sval = cd.get_arg_svalue (0);
    cd.maybe_set_lhs (sval);
  }
};

/* Handler for "calloc".  */

class kf_calloc : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2
	    && cd.arg_is_size_p (0)
	    && cd.arg_is_size_p (1));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_CALLOC;
  }

  void impl_call_pre (const call_details &cd) const final override;
};

void
kf_calloc::impl_call_pre (const call_details &cd) const
{
  region_model *model = cd.get_model ();
  region_model_manager *mgr = cd.get_manager ();
  const svalue *nmemb_sval = cd.get_arg_svalue (0);
  const svalue *size_sval = cd.get_arg_svalue (1);
  /* TODO: check for overflow here?  */
  const svalue *prod_sval
    = mgr->get_or_create_binop (size_type_node, MULT_EXPR,
				nmemb_sval, size_sval);
  const region *new_reg
    = model->get_or_create_region_for_heap_alloc (prod_sval, cd.get_ctxt ());
  const region *sized_reg
    = mgr->get_sized_region (new_reg, NULL_TREE, prod_sval);
  model->zero_fill_region (sized_reg, cd.get_ctxt ());
  if (cd.get_lhs_type ())
    {
      const svalue *ptr_sval
	= mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
      cd.maybe_set_lhs (ptr_sval);
    }
}

/* Handler for glibc's "__errno_location".  */

class kf_errno_location : public known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return cd.num_args () == 0;
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    if (cd.get_lhs_region ())
      {
	region_model_manager *mgr = cd.get_manager ();
	const region *errno_reg = mgr->get_errno_region ();
	const svalue *errno_ptr = mgr->get_ptr_svalue (cd.get_lhs_type (),
						       errno_reg);
	cd.maybe_set_lhs (errno_ptr);
      }
  }
};

/* Handler for "error" and "error_at_line" from GNU's non-standard <error.h>.
   MIN_ARGS identifies the minimum number of expected arguments
   to be consistent with such a call (3 and 5 respectively).  */

class kf_error : public known_function
{
public:
  kf_error (unsigned min_args) : m_min_args (min_args) {}

  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () >= m_min_args
	    && cd.get_arg_type (0) == integer_type_node);
  }

  void impl_call_pre (const call_details &cd) const final override;

private:
  unsigned m_min_args;
};

void
kf_error::impl_call_pre (const call_details &cd) const
{
  /* The process exits if status != 0, so it only continues
     for the case where status == 0.
     Add that constraint, or terminate this analysis path.  */
  tree status = cd.get_arg_tree (0);
  region_model_context *ctxt = cd.get_ctxt ();
  region_model *model = cd.get_model ();
  if (!model->add_constraint (status, EQ_EXPR, integer_zero_node, ctxt))
    if (ctxt)
      ctxt->terminate_path ();

  /* Check "format" arg.  */
  const int fmt_arg_idx = (m_min_args == 3) ? 2 : 4;
  model->check_for_null_terminated_string_arg (cd, fmt_arg_idx);
}

/* Handler for fopen.
     FILE *fopen (const char *filename, const char *mode);
   See e.g. https://en.cppreference.com/w/c/io/fopen
   https://www.man7.org/linux/man-pages/man3/fopen.3.html
   https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170  */

class kf_fopen : public known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1));
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    cd.check_for_null_terminated_string_arg (0);
    cd.check_for_null_terminated_string_arg (1);
    cd.set_any_lhs_with_defaults ();

    /* fopen's mode param is effectively a mini-DSL, but there are various
       non-standard extensions, so we don't bother to check it.  */
  }
};

/* Handler for "free", after sm-handling.

   If the ptr points to an underlying heap region, delete the region,
   poisoning pointers to it and regions within it.

   We delay this until after sm-state has been updated so that the
   sm-handling can transition all of the various casts of the pointer
   to a "freed" state *before* we delete the related region here.

   This has to be done here so that the sm-handling can use the fact
   that they point to the same region to establish that they are equal
   (in region_model::eval_condition), and thus transition
   all pointers to the region to the "freed" state together, regardless
   of casts.  */

class kf_free : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_FREE;
  }
  void impl_call_post (const call_details &cd) const final override;
};

void
kf_free::impl_call_post (const call_details &cd) const
{
  const svalue *ptr_sval = cd.get_arg_svalue (0);
  if (const region *freed_reg = ptr_sval->maybe_get_region ())
    {
      /* If the ptr points to an underlying heap region, delete it,
	 poisoning pointers.  */
      region_model *model = cd.get_model ();
      model->unbind_region_and_descendents (freed_reg, poison_kind::freed);
      model->unset_dynamic_extents (freed_reg);
    }
}

/* Handle the on_call_pre part of "malloc".  */

class kf_malloc : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 1
	    && cd.arg_is_size_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_MALLOC;
  }
  void impl_call_pre (const call_details &cd) const final override;
};

void
kf_malloc::impl_call_pre (const call_details &cd) const
{
  region_model *model = cd.get_model ();
  region_model_manager *mgr = cd.get_manager ();
  const svalue *size_sval = cd.get_arg_svalue (0);
  const region *new_reg
    = model->get_or_create_region_for_heap_alloc (size_sval, cd.get_ctxt ());
  if (cd.get_lhs_type ())
    {
      const svalue *ptr_sval
	= mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
      cd.maybe_set_lhs (ptr_sval);
    }
}

/* Handler for "memcpy" and "__builtin_memcpy",
   "memmove", and "__builtin_memmove".  */

class kf_memcpy_memmove : public builtin_known_function
{
public:
  enum kf_memcpy_memmove_variant
  {
    KF_MEMCPY,
    KF_MEMCPY_CHK,
    KF_MEMMOVE,
    KF_MEMMOVE_CHK,
  };
  kf_memcpy_memmove (enum kf_memcpy_memmove_variant variant)
    : m_variant (variant) {};
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 3
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1)
	    && cd.arg_is_size_p (2));
  }
  enum built_in_function builtin_code () const final override
  {
    switch (m_variant)
      {
      case KF_MEMCPY:
	return BUILT_IN_MEMCPY;
      case KF_MEMCPY_CHK:
	return BUILT_IN_MEMCPY_CHK;
      case KF_MEMMOVE:
	return BUILT_IN_MEMMOVE;
      case KF_MEMMOVE_CHK:
	return BUILT_IN_MEMMOVE_CHK;
      default:
	gcc_unreachable ();
      }
  }
  void impl_call_pre (const call_details &cd) const final override;
private:
  const enum kf_memcpy_memmove_variant m_variant;
};

void
kf_memcpy_memmove::impl_call_pre (const call_details &cd) const
{
  const svalue *dest_ptr_sval = cd.get_arg_svalue (0);
  const svalue *src_ptr_sval = cd.get_arg_svalue (1);
  const svalue *num_bytes_sval = cd.get_arg_svalue (2);

  region_model *model = cd.get_model ();

  const region *dest_reg
    = model->deref_rvalue (dest_ptr_sval, cd.get_arg_tree (0), cd.get_ctxt ());
  const region *src_reg
    = model->deref_rvalue (src_ptr_sval, cd.get_arg_tree (1), cd.get_ctxt ());

  cd.maybe_set_lhs (dest_ptr_sval);
  /* Check for overlap.  */
  switch (m_variant)
    {
    case KF_MEMCPY:
    case KF_MEMCPY_CHK:
      cd.complain_about_overlap (0, 1, num_bytes_sval);
      break;

    case KF_MEMMOVE:
    case KF_MEMMOVE_CHK:
      /* It's OK for memmove's arguments to overlap.  */
      break;

    default:
	gcc_unreachable ();
    }
  model->copy_bytes (dest_reg,
		     src_reg, cd.get_arg_tree (1),
		     num_bytes_sval,
		     cd.get_ctxt ());
}

/* Handler for "memset" and "__builtin_memset".  */

class kf_memset : public builtin_known_function
{
public:
  kf_memset (bool chk_variant) : m_chk_variant (chk_variant) {}
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 3 && cd.arg_is_pointer_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return m_chk_variant ? BUILT_IN_MEMSET_CHK : BUILT_IN_MEMSET;
  }
  void impl_call_pre (const call_details &cd) const final override;
private:
  const bool m_chk_variant;
};

void
kf_memset::impl_call_pre (const call_details &cd) const
{
  const svalue *dest_sval = cd.get_arg_svalue (0);
  const svalue *fill_value_sval = cd.get_arg_svalue (1);
  const svalue *num_bytes_sval = cd.get_arg_svalue (2);

  region_model *model = cd.get_model ();
  region_model_manager *mgr = cd.get_manager ();

  const region *dest_reg
    = model->deref_rvalue (dest_sval, cd.get_arg_tree (0), cd.get_ctxt ());

  const svalue *fill_value_u8
    = mgr->get_or_create_cast (unsigned_char_type_node, fill_value_sval);

  const region *sized_dest_reg = mgr->get_sized_region (dest_reg,
							NULL_TREE,
							num_bytes_sval);
  model->fill_region (sized_dest_reg, fill_value_u8, cd.get_ctxt ());

  cd.maybe_set_lhs (dest_sval);
}

/* A subclass of pending_diagnostic for complaining about 'putenv'
   called on an auto var.  */

class putenv_of_auto_var
: public pending_diagnostic_subclass<putenv_of_auto_var>
{
public:
  putenv_of_auto_var (tree fndecl, const region *reg)
  : m_fndecl (fndecl), m_reg (reg),
    m_var_decl (reg->get_base_region ()->maybe_get_decl ())
  {
  }

  const char *get_kind () const final override
  {
    return "putenv_of_auto_var";
  }

  bool operator== (const putenv_of_auto_var &other) const
  {
    return (m_fndecl == other.m_fndecl
	    && m_reg == other.m_reg
	    && same_tree_p (m_var_decl, other.m_var_decl));
  }

  int get_controlling_option () const final override
  {
    return OPT_Wanalyzer_putenv_of_auto_var;
  }

  bool emit (diagnostic_emission_context &ctxt) final override
  {
    auto_diagnostic_group d;

    /* SEI CERT C Coding Standard: "POS34-C. Do not call putenv() with a
       pointer to an automatic variable as the argument".  */
    diagnostics::metadata::precanned_rule
      rule ("POS34-C", "https://wiki.sei.cmu.edu/confluence/x/6NYxBQ");
    ctxt.add_rule (rule);

    bool warned;
    if (m_var_decl)
      warned = ctxt.warn ("%qE on a pointer to automatic variable %qE",
			  m_fndecl, m_var_decl);
    else
      warned = ctxt.warn ("%qE on a pointer to an on-stack buffer",
			  m_fndecl);
    if (warned)
      {
	if (m_var_decl)
	  inform (DECL_SOURCE_LOCATION (m_var_decl),
		  "%qE declared on stack here", m_var_decl);
	inform (ctxt.get_location (), "perhaps use %qs rather than %qE",
		"setenv", m_fndecl);
      }

    return warned;
  }

  bool
  describe_final_event (pretty_printer &pp,
			const evdesc::final_event &) final override
  {
    if (m_var_decl)
      pp_printf  (&pp,
		  "%qE on a pointer to automatic variable %qE",
		  m_fndecl, m_var_decl);
    else
      pp_printf  (&pp,
		  "%qE on a pointer to an on-stack buffer",
		  m_fndecl);
    return true;
  }

  void mark_interesting_stuff (interesting_t *interest) final override
  {
    if (!m_var_decl)
      interest->add_region_creation (m_reg->get_base_region ());
  }

private:
  tree m_fndecl; // non-NULL
  const region *m_reg; // non-NULL
  tree m_var_decl; // could be NULL
};

/* Handler for calls to "putenv".

   In theory we could try to model the state of the environment variables
   for the process; for now we merely complain about putenv of regions
   on the stack.  */

class kf_putenv : public known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    tree fndecl = cd.get_fndecl_for_call ();
    gcc_assert (fndecl);
    region_model_context *ctxt = cd.get_ctxt ();
    region_model *model = cd.get_model ();
    model->check_for_null_terminated_string_arg (cd, 0);
    const svalue *ptr_sval = cd.get_arg_svalue (0);
    const region *reg
      = model->deref_rvalue (ptr_sval, cd.get_arg_tree (0), ctxt);
    model->get_store ()->mark_as_escaped (reg);
    enum memory_space mem_space = reg->get_memory_space ();
    switch (mem_space)
      {
      default:
	gcc_unreachable ();
      case MEMSPACE_UNKNOWN:
      case MEMSPACE_CODE:
      case MEMSPACE_GLOBALS:
      case MEMSPACE_HEAP:
      case MEMSPACE_READONLY_DATA:
	break;
      case MEMSPACE_STACK:
	if (ctxt)
	  ctxt->warn (std::make_unique<putenv_of_auto_var> (fndecl, reg));
	break;
      }
    cd.set_any_lhs_with_defaults ();
  }
};

/* Handler for "realloc":

     void *realloc(void *ptr, size_t size);

   realloc(3) is awkward, since it has various different outcomes
   that are best modelled as separate exploded nodes/edges.

   We first check for sm-state, in
   malloc_state_machine::on_realloc_call, so that we
   can complain about issues such as realloc of a non-heap
   pointer, and terminate the path for such cases (and issue
   the complaints at the call's exploded node).

   Assuming that these checks pass, we split the path here into
   three special cases (and terminate the "standard" path):
   (A) failure, returning NULL
   (B) success, growing the buffer in-place without moving it
   (C) success, allocating a new buffer, copying the content
   of the old buffer to it, and freeing the old buffer.

   Each of these has a custom_edge_info subclass, which updates
   the region_model and sm-state of the destination state.  */

class kf_realloc : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_size_p (1));
  }

  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_REALLOC;
  }

  void impl_call_post (const call_details &cd) const final override;
};

void
kf_realloc::impl_call_post (const call_details &cd) const
{
  /* Three custom subclasses of custom_edge_info, for handling the various
     outcomes of "realloc".  */

  /* Concrete custom_edge_info: a realloc call that fails, returning NULL.  */
  class failure : public failed_call_info
  {
  public:
    failure (const call_details &cd)
    : failed_call_info (cd)
    {
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      /* Return NULL; everything else is unchanged.  */
      const call_details cd (get_call_details (model, ctxt));
      region_model_manager *mgr = cd.get_manager ();
      if (cd.get_lhs_type ())
	{
	  const svalue *zero
	    = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
	  model->set_value (cd.get_lhs_region (),
			    zero,
			    cd.get_ctxt ());
	}
      return true;
    }
  };

  /* Concrete custom_edge_info: a realloc call that succeeds, growing
     the existing buffer without moving it.  */
  class success_no_move : public call_info
  {
  public:
    success_no_move (const call_details &cd)
    : call_info (cd)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      pp_printf (&pp,
		 "when %qE succeeds, without moving buffer",
		 get_fndecl ());
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      /* Update size of buffer and return the ptr unchanged.  */
      const call_details cd (get_call_details (model, ctxt));
      region_model_manager *mgr = cd.get_manager ();
      const svalue *ptr_sval = cd.get_arg_svalue (0);
      const svalue *size_sval = cd.get_arg_svalue (1);

      /* We can only grow in place with a non-NULL pointer.  */
      {
	const svalue *null_ptr
	  = mgr->get_or_create_int_cst (ptr_sval->get_type (), 0);
	if (!model->add_constraint (ptr_sval, NE_EXPR, null_ptr,
				    cd.get_ctxt ()))
	  return false;
      }

      if (const region *buffer_reg = model->deref_rvalue (ptr_sval, NULL_TREE,
							  ctxt))
	if (compat_types_p (size_sval->get_type (), size_type_node))
	  model->set_dynamic_extents (buffer_reg, size_sval, ctxt);
      if (cd.get_lhs_region ())
	{
	  model->set_value (cd.get_lhs_region (), ptr_sval, cd.get_ctxt ());
	  const svalue *zero
	    = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
	  return model->add_constraint (ptr_sval, NE_EXPR, zero, ctxt);
	}
      else
	return true;
    }
  };

  /* Concrete custom_edge_info: a realloc call that succeeds, freeing
     the existing buffer and moving the content to a freshly allocated
     buffer.  */
  class success_with_move : public call_info
  {
  public:
    success_with_move (const call_details &cd)
    : call_info (cd)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      pp_printf (&pp,
		 "when %qE succeeds, moving buffer",
		 get_fndecl ());
    }
    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      const call_details cd (get_call_details (model, ctxt));
      region_model_manager *mgr = cd.get_manager ();
      const svalue *old_ptr_sval = cd.get_arg_svalue (0);
      const svalue *new_size_sval = cd.get_arg_svalue (1);

      /* Create the new region.  */
      const region *new_reg
	= model->get_or_create_region_for_heap_alloc (new_size_sval, ctxt);
      const svalue *new_ptr_sval
	= mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
      if (!model->add_constraint (new_ptr_sval, NE_EXPR, old_ptr_sval,
				  cd.get_ctxt ()))
	return false;

      if (cd.get_lhs_type ())
	cd.maybe_set_lhs (new_ptr_sval);

      if (const region *freed_reg = model->deref_rvalue (old_ptr_sval,
							 NULL_TREE, ctxt))
	{
	  /* Copy the data.  */
	  const svalue *old_size_sval = model->get_dynamic_extents (freed_reg);
	  if (old_size_sval)
	    {
	      const svalue *copied_size_sval
		= get_copied_size (model, old_size_sval, new_size_sval);
	      const region *copied_old_reg
		= mgr->get_sized_region (freed_reg, nullptr, copied_size_sval);
	      const svalue *buffer_content_sval
		= model->get_store_value (copied_old_reg, cd.get_ctxt ());
	      const region *copied_new_reg
		= mgr->get_sized_region (new_reg, nullptr, copied_size_sval);
	      model->set_value (copied_new_reg, buffer_content_sval,
				cd.get_ctxt ());
	    }
	  else
	    {
	      /* We don't know how big the old region was;
		 mark the new region as having been touched to avoid uninit
		 issues.  */
	      model->mark_region_as_unknown (new_reg, cd.get_uncertainty ());
	    }

	  /* Free the old region, so that pointers to the old buffer become
	     invalid.  */

	  /* If the ptr points to an underlying heap region, delete it,
	     poisoning pointers.  */
	  model->unbind_region_and_descendents (freed_reg, poison_kind::freed);
	  model->unset_dynamic_extents (freed_reg);
	}

      /* Update the sm-state: mark the old_ptr_sval as "freed",
	 and the new_ptr_sval as "nonnull".  */
      model->on_realloc_with_move (cd, old_ptr_sval, new_ptr_sval);

      if (cd.get_lhs_type ())
	{
	  const svalue *zero
	    = mgr->get_or_create_int_cst (cd.get_lhs_type (), 0);
	  return model->add_constraint (new_ptr_sval, NE_EXPR, zero,
					cd.get_ctxt ());
	}
      else
	return true;
    }

  private:
    /* Return the lesser of OLD_SIZE_SVAL and NEW_SIZE_SVAL.
       If unknown, OLD_SIZE_SVAL is returned.  */
    const svalue *get_copied_size (region_model *model,
				   const svalue *old_size_sval,
				   const svalue *new_size_sval) const
    {
      tristate res
	= model->eval_condition (old_size_sval, GT_EXPR, new_size_sval);
      switch (res.get_value ())
	{
	case tristate::TS_TRUE:
	  return new_size_sval;
	case tristate::TS_FALSE:
	case tristate::TS_UNKNOWN:
	  return old_size_sval;
	default:
	  gcc_unreachable ();
	}
    }
  };

  /* Body of kf_realloc::impl_call_post.  */

  if (cd.get_ctxt ())
    {
      cd.get_ctxt ()->bifurcate (std::make_unique<failure> (cd));
      cd.get_ctxt ()->bifurcate (std::make_unique<success_no_move> (cd));
      cd.get_ctxt ()->bifurcate (std::make_unique<success_with_move> (cd));
      cd.get_ctxt ()->terminate_path ();
    }
}

/* Handler for "strchr" and "__builtin_strchr".  */

class kf_strchr : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2 && cd.arg_is_pointer_p (0));
  }
  void impl_call_pre (const call_details &cd) const final override
  {
    cd.check_for_null_terminated_string_arg (0);
  }

  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRCHR;
  }
  void impl_call_post (const call_details &cd) const final override;
};

void
kf_strchr::impl_call_post (const call_details &cd) const
{
  class strchr_call_info : public call_info
  {
  public:
    strchr_call_info (const call_details &cd, bool found)
    : call_info (cd), m_found (found)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      if (m_found)
	pp_printf (&pp,
		   "when %qE returns non-NULL",
		   get_fndecl ());
      else
	pp_printf (&pp,
		   "when %qE returns NULL",
		   get_fndecl ());
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      const call_details cd (get_call_details (model, ctxt));
      if (tree lhs_type = cd.get_lhs_type ())
	{
	  region_model_manager *mgr = model->get_manager ();
	  const svalue *result;
	  if (m_found)
	    {
	      const svalue *str_sval = cd.get_arg_svalue (0);
	      const region *str_reg
		= model->deref_rvalue (str_sval, cd.get_arg_tree (0),
				       cd.get_ctxt ());
	      /* We want str_sval + OFFSET for some unknown OFFSET.
		 Use a conjured_svalue to represent the offset,
		 using the str_reg as the id of the conjured_svalue.  */
	      const svalue *offset
		= mgr->get_or_create_conjured_svalue (size_type_node,
						      &cd.get_call_stmt (),
						      str_reg,
						      conjured_purge (model,
								      ctxt));
	      result = mgr->get_or_create_binop (lhs_type, POINTER_PLUS_EXPR,
						 str_sval, offset);
	    }
	  else
	    result = mgr->get_or_create_int_cst (lhs_type, 0);
	  cd.maybe_set_lhs (result);
	}
      return true;
    }
  private:
    bool m_found;
  };

  /* Body of kf_strchr::impl_call_post.  */
  if (cd.get_ctxt ())
    {
      cd.get_ctxt ()->bifurcate (std::make_unique<strchr_call_info> (cd, false));
      cd.get_ctxt ()->bifurcate (std::make_unique<strchr_call_info> (cd, true));
      cd.get_ctxt ()->terminate_path ();
    }
}

/* Handler for "sprintf".
     int sprintf(char *str, const char *format, ...);
*/

class kf_sprintf : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () >= 2
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1));
  }

  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_SPRINTF;
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    /* For now, merely assume that the destination buffer gets set to a
       new svalue.  */
    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();
    const svalue *dst_ptr = cd.get_arg_svalue (0);
    const region *dst_reg
      = model->deref_rvalue (dst_ptr, cd.get_arg_tree (0), ctxt);
    const svalue *content = cd.get_or_create_conjured_svalue (dst_reg);
    model->set_value (dst_reg, content, ctxt);
    cd.set_any_lhs_with_defaults ();
  }
};

/* Handler for "__builtin_stack_restore".  */

class kf_stack_restore : public pure_known_function_with_default_return
{
public:
  bool matches_call_types_p (const call_details &) const final override
  {
    return true;
  }

  /* Currently a no-op.  */
};

/* Handler for "__builtin_stack_save".  */

class kf_stack_save : public pure_known_function_with_default_return
{
public:
  bool matches_call_types_p (const call_details &) const final override
  {
    return true;
  }

  /* Currently a no-op.  */
};

/* Handler for "__builtin_eh_pointer".  */

class kf_eh_pointer : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &) const final override
  {
    return true;
  }

  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_EH_POINTER;
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    cd.set_any_lhs_with_defaults ();
  }
};

/* Handler for "strcat" and "__builtin_strcat_chk".  */

class kf_strcat : public builtin_known_function
{
public:
  kf_strcat (unsigned int num_args, bool chk_variant)
    : m_num_args (num_args),
      m_chk_variant (chk_variant) {}
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == m_num_args
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1));
  }

  enum built_in_function builtin_code () const final override
  {
    return m_chk_variant ? BUILT_IN_STRCAT_CHK : BUILT_IN_STRCAT;
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    region_model *model = cd.get_model ();
    region_model_manager *mgr = cd.get_manager ();

    const svalue *dest_sval = cd.get_arg_svalue (0);
    const region *dest_reg = model->deref_rvalue (dest_sval, cd.get_arg_tree (0),
						  cd.get_ctxt ());

    const svalue *dst_strlen_sval
      = cd.check_for_null_terminated_string_arg (0, false, nullptr);
    if (!dst_strlen_sval)
      {
	if (cd.get_ctxt ())
	  cd.get_ctxt ()->terminate_path ();
	return;
      }

    const svalue *bytes_to_copy;
    const svalue *num_src_bytes_read_sval
      = cd.check_for_null_terminated_string_arg (1, true, &bytes_to_copy);
    if (!num_src_bytes_read_sval)
      {
	if (cd.get_ctxt ())
	  cd.get_ctxt ()->terminate_path ();
	return;
      }

    cd.maybe_set_lhs (dest_sval);
    cd.complain_about_overlap (0, 1, num_src_bytes_read_sval);

    const region *offset_reg
      = mgr->get_offset_region (dest_reg, NULL_TREE, dst_strlen_sval);
    model->write_bytes (offset_reg,
			num_src_bytes_read_sval,
			bytes_to_copy,
			cd.get_ctxt ());
  }

private:
  unsigned int m_num_args;
  const bool m_chk_variant;
};

/* Handler for "strcpy" and "__builtin_strcpy_chk".  */

class kf_strcpy : public builtin_known_function
{
public:
  kf_strcpy (unsigned int num_args, bool chk_variant)
    : m_num_args (num_args),
      m_chk_variant (chk_variant) {}
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == m_num_args
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1));
  }
  enum built_in_function builtin_code () const final override
  {
    return m_chk_variant ? BUILT_IN_STRCPY_CHK : BUILT_IN_STRCPY;
  }
  void impl_call_pre (const call_details &cd) const final override;

private:
  unsigned int m_num_args;
  const bool m_chk_variant;
};

void
kf_strcpy::impl_call_pre (const call_details &cd) const
{
  region_model *model = cd.get_model ();
  region_model_context *ctxt = cd.get_ctxt ();

  const svalue *dest_sval = cd.get_arg_svalue (0);
  const region *dest_reg = model->deref_rvalue (dest_sval, cd.get_arg_tree (0),
						    ctxt);
  /* strcpy returns the initial param.  */
  cd.maybe_set_lhs (dest_sval);

  const svalue *bytes_to_copy;
  if (const svalue *num_bytes_read_sval
      = cd.check_for_null_terminated_string_arg (1, true, &bytes_to_copy))
    {
      cd.complain_about_overlap (0, 1, num_bytes_read_sval);
      model->write_bytes (dest_reg, num_bytes_read_sval, bytes_to_copy, ctxt);
    }
  else
    {
      if (cd.get_ctxt ())
	cd.get_ctxt ()->terminate_path ();
    }
}

/* Handler for "strdup" and "__builtin_strdup".  */

class kf_strdup : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRDUP;
  }
  void impl_call_pre (const call_details &cd) const final override
  {
    region_model *model = cd.get_model ();
    region_model_context *ctxt = cd.get_ctxt ();
    region_model_manager *mgr = cd.get_manager ();
    const svalue *bytes_to_copy;
    if (const svalue *num_bytes_read_sval
	= cd.check_for_null_terminated_string_arg (0, true, &bytes_to_copy))
      {
	const region *new_reg
	  = model->get_or_create_region_for_heap_alloc (num_bytes_read_sval,
							ctxt);
	model->write_bytes (new_reg, num_bytes_read_sval, bytes_to_copy, ctxt);
	if (cd.get_lhs_type ())
	  {
	    const svalue *ptr_sval
	      = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
	    cd.maybe_set_lhs (ptr_sval);
	  }
      }
    else
      {
	if (ctxt)
	  ctxt->terminate_path ();
      }
  }
};

/* Handler for "strlen" and for "__analyzer_get_strlen".  */

class kf_strlen : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 1 && cd.arg_is_pointer_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRLEN;
  }

  void impl_call_pre (const call_details &cd) const final override
  {
    if (const svalue *strlen_sval
	  = cd.check_for_null_terminated_string_arg (0, false, nullptr))
      if (strlen_sval->get_kind () != SK_UNKNOWN)
	{
	  cd.maybe_set_lhs (strlen_sval);
	  return;
	}

    /* Use a conjured svalue.  */
    cd.set_any_lhs_with_defaults ();
  }
};

/* Factory function, so that kf-analyzer.cc can use this class.  */

std::unique_ptr<known_function>
make_kf_strlen ()
{
  return std::make_unique<kf_strlen> ();
}

/* Handler for "strncpy" and "__builtin_strncpy".
   See e.g. https://en.cppreference.com/w/c/string/byte/strncpy

     extern char *strncpy (char *dst, const char *src, size_t count);

   Handle this by splitting into two outcomes:
   (a) truncated read from "src" of "count" bytes,
       writing "count" bytes to "dst"
   (b) read from "src" of up to (and including) the null terminator,
       where the number of bytes read < "count" bytes,
       writing those bytes to "dst", and zero-filling the rest,
       up to "count".  */

class kf_strncpy : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 3
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1)
	    && cd.arg_is_integral_p (2));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRNCPY;
  }
  void impl_call_post (const call_details &cd) const final override;
};

void
kf_strncpy::impl_call_post (const call_details &cd) const
{
  class strncpy_call_info : public call_info
  {
  public:
    strncpy_call_info (const call_details &cd,
		       const svalue *num_bytes_with_terminator_sval,
		       bool truncated_read)
    : call_info (cd),
      m_num_bytes_with_terminator_sval (num_bytes_with_terminator_sval),
      m_truncated_read (truncated_read)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      if (m_truncated_read)
	pp_printf (&pp,
		   "when %qE truncates the source string",
		   get_fndecl ());
      else
	pp_printf (&pp,
		   "when %qE copies the full source string",
		   get_fndecl ());
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      const call_details cd (get_call_details (model, ctxt));

      const svalue *dest_sval = cd.get_arg_svalue (0);
      const region *dest_reg
	= model->deref_rvalue (dest_sval, cd.get_arg_tree (0), ctxt);

      const svalue *src_sval = cd.get_arg_svalue (1);
      const region *src_reg
	= model->deref_rvalue (src_sval, cd.get_arg_tree (1), ctxt);

      const svalue *count_sval = cd.get_arg_svalue (2);

      /* strncpy returns the initial param.  */
      cd.maybe_set_lhs (dest_sval);

      const svalue *num_bytes_read_sval;
      if (m_truncated_read)
	{
	  /* Truncated read.  */
	  num_bytes_read_sval = count_sval;

	  if (m_num_bytes_with_terminator_sval)
	    {
	      /* The terminator is after the limit.  */
	      if (!model->add_constraint (m_num_bytes_with_terminator_sval,
					  GT_EXPR,
					  count_sval,
					  ctxt))
		return false;
	    }
	  else
	    {
	      /* We don't know where the terminator is, or if there is one.
		 In theory we know that the first COUNT bytes are non-zero,
		 but we don't have a way to record that constraint.  */
	    }
	}
      else
	{
	  /* Full read of the src string before reaching the limit,
	     so there must be a terminator and it must be at or before
	     the limit.  */
	  if (m_num_bytes_with_terminator_sval)
	    {
	      if (!model->add_constraint (m_num_bytes_with_terminator_sval,
					  LE_EXPR,
					  count_sval,
					  ctxt))
		return false;
	      num_bytes_read_sval = m_num_bytes_with_terminator_sval;

	      /* First, zero-fill the dest buffer.
		 We don't need to do this for the truncation case, as
		 this fully populates the dest buffer.  */
	      const region *sized_dest_reg
		= model->get_manager ()->get_sized_region (dest_reg,
							   NULL_TREE,
							   count_sval);
	      model->zero_fill_region (sized_dest_reg, ctxt);
	    }
	  else
	    {
	      /* Don't analyze this case; the other case will
		 assume a "truncated" read up to the limit.  */
	      return false;
	    }
	}

      gcc_assert (num_bytes_read_sval);

      const svalue *bytes_to_copy
	= model->read_bytes (src_reg,
			     cd.get_arg_tree (1),
			     num_bytes_read_sval,
			     ctxt);
      cd.complain_about_overlap (0, 1, num_bytes_read_sval);
      model->write_bytes (dest_reg,
			  num_bytes_read_sval,
			  bytes_to_copy,
			  ctxt);

      return true;
    }
  private:
    /* (strlen + 1) of the source string if it has a terminator,
       or nullptr for the case where UB would happen before
       finding any terminator.  */
    const svalue *m_num_bytes_with_terminator_sval;

    /* true: if this is the outcome where the limit was reached before
       the null terminator
       false: if the null terminator was reached before the limit.  */
    bool m_truncated_read;
  };

  /* Body of kf_strncpy::impl_call_post.  */
  if (cd.get_ctxt ())
    {
      /* First, scan for a null terminator as if there were no limit,
	 with a null ctxt so no errors are reported.  */
      const region_model *model = cd.get_model ();
      const svalue *ptr_arg_sval = cd.get_arg_svalue (1);
      const region *buf_reg
	= model->deref_rvalue (ptr_arg_sval, cd.get_arg_tree (1), nullptr);
      const svalue *num_bytes_with_terminator_sval
	= model->scan_for_null_terminator (buf_reg,
					   cd.get_arg_tree (1),
					   nullptr,
					   nullptr);
      cd.get_ctxt ()->bifurcate
	(std::make_unique<strncpy_call_info>
	   (cd, num_bytes_with_terminator_sval,
	    false));
      cd.get_ctxt ()->bifurcate
	(std::make_unique<strncpy_call_info>
	   (cd, num_bytes_with_terminator_sval,
	    true));
      cd.get_ctxt ()->terminate_path ();
    }
};

/* Handler for "strndup" and "__builtin_strndup".  */

class kf_strndup : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2 && cd.arg_is_pointer_p (0));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRNDUP;
  }
  void impl_call_pre (const call_details &cd) const final override
  {
    region_model *model = cd.get_model ();
    region_model_manager *mgr = cd.get_manager ();
    /* Ideally we'd get the size here, and simulate copying the bytes.  */
    const region *new_reg
      = model->get_or_create_region_for_heap_alloc (nullptr, cd.get_ctxt ());
    model->mark_region_as_unknown (new_reg, nullptr);
    if (cd.get_lhs_type ())
      {
	const svalue *ptr_sval
	  = mgr->get_ptr_svalue (cd.get_lhs_type (), new_reg);
	cd.maybe_set_lhs (ptr_sval);
      }
  }
};

/* Handler for "strstr" and "__builtin_strstr".
     extern char *strstr (const char* str, const char* substr);
   See e.g. https://en.cppreference.com/w/c/string/byte/strstr  */

class kf_strstr : public builtin_known_function
{
public:
  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2
	    && cd.arg_is_pointer_p (0)
	    && cd.arg_is_pointer_p (1));
  }
  enum built_in_function builtin_code () const final override
  {
    return BUILT_IN_STRSTR;
  }
  void impl_call_pre (const call_details &cd) const final override
  {
    cd.check_for_null_terminated_string_arg (0);
    cd.check_for_null_terminated_string_arg (1);
  }
  void impl_call_post (const call_details &cd) const final override;
};

void
kf_strstr::impl_call_post (const call_details &cd) const
{
  class strstr_call_info : public call_info
  {
  public:
    strstr_call_info (const call_details &cd, bool found)
    : call_info (cd), m_found (found)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      if (m_found)
	pp_printf (&pp,
		   "when %qE returns non-NULL",
		   get_fndecl ());
      else
	pp_printf (&pp,
		   "when %qE returns NULL",
		   get_fndecl ());
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      const call_details cd (get_call_details (model, ctxt));
      if (tree lhs_type = cd.get_lhs_type ())
	{
	  region_model_manager *mgr = model->get_manager ();
	  const svalue *result;
	  if (m_found)
	    {
	      const svalue *str_sval = cd.get_arg_svalue (0);
	      const region *str_reg
		= model->deref_rvalue (str_sval, cd.get_arg_tree (0),
				       cd.get_ctxt ());
	      /* We want str_sval + OFFSET for some unknown OFFSET.
		 Use a conjured_svalue to represent the offset,
		 using the str_reg as the id of the conjured_svalue.  */
	      const svalue *offset
		= mgr->get_or_create_conjured_svalue (size_type_node,
						      &cd.get_call_stmt (),
						      str_reg,
						      conjured_purge (model,
								      ctxt));
	      result = mgr->get_or_create_binop (lhs_type, POINTER_PLUS_EXPR,
						 str_sval, offset);
	    }
	  else
	    result = mgr->get_or_create_int_cst (lhs_type, 0);
	  cd.maybe_set_lhs (result);
	}
      return true;
    }
  private:
    bool m_found;
  };

  /* Body of kf_strstr::impl_call_post.  */
  if (cd.get_ctxt ())
    {
      cd.get_ctxt ()->bifurcate (std::make_unique<strstr_call_info> (cd, false));
      cd.get_ctxt ()->bifurcate (std::make_unique<strstr_call_info> (cd, true));
      cd.get_ctxt ()->terminate_path ();
    }
}

/* Handle calls to "strtok".
   See e.g.
     https://en.cppreference.com/w/c/string/byte/strtok
     https://man7.org/linux/man-pages/man3/strtok.3.html  */

class kf_strtok : public known_function
{
public:
  class undefined_behavior : public undefined_function_behavior
  {
  public:
    undefined_behavior (const call_details &cd)
    : undefined_function_behavior (cd)
    {
    }
    int get_controlling_option () const final override
    {
      return OPT_Wanalyzer_undefined_behavior_strtok;
    }

    bool emit (diagnostic_emission_context &ctxt) final override
    {
      /* CWE-476: NULL Pointer Dereference.  */
      ctxt.add_cwe (476);
      if (ctxt.warn ("calling %qD for first time with NULL as argument 1"
		     " has undefined behavior",
		     get_callee_fndecl ()))
	{
	  inform (ctxt.get_location (),
		  "some implementations of %qD may crash on such input",
		  get_callee_fndecl ());
	  return true;
	}
      return false;
    }

    bool
    describe_final_event (pretty_printer &pp,
			  const evdesc::final_event &) final override
    {
      pp_printf (&pp,
		 "calling %qD for first time with NULL as argument 1"
		 " has undefined behavior",
		 get_callee_fndecl ());
      return true;
    }
  };

  /* An outcome of a "strtok" call.
     We have a four-way bifurcation of the analysis via the
     4 combinations of two flags:
     - m_nonnull_str covers whether the "str" param was null or non-null
     - m_found covers whether the result is null or non-null
   */
  class strtok_call_info : public call_info
  {
  public:
    strtok_call_info (const call_details &cd,
		      const private_region &private_reg,
		      bool nonnull_str,
		      bool found)
    : call_info (cd),
      m_private_reg (private_reg),
      m_nonnull_str (nonnull_str),
      m_found (found)
    {
    }

    void print_desc (pretty_printer &pp) const final override
    {
      if (m_nonnull_str)
	{
	  if (m_found)
	    pp_printf (&pp,
		       "when %qE on non-NULL string returns non-NULL",
		       get_fndecl ());
	  else
	    pp_printf (&pp,
		       "when %qE on non-NULL string returns NULL",
		       get_fndecl ());
	}
      else
	{
	  if (m_found)
	    pp_printf (&pp,
		       "when %qE with NULL string (using prior) returns"
		       " non-NULL",
		       get_fndecl ());
	  else
	    pp_printf (&pp,
		       "when %qE with NULL string (using prior) returns NULL",
		       get_fndecl ());
	}
    }

    bool update_model (region_model *model,
		       const exploded_edge *,
		       region_model_context *ctxt) const final override
    {
      region_model_manager *mgr = model->get_manager ();
      const call_details cd (get_call_details (model, ctxt));
      const svalue *str_sval = cd.get_arg_svalue (0);
      /* const svalue *delim_sval = cd.get_arg_svalue (1); */

      cd.check_for_null_terminated_string_arg (1);
      /* We check that either arg 0 or the private region is null
	 terminated below.  */

      const svalue *null_ptr_sval
	= mgr->get_or_create_null_ptr (cd.get_arg_type (0));;
      if (!model->add_constraint (str_sval,
				  m_nonnull_str ? NE_EXPR : EQ_EXPR,
				  null_ptr_sval,
				  cd.get_ctxt ()))
	return false;

      if (m_nonnull_str)
	{
	  /* Update internal buffer.  */
	  model->set_value (&m_private_reg,
			    mgr->get_or_create_unmergeable (str_sval),
			    ctxt);
	}
      else
	{
	  /* Read from internal buffer.  */
	  str_sval = model->get_store_value (&m_private_reg, ctxt);

	  /* The initial value of the private region is NULL when we're
	     on a path from main.  */
	  if (const initial_svalue *initial_sval
		= str_sval->dyn_cast_initial_svalue ())
	    if (initial_sval->get_region () == &m_private_reg
		&& model->called_from_main_p ())
	      {
		/* Implementations of strtok do not necessarily check for NULL
		   here, and may crash; see PR analyzer/107573.
		   Warn for this, if we were definitely passed NULL.  */
		if (cd.get_arg_svalue (0)->all_zeroes_p ())
		  {
		    if (ctxt)
		      ctxt->warn (::std::make_unique<undefined_behavior> (cd));
		  }

		/* Assume that "str" was actually non-null; terminate
		   this path.  */
		return false;
	      }

	  /* Now assume str_sval is non-null.  */
	  if (!model->add_constraint (str_sval,
				      NE_EXPR,
				      null_ptr_sval,
				      cd.get_ctxt ()))
	    return false;
	}

      const region *buf_reg = model->deref_rvalue (str_sval, NULL_TREE, ctxt);
      model->scan_for_null_terminator (buf_reg,
				       NULL_TREE,
				       nullptr,
				       ctxt);

      if (m_found)
	{
	  const region *str_reg
	    = model->deref_rvalue (str_sval, cd.get_arg_tree (0),
				   cd.get_ctxt ());
	  /* We want to figure out the start and nul terminator
	     for the token.
	     For each, we want str_sval + OFFSET for some unknown OFFSET.
	     Use a conjured_svalue to represent the offset,
	     using the str_reg as the id of the conjured_svalue.  */
	  const svalue *start_offset
	    = mgr->get_or_create_conjured_svalue (size_type_node,
						  &cd.get_call_stmt (),
						  str_reg,
						  conjured_purge (model,
								  ctxt),
						  0);
	  const svalue *nul_offset
	    = mgr->get_or_create_conjured_svalue (size_type_node,
						  &cd.get_call_stmt (),
						  str_reg,
						  conjured_purge (model,
								  ctxt),
						  1);

	  tree char_ptr_type = build_pointer_type (char_type_node);
	  const svalue *result
	    = mgr->get_or_create_binop (char_ptr_type, POINTER_PLUS_EXPR,
					str_sval, start_offset);
	  cd.maybe_set_lhs (result);

	  /* nul_offset + 1; the offset to use for the next call.  */
	  const svalue *next_offset
	    = mgr->get_or_create_binop (size_type_node, PLUS_EXPR,
					nul_offset,
					mgr->get_or_create_int_cst
					(char_type_node, 1));

	  /* Write '\0' to str_sval[nul_offset].  */
	  const svalue *ptr_to_term
	    = mgr->get_or_create_binop (char_ptr_type, POINTER_PLUS_EXPR,
					str_sval, nul_offset);
	  const region *terminator_reg
	    = model->deref_rvalue (ptr_to_term, NULL_TREE, cd.get_ctxt ());
	  model->set_value (terminator_reg,
			    mgr->get_or_create_unmergeable
			    (mgr->get_or_create_int_cst (char_type_node,
							 0)),
			    cd.get_ctxt ());

	  /* Update saved ptr to be at [nul_offset + 1].  */
	  const svalue *ptr_to_next
	    = mgr->get_or_create_binop (cd.get_lhs_type (), POINTER_PLUS_EXPR,
					str_sval, next_offset);
	  model->set_value (&m_private_reg, ptr_to_next, ctxt);
	}
      else
	if (tree lhs_type = cd.get_lhs_type ())
	  {
	    const svalue *result
	      = mgr->get_or_create_int_cst (lhs_type, 0);
	    cd.maybe_set_lhs (result);
	  }
      return true;
    }
  private:
    const private_region &m_private_reg;
    bool m_nonnull_str;
    bool m_found;
  }; // class strtok_call_info

  kf_strtok (region_model_manager &mgr)
  : m_private_reg (mgr.alloc_symbol_id (),
		   mgr.get_root_region (),
		   get_region_type (),
		   "strtok buffer")
  {
  }

  bool matches_call_types_p (const call_details &cd) const final override
  {
    return (cd.num_args () == 2
	    && POINTER_TYPE_P (cd.get_arg_type (0))
	    && POINTER_TYPE_P (cd.get_arg_type (1)));
  }

  void impl_call_post (const call_details &cd) const final override
  {
    if (cd.get_ctxt ())
      {
	/* Four-way bifurcation, based on whether:
	   - the str is non-null
	   - the result is non-null
	   Typically the str is either null or non-null at a particular site,
	   so hopefully this will generally just lead to two out-edges.  */
	cd.get_ctxt ()->bifurcate
	  (std::make_unique<strtok_call_info> (cd, m_private_reg, false, false));
	cd.get_ctxt ()->bifurcate
	  (std::make_unique<strtok_call_info> (cd, m_private_reg, false, true));
	cd.get_ctxt ()->bifurcate
	  (std::make_unique<strtok_call_info> (cd, m_private_reg, true, false));
	cd.get_ctxt ()->bifurcate
	  (std::make_unique<strtok_call_info> (cd, m_private_reg, true, true));
	cd.get_ctxt ()->terminate_path ();
      }
  }

private:
  static tree get_region_type ()
  {
    return build_pointer_type (char_type_node);
  }
  const private_region m_private_reg;
};

/* Handle calls to functions referenced by
   __attribute__((malloc(FOO))).  */

void
region_model::impl_deallocation_call (const call_details &cd)
{
  kf_free kf;
  kf.impl_call_post (cd);
}

static void
register_atomic_builtins (known_function_manager &kfm)
{
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE, std::make_unique<kf_atomic_exchange> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_N, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_1, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_2, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_4, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_8, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_EXCHANGE_16, std::make_unique<kf_atomic_exchange_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD, std::make_unique<kf_atomic_load> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_N, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_1, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_2, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_4, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_8, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_LOAD_16, std::make_unique<kf_atomic_load_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE, std::make_unique<kf_atomic_store> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_N, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_1, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_2, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_4, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_8, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_STORE_16, std::make_unique<kf_atomic_store_n> ());
  kfm.add (BUILT_IN_ATOMIC_ADD_FETCH_1,
	   std::make_unique<kf_atomic_op_fetch> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_ADD_FETCH_2,
	   std::make_unique<kf_atomic_op_fetch> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_ADD_FETCH_4,
	   std::make_unique<kf_atomic_op_fetch> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_ADD_FETCH_8,
	   std::make_unique<kf_atomic_op_fetch> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_ADD_FETCH_16,
	   std::make_unique<kf_atomic_op_fetch> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_SUB_FETCH_1,
	   std::make_unique<kf_atomic_op_fetch> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_SUB_FETCH_2,
	   std::make_unique<kf_atomic_op_fetch> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_SUB_FETCH_4,
	   std::make_unique<kf_atomic_op_fetch> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_SUB_FETCH_8,
	   std::make_unique<kf_atomic_op_fetch> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_SUB_FETCH_16,
	   std::make_unique<kf_atomic_op_fetch> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_AND_FETCH_1,
	   std::make_unique<kf_atomic_op_fetch> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_AND_FETCH_2,
	   std::make_unique<kf_atomic_op_fetch> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_AND_FETCH_4,
	   std::make_unique<kf_atomic_op_fetch> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_AND_FETCH_8,
	   std::make_unique<kf_atomic_op_fetch> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_AND_FETCH_16,
	   std::make_unique<kf_atomic_op_fetch> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_XOR_FETCH_1,
	   std::make_unique<kf_atomic_op_fetch> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_XOR_FETCH_2,
	   std::make_unique<kf_atomic_op_fetch> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_XOR_FETCH_4,
	   std::make_unique<kf_atomic_op_fetch> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_XOR_FETCH_8,
	   std::make_unique<kf_atomic_op_fetch> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_XOR_FETCH_16,
	   std::make_unique<kf_atomic_op_fetch> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_OR_FETCH_1,
	   std::make_unique<kf_atomic_op_fetch> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_OR_FETCH_2,
	   std::make_unique<kf_atomic_op_fetch> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_OR_FETCH_4,
	   std::make_unique<kf_atomic_op_fetch> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_OR_FETCH_8,
	   std::make_unique<kf_atomic_op_fetch> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_OR_FETCH_16,
	   std::make_unique<kf_atomic_op_fetch> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_ADD_1,
	   std::make_unique<kf_atomic_fetch_op> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_ADD_2,
	   std::make_unique<kf_atomic_fetch_op> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_ADD_4,
	   std::make_unique<kf_atomic_fetch_op> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_ADD_8,
	   std::make_unique<kf_atomic_fetch_op> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_ADD_16,
	   std::make_unique<kf_atomic_fetch_op> (PLUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_SUB_1,
	   std::make_unique<kf_atomic_fetch_op> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_SUB_2,
	   std::make_unique<kf_atomic_fetch_op> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_SUB_4,
	   std::make_unique<kf_atomic_fetch_op> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_SUB_8,
	   std::make_unique<kf_atomic_fetch_op> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_SUB_16,
	   std::make_unique<kf_atomic_fetch_op> (MINUS_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_AND_1,
	   std::make_unique<kf_atomic_fetch_op> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_AND_2,
	   std::make_unique<kf_atomic_fetch_op> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_AND_4,
	   std::make_unique<kf_atomic_fetch_op> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_AND_8,
	   std::make_unique<kf_atomic_fetch_op> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_AND_16,
	   std::make_unique<kf_atomic_fetch_op> (BIT_AND_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_XOR_1,
	   std::make_unique<kf_atomic_fetch_op> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_XOR_2,
	   std::make_unique<kf_atomic_fetch_op> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_XOR_4,
	   std::make_unique<kf_atomic_fetch_op> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_XOR_8,
	   std::make_unique<kf_atomic_fetch_op> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_XOR_16,
	   std::make_unique<kf_atomic_fetch_op> (BIT_XOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_OR_1,
	   std::make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_OR_2,
	   std::make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_OR_4,
	   std::make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_OR_8,
	   std::make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
  kfm.add (BUILT_IN_ATOMIC_FETCH_OR_16,
	   std::make_unique<kf_atomic_fetch_op> (BIT_IOR_EXPR));
}

/* Handle calls to the various IFN_UBSAN_* with no return value.
   For now, treat these as no-ops.  */

class kf_ubsan_noop : public internal_known_function
{
};

/* Handle calls to the various __builtin___ubsan_handle_*.
   These can return, but continuing after such a return
   isn't likely to be interesting to the user of the analyzer.
   Hence we terminate the analysis path at one of these calls.  */

class kf_ubsan_handler : public internal_known_function
{
  void impl_call_post (const call_details &cd) const final override
  {
    if (cd.get_ctxt ())
      cd.get_ctxt ()->terminate_path ();
  }
};

static void
register_sanitizer_builtins (known_function_manager &kfm)
{
  /* Handle calls to the various IFN_UBSAN_* with no return value.
     For now, treat these as no-ops.  */
  kfm.add (IFN_UBSAN_NULL,
	   std::make_unique<kf_ubsan_noop> ());
  kfm.add (IFN_UBSAN_BOUNDS,
	   std::make_unique<kf_ubsan_noop> ());
  kfm.add (IFN_UBSAN_PTR,
	   std::make_unique<kf_ubsan_noop> ());

  kfm.add (BUILT_IN_UBSAN_HANDLE_NONNULL_ARG,
	   std::make_unique<kf_ubsan_handler> ());
}

/* Populate KFM with instances of known functions supported by the core of the
   analyzer (as opposed to plugins).  */

void
register_known_functions (known_function_manager &kfm,
			  region_model_manager &rmm)
{
  /* Debugging/test support functions, all  with a "__analyzer_" prefix.  */
  register_known_analyzer_functions (kfm);

  /* Internal fns the analyzer has known_functions for.  */
  {
    kfm.add (IFN_BUILTIN_EXPECT, std::make_unique<kf_expect> ());
  }

  /* GCC built-ins that do not correspond to a function
     in the standard library.  */
  {
    kfm.add (BUILT_IN_EXPECT, std::make_unique<kf_expect> ());
    kfm.add (BUILT_IN_EXPECT_WITH_PROBABILITY, std::make_unique<kf_expect> ());
    kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, std::make_unique<kf_alloca> ());
    kfm.add (BUILT_IN_STACK_RESTORE, std::make_unique<kf_stack_restore> ());
    kfm.add (BUILT_IN_STACK_SAVE, std::make_unique<kf_stack_save> ());

    kfm.add (BUILT_IN_EH_POINTER, std::make_unique<kf_eh_pointer> ());

    register_atomic_builtins (kfm);
    register_sanitizer_builtins (kfm);
    register_varargs_builtins (kfm);
  }

  /* Known builtins and C standard library functions
     the analyzer has known functions for.  */
  {
    kfm.add ("alloca", std::make_unique<kf_alloca> ());
    kfm.add ("__builtin_alloca", std::make_unique<kf_alloca> ());
    kfm.add ("calloc", std::make_unique<kf_calloc> ());
    kfm.add ("__builtin_calloc", std::make_unique<kf_calloc> ());
    kfm.add ("free", std::make_unique<kf_free> ());
    kfm.add ("__builtin_free", std::make_unique<kf_free> ());
    kfm.add ("malloc", std::make_unique<kf_malloc> ());
    kfm.add ("__builtin_malloc", std::make_unique<kf_malloc> ());
    kfm.add ("memcpy",
	      std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
    kfm.add ("__builtin_memcpy",
	      std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
    kfm.add ("__memcpy_chk", std::make_unique<kf_memcpy_memmove>
			      (kf_memcpy_memmove::KF_MEMCPY_CHK));
    kfm.add ("__builtin___memcpy_chk", std::make_unique<kf_memcpy_memmove>
			      (kf_memcpy_memmove::KF_MEMCPY_CHK));
    kfm.add ("memmove",
	      std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
    kfm.add ("__builtin_memmove",
	      std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
    kfm.add ("__memmove_chk", std::make_unique<kf_memcpy_memmove>
			      (kf_memcpy_memmove::KF_MEMMOVE_CHK));
    kfm.add ("__builtin___memmove_chk", std::make_unique<kf_memcpy_memmove>
			      (kf_memcpy_memmove::KF_MEMMOVE_CHK));
    kfm.add ("memset", std::make_unique<kf_memset> (false));
    kfm.add ("__builtin_memset", std::make_unique<kf_memset> (false));
    kfm.add ("__memset_chk", std::make_unique<kf_memset> (true));
    kfm.add ("__builtin___memset_chk", std::make_unique<kf_memset> (true));
    kfm.add ("realloc", std::make_unique<kf_realloc> ());
    kfm.add ("__builtin_realloc", std::make_unique<kf_realloc> ());
    kfm.add ("sprintf", std::make_unique<kf_sprintf> ());
    kfm.add ("__builtin_sprintf", std::make_unique<kf_sprintf> ());
    kfm.add ("strchr", std::make_unique<kf_strchr> ());
    kfm.add ("__builtin_strchr", std::make_unique<kf_strchr> ());
    kfm.add ("strcpy", std::make_unique<kf_strcpy> (2, false));
    kfm.add ("__builtin_strcpy", std::make_unique<kf_strcpy> (2, false));
    kfm.add ("__strcpy_chk", std::make_unique<kf_strcpy> (3, true));
    kfm.add ("__builtin___strcpy_chk", std::make_unique<kf_strcpy> (3, true));
    kfm.add ("strcat", std::make_unique<kf_strcat> (2, false));
    kfm.add ("__builtin_strcat", std::make_unique<kf_strcat> (2, false));
    kfm.add ("__strcat_chk", std::make_unique<kf_strcat> (3, true));
    kfm.add ("__builtin___strcat_chk", std::make_unique<kf_strcat> (3, true));
    kfm.add ("strdup", std::make_unique<kf_strdup> ());
    kfm.add ("__builtin_strdup", std::make_unique<kf_strdup> ());
    kfm.add ("strncpy", std::make_unique<kf_strncpy> ());
    kfm.add ("__builtin_strncpy", std::make_unique<kf_strncpy> ());
    kfm.add ("strndup", std::make_unique<kf_strndup> ());
    kfm.add ("__builtin_strndup", std::make_unique<kf_strndup> ());
    kfm.add ("strlen", std::make_unique<kf_strlen> ());
    kfm.add ("__builtin_strlen", std::make_unique<kf_strlen> ());
    kfm.add ("strstr", std::make_unique<kf_strstr> ());
    kfm.add ("__builtin_strstr", std::make_unique<kf_strstr> ());

    register_atomic_builtins (kfm);
    register_varargs_builtins (kfm);
  }

  /* Known POSIX functions, and some non-standard extensions.  */
  {
    kfm.add ("fopen", std::make_unique<kf_fopen> ());
    kfm.add ("putenv", std::make_unique<kf_putenv> ());
    kfm.add ("strtok", std::make_unique<kf_strtok> (rmm));

    register_known_fd_functions (kfm);
    register_known_file_functions (kfm);
  }

  /* glibc functions.  */
  {
    kfm.add ("__errno_location", std::make_unique<kf_errno_location> ());
    kfm.add ("error", std::make_unique<kf_error> (3));
    kfm.add ("error_at_line", std::make_unique<kf_error> (5));
    /* Variants of "error" and "error_at_line" seen by the
       analyzer at -O0 (PR analyzer/115724).  */
    kfm.add ("__error_alias", std::make_unique<kf_error> (3));
    kfm.add ("__error_at_line_alias", std::make_unique<kf_error> (5));
  }

  /* Other implementations of C standard library.  */
  {
    /* According to PR 107807 comment #2, Solaris implements "errno"
       like this:
	 extern int *___errno(void) __attribute__((__const__));
	 #define errno (*(___errno()))
       and macOS like this:
	 extern int * __error(void);
	 #define errno (*__error())
       and similarly __errno for newlib.
       Add these as synonyms for "__errno_location".  */
    kfm.add ("___errno", std::make_unique<kf_errno_location> ());
    kfm.add ("__error", std::make_unique<kf_errno_location> ());
    kfm.add ("__errno", std::make_unique<kf_errno_location> ());
  }

  /* Language-specific support functions.  */
  register_known_functions_lang_cp (kfm);

  /* Some C++ implementations use the std:: copies of these functions
     from <cstdlib> etc for the C spellings of these headers (e.g. <stdlib.h>),
     so we must match against these too.  */
  {
    kfm.add_std_ns ("malloc", std::make_unique<kf_malloc> ());
    kfm.add_std_ns ("free", std::make_unique<kf_free> ());
    kfm.add_std_ns ("realloc", std::make_unique<kf_realloc> ());
    kfm.add_std_ns ("calloc", std::make_unique<kf_calloc> ());
    kfm.add_std_ns
      ("memcpy",
       std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
    kfm.add_std_ns
      ("memmove",
       std::make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
    kfm.add_std_ns ("memset", std::make_unique<kf_memset> (false));
    kfm.add_std_ns ("strcat", std::make_unique<kf_strcat> (2, false));
    kfm.add_std_ns ("strcpy", std::make_unique<kf_strcpy> (2, false));
    kfm.add_std_ns ("strlen", std::make_unique<kf_strlen> ());
    kfm.add_std_ns ("strncpy", std::make_unique<kf_strncpy> ());
    kfm.add_std_ns ("strtok", std::make_unique<kf_strtok> (rmm));
  }
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
