--- gcc/doc/extend.texi.jj	2024-07-29 09:16:15.159636903 +0200
+++ gcc/doc/extend.texi	2024-07-30 15:59:01.158715051 +0200
@@ -4024,6 +4024,68 @@ diagnosed.  Because a pure function cann
 effects it does not make sense for such a function to return @code{void}.
 Declaring such a function is diagnosed.
 
+@cindex @code{unsequenced} function type attribute
+@cindex functions that have no side effects
+@item unsequenced
+
+This attribute is a GNU counterpart of the C23 @code{[[unsequenced]]}
+attribute, used to specify function pointers to effectless, idempotent,
+stateless and independent functions according to the C23 definition.
+
+Unlike the standard C23 attribute it can be also specified in attributes
+which appertain to function declarations and applies to the their function
+type even in that case.
+
+Unsequenced functions without pointer or reference arguments (in the
+declaration or through @code{va_arg} on variadic functions) are similar
+to functions with the @code{const} attribute, except that @code{const}
+attribute also requires finitness.  So, both functions with @code{const}
+and with @code{unsequenced} attributes can be optimized by common
+subexpression elimination, but only functions with @code{const}
+attribute can be optimized by dead code elimination if their result is
+unused or is used only by dead code.  Unsequenced functions without pointer
+or reference arguments with @code{void} return type are diagnosed because
+they can't store any results and don't have other observable side-effects
+either.
+
+Unsequenced functions with pointer or reference arguments can inspect
+objects through the passed pointers/references or can store additional
+results through those pointers/references.
+
+The @code{unsequenced} attribute imposes greater restrictions than
+the similar @code{reproducible} attribute and fewer restrictions than
+the @code{const} attribute, so during optimization @code{const} has
+precedence over @code{unsequenced} which has precedence over
+@code{reproducible}.
+
+@cindex @code{reproducible} function type attribute
+@cindex functions that have no side effects
+@item reproducible
+
+This attribute is a GNU counterpart of the C23 @code{[[reproducible]]}
+attribute, used to specify function pointers to effectless and idempotent
+functions according to the C23 definition.
+
+Unlike the standard C23 attribute it can be also specified in attributes
+which appertain to function declarations and applies to the their function
+type even in that case.
+
+Reproducible functions without pointer or reference arguments or which do
+not modify objects referenced by those pointer/reference arguments are
+similar to functions with the @code{pure} attribute, except that
+@code{pure} attribute also requires finitness.  So, both functions with
+@code{pure} and with @code{reproducible} attributes can be optimized by common
+subexpression elimination if the global state or anything reachable through
+the pointer/reference arguments isn't modified, but only functions with
+@code{pure} attribute can be optimized by dead code elimination if their result is
+unused or is used only by dead code.  Reproducible functions without pointer
+or reference arguments with @code{void} return type are diagnosed because
+they can't store any results and don't have other observable side-effects
+either.
+
+Reproducible functions with pointer or reference arguments can store
+additional results through those pointers or references.
+
 @cindex @code{retain} function attribute
 @item retain
 For ELF targets that support the GNU or FreeBSD OSABIs, this attribute
--- gcc/calls.cc.jj	2024-07-18 09:20:31.624543703 +0200
+++ gcc/calls.cc	2024-07-30 13:18:34.350571711 +0200
@@ -852,6 +852,23 @@ flags_from_decl_or_type (const_tree exp)
 	flags |= ECF_XTHROW;
 
       flags = special_function_p (exp, flags);
+
+      if ((flags & ECF_CONST) == 0
+	  && lookup_attribute ("unsequenced noptr",
+			       TYPE_ATTRIBUTES (TREE_TYPE (exp))))
+	{
+	  /* [[unsequenced]] with no pointers in arguments is like
+	     [[gnu::const]] without finite guarantee.  */
+	  flags |= ECF_CONST;
+	  if ((flags & ECF_PURE) == 0)
+	    flags |= ECF_LOOPING_CONST_OR_PURE;
+	}
+      if ((flags & (ECF_CONST | ECF_PURE)) == 0
+	  && lookup_attribute ("reproducible noptr",
+			       TYPE_ATTRIBUTES (TREE_TYPE (exp))))
+	/* [[reproducible]] with no pointers in arguments is like
+	   [[gnu::pure]] without finite guarantee.  */
+	flags |= ECF_PURE | ECF_LOOPING_CONST_OR_PURE;
     }
   else if (TYPE_P (exp))
     {
@@ -862,6 +879,17 @@ flags_from_decl_or_type (const_tree exp)
 	  && ((flags & ECF_CONST) != 0
 	      || lookup_attribute ("transaction_pure", TYPE_ATTRIBUTES (exp))))
 	flags |= ECF_TM_PURE;
