diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index ed79cc3ca40..6742f447ff5 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3809,12 +3809,9 @@ check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
 			   location_t operator_loc,
 			   tree rhs_val)
 {
-  /* Only complain if both args are non-negative integer constants.  */
-  if (!(TREE_CODE (lhs_val) == INTEGER_CST
-	&& tree_int_cst_sgn (lhs_val) >= 0))
-    return;
-  if (!(TREE_CODE (rhs_val) == INTEGER_CST
-	&& tree_int_cst_sgn (rhs_val) >= 0))
+  /* Only complain if both args are non-negative integer constants that fit
+     in uhwi.  */
+  if (!tree_fits_uhwi_p (lhs_val) || !tree_fits_uhwi_p (rhs_val))
     return;
 
   /* Only complain if the LHS is 2 or 10.  */
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 72db5b527f8..600ba4429ed 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -5462,6 +5462,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
 		    = objc_build_message_expr (rec, args);
 		  mexpr.original_code = ERROR_MARK;
 		  mexpr.original_type = NULL;
+		  mexpr.m_decimal = 0;
 		  /* Now parse and process the remainder of the
 		     initializer, starting with this message
 		     expression as a primary-expression.  */
@@ -8144,6 +8145,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
 	set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
+      ret.m_decimal = 0;
       return ret;
     }
   else
@@ -8460,6 +8462,7 @@ c_parser_alignof_expression (c_parser *parser)
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
       set_c_expr_source_range (&ret, start_loc, end_loc);
+      ret.m_decimal = 0;
       return ret;
     }
   else
@@ -8479,6 +8482,7 @@ c_parser_alignof_expression (c_parser *parser)
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
       set_c_expr_source_range (&ret, start_loc, end_loc);
+      ret.m_decimal = 0;
       return ret;
     }
 }
@@ -10369,6 +10373,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
   expr.value = build_compound_literal (start_loc, type, init.value, non_const,
 				       alignas_align);
   set_c_expr_source_range (&expr, init.src_range);
+  expr.m_decimal = 0;
   expr.original_code = ERROR_MARK;
   expr.original_type = NULL;
   if (type != error_mark_node
@@ -10583,6 +10588,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 	  set_c_expr_source_range (&expr, start, finish);
 	  expr.original_code = ERROR_MARK;
 	  expr.original_type = NULL;
+	  expr.m_decimal = 0;
 	  break;
 	case CPP_OPEN_PAREN:
 	  /* Function call.  */
@@ -10631,6 +10637,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 	    = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
 					 exprlist, origtypes);
 	  set_c_expr_source_range (&expr, start, finish);
+	  expr.m_decimal = 0;
 
 	  expr.original_code = ERROR_MARK;
 	  if (TREE_CODE (expr.value) == INTEGER_CST
@@ -10681,6 +10688,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 	      else
 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
 	    }
+	  expr.m_decimal = 0;
 	  break;
 	case CPP_DEREF:
 	  /* Structure element reference.  */
@@ -10722,6 +10730,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
 	      else
 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
 	    }
+	  expr.m_decimal = 0;
 	  break;
 	case CPP_PLUS_PLUS:
 	  /* Postincrement.  */
@@ -10792,6 +10801,7 @@ c_parser_expression (c_parser *parser)
       expr.value = build_compound_expr (loc, expr.value, next.value);
       expr.original_code = COMPOUND_EXPR;
       expr.original_type = next.original_type;
+      expr.m_decimal = 0;
     }
   return expr;
 }
@@ -13242,6 +13252,7 @@ c_parser_omp_variable_list (c_parser *parser,
 		      t_expr.original_code = ERROR_MARK;
 		      t_expr.original_type = NULL;
 		      set_c_expr_source_range (&t_expr, op_loc, op_loc);
+		      t_expr.m_decimal = 0;
 		      t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
 							 true, false);
 		      t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
@@ -23552,6 +23563,7 @@ c_parser_transaction_expression (c_parser *parser, enum rid keyword)
 	TRANSACTION_EXPR_RELAXED (ret.value) = 1;
       SET_EXPR_LOCATION (ret.value, loc);
       ret.original_code = TRANSACTION_EXPR;
