The attached patch replaces the uses of TREE_NO_WARNING in the C++
front end.  For the set/get_no_warning calls I tried to find the most
appropriate option to disable and query.  In some cases there are
helpful comments nearby that made this easy.  In other cases it was
less straightforward, and in some I didn't know.  In some of those,
disabling all warnings may be what we want, but in others we might
want to be more selective to further improve efficacy.
Add support for per-location warning groups.

	* call.c (build_over_call): Replace direct uses of TREE_NO_WARNING
	with get_no_warning, set_no_warning, and copy_no_warning, or nothing
	if not necessary.
	(set_up_extended_ref_temp): Same.
	* class.c (layout_class_type): Same.
	* constraint.cc (constraint_satisfaction_value): Same.
	* coroutines.cc (finish_co_await_expr): Same.
	(finish_co_yield_expr): Same.
	(finish_co_return_stmt): Same.
	(build_actor_fn): Same.
	(coro_rewrite_function_body): Same.
	(morph_fn_to_coro): Same.
	* cp-gimplify.c (genericize_eh_spec_block): Same.
	(gimplify_expr_stmt): Same.
	(cp_genericize_r): Same.
	(cp_fold): Same.
	* cp-ubsan.c (cp_ubsan_instrument_vptr): Same.
	* cvt.c (cp_fold_convert): Same.
	(convert_to_void): Same.
	* decl.c (wrapup_namespace_globals): Same.
	(grokdeclarator): Same.
	(finish_function): Same.
	(require_deduced_type): Same.
	* decl2.c (no_linkage_error): Same.
	(c_parse_final_cleanups): Same.
	* except.c (expand_end_catch_block): Same.
	* init.c (build_new_1): Same.
	(build_new): Same.
	(build_vec_delete_1): Same.
	(build_vec_init): Same.
	(build_delete): Same.
	* method.c (defaultable_fn_check): Same.
	* parser.c (cp_parser_fold_expression): Same.
	(cp_parser_primary_expression): Same.
	* pt.c (push_tinst_level_loc): Same.
	(tsubst_copy): Same.
	(tsubst_omp_udr): Same.
	(tsubst_copy_and_build): Same.
	* rtti.c (build_if_nonnull): Same.
	* semantics.c (maybe_convert_cond): Same.
	(finish_return_stmt): Same.
	(finish_parenthesized_expr): Same.
	(cp_check_omp_declare_reduction): Same.
	* tree.c (build_cplus_array_type): Same.
	* typeck.c (build_ptrmemfunc_access_expr): Same.
	(cp_build_indirect_ref_1): Same.
	(cp_build_function_call_vec): Same.
	(warn_for_null_address): Same.
	(cp_build_binary_op): Same.
	(unary_complex_lvalue): Same.
	(cp_build_modify_expr): Same.
	(build_x_modify_expr): Same.
	(convert_for_assignment): Same.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4a59b97c110..2355020066a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9437,7 +9437,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 	{
 	  /* Avoid copying empty classes.  */
 	  val = build2 (COMPOUND_EXPR, type, arg, to);
-	  TREE_NO_WARNING (val) = 1;
+	  set_no_warning (val, OPT_Wunused);
 	}
       else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
 	{
@@ -9468,7 +9468,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 		      build2 (MEM_REF, array_type, arg0, alias_set),
 		      build2 (MEM_REF, array_type, arg, alias_set));
 	  val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);
-          TREE_NO_WARNING (val) = 1;
+          set_no_warning (val, OPT_Wunused);
 	}
 
       cp_warn_deprecated_use (fn, complain);
@@ -9542,7 +9542,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       tree c = extract_call_expr (call);
       if (TREE_CODE (c) == CALL_EXPR)
-	TREE_NO_WARNING (c) = 1;
+	set_no_warning (c /* Suppress all warnings.  */);
     }
   if (TREE_CODE (fn) == ADDR_EXPR)
     {
@@ -12491,11 +12491,11 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
     TREE_ADDRESSABLE (var) = 1;
 
   if (TREE_CODE (decl) == FIELD_DECL
-      && extra_warnings && !TREE_NO_WARNING (decl))
+      && extra_warnings && !get_no_warning (decl))
     {
       warning (OPT_Wextra, "a temporary bound to %qD only persists "
 	       "until the constructor exits", decl);
-      TREE_NO_WARNING (decl) = true;
+      set_no_warning (decl);
     }
 
   /* Recursively extend temps in this initializer.  */
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 354addde773..c3024842f87 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6689,7 +6689,7 @@ layout_class_type (tree t, tree *virtuals_p)
 	     laying out an Objective-C class.  The ObjC ABI differs
 	     from the C++ ABI, and so we do not want a warning
 	     here.  */