+
+      if ((flags & ECF_CONST) == 0
+	  && lookup_attribute ("unsequenced noptr", TYPE_ATTRIBUTES (exp)))
+	/* [[unsequenced]] with no pointers in arguments is like
+	   [[gnu::const]] without finite guarantee.  */
+	flags |= ECF_CONST | ECF_LOOPING_CONST_OR_PURE;
+      if ((flags & ECF_CONST) == 0
+	  && lookup_attribute ("reproducible noptr", TYPE_ATTRIBUTES (exp)))
+	/* [[reproducible]] with no pointers in arguments is like
+	   [[gnu::pure]] without finite guarantee.  */
+	flags |= ECF_PURE | ECF_LOOPING_CONST_OR_PURE;
     }
   else
     gcc_unreachable ();
--- gcc/c-family/c-attribs.cc.jj	2024-07-29 13:21:55.917705757 +0200
+++ gcc/c-family/c-attribs.cc	2024-07-29 19:40:46.020519425 +0200
@@ -444,6 +444,14 @@ const struct attribute_spec c_common_gnu
   { "pure",                   0, 0, true,  false, false, false,
 			      handle_pure_attribute,
 	                      attr_const_pure_exclusions },
+  { "reproducible",           0, 0, false, true,  true,  false,
+			      handle_reproducible_attribute, NULL },
+  { "unsequenced",            0, 0, false, true,  true,  false,
+			      handle_unsequenced_attribute, NULL },
+  { "reproducible noptr",     0, 0, false, true,  true,  false,
+			      handle_reproducible_attribute, NULL },
+  { "unsequenced noptr",      0, 0, false, true,  true,  false,
+			      handle_unsequenced_attribute, NULL },
   { "transaction_callable",   0, 0, false, true,  false, false,
 			      handle_tm_attribute, NULL },
   { "transaction_unsafe",     0, 0, false, true,  false, true,
@@ -4280,6 +4288,101 @@ handle_pure_attribute (tree *node, tree
   return NULL_TREE;
 }
 
+/* Return true if type TYPE contains or may contain any data pointers
+   (may in case of C++ dependent types).  */
+
+static bool
+c_maybe_contains_pointers_p (tree type)
+{
+  switch (TREE_CODE (type))
+    {
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+      return true;
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      if (COMPLETE_TYPE_P (type))
+	{
+	  for (tree fields = TYPE_FIELDS (type); fields; fields = DECL_CHAIN (fields))
+	    if (TREE_CODE (fields) == FIELD_DECL
+		&& c_maybe_contains_pointers_p (TREE_TYPE (fields)))
+	      return true;
+	  return false;
+	}
+      return false;
+
+    case ARRAY_TYPE:
+      return c_maybe_contains_pointers_p (TREE_TYPE (type));
+
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+    case INTEGER_TYPE:
+    case BITINT_TYPE:
+    case REAL_TYPE:
+    case NULLPTR_TYPE:
+    case FIXED_POINT_TYPE:
+    case COMPLEX_TYPE:
+    case VECTOR_TYPE:
+    case FUNCTION_TYPE:
+    case METHOD_TYPE:
+      return false;
+
+    default:
+      return true;
+    }
+}
+
+/* Handle an "unsequenced" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+tree
+handle_unsequenced_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+			      int flags, bool *no_add_attrs)
+{
+  tree fntype = *node;
+  for (tree argtype = TYPE_ARG_TYPES (fntype); argtype;
+       argtype = TREE_CHAIN (argtype))
+    if (argtype == void_list_node)
+      {
+	if (VOID_TYPE_P (TREE_TYPE (fntype)))
+	  warning (OPT_Wattributes, "%qE attribute on function type "
+		   "without pointer arguments returning %<void%>", name);
+	const char *name2;
+	if (IDENTIFIER_LENGTH (name) == sizeof ("unsequenced") - 1)
+	  name2 = "unsequenced noptr";
+	else
+	  name2 = "reproducible noptr";
+	if (!lookup_attribute (name2, TYPE_ATTRIBUTES (fntype)))
+	  {
+	    *no_add_attrs = true;
+	    gcc_assert ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE) == 0);
+	    tree attr = tree_cons (get_identifier (name2), NULL_TREE,
+				   TYPE_ATTRIBUTES (fntype));
+	    if (!lookup_attribute (IDENTIFIER_POINTER (name),
+				   TYPE_ATTRIBUTES (fntype)))
+	      attr = tree_cons (name, NULL_TREE, attr);
+	    *node = build_type_attribute_variant (*node, attr);
+	  }
+	return NULL_TREE;
+      }
+    else if (c_maybe_contains_pointers_p (TREE_VALUE (argtype)))
+      break;
+
+  return NULL_TREE;
+}
+
+/* Handle a "reproducible" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+tree
+handle_reproducible_attribute (tree *node, tree name, tree args, int flags,
+			       bool *no_add_attrs)
+{
+  return handle_unsequenced_attribute (node, name, args, flags, no_add_attrs);
+}
+
 /* Digest an attribute list destined for a transactional memory statement.
    ALLOWED is the set of attributes that are allowed for this statement;
    return the attribute we parsed.  Multiple attributes are never allowed.  */
--- gcc/c-family/c-common.h.jj	2024-07-24 15:47:15.122478781 +0200
+++ gcc/c-family/c-common.h	2024-07-29 19:03:55.569066565 +0200
@@ -864,6 +864,8 @@ extern void check_function_format (const
 extern bool attribute_fallthrough_p (tree);
 extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
 extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
+extern tree handle_unsequenced_attribute (tree *, tree, tree, int, bool *);
+extern tree handle_reproducible_attribute (tree *, tree, tree, int, bool *);
 extern bool c_common_handle_option (size_t, const char *, HOST_WIDE_INT, int,
 				    location_t,
 				    const struct cl_option_handlers *);
--- gcc/c-family/c-lex.cc.jj	2024-07-29 13:21:55.935705521 +0200
+++ gcc/c-family/c-lex.cc	2024-07-29 17:14:49.393945048 +0200
@@ -445,7 +445,9 @@ c_common_has_attribute (cpp_reader *pfil
 		  || is_attribute_p ("maybe_unused", attr_name)
 		  || is_attribute_p ("nodiscard", attr_name)
 		  || is_attribute_p ("noreturn", attr_name)
-		  || is_attribute_p ("_Noreturn", attr_name))
+		  || is_attribute_p ("_Noreturn", attr_name)
+		  || is_attribute_p ("reproducible", attr_name)
+		  || is_attribute_p ("unsequenced", attr_name))
 		result = 202311;
 	    }
 	  if (result)
