/* Functions to enable and disable individual warnings on an expression
   and statement basis.
   Copyright (C) 2021-2022 Free Software Foundation, Inc.
   Contributed by Martin Sebor <msebor@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 "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "bitmap.h"
#include "tree.h"
#include "cgraph.h"
#include "hash-map.h"
#include "diagnostic-spec.h"
#include "pretty-print.h"
#include "options.h"

/* Initialize *THIS from warning option OPT.  */

nowarn_spec_t::nowarn_spec_t (opt_code opt)
{
  /* Create a very simple mapping based on testing and experience.
     It should become more refined with time. */
  switch (opt)
    {
    case no_warning:
      m_bits = 0;
      break;

    case all_warnings:
      m_bits = -1;
      break;

      /* Flow-sensitive warnings about pointer problems issued by both
	 front ends and the middle end.  */
    case OPT_Waddress:
    case OPT_Wnonnull:
      m_bits = NW_NONNULL;
      break;

      /* Flow-sensitive warnings about arithmetic overflow issued by both
	 front ends and the middle end.  */
    case OPT_Woverflow:
    case OPT_Wshift_count_negative:
    case OPT_Wshift_count_overflow:
    case OPT_Wstrict_overflow:
      m_bits = NW_VFLOW;
      break;

      /* Lexical warnings issued by front ends.  */
    case OPT_Wabi:
    case OPT_Wlogical_op:
    case OPT_Wparentheses:
    case OPT_Wreturn_type:
    case OPT_Wsizeof_array_div:
    case OPT_Wstrict_aliasing:
    case OPT_Wunused:
    case OPT_Wunused_function:
    case OPT_Wunused_but_set_variable:
    case OPT_Wunused_variable:
    case OPT_Wunused_but_set_parameter:
      m_bits = NW_LEXICAL;
      break;

      /* Access warning group.  */
    case OPT_Warray_bounds:
    case OPT_Warray_bounds_:
    case OPT_Wformat_overflow_:
    case OPT_Wformat_truncation_:
    case OPT_Wrestrict:
    case OPT_Wsizeof_pointer_memaccess:
    case OPT_Wstrict_aliasing_:
    case OPT_Wstringop_overflow_:
    case OPT_Wstringop_overread:
    case OPT_Wstringop_truncation:
      m_bits = NW_ACCESS;
      break;

      /* Initialization warning group.  */
    case OPT_Winit_self:
    case OPT_Wuninitialized:
    case OPT_Wmaybe_uninitialized:
      m_bits = NW_UNINIT;
      break;

    case OPT_Wdangling_pointer_:
    case OPT_Wreturn_local_addr:
    case OPT_Wuse_after_free_:
      m_bits = NW_DANGLING;
      break;

    case OPT_Wpessimizing_move:
    case OPT_Wredundant_move:
      m_bits = NW_REDUNDANT;
      break;

    default:
      /* A catchall group for everything else.  */
      m_bits = NW_OTHER;
    }
}

/* A mapping from a 'location_t' to the warning spec set for it.  */

GTY(()) nowarn_map_t *nowarn_map;

/* Return the no-warning disposition for location LOC and option OPT
   or for all/any otions by default.  */

bool
warning_suppressed_at (location_t loc, opt_code opt /* = all_warnings */)
{
  gcc_checking_assert (!RESERVED_LOCATION_P (loc));

  if (!nowarn_map)
    return false;

  if (const nowarn_spec_t* const pspec = nowarn_map->get (loc))
    {
      const nowarn_spec_t optspec (opt);
      return *pspec & optspec;
    }

  return false;
}

 /* Change the supression of warnings for location LOC.
    OPT controls which warnings are affected.
    The wildcard OPT of -1 controls all warnings.
    If SUPP is true (the default), enable the suppression of the warnings.
    If SUPP is false, disable the suppression of the warnings.  */

bool
suppress_warning_at (location_t loc, opt_code opt /* = all_warnings */,
		     bool supp /* = true */)
{
  gcc_checking_assert (!RESERVED_LOCATION_P (loc));

  const nowarn_spec_t optspec (supp ? opt : opt_code ());

  if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL)
    {
      if (supp)
	{
	  *pspec |= optspec;
	  return true;
	}

      *pspec &= optspec;
      if (*pspec)
	return true;

      nowarn_map->remove (loc);
      return false;
    }

  if (!supp || opt == no_warning)
    return false;

  if (!nowarn_map)
    nowarn_map = nowarn_map_t::create_ggc (32);

  nowarn_map->put (loc, optspec);
  return true;
}

/* Copy the no-warning disposition from one location to another.  */

void
copy_warning (location_t to, location_t from)
{
  if (!nowarn_map)
    return;

  nowarn_spec_t *from_spec;
  if (RESERVED_LOCATION_P (from))
    from_spec = NULL;
  else
    from_spec = nowarn_map->get (from);
  if (RESERVED_LOCATION_P (to))
    /* We cannot set no-warning dispositions for 'to', so we have no chance but
       lose those potentially set for 'from'.  */
    ;
  else
    {
      if (from_spec)
	{
	  nowarn_spec_t tem = *from_spec;
	  nowarn_map->put (to, tem);
	}
      else
	nowarn_map->remove (to);
    }
}