-	  && !TREE_NO_WARNING (field)
+	  && !get_no_warning (field, OPT_Wabi)
 	  && !last_field_was_bitfield
 	  && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
 					 DECL_FIELD_BIT_OFFSET (field),
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 03ce8eb9ff2..c30127662b5 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3281,14 +3281,14 @@ constraint_satisfaction_value (tree t, tree args, sat_info info)
   else
     r = satisfy_nondeclaration_constraints (t, args, info);
   if (r == error_mark_node && info.quiet ()
-      && !(DECL_P (t) && TREE_NO_WARNING (t)))
+      && !(DECL_P (t) && get_no_warning (t)))
     {
       /* Replay the error noisily.  */
       sat_info noisy (tf_warning_or_error, info.in_decl);
       constraint_satisfaction_value (t, args, noisy);
       if (DECL_P (t) && !args)
 	/* Avoid giving these errors again.  */
-	TREE_NO_WARNING (t) = true;
+	set_no_warning (t);
     }
   return r;
 }
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 71662061f5a..786bffcfad7 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1078,7 +1078,7 @@ finish_co_await_expr (location_t kw, tree expr)
      is declared to return non-void (most likely).  This is correct - we
      synthesize the return for the ramp in the compiler.  So suppress any
      extraneous warnings during substitution.  */
-  TREE_NO_WARNING (current_function_decl) = true;
+  set_no_warning (current_function_decl, OPT_Wreturn_type);
 
   /* If we don't know the promise type, we can't proceed, build the
      co_await with the expression unchanged.  */
@@ -1154,7 +1154,7 @@ finish_co_yield_expr (location_t kw, tree expr)
      is declared to return non-void (most likely).  This is correct - we
      synthesize the return for the ramp in the compiler.  So suppress any
      extraneous warnings during substitution.  */
-  TREE_NO_WARNING (current_function_decl) = true;
+  set_no_warning (current_function_decl, OPT_Wreturn_type);
 
   /* If we don't know the promise type, we can't proceed, build the
      co_await with the expression unchanged.  */
@@ -1235,7 +1235,7 @@ finish_co_return_stmt (location_t kw, tree expr)
      is declared to return non-void (most likely).  This is correct - we
      synthesize the return for the ramp in the compiler.  So suppress any
      extraneous warnings during substitution.  */
-  TREE_NO_WARNING (current_function_decl) = true;
+  set_no_warning (current_function_decl, OPT_Wreturn_type);
 
   if (processing_template_decl
       && check_for_bare_parameter_packs (expr))
@@ -1259,7 +1259,7 @@ finish_co_return_stmt (location_t kw, tree expr)
 
   /* Suppress -Wreturn-type for co_return, we need to check indirectly
      whether the promise type has a suitable return_void/return_value.  */
-  TREE_NO_WARNING (current_function_decl) = true;
+  set_no_warning (current_function_decl, OPT_Wreturn_type);
 
   if (!processing_template_decl && warn_sequence_point)
     verify_sequence_points (expr);
@@ -2459,7 +2459,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
 
   /* done.  */
   r = build_stmt (loc, RETURN_EXPR, NULL);
-  TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this.  */
+  set_no_warning (r); /* We don't want a warning about this.  */
   r = maybe_cleanup_point_expr_void (r);
   add_stmt (r);
 
@@ -2468,7 +2468,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
   add_stmt (r);
 
   r = build_stmt (loc, RETURN_EXPR, NULL);
-  TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this.  */
+  set_no_warning (r); /* We don't want a warning about this.  */
   r = maybe_cleanup_point_expr_void (r);
   add_stmt (r);
 
@@ -4144,7 +4144,7 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig,
       finish_if_stmt_cond (not_iarc, not_iarc_if);
       /* If the initial await resume called value is false, rethrow...  */
       tree rethrow = build_throw (fn_start, NULL_TREE);
-      TREE_NO_WARNING (rethrow) = true;
+      set_no_warning (rethrow);
       finish_expr_stmt (rethrow);
       finish_then_clause (not_iarc_if);
       tree iarc_scope = IF_SCOPE (not_iarc_if);
@@ -4245,7 +4245,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
       /* For early errors, we do not want a diagnostic about the missing
 	 ramp return value, since the user cannot fix this - a 'return' is
 	 not allowed in a coroutine.  */