--- gcc/c/c-decl.cc.jj	2024-07-29 13:21:55.943705415 +0200
+++ gcc/c/c-decl.cc	2024-07-30 12:46:40.166828455 +0200
@@ -4702,6 +4702,39 @@ handle_std_noreturn_attribute (tree *nod
     }
 }
 
+/* Handle the standard [[unsequenced]] attribute.  */
+
+static tree
+handle_std_unsequenced_attribute (tree *node, tree name, tree args,
+				  int flags, bool *no_add_attrs)
+{
+  /* Unlike GNU __attribute__ ((unsequenced)), the standard [[unsequenced]]
+     should be only applied to function declarators or type specifiers which
+     have function type.  */
+  if (node[2])
+    {
+      auto_diagnostic_group d;
+      if (pedwarn (input_location, OPT_Wattributes,
+		   "standard %qE attribute can only be applied to function "
+		   "declarators or type specifiers with function type", name))
+	inform (input_location, "did you mean to specify it after %<)%> "
+				"following function parameters?");
+      *no_add_attrs = true;
+      return NULL_TREE;
+    }
+  return handle_unsequenced_attribute (node, name, args, flags, no_add_attrs);
+}
+
+/* Handle the standard [[reproducible]] attribute.  */
+
+static tree
+handle_std_reproducible_attribute (tree *node, tree name, tree args,
+				   int flags, bool *no_add_attrs)
+{
+  return handle_std_unsequenced_attribute (node, name, args, flags,
+					   no_add_attrs);
+}
+
 /* Table of supported standard (C23) attributes.  */
 static const attribute_spec std_attributes[] =
 {
@@ -4718,7 +4751,11 @@ static const attribute_spec std_attribut
   { "nodiscard", 0, 1, false, false, false, false,
     handle_nodiscard_attribute, NULL },
   { "noreturn", 0, 0, false, false, false, false,
-    handle_std_noreturn_attribute, NULL }
+    handle_std_noreturn_attribute, NULL },
+  { "reproducible", 0, 0, false, true, true, false,
+    handle_std_reproducible_attribute, NULL },
+  { "unsequenced", 0, 0, false, true, true, false,
+    handle_std_unsequenced_attribute, NULL }
 };
 
 const scoped_attribute_specs std_attribute_table =
@@ -4911,12 +4948,24 @@ c_warn_unused_attributes (tree attrs)
    list of attributes with them removed.  */
 
 tree
