--- gcc/gimplify.c.jj	2013-06-12 11:53:15.000000000 +0200
+++ gcc/gimplify.c	2013-06-12 12:16:51.123583143 +0200
@@ -6420,6 +6420,7 @@ gimplify_scan_omp_clauses (tree *list_p,
 	case OMP_CLAUSE_SCHEDULE:
 	case OMP_CLAUSE_NUM_THREADS:
 	case OMP_CLAUSE_NUM_TEAMS:
+	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_DEVICE:
 	  if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
--- gcc/tree.c.jj	2013-06-12 11:53:15.000000000 +0200
+++ gcc/tree.c	2013-06-12 12:15:58.026440954 +0200
@@ -257,6 +257,7 @@ unsigned const char omp_clause_num_ops[]
   0, /* OMP_CLAUSE_INBRANCH  */
   0, /* OMP_CLAUSE_NOTINBRANCH  */
   1, /* OMP_CLAUSE_NUM_TEAMS  */
+  1, /* OMP_CLAUSE_THREAD_LIMIT  */
   0, /* OMP_CLAUSE_PROC_BIND  */
   1, /* OMP_CLAUSE_SAFELEN  */
   1, /* OMP_CLAUSE_SIMDLEN  */
@@ -298,6 +299,7 @@ const char * const omp_clause_code_name[
   "inbranch",
   "notinbranch",
   "num_teams",
+  "thread_limit",
   "proc_bind",
   "safelen",
   "simdlen",
@@ -11014,6 +11016,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func
 	case OMP_CLAUSE_UNIFORM:
 	case OMP_CLAUSE_DEPEND:
 	case OMP_CLAUSE_NUM_TEAMS:
+	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_DEVICE:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_SAFELEN:
--- gcc/cp/semantics.c.jj	2013-06-04 20:55:56.000000000 +0200
+++ gcc/cp/semantics.c	2013-06-12 14:46:18.251419189 +0200
@@ -4779,6 +4779,25 @@ finish_omp_clauses (tree clauses)
 	    }
 	  break;
 
+	case OMP_CLAUSE_THREAD_LIMIT:
+	  t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
+	  if (t == error_mark_node)
+	    remove = true;
+	  else if (!type_dependent_expression_p (t)
+		   && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+	    {
+	      error ("%<thread_limit%> expression must be integral");
+	      remove = true;
+	    }
+	  else
+	    {
+	      t = mark_rvalue_use (t);
+	      if (!processing_template_decl)
+		t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+	      OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+	    }
+	  break;
+
 	case OMP_CLAUSE_DEVICE:
 	  t = OMP_CLAUSE_DEVICE_ID (c);
 	  if (t == error_mark_node)
--- gcc/cp/parser.c.jj	2013-06-04 20:55:56.000000000 +0200
+++ gcc/cp/parser.c	2013-06-12 12:22:01.239604269 +0200
@@ -26225,6 +26225,8 @@ cp_parser_omp_clause_name (cp_parser *pa
 	case 't':
 	  if (!strcmp ("taskgroup", p))
 	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
+	  else if (!strcmp ("thread_limit", p))
+	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
 	  else if (!strcmp ("to", p))
 	    result = PRAGMA_OMP_CLAUSE_TO;
 	  break;
@@ -26892,6 +26900,36 @@ cp_parser_omp_clause_num_teams (cp_parse
 }
 
 /* OpenMP 4.0:
+   thread_limit ( expression ) */
+
+static tree
+cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
+				   location_t location)
+{
+  tree t, c;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  t = cp_parser_expression (parser, false, NULL);
+
+  if (t == error_mark_node
+      || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+					   /*or_comma=*/false,
+					   /*consume_paren=*/true);
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
+			     "thread_limit", location);
+
+  c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
+  OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+  OMP_CLAUSE_CHAIN (c) = list;
+
+  return c;
+}
+
+/* OpenMP 4.0:
    aligned ( variable-list )
    aligned ( variable-list : constant-expression )  */
 
@@ -27429,6 +27463,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
 						    token->location);
 	  c_name = "num_teams";
 	  break;
+	case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
+	  clauses = cp_parser_omp_clause_thread_limit (parser, clauses,
+						       token->location);
+	  c_name = "thread_limit";
+	  break;
 	case PRAGMA_OMP_CLAUSE_ALIGNED:
 	  clauses = cp_parser_omp_clause_aligned (parser, clauses);
 	  c_name = "aligned";
@@ -29058,7 +29097,7 @@ cp_parser_omp_cancellation_point (cp_par
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)	\
-	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
 
 static tree
--- gcc/cp/pt.c.jj	2013-06-04 20:55:40.000000000 +0200
+++ gcc/cp/pt.c	2013-06-12 12:22:24.221366949 +0200
@@ -12667,6 +12667,7 @@ tsubst_omp_clauses (tree clauses, bool d
 	case OMP_CLAUSE_DEVICE:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_NUM_TEAMS:
+	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_SAFELEN:
 	case OMP_CLAUSE_SIMDLEN:
 	  OMP_CLAUSE_OPERAND (nc, 0)
--- gcc/tree-pretty-print.c.jj	2013-06-12 11:53:15.000000000 +0200
+++ gcc/tree-pretty-print.c	2013-06-12 12:16:32.441883566 +0200
@@ -533,6 +533,13 @@ dump_omp_clause (pretty_printer *buffer,
       pp_character (buffer, ')');
       break;
 
+    case OMP_CLAUSE_THREAD_LIMIT:
+      pp_string (buffer, "thread_limit(");
+      dump_generic_node (buffer, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause),
+			 spc, flags, false);
+      pp_character (buffer, ')');
+      break;
+
     case OMP_CLAUSE_DEVICE:
       pp_string (buffer, "device(");
       dump_generic_node (buffer, OMP_CLAUSE_DEVICE_ID (clause),
--- gcc/tree.h.jj	2013-06-12 11:53:15.000000000 +0200
+++ gcc/tree.h	2013-06-12 12:13:18.799984270 +0200
@@ -431,6 +431,9 @@ enum omp_clause_code
   /* OpenMP clause: num_teams(integer-expression).  */
   OMP_CLAUSE_NUM_TEAMS,
 
+  /* OpenMP clause: thread_limit(integer-expression).  */
+  OMP_CLAUSE_THREAD_LIMIT,
+
   /* OpenMP clause: proc_bind ({master,close,spread}).  */
   OMP_CLAUSE_PROC_BIND,
 
@@ -1978,6 +1981,10 @@ extern void protected_set_expr_location
 #define OMP_CLAUSE_NUM_TEAMS_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TEAMS), 0)
 
+#define OMP_CLAUSE_THREAD_LIMIT_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, \
+						OMP_CLAUSE_THREAD_LIMIT), 0)
+
 #define OMP_CLAUSE_DEVICE_ID(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE), 0)
 
--- gcc/c-family/c-pragma.h.jj	2013-03-27 13:01:09.000000000 +0100
+++ gcc/c-family/c-pragma.h	2013-06-12 12:18:48.668687172 +0200
@@ -104,6 +104,7 @@ typedef enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_SHARED,
   PRAGMA_OMP_CLAUSE_SIMDLEN,
   PRAGMA_OMP_CLAUSE_TASKGROUP,
+  PRAGMA_OMP_CLAUSE_THREAD_LIMIT,
   PRAGMA_OMP_CLAUSE_TO,
   PRAGMA_OMP_CLAUSE_UNIFORM,
   PRAGMA_OMP_CLAUSE_UNTIED