-      TREE_NO_WARNING (orig) = true;
+      set_no_warning (orig, OPT_Wreturn_type);
       /* Discard the body, we can't process it further.  */
       pop_stmt_list (DECL_SAVED_TREE (orig));
       DECL_SAVED_TREE (orig) = push_stmt_list ();
@@ -4271,7 +4271,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
       DECL_SAVED_TREE (orig) = push_stmt_list ();
       append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
       /* Suppress warnings about the missing return value.  */
-      TREE_NO_WARNING (orig) = true;
+      set_no_warning (orig, OPT_Wreturn_type);
       return false;
     }
 
@@ -4950,7 +4950,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
       BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
       DECL_SAVED_TREE (orig) = newbody;
       /* Suppress warnings about the missing return value.  */
-      TREE_NO_WARNING (orig) = true;
+      set_no_warning (orig, OPT_Wreturn_type);
       return false;
     }
 
@@ -5161,7 +5161,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
 					      promise_type, fn_start);
       finish_expr_stmt (del_coro_fr);
       tree rethrow = build_throw (fn_start, NULL_TREE);
-      TREE_NO_WARNING (rethrow) = true;
+      set_no_warning (rethrow);
       finish_expr_stmt (rethrow);
       finish_handler (handler);
       TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup));
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 9079a5b90ca..2b3ec745912 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -101,8 +101,8 @@ genericize_eh_spec_block (tree *stmt_p)
   tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
 
   *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
-  TREE_NO_WARNING (*stmt_p) = true;
-  TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true;
+  set_no_warning (*stmt_p);
+  set_no_warning (TREE_OPERAND (*stmt_p, 1));
 }
 
 /* Return the first non-compound statement in STMT.  */
@@ -214,7 +214,7 @@ gimplify_expr_stmt (tree *stmt_p)
 	{
 	  if (!IS_EMPTY_STMT (stmt)
 	      && !VOID_TYPE_P (TREE_TYPE (stmt))
-	      && !TREE_NO_WARNING (stmt))
+	      && !get_no_warning (stmt, OPT_Wunused_value))
 	    warning (OPT_Wunused_value, "statement with no effect");
 	}
       else
@@ -1322,7 +1322,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
     case THROW_EXPR:
       {
 	location_t loc = location_of (stmt);
-	if (TREE_NO_WARNING (stmt))
+	if (get_no_warning (stmt /* What warning? */))
 	  /* Never mind.  */;
 	else if (wtd->try_block)
 	  {
@@ -2443,8 +2443,9 @@ cp_fold (tree x)
 	    ;
 	  else if (COMPARISON_CLASS_P (x))
 	    {
-	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
-		TREE_NO_WARNING (x) = 1;
+	      if (warn_nonnull_compare
+		  && get_no_warning (org_x, OPT_Wnonnull_compare))
+		set_no_warning (x, OPT_Wnonnull_compare);
 	    }
 	  /* Otherwise give up on optimizing these, let GIMPLE folders
 	     optimize those later on.  */
@@ -2452,8 +2453,9 @@ cp_fold (tree x)
 		   || op1 != TREE_OPERAND (org_x, 1))
 	    {
 	      x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
-	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
-		TREE_NO_WARNING (x) = 1;
+	      if (warn_nonnull_compare
+		  && get_no_warning (org_x, OPT_Wnonnull_compare))
+		set_no_warning (x, OPT_Wnonnull_compare);
 	    }
 	  else
 	    x = org_x;
@@ -2709,7 +2711,7 @@ cp_fold (tree x)
   if (EXPR_P (x) && TREE_CODE (x) == code)
     {
       TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
-      TREE_NO_WARNING (x) = TREE_NO_WARNING (org_x);
+      copy_no_warning (x, org_x);
     }
 
   if (!c.evaluation_restricted_p ())
diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c
index 3dabb6aa18a..bd38faf17f6 100644
--- a/gcc/cp/cp-ubsan.c
+++ b/gcc/cp/cp-ubsan.c
@@ -81,7 +81,7 @@ cp_ubsan_instrument_vptr (location_t loc, tree op, tree type, bool is_addr,
 			      build_zero_cst (TREE_TYPE (op)));
       /* This is a compiler generated comparison, don't emit
 	 e.g. -Wnonnull-compare warning for it.  */
-      TREE_NO_WARNING (cond) = 1;
+      set_no_warning (cond, OPT_Wnonnull_compare);
       vptr = build3_loc (loc, COND_EXPR, uint64_type_node, cond,
 			 vptr, build_int_cst (uint64_type_node, 0));
     }
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 7fa6e8df52b..90beaccc1aa 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -605,8 +605,6 @@ ignore_overflows (tree expr, tree orig)
 tree
 cp_fold_convert (tree type, tree expr)
 {
-  bool nowarn = TREE_NO_WARNING (expr);
-
   tree conv;
   if (TREE_TYPE (expr) == type)
     conv = expr;
@@ -630,8 +628,8 @@ cp_fold_convert (tree type, tree expr)
       conv = ignore_overflows (conv, expr);
     }
 