-c_warn_type_attributes (tree attrs)
+c_warn_type_attributes (tree type, tree attrs)
 {
   tree *attr_ptr = &attrs;
   while (*attr_ptr)
     if (get_attribute_namespace (*attr_ptr) == NULL_TREE)
       {
+	if (TREE_CODE (type) == FUNCTION_TYPE)
+	  {
+	    tree name = get_attribute_name (*attr_ptr);
+	    /* [[unsequenced]] and [[reproducible]] is fine on function
+	       types that aren't being defined.  */
+	    if (is_attribute_p ("unsequenced", name)
+		|| is_attribute_p ("reproducible", name))
+	      {
+		attr_ptr = &TREE_CHAIN (*attr_ptr);
+		continue;
+	      }
+	  }
 	pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
 		 get_attribute_name (*attr_ptr));
 	*attr_ptr = TREE_CHAIN (*attr_ptr);
@@ -5386,7 +5435,7 @@ groktypename (struct c_type_name *type_n
 			 DEPRECATED_NORMAL);
 
   /* Apply attributes.  */
-  attrs = c_warn_type_attributes (attrs);
+  attrs = c_warn_type_attributes (type, attrs);
   decl_attributes (&type, attrs, 0);
 
   return type;
@@ -7196,7 +7245,7 @@ grokdeclarator (const struct c_declarato
 		else if (inner_decl->kind == cdk_array)
 		  attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
 	      }
-	    attrs = c_warn_type_attributes (attrs);
+	    attrs = c_warn_type_attributes (type, attrs);
 	    returned_attrs = decl_attributes (&type,
 					      chainon (returned_attrs, attrs),
 					      attr_flags);
@@ -13433,7 +13482,8 @@ finish_declspecs (struct c_declspecs *sp
  handle_postfix_attrs:
   if (specs->type != NULL)
     {
-      specs->postfix_attrs = c_warn_type_attributes (specs->postfix_attrs);
+      specs->postfix_attrs
+	= c_warn_type_attributes (specs->type, specs->postfix_attrs);
       decl_attributes (&specs->type, specs->postfix_attrs, 0);
       specs->postfix_attrs = NULL_TREE;
     }
--- gcc/c/c-parser.cc.jj	2024-07-24 17:55:57.388097924 +0200
+++ gcc/c/c-parser.cc	2024-07-30 11:22:32.915821271 +0200
@@ -2677,8 +2677,9 @@ c_parser_declaration_or_fndef (c_parser
 		      /* Postfix [[]] attributes are valid with C23
 			 auto, although not with __auto_type, and
 			 modify the type given by the initializer.  */
-		      specs->postfix_attrs =
-			c_warn_type_attributes (specs->postfix_attrs);
+		      specs->postfix_attrs
+			= c_warn_type_attributes (specs->type,
+						  specs->postfix_attrs);
 		      decl_attributes (&specs->type, specs->postfix_attrs, 0);
 		      specs->postfix_attrs = NULL_TREE;
 		    }
--- gcc/c/c-tree.h.jj	2024-07-24 15:47:15.129478691 +0200
+++ gcc/c/c-tree.h	2024-07-30 11:22:04.963197642 +0200
@@ -680,7 +680,7 @@ extern tree c_builtin_function (tree);
 extern tree c_builtin_function_ext_scope (tree);
 extern tree c_simulate_builtin_function_decl (tree);
 extern void c_warn_unused_attributes (tree);
-extern tree c_warn_type_attributes (tree);
+extern tree c_warn_type_attributes (tree, tree);
 extern void shadow_tag (const struct c_declspecs *);
 extern void shadow_tag_warned (const struct c_declspecs *, int);
 extern tree start_enum (location_t, struct c_enum_contents *, tree, tree,
--- gcc/testsuite/c-c++-common/attr-reproducible-1.c.jj	2024-07-30 13:32:10.090796441 +0200
+++ gcc/testsuite/c-c++-common/attr-reproducible-1.c	2024-07-30 13:43:41.088667213 +0200
@@ -0,0 +1,80 @@
+/* Test gnu::reproducible attribute: valid uses.  */
+/* { dg-do compile { target { c || c++11 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-additional-options "-std=gnu23" { target c } } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 2 "optimized" } } */
+
+int f1 () [[gnu::reproducible]];
+int f2 () [[gnu::reproducible]], f3 (int) [[__gnu__::__reproducible__]];
+int f4 (int, int *) [[gnu::reproducible]];
+int f5 (int) [[gnu::reproducible]];
+int f6 (int);
+int (*fp1) (int) [[gnu::reproducible]] = f6;
+typedef int ft1 (int) [[gnu::reproducible]];
+typedef int ft2 (int);
+#ifndef __cplusplus
+extern __typeof (f6) [[gnu::reproducible]] f7;
+extern ft2 [[__gnu__::__reproducible__]] f8;
+#else
+int f7 (int) [[gnu::reproducible, gnu::reproducible]];
+int f8 (int) [[__gnu__::reproducible, gnu::__reproducible__]];
+#endif
+int f1 ();
+int f9 (int);
+int f9 (int) [[__gnu__::__reproducible__]];
+extern int x;
+
+int
+f10 (int w) [[gnu::reproducible]]
+{
+  return w + 42 + x;
+}
+
+int
+f11 (int *w, long long y[1], int z) [[__gnu__::__reproducible__]]
+{
+  w[0] = z + x;
+  w[1] = z + x + 1;
+  w[2] = z + x + 2;
+  *y = z + x + 3;
+  return z + 4 + f10 (-42);
+}
+
+int
+g ()
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h ()
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/c-c++-common/attr-reproducible-2.c.jj	2024-07-30 13:58:38.433861263 +0200
+++ gcc/testsuite/c-c++-common/attr-reproducible-2.c	2024-07-30 14:26:47.293852999 +0200
@@ -0,0 +1,74 @@
+/* Test reproducible attribute: valid uses.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 2 "optimized" } } */
+
+__attribute__((reproducible)) int f1 (void);
+__attribute__((__reproducible__)) int f2 (void), f3 (int);
+int f4 (int, int *) __attribute__((reproducible));
+int f5 (int) __attribute__((reproducible));
+int f6 (int);
+int (*fp1) (int) __attribute__((reproducible)) = f6;
+typedef int ft1 (int) __attribute__((reproducible));
+typedef int ft2 (int);
+extern __typeof (f6) __attribute__((reproducible)) f7;
+extern ft2 __attribute__((__reproducible__)) f8;
+int f1 (void);
+int f9 (int);
+int f9 (int) __attribute__((__reproducible__));
+extern int x;
+
+__attribute__((reproducible)) int
+f10 (int w)
+{
+  return w + 42 + x;
+}
+
+__attribute__((reproducible)) int
+f11 (int *w, long long y[1], int z)
+{
+  w[0] = z + x;
+  w[1] = z + x + 1;
+  w[2] = z + x + 2;
+  *y = z + x + 3;
+  return z + 4 + f10 (-42);
+}
+
+int
+g (void)
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h (void)
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/c-c++-common/attr-unsequenced-1.c.jj	2024-07-30 13:29:39.757782214 +0200
+++ gcc/testsuite/c-c++-common/attr-unsequenced-1.c	2024-07-30 13:44:47.992783260 +0200
@@ -0,0 +1,87 @@
+/* Test gnu::unsequenced attribute: valid uses.  */
+/* { dg-do compile { target { c || c++11 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-additional-options "-std=gnu23" { target c } } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f12 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f13 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 1 "optimized" } } */
+
+[[gnu::unsequenced]] int f1 ();
+[[gnu::unsequenced]] int f2 (), f3 (int);
+int f4 (int, int *) [[gnu::unsequenced]];
+int f5 (int) [[gnu::unsequenced]];
+int f6 (int);
+int (*fp1) (int) [[gnu::unsequenced]] = f6;
+typedef int ft1 (int) [[gnu::unsequenced]];
+typedef int ft2 (int);
+#ifndef __cplusplus
+extern __typeof (f6) [[gnu::unsequenced]] f7;
+extern ft2 [[__gnu__::__unsequenced__]] f8;
+#else
+int f7 (int) [[gnu::unsequenced, gnu::unsequenced]];
+int f8 (int) [[__gnu__::unsequenced, gnu::__unsequenced__]];
+#endif
+int f1 ();
+int f9 (int);
+int f9 (int) [[__gnu__::__unsequenced__]];
+extern int x;
+
+int
+f10 (int x) [[gnu::unsequenced]]
+{
+  return x + 42;
+}
+
+int
+f11 (int *x, long long y[1], int z) [[__gnu__::__unsequenced__]]
+{
+  x[0] = z;
+  x[1] = z + 1;
+  x[2] = z + 2;
+  *y = z + 3;
+  return z + 4 + f10 (-42);
+}
+
+int f12 () [[gnu::unsequenced]];
+int f12 () [[gnu::reproducible]];
+int f13 () [[gnu::reproducible]];
+int f13 () [[gnu::unsequenced]];
+
+int
+g ()
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h ()
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/c-c++-common/attr-unsequenced-2.c.jj	2024-07-30 13:45:58.221855370 +0200
+++ gcc/testsuite/c-c++-common/attr-unsequenced-2.c	2024-07-30 14:03:45.395843298 +0200
@@ -0,0 +1,81 @@
+/* Test unsequenced attribute: valid uses.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f12 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f13 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 1 "optimized" } } */
+
+__attribute__((unsequenced)) int f1 (void);
+__attribute__((unsequenced)) int f2 (void), f3 (int);
+int f4 (int, int *) __attribute__((unsequenced));
+int f5 (int) __attribute__((unsequenced));
+int f6 (int);
+int (*fp1) (int) __attribute__((unsequenced)) = f6;
+typedef int ft1 (int) __attribute__((unsequenced));
+typedef int ft2 (int);
+extern __typeof (f6) __attribute__((unsequenced)) f7;
+extern ft2 __attribute__((__unsequenced__)) f8;
+int f1 (void);
+int f9 (int);
+int f9 (int) __attribute__((__unsequenced__));
+extern int x;
+
+__attribute__((unsequenced)) int
+f10 (int x)
+{
+  return x + 42;
+}
+
+__attribute__((__unsequenced__)) int
+f11 (int *x, long long y[1], int z)
+{
+  x[0] = z;
+  x[1] = z + 1;
+  x[2] = z + 2;
+  *y = z + 3;
+  return z + 4 + f10 (-42);
+}
+
+int f12 (void) __attribute__((unsequenced));
+int f12 (void) __attribute__((reproducible));
+int f13 (void) __attribute__((reproducible));
+int f13 (void) __attribute__((unsequenced));
+
+int
+g (void)
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h (void)
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-1.c.jj	2024-07-30 10:39:09.790803085 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-1.c	2024-07-30 13:19:09.908102024 +0200
@@ -0,0 +1,74 @@
+/* Test C23 reproducible attribute: valid uses.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors -O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 2 "optimized" } } */
+
+int f1 () [[reproducible]];
+int f2 () [[reproducible]], f3 (int) [[__reproducible__]];
+int f4 (int, int *restrict) [[reproducible]];
+int f5 (int) [[reproducible]];
+int f6 (int);
+int (*fp1) (int) [[reproducible]] = f6;
+typedef int ft1 (int) [[reproducible]];
+typedef int ft2 (int);
+extern typeof (f6) [[reproducible]] f7;
+extern ft2 [[__reproducible__]] f8;
+int f1 ();
+int f9 (int);
+int f9 (int) [[__reproducible__]];
+extern int x;
+
+int
+f10 (int w) [[reproducible]]
+{
+  return w + 42 + x;
+}
+
+int
+f11 (int *restrict w, long long y[restrict static 1], int z) [[__reproducible__]]
+{
+  w[0] = z + x;
+  w[1] = z + x + 1;
+  w[2] = z + x + 2;
+  *y = z + x + 3;
+  return z + 4 + f10 (-42);
+}
+
+int
+g ()
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42);
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h ()
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-2.c.jj	2024-07-30 10:39:12.632764961 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-2.c	2024-07-30 13:09:35.803687498 +0200
@@ -0,0 +1,47 @@
+/* Test C23 reproducible attribute: invalid contexts.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+/* This attribute is not valid in most cases on types other than
+   type specifiers with function type or function declarators.  */
+
+[[reproducible]]; /* { dg-error "ignored" } */
+
+int [[reproducible]] var; /* { dg-error "ignored" } */
+
+int array_with_dep_type[2] [[reproducible]]; /* { dg-error "ignored" } */
+
+[[reproducible]] int fn1 (); /* { dg-error "standard 'reproducible' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+[[reproducible]] int fn2 (), fn3 (); /* { dg-error "standard 'reproducible' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+int var2 [[reproducible]]; /* { dg-warning "'reproducible' attribute only applies to function types" } */
+
+int fn4 [[reproducible]] (); /* { dg-error "standard 'reproducible' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+int [[reproducible]] fn5 (); /* { dg-error "ignored" } */
+
+int z = sizeof (int [[__reproducible__]]); /* { dg-error "ignored" } */
+
+/* This is valid, but not really useful, as it can't return results
+   in return type nor has any pointer arguments to store results into.  */
+void
+fn6 (int x, double y) [[reproducible]]
+{ /* { dg-warning "reproducible' attribute on function type without pointer arguments returning 'void'" } */
+  y = x;
+  (void) y;
+}
+
+void
+f (void)
+{
+  int a;
+  [[reproducible]]; /* { dg-error "ignored" } */
+  [[reproducible]] a = 1; /* { dg-error "ignored" } */
+  [[reproducible]] label: ; /* { dg-warning "'reproducible' attribute only applies to function types" } */
+  switch (var)
+    {
+    [[reproducible]] case 1: ; /* { dg-warning "'reproducible' attribute only applies to function types" } */
+    [[reproducible]] default: ; /* { dg-warning "'reproducible' attribute only applies to function types" } */
+    }
+}
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-3.c.jj	2024-07-30 10:39:15.313728999 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-3.c	2024-07-30 13:10:14.556175440 +0200
@@ -0,0 +1,14 @@
+/* Test C23 reproducible attribute: invalid syntax.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a () [[reproducible()]]; /* { dg-error "'reproducible' attribute does not take any arguments" } */
+
+int b () [[reproducible(0)]]; /* { dg-error "expected" } */
+			      /* { dg-error "'reproducible' attribute does not take any arguments" "" { target *-*-* } .-1 } */
+
+int c () [[reproducible("", 123)]]; /* { dg-error "expected" } */
+				    /* { dg-error "'reproducible' attribute does not take any arguments" "" { target *-*-* } .-1 } */
+
+int d () [[reproducible((""))]]; /* { dg-error "expected" } */
+				 /* { dg-error "'reproducible' attribute does not take any arguments" "" { target *-*-* } .-1 } */
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-4.c.jj	2024-07-30 10:39:18.168690708 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-4.c	2024-07-30 13:10:26.005024168 +0200
@@ -0,0 +1,12 @@
+/* Test C23 reproducible attribute: duplicates (allowed after N2557).  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a () [[reproducible, __reproducible__]];
+int b () [[__reproducible__, reproducible]];
+int c () [[reproducible, reproducible]];
+int d () [[__reproducible__, __reproducible__]];
+int d () [[reproducible]];
+int d () [[__reproducible__]];
+[[reproducible, reproducible]];
+/* { dg-error "ignored" "ignored" { target *-*-* } .-1 } */
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-5.c.jj	2024-07-30 14:44:26.750009364 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-5.c	2024-07-30 14:54:04.312467597 +0200
@@ -0,0 +1,44 @@
+/* Test C23 reproducible attribute: composite type on ?:.  */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-additional-sources "c23-attr-reproducible-6.c" } */
+
+int f1 () [[reproducible]];
+int f2 ();
+int f3 ();
+int (*fp1) () [[reproducible]] = f2;
+int (*fp2) () [[reproducible]] = f3;
+extern void abort ();
+
+int
+foo (int x)
+{
+  return __builtin_has_attribute (*(x ? f1 : f3), reproducible);
+}
+
+int
+bar (int x)
+{
+  return __builtin_has_attribute (*(x ? fp1 : fp2), reproducible);
+}
+
+int
+baz (int x)
+{
+  return __builtin_has_attribute (*(x ? f3 : f1), reproducible);
+}
+
+int
+qux (int x)
+{
+  return __builtin_has_attribute (*(x ? fp2 : fp1), reproducible);
+}
+
+int
+main ()
+{
+  if (!foo (0) || !bar (0) || !baz (0) || !qux (0))
+    abort ();
+  if (!foo (1) || !bar (1) || !baz (1) || !qux (1))
+    abort ();
+}
--- gcc/testsuite/gcc.dg/c23-attr-reproducible-6.c.jj	2024-07-30 14:50:39.070147636 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-reproducible-6.c	2024-07-30 14:51:28.339504281 +0200
@@ -0,0 +1,21 @@
+/* Test C23 reproducible attribute: composite type on ?:.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int
+f1 () [[reproducible]]
+{
+  return 42;
+}
+
+int
+f2 ()
+{
+  return 43;
+}
+
+int
+f3 ()
+{
+  return 44;
+}
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-1.c.jj	2024-07-30 10:39:09.790803085 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-1.c	2024-07-30 13:07:48.585104231 +0200
@@ -0,0 +1,81 @@
+/* Test C23 unsequenced attribute: valid uses.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors -O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " f1 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f2 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f12 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f13 \\\(\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f3 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f5 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f7 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f8 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " f9 \\\(-42\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump " f3 \\\(52\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " fp1\.\[0-9]*_\[0-9]* \\\(14\\\);" 1 "optimized" } } */
+
+int f1 () [[unsequenced]];
+int f2 () [[unsequenced]], f3 (int) [[__unsequenced__]];
+int f4 (int, int *restrict) [[unsequenced]];
+int f5 (int) [[unsequenced]];
+int f6 (int);
+int (*fp1) (int) [[unsequenced]] = f6;
+typedef int ft1 (int) [[unsequenced]];
+typedef int ft2 (int);
+extern typeof (f6) [[unsequenced]] f7;
+extern ft2 [[__unsequenced__]] f8;
+int f1 ();
+int f9 (int);
+int f9 (int) [[__unsequenced__]];
+extern int x;
+
+int
+f10 (int x) [[unsequenced]]
+{
+  return x + 42;
+}
+
+int
+f11 (int *restrict x, long long y[restrict static 1], int z) [[__unsequenced__]]
+{
+  x[0] = z;
+  x[1] = z + 1;
+  x[2] = z + 2;
+  *y = z + 3;
+  return z + 4 + f10 (-42);
+}
+
+int f12 () [[unsequenced]];
+int f12 () [[reproducible]];
+int f13 () [[reproducible]];
+int f13 () [[unsequenced]];
+
+int
+g ()
+{
+  int a = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int b = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int c = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int d = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int e = fp1 (14) + fp1 (14);
+  x++;
+  int f = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int g = f1 () + f2 () + f3 (42) + f5 (42) + f7 (42) + f8 (42) + f9 (42) + f12 () + f13 ();
+  int h = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int i = f3 (-42) + f5 (-42) + f7 (-42) + f8 (-42) + f9 (-42);
+  int j = fp1 (14) + fp1 (14);
+  return a + b + c + d + e + f + g + h + i + j;
+}
+
+int
+h ()
+{
+  f3 (52);
+  f3 (52);
+  f3 (52);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-2.c.jj	2024-07-30 10:39:12.632764961 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-2.c	2024-07-30 13:04:18.566879305 +0200
@@ -0,0 +1,47 @@
+/* Test C23 unsequenced attribute: invalid contexts.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+/* This attribute is not valid in most cases on types other than
+   type specifiers with function type or function declarators.  */
+
+[[unsequenced]]; /* { dg-error "ignored" } */
+
+int [[unsequenced]] var; /* { dg-error "ignored" } */
+
+int array_with_dep_type[2] [[unsequenced]]; /* { dg-error "ignored" } */
+
+[[unsequenced]] int fn1 (); /* { dg-error "standard 'unsequenced' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+[[unsequenced]] int fn2 (), fn3 (); /* { dg-error "standard 'unsequenced' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+int var2 [[unsequenced]]; /* { dg-warning "'unsequenced' attribute only applies to function types" } */
+
+int fn4 [[unsequenced]] (); /* { dg-error "standard 'unsequenced' attribute can only be applied to function declarators or type specifiers with function type" } */
+
+int [[unsequenced]] fn5 (); /* { dg-error "ignored" } */
+
+int z = sizeof (int [[__unsequenced__]]); /* { dg-error "ignored" } */
+
+/* This is valid, but not really useful, as it can't return results
+   in return type nor has any pointer arguments to store results into.  */
+void
+fn6 (int x, double y) [[unsequenced]]
+{ /* { dg-warning "unsequenced' attribute on function type without pointer arguments returning 'void'" } */
+  y = x;
+  (void) y;
+}
+
+void
+f (void)
+{
+  int a;
+  [[unsequenced]]; /* { dg-error "ignored" } */
+  [[unsequenced]] a = 1; /* { dg-error "ignored" } */
+  [[unsequenced]] label: ; /* { dg-warning "'unsequenced' attribute only applies to function types" } */
+  switch (var)
+    {
+    [[unsequenced]] case 1: ; /* { dg-warning "'unsequenced' attribute only applies to function types" } */
+    [[unsequenced]] default: ; /* { dg-warning "'unsequenced' attribute only applies to function types" } */
+    }
+}
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-3.c.jj	2024-07-30 10:39:15.313728999 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-3.c	2024-07-30 12:59:47.146465073 +0200
@@ -0,0 +1,14 @@
+/* Test C23 unsequenced attribute: invalid syntax.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a () [[unsequenced()]]; /* { dg-error "'unsequenced' attribute does not take any arguments" } */
+
+int b () [[unsequenced(0)]]; /* { dg-error "expected" } */
+			     /* { dg-error "'unsequenced' attribute does not take any arguments" "" { target *-*-* } .-1 } */
+
+int c () [[unsequenced("", 123)]]; /* { dg-error "expected" } */
+				   /* { dg-error "'unsequenced' attribute does not take any arguments" "" { target *-*-* } .-1 } */
+
+int d () [[unsequenced((""))]]; /* { dg-error "expected" } */
+				/* { dg-error "'unsequenced' attribute does not take any arguments" "" { target *-*-* } .-1 } */
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-4.c.jj	2024-07-30 10:39:18.168690708 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-4.c	2024-07-30 12:45:58.298379802 +0200
@@ -0,0 +1,12 @@
+/* Test C23 unsequenced attribute: duplicates (allowed after N2557).  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a () [[unsequenced, __unsequenced__]];
+int b () [[__unsequenced__, unsequenced]];
+int c () [[unsequenced, unsequenced]];
+int d () [[__unsequenced__, __unsequenced__]];
+int d () [[unsequenced]];
+int d () [[__unsequenced__]];
+[[unsequenced, unsequenced]];
+/* { dg-error "ignored" "ignored" { target *-*-* } .-1 } */
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-5.c.jj	2024-07-30 14:44:26.750009364 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-5.c	2024-07-30 14:53:55.734579606 +0200
@@ -0,0 +1,44 @@
+/* Test C23 unsequenced attribute: composite type on ?:.  */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-additional-sources "c23-attr-unsequenced-6.c" } */
+
+int f1 () [[unsequenced]];
+int f2 ();
+int f3 ();
+int (*fp1) () [[unsequenced]] = f2;
+int (*fp2) () [[unsequenced]] = f3;
+extern void abort ();
+
+int
+foo (int x)
+{
+  return __builtin_has_attribute (*(x ? f1 : f3), unsequenced);
+}
+
+int
+bar (int x)
+{
+  return __builtin_has_attribute (*(x ? fp1 : fp2), unsequenced);
+}
+
+int
+baz (int x)
+{
+  return __builtin_has_attribute (*(x ? f3 : f1), unsequenced);
+}
+
+int
+qux (int x)
+{
+  return __builtin_has_attribute (*(x ? fp2 : fp1), unsequenced);
+}
+
+int
+main ()
+{
+  if (!foo (0) || !bar (0) || !baz (0) || !qux (0))
+    abort ();
+  if (!foo (1) || !bar (1) || !baz (1) || !qux (1))
+    abort ();
+}
--- gcc/testsuite/gcc.dg/c23-attr-unsequenced-6.c.jj	2024-07-30 14:50:39.070147636 +0200
+++ gcc/testsuite/gcc.dg/c23-attr-unsequenced-6.c	2024-07-30 14:52:50.354433341 +0200
@@ -0,0 +1,21 @@
+/* Test C23 unsequenced attribute: composite type on ?:.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int
+f1 () [[unsequenced]]
+{
+  return 42;
+}
+
+int
+f2 ()
+{
+  return 43;
+}
+
+int
+f3 ()
+{
+  return 44;
+}
--- gcc/testsuite/gcc.dg/c23-has-c-attribute-2.c.jj	2023-11-09 09:04:19.505530809 +0100
+++ gcc/testsuite/gcc.dg/c23-has-c-attribute-2.c	2024-07-30 09:52:19.525586926 +0200
@@ -50,6 +50,22 @@
 #error "bad result for ___Noreturn__"
 #endif
   
+#if __has_c_attribute (unsequenced) != 202311L
+#error "bad result for unsequenced"
+#endif
+
+#if __has_c_attribute (__unsequenced__) != 202311L
+#error "bad result for __unsequenced__"
+#endif
+
+#if __has_c_attribute (reproducible) != 202311L
+#error "bad result for reproducible"
+#endif
+
+#if __has_c_attribute (__reproducible__) != 202311L
+#error "bad result for __reproducible__"
+#endif
+
 /* Macros in the attribute name are expanded.  */
 #define foo deprecated
 #if __has_c_attribute (foo) != 202311L