+      ret.m_decimal = 0;
       if (!parens.require_close (parser))
 	{
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index b4231a17859..46a3e8e9709 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -164,12 +164,13 @@ struct c_expr
   }
 
   /* Set the value to error_mark_node whilst ensuring that src_range
-     is initialized.  */
+     and m_decimal are initialized.  */
   void set_error ()
   {
     value = error_mark_node;
     src_range.m_start = UNKNOWN_LOCATION;
     src_range.m_finish = UNKNOWN_LOCATION;
+    m_decimal = 0;
   }
 };
 
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 9ada5d25531..ae9418a3f11 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2994,6 +2994,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
       ret.value = error_mark_node;
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
+      ret.m_decimal = 0;
       pop_maybe_used (false);
     }
   else
@@ -3017,6 +3018,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
       c_last_sizeof_loc = loc;
       ret.original_code = SIZEOF_EXPR;
       ret.original_type = NULL;
+      ret.m_decimal = 0;
       if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr)))
 	{
 	  /* sizeof is evaluated when given a vla (C99 6.5.3.4p2).  */
@@ -3047,6 +3049,7 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t)
   c_last_sizeof_loc = loc;
   ret.original_code = SIZEOF_EXPR;
   ret.original_type = NULL;
+  ret.m_decimal = 0;
   if (type == error_mark_node)
     {
       ret.value = error_mark_node;
@@ -3782,6 +3785,7 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
 
   result.original_code = code;
   result.original_type = NULL;
+  result.m_decimal = 0;
 
   if (reject_gcc_builtin (arg.value))
     {
@@ -3844,6 +3848,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
 				  arg1.value, arg2.value, true);
   result.original_code = code;
   result.original_type = NULL;
+  result.m_decimal = 0;
 
   if (TREE_CODE (result.value) == ERROR_MARK)
     {
@@ -8072,6 +8077,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	  expr.value = inside_init;
 	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
 	  expr.original_type = NULL;
+	  expr.m_decimal = 0;
 	  maybe_warn_string_init (init_loc, type, expr);
 
 	  if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
@@ -8936,6 +8942,7 @@ pop_init_level (location_t loc, int implicit,
   ret.value = NULL_TREE;
   ret.original_code = ERROR_MARK;
   ret.original_type = NULL;
+  ret.m_decimal = 0;
 
   if (implicit == 0)
     {
diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index b909eac498d..5a2da2cfa0e 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -1332,6 +1332,7 @@ c_parser_gimple_call_internal (gimple_parser &parser)
 	     exprlist.address ());
 	  expr.original_code = ERROR_MARK;
 	  expr.original_type = NULL;
+	  expr.m_decimal = 0;
 	}
     }
   return expr;
@@ -1751,6 +1752,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
 	    finish = c_parser_tokens_buf (parser, 0)->location;
 	    expr.value = build_array_ref (op_loc, expr.value, idx);
 	    set_c_expr_source_range (&expr, start, finish);
+	    expr.m_decimal = 0;
 
 	    expr.original_code = ERROR_MARK;
 	    expr.original_type = NULL;
@@ -1774,6 +1776,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
 	    expr.value = build_call_array_loc
 		(expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
 		 expr.value, exprlist.length (), exprlist.address ());
+	    expr.m_decimal = 0;
 	    expr.original_code = ERROR_MARK;
 	    expr.original_type = NULL;
 	    break;
@@ -1802,6 +1805,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
 	    expr.value = build_component_ref (op_loc, expr.value, ident,
 					      comp_loc, UNKNOWN_LOCATION);
 	    set_c_expr_source_range (&expr, start, finish);
+	    expr.m_decimal = 0;
 	    expr.original_code = ERROR_MARK;
 	    if (TREE_CODE (expr.value) != COMPONENT_REF)
 	      expr.original_type = NULL;
@@ -1851,6 +1855,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
 					      ident, comp_loc,
 					      expr.get_location ());
 	    set_c_expr_source_range (&expr, start, finish);
+	    expr.m_decimal = 0;
 	    expr.original_code = ERROR_MARK;
 	    if (TREE_CODE (expr.value) != COMPONENT_REF)
 	      expr.original_type = NULL;
diff --git a/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c b/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c
new file mode 100644
index 00000000000..104897a5f39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c
@@ -0,0 +1,6 @@
+/* { dg-require-effective-target int128 }
+   { dg-options "-Wno-pedantic" }  */
+
+void foo0_u16_0() {
+  (__int128)(18302628885633695743 << 4) ^ 0; /* { dg-warning "integer constant is so large that it is unsigned" } */
+}