-  if (nowarn && TREE_CODE (expr) == TREE_CODE (conv))
-    TREE_NO_WARNING (conv) = nowarn;
+  if (TREE_CODE (expr) == TREE_CODE (conv))
+    copy_no_warning (conv, expr);
 
   return conv;
 }
@@ -1208,7 +1206,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
 	/* The second part of a compound expr contains the value.  */
 	tree op1 = TREE_OPERAND (expr,1);
 	tree new_op1;
-	if (implicit != ICV_CAST && !TREE_NO_WARNING (expr))
+	if (implicit != ICV_CAST && !get_no_warning (expr /* What warning? */))
 	  new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain);
 	else
 	  new_op1 = convert_to_void (op1, ICV_CAST, complain);
@@ -1394,7 +1392,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
             if (warn_unused_value
 		&& implicit != ICV_CAST
                 && (complain & tf_warning)
-                && !TREE_NO_WARNING (expr)
+                && !get_no_warning (expr, OPT_Wunused_value)
                 && !is_reference)
               warning_at (loc, OPT_Wunused_value, "value computed is not used");
             expr = TREE_OPERAND (expr, 0);
@@ -1578,7 +1576,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
     {
       if (implicit != ICV_CAST
 	  && warn_unused_value
-	  && !TREE_NO_WARNING (expr)
+	  && !get_no_warning (expr, OPT_Wunused_value)
 	  && !processing_template_decl
 	  && !cp_unevaluated_operand
 	  && (complain & tf_warning))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 28052df9f45..b23d1eaeb3d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -839,7 +839,7 @@ wrapup_namespace_globals ()
 	      && !TREE_PUBLIC (decl)
 	      && !DECL_ARTIFICIAL (decl)
 	      && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
-	      && !TREE_NO_WARNING (decl))
+	      && !get_no_warning (decl, OPT_Wunused_function))
 	    warning_at (DECL_SOURCE_LOCATION (decl),
 			OPT_Wunused_function,
 			"%qF declared %<static%> but never defined", decl);
@@ -13851,10 +13851,7 @@ grokdeclarator (const cp_declarator *declarator,
 		decl = build_decl (id_loc, FIELD_DECL, unqualified_id, type);
 		DECL_NONADDRESSABLE_P (decl) = bitfield;
 		if (bitfield && !unqualified_id)
-		  {
-		    TREE_NO_WARNING (decl) = 1;
-		    DECL_PADDING_P (decl) = 1;
-		  }
+		  DECL_PADDING_P (decl) = 1;
 
 		if (storage_class == sc_mutable)
 		  {
@@ -17448,7 +17445,7 @@ finish_function (bool inline_p)
       /* Don't complain if we are declared noreturn.  */
       && !TREE_THIS_VOLATILE (fndecl)
       && !DECL_NAME (DECL_RESULT (fndecl))
-      && !TREE_NO_WARNING (fndecl)
+      && !get_no_warning (fndecl, OPT_Wreturn_type)
       /* Structor return values (if any) are set by the compiler.  */
       && !DECL_CONSTRUCTOR_P (fndecl)
       && !DECL_DESTRUCTOR_P (fndecl)
@@ -17476,7 +17473,7 @@ finish_function (bool inline_p)
       else if (warning_at (&richloc, OPT_Wreturn_type,
 			   "no return statement in function returning "
 			   "non-void"))
-	TREE_NO_WARNING (fndecl) = 1;
+	set_no_warning (fndecl, OPT_Wreturn_type);
     }
 
   /* Lambda closure members are implicitly constexpr if possible.  */
@@ -17550,7 +17547,7 @@ finish_function (bool inline_p)
 	    && !DECL_READ_P (decl)
 	    && DECL_NAME (decl)
 	    && !DECL_ARTIFICIAL (decl)
-	    && !TREE_NO_WARNING (decl)
+	    && !get_no_warning (decl,OPT_Wunused_but_set_parameter)
 	    && !DECL_IN_SYSTEM_HEADER (decl)
 	    && TREE_TYPE (decl) != error_mark_node
 	    && !TYPE_REF_P (TREE_TYPE (decl))
@@ -18041,7 +18038,7 @@ require_deduced_type (tree decl, tsubst_flags_t complain)
 {
   if (undeduced_auto_decl (decl))
     {
-      if (TREE_NO_WARNING (decl) && seen_error ())
+      if (get_no_warning (decl) && seen_error ())
 	/* We probably already complained about deduction failure.  */;
       else if (complain & tf_error)
 	error ("use of %qD before deduction of %<auto%>", decl);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 89f874a32cc..b939c884b95 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4529,7 +4529,7 @@ no_linkage_error (tree decl)
 	  || (errorcount + sorrycount > 0
 	      && DECL_LANG_SPECIFIC (decl)
 	      && DECL_TEMPLATE_INFO (decl)
-	      && TREE_NO_WARNING (decl))))
+	      && get_no_warning (decl /* What warning? */))))
     /* In C++11 it's ok if the decl is defined.  */
     return;
 
@@ -5204,7 +5204,7 @@ c_parse_final_cleanups (void)
 	  && warning_at (DECL_SOURCE_LOCATION (decl), 0,
 			 "inline function %qD used but never defined", decl))
 	/* Avoid a duplicate warning from check_global_declaration.  */
-	TREE_NO_WARNING (decl) = 1;
+	set_no_warning (decl, OPT_Wunused);
     }
 
   /* So must decls that use a type with no linkage.  */
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index cbafc09629b..19ea97ce19b 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -466,7 +466,8 @@ expand_end_catch_block (void)
 	  || DECL_DESTRUCTOR_P (current_function_decl)))
     {
       tree rethrow = build_throw (input_location, NULL_TREE);
-      TREE_NO_WARNING (rethrow) = true;
+      /* Disable all warnings for the generated rethrow statement.  */
+      set_no_warning (rethrow);
       finish_expr_stmt (rethrow);
     }
 }
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a85f4d50750..52055f10cad 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3536,11 +3536,11 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	       the arguments to the constructor call.  */
 	    {
 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
-	      TREE_NO_WARNING (cleanup) = true;
+	      set_no_warning (cleanup);
 	      init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
 				  init_expr, cleanup);
 	      /* Likewise, this try-catch is compiler-generated.  */
-	      TREE_NO_WARNING (init_expr) = true;
+	      set_no_warning (init_expr);
 	    }
 	  else
 	    /* Ack!  First we allocate the memory.  Then we set our sentry
@@ -3562,7 +3562,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	      sentry = TARGET_EXPR_SLOT (begin);
 
 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
-	      TREE_NO_WARNING (cleanup) = true;
+	      set_no_warning (cleanup);
 
 	      TARGET_EXPR_CLEANUP (begin)
 		= build3 (COND_EXPR, void_type_node, sentry,
@@ -3576,7 +3576,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 			  build2 (COMPOUND_EXPR, void_type_node, init_expr,
 				  end));
 	      /* Likewise, this is compiler-generated.  */
-	      TREE_NO_WARNING (init_expr) = true;
+	      set_no_warning (init_expr);
 	    }
 	}
     }
@@ -3823,7 +3823,7 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type,
 
   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
   rval = build1_loc (loc, NOP_EXPR, TREE_TYPE (rval), rval);
-  TREE_NO_WARNING (rval) = 1;
+  set_no_warning (rval, OPT_Wunused_value);
 
   return rval;
 }
@@ -3995,7 +3995,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type,
 			  fold_convert (TREE_TYPE (base), nullptr_node));
   /* This is a compiler generated comparison, don't emit
      e.g. -Wnonnull-compare warning for it.  */
-  TREE_NO_WARNING (cond) = 1;
+  set_no_warning (cond, OPT_Wnonnull_compare);
   body = build3_loc (loc, COND_EXPR, void_type_node,
 		     cond, body, integer_zero_node);
   COND_EXPR_IS_VEC_DELETE (body) = true;
@@ -4657,7 +4657,7 @@ build_vec_init (tree base, tree maxindex, tree init,
       atype = build_pointer_type (atype);
       stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
       stmt_expr = cp_build_fold_indirect_ref (stmt_expr);
-      TREE_NO_WARNING (stmt_expr) = 1;
+      set_no_warning (stmt_expr /* What warning? */);
     }
 
   return stmt_expr;
@@ -4924,7 +4924,7 @@ build_delete (location_t loc, tree otype, tree addr,
   /* This is a compiler generated comparison, don't emit
      e.g. -Wnonnull-compare warning for it.  */
   else if (TREE_CODE (ifexp) == NE_EXPR)
-    TREE_NO_WARNING (ifexp) = 1;
+    set_no_warning (ifexp, OPT_Wnonnull_compare);
 
   if (!integer_nonzerop (ifexp))
     expr = build3 (COND_EXPR, void_type_node, ifexp, expr, void_node);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index dd745237f22..9942a73ba6e 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -3284,7 +3284,7 @@ defaultable_fn_check (tree fn)
       /* Avoid do_warn_unused_parameter warnings.  */
       for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
 	if (DECL_NAME (p))
-	  TREE_NO_WARNING (p) = 1;
+	  set_no_warning (p, OPT_Wunused_parameter);
 
       if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
 	/* Defer checking.  */;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bc0505df502..32dced21f5c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1,3 +1,4 @@
+
 /* -*- C++ -*- Parser.
    Copyright (C) 2000-2021 Free Software Foundation, Inc.
    Written by Mark Mitchell <m...@codesourcery.com>.
@@ -5322,7 +5323,7 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
   /* The operands of a fold-expression are cast-expressions, so binary or
      conditional expressions are not allowed.  We check this here to avoid
      tentative parsing.  */
-  if (EXPR_P (expr1) && TREE_NO_WARNING (expr1))
+  if (EXPR_P (expr1) && get_no_warning (expr1, OPT_Wparentheses))
     /* OK, the expression was parenthesized.  */;
   else if (is_binary_op (TREE_CODE (expr1)))
     error_at (location_of (expr1),
@@ -5603,7 +5604,10 @@ cp_parser_primary_expression (cp_parser *parser,
 	/* Consume the `)'.  */
 	token = cp_lexer_peek_token (parser->lexer);
 	location_t close_paren_loc = token->location;
+	bool no_wparens = get_no_warning (expr, OPT_Wparentheses);
 	expr.set_range (open_paren_loc, close_paren_loc);
+	if (no_wparens)
+	  set_no_warning (expr, OPT_Wparentheses);
 	if (!parens.require_close (parser)
 	    && !cp_parser_uncommitted_to_tentative_parse_p (parser))
 	  cp_parser_skip_to_end_of_statement (parser);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cbd2f3dc338..170cb4eead0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10942,9 +10942,9 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
      constant expressions.  */
   if (!targs && limit_bad_template_recursion (tldcl))
     {
-      /* Avoid no_linkage_errors and unused function warnings for this
-	 decl.  */
-      TREE_NO_WARNING (tldcl) = 1;
+      /* Avoid no_linkage_errors and unused function (and all other)
+	 warnings for this decl.  */
+      set_no_warning (tldcl);
       return false;
     }
 
@@ -17087,7 +17087,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
 	tree op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl);
 	r = build_nt (code, op0, op1, op2);
-	TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+	copy_no_warning (r, t);
 	return r;
       }
 
@@ -19169,8 +19169,7 @@ tsubst_omp_udr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       block = finish_omp_structured_block (block);
       block = maybe_cleanup_point_expr_void (block);
       add_decl_expr (omp_out);
-      if (TREE_NO_WARNING (DECL_EXPR_DECL (stmts[0])))
-	TREE_NO_WARNING (omp_out) = 1;
+      copy_no_warning (omp_out, DECL_EXPR_DECL (stmts[0]));
       add_decl_expr (omp_in);
       finish_expr_stmt (block);
     }
@@ -19846,17 +19845,17 @@ tsubst_copy_and_build (tree t,
 	tree r = build_x_binary_op
 	  (input_location, TREE_CODE (t),
 	   op0,
-	   (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+	   (get_no_warning (TREE_OPERAND (t, 0))
 	    ? ERROR_MARK
 	    : TREE_CODE (TREE_OPERAND (t, 0))),
 	   op1,
-	   (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+	   (get_no_warning (TREE_OPERAND (t, 1))
 	    ? ERROR_MARK
 	    : TREE_CODE (TREE_OPERAND (t, 1))),
 	   /*overload=*/NULL,
 	   complain|decltype_flag);
-	if (EXPR_P (r) && TREE_NO_WARNING (t))
-	  TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+	if (EXPR_P (r))
+	  copy_no_warning (r, t);
 
 	RETURN (r);
       }
@@ -19992,8 +19991,8 @@ tsubst_copy_and_build (tree t,
 	   set and must be copied.  In the latter case,
 	   build_x_modify_expr sets it and it must not be reset
 	   here.  */
-	if (TREE_NO_WARNING (t))
-	  TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+	if (get_no_warning (t, OPT_Wparentheses))
+	  set_no_warning (r, OPT_Wparentheses);
 
 	RETURN (r);
       }
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 82eaa286514..328067bcb6c 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -536,14 +536,14 @@ build_if_nonnull (tree test, tree result, tsubst_flags_t complain)
 
   /* This is a compiler generated comparison, don't emit
      e.g. -Wnonnull-compare warning for it.  */
-  TREE_NO_WARNING (cond) = 1;
+  set_no_warning (cond, OPT_Wnonnull);
 
   null_ptr = cp_convert (TREE_TYPE (result), nullptr_node, complain);
   cond = build3 (COND_EXPR, TREE_TYPE (result), cond, result, null_ptr);
 
   /* Likewise, don't emit -Wnonnull for using the result to call
      a member function.  */
-  TREE_NO_WARNING (cond) = 1;
+  set_no_warning (cond, OPT_Wnonnull);
   return cond;
 }
 
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0d590c318fb..9454f094374 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -836,12 +836,12 @@ maybe_convert_cond (tree cond)
   cond = convert_from_reference (cond);
 
   if (TREE_CODE (cond) == MODIFY_EXPR
-      && !TREE_NO_WARNING (cond)
       && warn_parentheses
+      && !get_no_warning (cond, OPT_Wparentheses)
       && warning_at (cp_expr_loc_or_input_loc (cond),
 		     OPT_Wparentheses, "suggest parentheses around "
 				       "assignment used as truth value"))
-    TREE_NO_WARNING (cond) = 1;
+    set_no_warning (cond, OPT_Wparentheses);
 
   return condition_conversion (cond);
 }
@@ -1144,7 +1144,7 @@ finish_return_stmt (tree expr)
     {
       /* Suppress -Wreturn-type for this function.  */
       if (warn_return_type)
-	TREE_NO_WARNING (current_function_decl) = true;
+	set_no_warning (current_function_decl, OPT_Wreturn_type);
       return error_mark_node;
     }
 
@@ -1166,7 +1166,8 @@ finish_return_stmt (tree expr)
     }
 
   r = build_stmt (input_location, RETURN_EXPR, expr);
-  TREE_NO_WARNING (r) |= no_warning;
+  if (no_warning)
+    set_no_warning (r, OPT_Wreturn_type);
   r = maybe_cleanup_point_expr_void (r);
   r = add_stmt (r);
 
@@ -2052,7 +2053,7 @@ finish_parenthesized_expr (cp_expr expr)
 {
   if (EXPR_P (expr))
     /* This inhibits warnings in c_common_truthvalue_conversion.  */
-    TREE_NO_WARNING (expr) = 1;
+    set_no_warning (expr, OPT_Wparentheses);
 
   if (TREE_CODE (expr) == OFFSET_REF
       || TREE_CODE (expr) == SCOPE_REF)
@@ -5911,12 +5912,12 @@ cp_check_omp_declare_reduction (tree udr)
     {
       gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
 		  && TREE_CODE (data.stmts[1]) == DECL_EXPR);
-      if (TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])))
+      if (get_no_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */))
 	return true;
       data.combiner_p = true;
       if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
 			&data, NULL))
-	TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1;
+	set_no_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */);
     }
   if (i >= 6)
     {
@@ -5927,7 +5928,7 @@ cp_check_omp_declare_reduction (tree udr)
 			&data, NULL)
 	  || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
 			   cp_check_omp_declare_reduction_r, &data, NULL))
-	TREE_NO_WARNING (DECL_EXPR_DECL (data.stmts[0])) = 1;
+	set_no_warning (DECL_EXPR_DECL (data.stmts[0])  /* Wat warning? */);
       if (i == 7)
 	gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
     }
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 72f498f4b3b..c0c0dd128ce 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1126,7 +1126,7 @@ build_cplus_array_type (tree elt_type, tree index_type, int dependent)
 
   /* Avoid spurious warnings with VLAs (c++/54583).  */
   if (TYPE_SIZE (t) && EXPR_P (TYPE_SIZE (t)))
-    TREE_NO_WARNING (TYPE_SIZE (t)) = 1;
+    set_no_warning (TYPE_SIZE (t), OPT_Wunused);
 
   /* Push these needs up to the ARRAY_TYPE so that initialization takes
      place more easily.  */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 703ddd3cc7a..3fe8b0cc7a9 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3316,10 +3316,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
        member = DECL_CHAIN (member))
     if (DECL_NAME (member) == member_name)
       break;
-  tree res = build_simple_component_ref (ptrmem, member);
-
-  TREE_NO_WARNING (res) = 1;
-  return res;
+  return build_simple_component_ref (ptrmem, member);
 }
 
 /* Given an expression PTR for a pointer, return an expression
@@ -3433,7 +3430,7 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring,
 	  if (warn_strict_aliasing > 2
 	      && cp_strict_aliasing_warning (EXPR_LOCATION (ptr),
 					     type, TREE_OPERAND (ptr, 0)))
-	    TREE_NO_WARNING (ptr) = 1;
+	    set_no_warning (ptr, OPT_Wstrict_aliasing);
 	}
 
       if (VOID_TYPE_P (t))
@@ -4058,7 +4055,7 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
     {
       tree c = extract_call_expr (ret);
       if (TREE_CODE (c) == CALL_EXPR)
-	TREE_NO_WARNING (c) = 1;
+	set_no_warning (c, OPT_Wnonnull);
     }
 
   if (allocated != NULL)
@@ -4440,14 +4437,14 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain)
   if (!warn_address
       || (complain & tf_warning) == 0
       || c_inhibit_evaluation_warnings != 0
-      || TREE_NO_WARNING (op))
+      || get_no_warning (op, OPT_Waddress))
     return;
 
   tree cop = fold_for_warn (op);
 
   if (TREE_CODE (cop) == ADDR_EXPR
       && decl_with_nonnull_addr_p (TREE_OPERAND (cop, 0))
-      && !TREE_NO_WARNING (cop))
+      && !get_no_warning (cop, OPT_Waddress))
     warning_at (location, OPT_Waddress, "the address of %qD will never "
 		"be NULL", TREE_OPERAND (cop, 0));
 
@@ -4868,7 +4865,7 @@ cp_build_binary_op (const op_location_t &location,
 	  else if (TREE_CODE (type0) == ARRAY_TYPE
 		   && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))
 		   /* Set by finish_parenthesized_expr.  */
-		   && !TREE_NO_WARNING (op1)
+		   && !get_no_warning (op1, OPT_Wsizeof_array_div)
 		   && (complain & tf_warning))
 	    maybe_warn_sizeof_array_div (location, first_arg, type0,
 					 op1, non_reference (type1));
@@ -5287,7 +5284,7 @@ cp_build_binary_op (const op_location_t &location,
 	  pfn0 = cp_fully_fold (pfn0);
 	  /* Avoid -Waddress warnings (c++/64877).  */
 	  if (TREE_CODE (pfn0) == ADDR_EXPR)
-	    TREE_NO_WARNING (pfn0) = 1;
+	    set_no_warning (pfn0, OPT_Waddress);
 	  pfn1 = pfn_from_ptrmemfunc (op1);
 	  pfn1 = cp_fully_fold (pfn1);
 	  delta0 = delta_from_ptrmemfunc (op0);
@@ -7016,7 +7013,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
                                             tf_warning_or_error);
       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
 		    arg, real_result);
-      TREE_NO_WARNING (arg) = 1;
+      set_no_warning (arg);
       return arg;
     }
 
@@ -8927,7 +8924,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
 
   TREE_SIDE_EFFECTS (result) = 1;
   if (!plain_assign)
-    TREE_NO_WARNING (result) = 1;
+    set_no_warning (result, OPT_Wparentheses);
 
  ret:
   if (preeval)
@@ -8971,7 +8968,7 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
 	{
 	  if (rval == error_mark_node)
 	    return rval;
-	  TREE_NO_WARNING (rval) = 1;
+	  set_no_warning (rval /* What warning? */);
 	  if (processing_template_decl)
 	    {
 	      if (overload != NULL_TREE)
@@ -9578,13 +9575,13 @@ convert_for_assignment (tree type, tree rhs,
   if (warn_parentheses
       && TREE_CODE (type) == BOOLEAN_TYPE
       && TREE_CODE (rhs) == MODIFY_EXPR
-      && !TREE_NO_WARNING (rhs)
+      && !get_no_warning (rhs, OPT_Wparentheses)
       && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
       && (complain & tf_warning)
       && warning_at (rhs_loc, OPT_Wparentheses,
 		     "suggest parentheses around assignment used as "
 		     "truth value"))
-    TREE_NO_WARNING (rhs) = 1;
+    set_no_warning (rhs, OPT_Wparentheses);
 
   if (complain & tf_warning)
     warn_for_address_or_pointer_of_packed_member (type, rhs);

Reply via email to