about summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/regcomp.c249
-rw-r--r--posix/regex.c6
-rw-r--r--posix/regex_internal.c146
-rw-r--r--posix/regex_internal.h6
-rw-r--r--posix/regexec.c156
5 files changed, 267 insertions, 296 deletions
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 44f55f24af..930e8a61b5 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -424,7 +424,7 @@ regcomp (preg, pattern, cflags)
 
   /* Try to allocate space for the fastmap.  */
   preg->fastmap = re_malloc (char, SBC_MAX);
-  if (preg->fastmap == NULL)
+  if (BE (preg->fastmap == NULL, 0))
     return REG_ESPACE;
 
   syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
@@ -450,11 +450,11 @@ regcomp (preg, pattern, cflags)
     ret = REG_EPAREN;
 
   /* We have already checked preg->fastmap != NULL.  */
-  if (ret == REG_NOERROR)
+  if (BE (ret == REG_NOERROR, 1))
     {
       /* Compute the fastmap now, since regexec cannot modify the pattern
 	 buffer.  */
-      if (re_compile_fastmap (preg) == -2)
+      if (BE (re_compile_fastmap (preg) == -2, 0))
 	{
 	  /* Some error occurred while computing the fastmap, just forget
 	     about it.  */
@@ -482,9 +482,9 @@ regerror (errcode, preg, errbuf, errbuf_size)
   const char *msg;
   size_t msg_size;
 
-  if (errcode < 0
-      || errcode >= (int) (sizeof (re_error_msgid_idx)
-			   / sizeof (re_error_msgid_idx[0])))
+  if (BE (errcode < 0
+          || errcode >= (int) (sizeof (re_error_msgid_idx)
+                               / sizeof (re_error_msgid_idx[0])), 0))
     /* Only error codes returned by the rest of the code should be passed
        to this routine.  If we are given anything else, or if other regex
        code generates an invalid error code, then the program has a bug.
@@ -495,9 +495,9 @@ regerror (errcode, preg, errbuf, errbuf_size)
 
   msg_size = strlen (msg) + 1; /* Includes the null.  */
 
-  if (errbuf_size != 0)
+  if (BE (errbuf_size != 0, 1))
     {
-      if (msg_size > errbuf_size)
+      if (BE (msg_size > errbuf_size, 0))
         {
 #if defined HAVE_MEMPCPY || defined _LIBC
 	  *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
@@ -524,7 +524,7 @@ regfree (preg)
 {
   int i, j;
   re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  if (dfa != NULL)
+  if (BE (dfa != NULL, 1))
     {
       re_free (dfa->subexps);
 
@@ -565,25 +565,20 @@ regfree (preg)
       for (i = 0; i <= dfa->state_hash_mask; ++i)
         {
           struct re_state_table_entry *entry = dfa->state_table + i;
-          if (entry->alloc == 0)
-            re_free (entry->entry.state);
-          else
+          for (j = 0; j < entry->num; ++j)
             {
-              for (j = 0; j < entry->num; ++j)
+              re_dfastate_t *state = entry->array[j];
+              if (state->entrance_nodes != &state->nodes)
                 {
-                  re_dfastate_t *state = entry->entry.array[j];
-                  if (state->entrance_nodes != &state->nodes)
-                    {
-                      re_node_set_free (state->entrance_nodes);
-                      re_free (state->entrance_nodes);
-                    }
-                  re_node_set_free (&state->nodes);
-                  re_free (state->trtable);
-                  re_free (state->trtable_search);
-                  re_free (state);
+                  re_node_set_free (state->entrance_nodes);
+                  re_free (state->entrance_nodes);
                 }
-              re_free (entry->entry.array);
+              re_node_set_free (&state->nodes);
+              re_free (state->trtable);
+              re_free (state->trtable_search);
+              re_free (state);
             }
+          re_free (entry->array);
         }
       re_free (dfa->state_table);
 
@@ -688,7 +683,7 @@ re_compile_internal (preg, pattern, length, syntax)
   preg->used = sizeof (re_dfa_t);
 
   err = init_dfa (dfa, length);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     {
       re_free (dfa);
       preg->buffer = NULL;
@@ -701,7 +696,7 @@ re_compile_internal (preg, pattern, length, syntax)
   else
     err = re_string_construct (&regexp, pattern, length, preg->translate);
 
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     {
       re_free (dfa);
       preg->buffer = NULL;
@@ -711,18 +706,18 @@ re_compile_internal (preg, pattern, length, syntax)
   /* Parse the regular expression, and build a structure tree.  */
   preg->re_nsub = 0;
   dfa->str_tree = parse (&regexp, preg, syntax, &err);
-  if (dfa->str_tree == NULL)
+  if (BE (dfa->str_tree == NULL, 0))
     goto re_compile_internal_free_return;
 
   /* Analyze the tree and collect information which is necessary to
      create the dfa.  */
   err = analyze (dfa);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     goto re_compile_internal_free_return;
 
   /* Then create the initial state of the dfa.  */
   err = create_initial_state (dfa);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     goto re_compile_internal_free_return;
 
  re_compile_internal_free_return:
@@ -759,7 +754,8 @@ init_dfa (dfa, pat_len)
   dfa->subexps = re_malloc (re_subexp_t, dfa->subexps_alloc);
   dfa->word_char = NULL;
 
-  if (dfa->nodes == NULL || dfa->state_table == NULL || dfa->subexps == NULL)
+  if (BE (dfa->nodes == NULL || dfa->state_table == NULL
+          || dfa->subexps == NULL, 0))
     {
       /* We don't bother to free anything which was allocated.  Very
 	 soon the process will go down anyway.  */
@@ -781,7 +777,7 @@ init_word_char (dfa)
 {
   int i, j, ch;
   dfa->word_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);
-  if (dfa->word_char == NULL)
+  if (BE (dfa->word_char == NULL, 0))
     return REG_ESPACE;
   for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
     for (j = 0; j < UINT_BITS; ++j, ++ch)
@@ -816,7 +812,7 @@ create_initial_state (dfa)
   first = dfa->str_tree->first;
   dfa->init_node = first;
   err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   /* The back-references which are in initial states can epsilon transit,
@@ -852,7 +848,7 @@ create_initial_state (dfa)
   /* It must be the first time to invoke acquire_state.  */
   dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
   /* We don't check ERR here, since the initial state must not be NULL.  */
-  if (dfa->init_state == NULL)
+  if (BE (dfa->init_state == NULL, 0))
     return err;
   if (dfa->init_state->has_constraint)
     {
@@ -864,8 +860,8 @@ create_initial_state (dfa)
                                                          &init_nodes,
                                                          CONTEXT_NEWLINE
                                                          | CONTEXT_BEGBUF);
-      if (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-          || dfa->init_state_begbuf == NULL)
+      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+              || dfa->init_state_begbuf == NULL, 0))
         return err;
     }
   else
@@ -892,8 +888,8 @@ analyze (dfa)
   dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  if (dfa->firsts == NULL || dfa->nexts == NULL || dfa->edests == NULL
-      || dfa->eclosures == NULL || dfa->inveclosures == NULL)
+  if (BE (dfa->firsts == NULL || dfa->nexts == NULL || dfa->edests == NULL
+          || dfa->eclosures == NULL || dfa->inveclosures == NULL, 0))
     return REG_ESPACE;
   /* Initialize them.  */
   for (i = 0; i < dfa->nodes_len; ++i)
@@ -906,7 +902,7 @@ analyze (dfa)
     }
 
   ret = analyze_tree (dfa, dfa->str_tree);
-  if (ret == REG_NOERROR)
+  if (BE (ret == REG_NOERROR, 1))
     {
       ret = calc_eclosure (dfa);
       if (ret == REG_NOERROR)
@@ -935,14 +931,14 @@ analyze_tree (dfa, node)
   if (node->left != NULL)
     {
       ret = analyze_tree (dfa, node->left);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   /* Calculate "first" etc. for the right child.  */
   if (node->right != NULL)
     {
       ret = analyze_tree (dfa, node->right);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -1158,7 +1154,7 @@ duplicate_node (new_idx, dfa, org_idx, constraint)
      we correct `entity' to real entity in calc_inveclosures(). */
   dup.opr.ctx_info = malloc (sizeof (*dup.opr.ctx_info));
   dup_idx = re_dfa_add_node (dfa, dup, 1);
-  if (dup.opr.ctx_info == NULL || dup_idx == -1)
+  if (BE (dup.opr.ctx_info == NULL || dup_idx == -1, 0))
     return REG_ESPACE;
   dup.opr.ctx_info->entity = org_idx;
   dup.opr.ctx_info->bkref_eclosure = NULL;
@@ -1167,15 +1163,15 @@ duplicate_node (new_idx, dfa, org_idx, constraint)
   dfa->firsts[dup_idx] = dfa->firsts[org_idx];
   dfa->nexts[dup_idx] = dfa->nexts[org_idx];
   err = re_node_set_init_copy (dfa->edests + dup_idx, dfa->edests + org_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   /* Since we don't duplicate epsilon nodes, epsilon closure have
      only itself.  */
   err = re_node_set_init_1 (dfa->eclosures + dup_idx, dup_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   err = re_node_set_init_1 (dfa->inveclosures + dup_idx, dup_idx);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   /* Then we must update inveclosure for this node.
      We process them at last part of calc_eclosure(),
@@ -1241,7 +1237,7 @@ calc_eclosure (dfa)
         continue;
       /* Calculate epsilon closure of `node_idx'.  */
       err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
 
       if (dfa->eclosures[node_idx].nelem == 0)
@@ -1265,7 +1261,7 @@ calc_eclosure (dfa)
          the next node. Since it may epsilon transit.  */
       /* Note: duplicate_node() may realloc dfa->eclosures, etc.  */
       bkref_eclosure = re_malloc (re_node_set, 1);
-      if (bkref_eclosure == NULL)
+      if (BE (bkref_eclosure == NULL, 0))
 	return REG_ESPACE;
       re_node_set_init_empty (bkref_eclosure);
       constraint = dfa->nodes[idx].constraint;
@@ -1277,7 +1273,7 @@ calc_eclosure (dfa)
               reg_errcode_t err;
               err = duplicate_node (&dest_node_idx, dfa, dest_node_idx,
                                     constraint);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return err;
             }
           re_node_set_insert (bkref_eclosure, dest_node_idx);
@@ -1301,7 +1297,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
   int i, max, incomplete = 0;
   re_node_set eclosure;
   err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   /* This indicates that we are calculating this node now.
@@ -1329,7 +1325,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
         if (dfa->eclosures[edest].nelem == 0)
           {
             err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);
-            if (err != REG_NOERROR)
+            if (BE (err != REG_NOERROR, 0))
               return err;
           }
         else
@@ -1356,7 +1352,7 @@ calc_eclosure_iter (new_set, dfa, node, root)
             int dup_dest;
             reg_errcode_t err;
             err = duplicate_node (&dup_dest, dfa, dest, constraint);
-            if (err != REG_NOERROR)
+            if (BE (err != REG_NOERROR, 0))
               return err;
             if (dest != dup_dest)
               {
@@ -1716,7 +1712,7 @@ parse (regexp, preg, syntax, err)
   int new_idx;
   current_token = fetch_token (regexp, syntax);
   tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
   new_idx = re_dfa_add_node (dfa, current_token, 0);
   eor = create_tree (NULL, NULL, 0, new_idx);
@@ -1724,7 +1720,7 @@ parse (regexp, preg, syntax, err)
     root = create_tree (tree, eor, CONCAT, 0);
   else
     root = eor;
-  if (new_idx == -1 || eor == NULL || root == NULL)
+  if (BE (new_idx == -1 || eor == NULL || root == NULL, 0))
     return *err = REG_ESPACE, NULL;
   return root;
 }
@@ -1751,7 +1747,7 @@ parse_reg_exp (regexp, preg, token, syntax, nest, err)
   bin_tree_t *tree, *branch = NULL;
   int new_idx;
   tree = parse_branch (regexp, preg, token, syntax, nest, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
 
   while (token->type == OP_ALT)
@@ -1763,14 +1759,14 @@ parse_reg_exp (regexp, preg, token, syntax, nest, err)
           && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
         {
           branch = parse_branch (regexp, preg, token, syntax, nest, err);
-          if (*err != REG_NOERROR && branch == NULL)
+          if (BE (*err != REG_NOERROR && branch == NULL, 0))
             {
               free_bin_tree (tree);
               return NULL;
             }
         }
       tree = create_tree (tree, branch, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
   return tree;
@@ -1796,14 +1792,14 @@ parse_branch (regexp, preg, token, syntax, nest, err)
 {
   bin_tree_t *tree, *exp;
   tree = parse_expression (regexp, preg, token, syntax, nest, err);
-  if (*err != REG_NOERROR && tree == NULL)
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
 
   while (token->type != OP_ALT && token->type != END_OF_RE
          && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
     {
       exp = parse_expression (regexp, preg, token, syntax, nest, err);
-      if (*err != REG_NOERROR && exp == NULL)
+      if (BE (*err != REG_NOERROR && exp == NULL, 0))
         {
           free_bin_tree (tree);
           return NULL;
@@ -1844,7 +1840,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
     case CHARACTER:
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
 #ifdef RE_ENABLE_I18N
       if (MB_CUR_MAX > 1)
@@ -1857,7 +1853,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
               new_idx = re_dfa_add_node (dfa, *token, 0);
               mbc_remain = create_tree (NULL, NULL, 0, new_idx);
               tree = create_tree (tree, mbc_remain, CONCAT, 0);
-              if (new_idx == -1 || mbc_remain == NULL || tree == NULL)
+              if (BE (new_idx == -1 || mbc_remain == NULL || tree == NULL, 0))
                 return *err = REG_ESPACE, NULL;
             }
 	}
@@ -1865,24 +1861,24 @@ parse_expression (regexp, preg, token, syntax, nest, err)
       break;
     case OP_OPEN_SUBEXP:
       tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_OPEN_BRACKET:
       tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_BACK_REF:
-      if (preg->re_nsub < token->opr.idx
-          || dfa->subexps[token->opr.idx - 1].end == -1)
+      if (BE (preg->re_nsub < token->opr.idx
+              || dfa->subexps[token->opr.idx - 1].end == -1, 0))
         {
           *err = REG_ESUBREG;
           return NULL;
         }
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       ++dfa->nbackref;
       dfa->has_mb_node = 1;
@@ -1911,14 +1907,14 @@ parse_expression (regexp, preg, token, syntax, nest, err)
       token->type = CHARACTER;
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       break;
     case ANCHOR:
       if (dfa->word_char == NULL)
         {
           *err = init_word_char (dfa);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
       if (token->opr.ctx_type == WORD_DELIM)
@@ -1934,15 +1930,16 @@ parse_expression (regexp, preg, token, syntax, nest, err)
           token->type = OP_ALT;
           new_idx = re_dfa_add_node (dfa, *token, 0);
           tree = create_tree (tree_first, tree_last, 0, new_idx);
-          if (idx_first == -1 || idx_last == -1 || new_idx == -1
-              || tree_first == NULL || tree_last == NULL || tree == NULL)
+          if (BE (idx_first == -1 || idx_last == -1 || new_idx == -1
+                  || tree_first == NULL || tree_last == NULL
+                  || tree == NULL, 0))
             return *err = REG_ESPACE, NULL;
         }
       else
         {
           new_idx = re_dfa_add_node (dfa, *token, 0);
           tree = create_tree (NULL, NULL, 0, new_idx);
-          if (new_idx == -1 || tree == NULL)
+          if (BE (new_idx == -1 || tree == NULL, 0))
             return *err = REG_ESPACE, NULL;
         }
       /* We must return here, since ANCHORs can't be followed
@@ -1954,19 +1951,19 @@ parse_expression (regexp, preg, token, syntax, nest, err)
     case OP_PERIOD:
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       if (MB_CUR_MAX > 1)
         dfa->has_mb_node = 1;
       break;
     case OP_WORD:
       tree = build_word_op (dfa, 0, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_NOTWORD:
       tree = build_word_op (dfa, 1, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       break;
     case OP_ALT:
@@ -1988,7 +1985,7 @@ parse_expression (regexp, preg, token, syntax, nest, err)
          || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
       tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
 
@@ -2020,7 +2017,7 @@ parse_sub_exp (regexp, preg, token, syntax, nest, err)
       re_subexp_t *new_array;
       dfa->subexps_alloc *= 2;
       new_array = re_realloc (dfa->subexps, re_subexp_t, dfa->subexps_alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
 	{
 	  dfa->subexps_alloc /= 2;
 	  *err = REG_ESPACE;
@@ -2036,17 +2033,17 @@ parse_sub_exp (regexp, preg, token, syntax, nest, err)
   if (token->type == OP_CLOSE_SUBEXP)
     {
       tree = create_tree (NULL, NULL, SUBEXP, 0);
-      if (tree == NULL)
+      if (BE (tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
       dfa->subexps[cur_nsub].end = dfa->nodes_len;
     }
   else
     {
       tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
-      if (*err != REG_NOERROR && tree == NULL)
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
         return NULL;
       dfa->subexps[cur_nsub].end = dfa->nodes_len;
-      if (token->type != OP_CLOSE_SUBEXP)
+      if (BE (token->type != OP_CLOSE_SUBEXP, 0))
         {
           free_bin_tree (tree);
           *err = REG_BADPAT;
@@ -2089,13 +2086,14 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
             }
           end = start; /* We treat "{n}" as "{n,n}".  */
         }
-      else if (start == -2 || token->type != CHARACTER || token->opr.c != ',')
+      else if (BE (start == -2 || token->type != CHARACTER
+                   || token->opr.c != ',', 0))
         /* Invalid sequence.  */
         goto parse_dup_op_invalid_interval;
       else
         {
           end = fetch_number (regexp, token, syntax);
-          if (end == -2 || token->type != OP_CLOSE_DUP_NUM)
+          if (BE (end == -2 || token->type != OP_CLOSE_DUP_NUM, 0))
             /* Invalid sequence.  */
             goto parse_dup_op_invalid_interval;
         }
@@ -2106,7 +2104,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
           {
             work_tree = duplicate_tree (elem, dfa);
             tree = create_tree (tree, work_tree, CONCAT, 0);
-            if (work_tree == NULL || tree == NULL)
+            if (BE (work_tree == NULL || tree == NULL, 0))
               goto parse_dup_op_espace;
           }
 
@@ -2120,15 +2118,15 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               work_tree = create_tree (elem, NULL, 0, new_idx);
               tree = create_tree (tree, work_tree, CONCAT, 0);
-              if (elem == NULL || new_idx == -1 || work_tree == NULL
-                  || tree == NULL)
+              if (BE (elem == NULL || new_idx == -1 || work_tree == NULL
+                      || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           else
             {
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               tree = create_tree (elem, NULL, 0, new_idx);
-              if (new_idx == -1 || tree == NULL)
+              if (BE (new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
         }
@@ -2142,21 +2140,21 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               elem = create_tree (elem, NULL, 0, new_idx);
               tree = create_tree (tree, elem, CONCAT, 0);
-              if (elem == NULL || new_idx == -1 || tree == NULL)
+              if (BE (elem == NULL || new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           else
             {
               new_idx = re_dfa_add_node (dfa, dup_token, 0);
               tree = elem = create_tree (elem, NULL, 0, new_idx);
-              if (new_idx == -1 || tree == NULL)
+              if (BE (new_idx == -1 || tree == NULL, 0))
                 goto parse_dup_op_espace;
             }
           for (i = 1; i < end - start; ++i)
             {
               work_tree = duplicate_tree (elem, dfa);
               tree = create_tree (tree, work_tree, CONCAT, 0);
-              if (work_tree == NULL || tree == NULL)
+              if (BE (work_tree == NULL || tree == NULL, 0))
                 return *err = REG_ESPACE, NULL;
             }
         }
@@ -2165,7 +2163,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
     {
       new_idx = re_dfa_add_node (dfa, *token, 0);
       tree = create_tree (tree, NULL, 0, new_idx);
-      if (new_idx == -1 || tree == NULL)
+      if (BE (new_idx == -1 || tree == NULL, 0))
         return *err = REG_ESPACE, NULL;
     }
   *token = fetch_token (regexp, syntax);
@@ -2177,7 +2175,7 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
   return NULL;
 
  parse_dup_op_invalid_interval:
-  if (!(syntax & RE_INVALID_INTERVAL_ORD))
+  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
     {
       *err = REG_EBRACE;
       return NULL;
@@ -2341,7 +2339,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
           new_array_end = re_realloc (mbcset->range_ends, uint32_t,
                                       new_nranges);
 
-          if (new_array_start == NULL || new_array_end == NULL)
+          if (BE (new_array_start == NULL || new_array_end == NULL, 0))
             return REG_ESPACE;
 
           mbcset->range_starts = new_array_start;
@@ -2349,16 +2347,17 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
 	  *range_alloc = new_nranges;
         }
 
-      if (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-          || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS)
+      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+              || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+              0))
         return REG_ERANGE;
 
       start_collseq = lookup_collation_sequence_value (start_elem);
       end_collseq = lookup_collation_sequence_value (end_elem);
       /* Check start/end collation sequence values.  */
-      if (start_collseq == UINT_MAX || end_collseq == UINT_MAX)
+      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
         return REG_ECOLLATE;
-      if ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq)
+      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
         return REG_ERANGE;
 
       /* Got valid collation sequence values, add them as a new entry.  */
@@ -2429,7 +2428,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
                  if *alloc == 0.  */
               mbcset->coll_syms = re_realloc (mbcset->coll_syms, int32_t,
                                               *coll_sym_alloc);
-              if (mbcset->coll_syms == NULL)
+              if (BE (mbcset->coll_syms == NULL, 0))
                 return REG_ESPACE;
             }
           mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
@@ -2438,7 +2437,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       else
 #endif
         {
-          if (strlen (name) != 1)
+          if (BE (strlen (name) != 1, 0))
             return REG_ECOLLATE;
           else
             {
@@ -2472,14 +2471,14 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
 #endif
   sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-  if (sbcset == NULL || mbcset == NULL)
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
     {
       *err = REG_ESPACE;
       return NULL;
     }
 
   token_len = peek_token_bracket (token, regexp, syntax);
-  if (token->type == END_OF_RE)
+  if (BE (token->type == END_OF_RE, 0))
     {
       re_free (sbcset);
       free_charset (mbcset);
@@ -2494,7 +2493,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
         bitset_set (sbcset, '\0');
       re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
       token_len = peek_token_bracket (token, regexp, syntax);
-      if (token->type == END_OF_RE)
+      if (BE (token->type == END_OF_RE, 0))
         {
           re_free (sbcset);
           free_charset (mbcset);
@@ -2523,11 +2522,11 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       start_elem.opr.name = start_name_buf;
       ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
                                    syntax);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         goto parse_bracket_exp_espace;
 
       token_len = peek_token_bracket (token, regexp, syntax);
-      if (token->type == END_OF_RE)
+      if (BE (token->type == END_OF_RE, 0))
         {
           re_free (sbcset);
           free_charset (mbcset);
@@ -2538,7 +2537,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
         {
           re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
           token_len2 = peek_token_bracket (&token2, regexp, syntax);
-          if (token->type == END_OF_RE)
+          if (BE (token->type == END_OF_RE, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2560,11 +2559,11 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
           end_elem.opr.name = end_name_buf;
           ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
                                        dfa, syntax);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             goto parse_bracket_exp_espace;
 
           token_len = peek_token_bracket (token, regexp, syntax);
-          if (token->type == END_OF_RE)
+          if (BE (token->type == END_OF_RE, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2573,7 +2572,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             }
           *err = build_range_exp (mbcset, sbcset, &range_alloc, &start_elem,
 				  &end_elem);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             {
               re_free (sbcset);
               free_charset (mbcset);
@@ -2597,7 +2596,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
                   /* Use realloc since array is NULL if *alloc == 0.  */
                   mbcset->mbchars = re_realloc (mbcset->mbchars, wchar_t,
                                                 mbchar_alloc);
-                  if (mbcset->mbchars == NULL)
+                  if (BE (mbcset->mbchars == NULL, 0))
                     goto parse_bracket_exp_espace;
                 }
               mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
@@ -2605,7 +2604,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case EQUIV_CLASS:
               *err = build_equiv_class (mbcset, sbcset, &equiv_class_alloc,
 					start_elem.opr.name);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 {
                   re_free (sbcset);
                   free_charset (mbcset);
@@ -2615,7 +2614,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case COLL_SYM:
               *err = build_collating_symbol (mbcset, sbcset, &coll_sym_alloc,
 					     start_elem.opr.name);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 {
                   re_free (sbcset);
                   free_charset (mbcset);
@@ -2625,7 +2624,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
             case CHAR_CLASS:
               ret = build_charclass (mbcset, sbcset, &char_class_alloc,
 				     start_elem.opr.name);
-              if (ret != REG_NOERROR)
+              if (BE (ret != REG_NOERROR, 0))
                goto parse_bracket_exp_espace;
               break;
             default:
@@ -2648,7 +2647,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
   br_token.opr.sbcset = sbcset;
   new_idx = re_dfa_add_node (dfa, br_token, 0);
   work_tree = create_tree (NULL, NULL, 0, new_idx);
-  if (new_idx == -1 || work_tree == NULL)
+  if (BE (new_idx == -1 || work_tree == NULL, 0))
     goto parse_bracket_exp_espace;
 
   if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
@@ -2662,13 +2661,13 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
       dfa->has_mb_node = 1;
       new_idx = re_dfa_add_node (dfa, br_token, 0);
       mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || mbc_tree == NULL)
+      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
         goto parse_bracket_exp_espace;
       /* Then join them by ALT node.  */
       alt_token.type = OP_ALT;
       new_idx = re_dfa_add_node (dfa, alt_token, 0);
       work_tree = create_tree (work_tree, mbc_tree, 0, new_idx);
-      if (new_idx != -1 && mbc_tree != NULL)
+      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
         return work_tree;
     }
   else
@@ -2787,7 +2786,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
       indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
                                                 _NL_COLLATE_INDIRECTMB);
       idx1 = findidx (&cp);
-      if (idx1 == 0 || cp < name + strlen (name))
+      if (BE (idx1 == 0 || cp < name + strlen (name), 0))
         /* This isn't a valid character.  */
         return REG_ECOLLATE;
 
@@ -2825,7 +2824,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
           /* Use realloc since the array is NULL if *alloc == 0.  */
           mbcset->equiv_classes = re_realloc (mbcset->equiv_classes, int32_t,
                                               *equiv_class_alloc);
-          if (mbcset->equiv_classes == NULL)
+          if (BE (mbcset->equiv_classes == NULL, 0))
             return REG_ESPACE;
         }
       mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
@@ -2833,7 +2832,7 @@ build_equiv_class (mbcset, sbcset, equiv_class_alloc, name)
   else
 #endif
     {
-      if (strlen (name) != 1)
+      if (BE (strlen (name) != 1, 0))
         return REG_ECOLLATE;
       bitset_set (sbcset, name[0]);
     }
@@ -2864,7 +2863,7 @@ build_charclass (mbcset, sbcset, char_class_alloc, name)
       /* Use realloc since array is NULL if *alloc == 0.  */
       mbcset->char_classes = re_realloc (mbcset->char_classes, wctype_t,
                                          *char_class_alloc);
-      if (mbcset->char_classes == NULL)
+      if (BE (mbcset->char_classes == NULL, 0))
         return REG_ESPACE;
     }
 
@@ -2922,7 +2921,7 @@ build_word_op (dfa, not, err)
 
   sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-  if (sbcset == NULL || mbcset == NULL)
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
     {
       *err = REG_ESPACE;
       return NULL;
@@ -2943,7 +2942,7 @@ build_word_op (dfa, not, err)
     }
 
   ret = build_charclass (mbcset, sbcset, &alloc, "alpha");
-  if (ret != REG_NOERROR)
+  if (BE (ret != REG_NOERROR, 0))
     {
       re_free (sbcset);
       free_charset (mbcset);
@@ -2960,7 +2959,7 @@ build_word_op (dfa, not, err)
   br_token.opr.sbcset = sbcset;
   new_idx = re_dfa_add_node (dfa, br_token, 0);
   tree = create_tree (NULL, NULL, 0, new_idx);
-  if (new_idx == -1 || tree == NULL)
+  if (BE (new_idx == -1 || tree == NULL, 0))
     goto build_word_op_espace;
 
   if (MB_CUR_MAX > 1)
@@ -2973,13 +2972,13 @@ build_word_op (dfa, not, err)
       dfa->has_mb_node = 1;
       new_idx = re_dfa_add_node (dfa, br_token, 0);
       mbc_tree = create_tree (NULL, NULL, 0, new_idx);
-      if (new_idx == -1 || mbc_tree == NULL)
+      if (BE (new_idx == -1 || mbc_tree == NULL, 0))
         goto build_word_op_espace;
       /* Then join them by ALT node.  */
       alt_token.type = OP_ALT;
       new_idx = re_dfa_add_node (dfa, alt_token, 0);
       tree = create_tree (tree, mbc_tree, 0, new_idx);
-      if (new_idx != -1 && mbc_tree != NULL)
+      if (BE (new_idx != -1 && mbc_tree != NULL, 1))
         return tree;
     }
   else
@@ -3013,11 +3012,11 @@ fetch_number (input, token, syntax)
       c = token->opr.c;
       if (token->type == OP_CLOSE_DUP_NUM || c == ',')
         break;
-      if (token->type != CHARACTER || c < '0' || '9' < c)
+      if (BE (token->type != CHARACTER || c < '0' || '9' < c, 0))
         return -2;
       num = (num == -1) ? c - '0' : num * 10 + c - '0';
     }
-  if (num > RE_DUP_MAX)
+  if (BE (num > RE_DUP_MAX, 0))
     return -2;
   return num;
 }
@@ -3050,7 +3049,7 @@ create_tree (left, right, type, index)
 {
   bin_tree_t *tree;
   tree = re_malloc (bin_tree_t, 1);
-  if (tree == NULL)
+  if (BE (tree == NULL, 0))
     {
       free_bin_tree (left);
       free_bin_tree (right);
@@ -3120,7 +3119,7 @@ duplicate_tree (src, dfa)
     {
       new_node_idx = re_dfa_add_node (dfa, dfa->nodes[src->node_idx], 0);
       dfa->nodes[new_node_idx].duplicated = 1;
-      if (new_node_idx == -1)
+      if (BE (new_node_idx == -1, 0))
         {
           free_bin_tree (left);
           free_bin_tree (right);
@@ -3131,7 +3130,7 @@ duplicate_tree (src, dfa)
     new_node_idx = src->type;
 
   new_tree = create_tree (left, right, src->type, new_node_idx);
-  if (new_tree == NULL)
+  if (BE (new_tree == NULL, 0))
     {
       free_bin_tree (left);
       free_bin_tree (right);
diff --git a/posix/regex.c b/posix/regex.c
index 0d5b51f013..03bda25f0b 100644
--- a/posix/regex.c
+++ b/posix/regex.c
@@ -41,6 +41,12 @@
 #  define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
 #endif
 
+#if _LIBC || __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+#endif
+
 #include "regcomp.c"
 #include "regexec.c"
 #include "regex_internal.c"
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index 11726b340d..c2b0f9b4b0 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -96,7 +96,7 @@ re_string_construct (pstr, str, len, trans)
   if (MB_CUR_MAX >1 && pstr->len > 0)
     {
       ret = build_wcs_buffer (pstr);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
 #endif /* RE_ENABLE_I18N  */
@@ -104,7 +104,7 @@ re_string_construct (pstr, str, len, trans)
   if (trans != NULL)
     {
       ret = re_string_translate_buffer (pstr, trans);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -126,20 +126,20 @@ re_string_construct_toupper (pstr, str, len, trans)
 #ifdef RE_ENABLE_I18N
   if (MB_CUR_MAX >1)
     {
-      if (pstr->len > 0)
+      if (BE (pstr->len > 0, 1))
         {
           ret = build_wcs_upper_buffer (pstr);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             return ret;
         }
     }
   else
 #endif /* RE_ENABLE_I18N  */
     {
-      if (pstr->len > 0)
+      if (BE (pstr->len > 0, 1))
         {
           ret = build_upper_buffer (pstr);
-          if (ret != REG_NOERROR)
+          if (BE (ret != REG_NOERROR, 0))
             return ret;
         }
     }
@@ -147,7 +147,7 @@ re_string_construct_toupper (pstr, str, len, trans)
   if (trans != NULL)
     {
       ret = re_string_translate_buffer (pstr, trans);
-      if (ret != REG_NOERROR)
+      if (BE (ret != REG_NOERROR, 0))
         return ret;
     }
   return REG_NOERROR;
@@ -190,7 +190,7 @@ build_wcs_buffer (pstr)
   int char_idx, char_len, mbclen;
 
   pstr->wcs = re_malloc (wchar_t, pstr->len + 1);
-  if (pstr->wcs == NULL)
+  if (BE (pstr->wcs == NULL, 0))
     return REG_ESPACE;
 
   memset (&state, '\0', sizeof (mbstate_t));
@@ -200,7 +200,7 @@ build_wcs_buffer (pstr)
       int next_idx, remain_len = char_len - char_idx;
       prev_st = state;
       mbclen = mbrtowc (&wc, pstr->mbs + char_idx, remain_len, &state);
-      if (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0)
+      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
         /* We treat these cases as a singlebyte character.  */
         {
           mbclen = 1;
@@ -226,7 +226,7 @@ build_wcs_upper_buffer (pstr)
 
   pstr->wcs = re_malloc (wchar_t, pstr->len + 1);
   mbs_upper = re_malloc (unsigned char, pstr->len + 1);
-  if (pstr->wcs == NULL || mbs_upper == NULL)
+  if (BE (pstr->wcs == NULL || mbs_upper == NULL, 0))
     {
       pstr->wcs = NULL;
       return REG_ESPACE;
@@ -247,7 +247,8 @@ build_wcs_upper_buffer (pstr)
           else
             mbs_upper[char_idx] = pstr->mbs[char_idx];
         }
-      else if (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0)
+      else if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1
+                   || mbclen == 0, 0))
         /* We treat these cases as a singlebyte character.  */
         {
           mbclen = 1;
@@ -280,7 +281,7 @@ build_upper_buffer (pstr)
   int char_idx, char_len;
 
   mbs_upper = re_malloc (unsigned char, pstr->len + 1);
-  if (mbs_upper == NULL)
+  if (BE (mbs_upper == NULL, 0))
     return REG_ESPACE;
 
   char_len = pstr->len;
@@ -313,14 +314,14 @@ re_string_translate_buffer (pstr, trans)
     {
       transed_buf = (unsigned char *) pstr->mbs;
       transed_case_buf = re_malloc (unsigned char, pstr->len + 1);
-      if (transed_case_buf == NULL)
+      if (BE (transed_case_buf == NULL, 0))
         return REG_ESPACE;
       pstr->mbs_case_alloc = 1;
     }
   else
     {
       transed_buf = re_malloc (unsigned char, pstr->len + 1);
-      if (transed_buf == NULL)
+      if (BE (transed_buf == NULL, 0))
         return REG_ESPACE;
       transed_case_buf = NULL;
       pstr->mbs_alloc = 1;
@@ -381,7 +382,7 @@ re_string_context_at (input, idx, eflags, newline_anchor)
       unsigned int context = 0;
       if (idx < 0)
         context = CONTEXT_BEGBUF;
-      else if (idx == input->len)
+      else /* (idx == input->len) */
         context = CONTEXT_ENDBUF;
 
       if ((idx < 0 && !(eflags & REG_NOTBOL))
@@ -406,7 +407,7 @@ re_node_set_alloc (set, size)
   set->alloc = size;
   set->nelem = 0;
   set->elems = re_malloc (int, size);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   return REG_NOERROR;
 }
@@ -419,7 +420,7 @@ re_node_set_init_1 (set, elem)
   set->alloc = 1;
   set->nelem = 1;
   set->elems = re_malloc (int, 1);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   set->elems[0] = elem;
   return REG_NOERROR;
@@ -432,7 +433,7 @@ re_node_set_init_2 (set, elem1, elem2)
 {
   set->alloc = 2;
   set->elems = re_malloc (int, 2);
-  if (set->elems == NULL)
+  if (BE (set->elems == NULL, 0))
     return REG_ESPACE;
   if (elem1 == elem2)
     {
@@ -466,7 +467,7 @@ re_node_set_init_copy (dest, src)
     {
       dest->alloc = dest->nelem;
       dest->elems = re_malloc (int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
       memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
     }
@@ -491,7 +492,7 @@ re_node_set_intersect (dest, src1, src2)
         {
           dest->alloc = src1->nelem + src2->nelem;
           dest->elems = re_realloc (dest->elems, int, dest->alloc);
-          if (dest->elems == NULL)
+          if (BE (dest->elems == NULL, 0))
             return REG_ESPACE;
         }
     }
@@ -535,7 +536,7 @@ re_node_set_add_intersect (dest, src1, src2)
         {
           dest->alloc = src1->nelem + src2->nelem + dest->nelem;
           dest->elems = re_realloc (dest->elems, int, dest->alloc);
-          if (dest->elems == NULL)
+          if (BE (dest->elems == NULL, 0))
             return REG_ESPACE;
         }
     }
@@ -581,7 +582,7 @@ re_node_set_init_union (dest, src1, src2)
     {
       dest->alloc = src1->nelem + src2->nelem;
       dest->elems = re_malloc (int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -632,18 +633,11 @@ re_node_set_merge (dest, src)
   int si, di;
   if (src == NULL || src->nelem == 0)
     return REG_NOERROR;
-  else if (dest == NULL)
-    {
-      dest = re_malloc (re_node_set, 1);
-      if (dest == NULL)
-        return REG_ESPACE;
-      return re_node_set_init_copy (dest, src);
-    }
   if (dest->alloc < src->nelem + dest->nelem)
     {
       dest->alloc = 2 * (src->nelem + dest->alloc);
       dest->elems = re_realloc (dest->elems, int, dest->alloc);
-      if (dest->elems == NULL)
+      if (BE (dest->elems == NULL, 0))
         return REG_ESPACE;
     }
 
@@ -709,7 +703,7 @@ re_node_set_insert (set, elem)
   /* In case of the set is empty.  */
   if (set->elems == NULL || set->alloc == 0)
     {
-      if (re_node_set_init_1 (set, elem) == REG_NOERROR)
+      if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
         return 1;
       else
         return -1;
@@ -733,7 +727,7 @@ re_node_set_insert (set, elem)
       int *new_array;
       set->alloc = set->alloc * 2;
       new_array = re_malloc (int, set->alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
         return -1;
       /* Copy the elements they are followed by the new element.  */
       if (idx > 0)
@@ -826,7 +820,7 @@ re_dfa_add_node (dfa, token, mode)
       re_token_t *new_array;
       dfa->nodes_alloc *= 2;
       new_array = re_realloc (dfa->nodes, re_token_t, dfa->nodes_alloc);
-      if (new_array == NULL)
+      if (BE (new_array == NULL, 0))
         return -1;
       else
         dfa->nodes = new_array;
@@ -842,8 +836,8 @@ re_dfa_add_node (dfa, token, mode)
                                       dfa->nodes_alloc);
           new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
                                          dfa->nodes_alloc);
-          if (new_firsts == NULL || new_nexts == NULL || new_edests == NULL
-              || new_eclosures == NULL || new_inveclosures == NULL)
+          if (BE (new_firsts == NULL || new_nexts == NULL || new_edests == NULL
+                  || new_eclosures == NULL || new_inveclosures == NULL, 0))
             return -1;
           dfa->firsts = new_firsts;
           dfa->nexts = new_nexts;
@@ -888,7 +882,7 @@ re_acquire_state (err, dfa, nodes)
   re_dfastate_t *new_state;
   struct re_state_table_entry *spot;
   int i;
-  if (nodes->nelem == 0)
+  if (BE (nodes->nelem == 0, 0))
     {
       *err = REG_NOERROR;
       return NULL;
@@ -896,26 +890,18 @@ re_acquire_state (err, dfa, nodes)
   hash = calc_state_hash (nodes, 0);
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
 
-  if (spot->alloc == 0)
+  for (i = 0 ; i < spot->num ; i++)
     {
-      /* Currently there are only one state in this spot.  */
-      if (spot->entry.state != NULL && hash == spot->entry.state->hash
-          && re_node_set_compare (&spot->entry.state->nodes, nodes))
-        return spot->entry.state;
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+        continue;
+      if (re_node_set_compare (&state->nodes, nodes))
+        return state;
     }
-  else
-    for (i = 0 ; i < spot->num ; i++)
-      {
-        re_dfastate_t *state = spot->entry.array[i];
-        if (hash != state->hash)
-          continue;
-        if (re_node_set_compare (&state->nodes, nodes))
-          return state;
-      }
 
   /* There are no appropriate state in the dfa, create the new one.  */
   new_state = create_ci_newstate (dfa, nodes, hash);
-  if (new_state != NULL)
+  if (BE (new_state != NULL, 1))
     return new_state;
   else
     {
@@ -953,27 +939,18 @@ re_acquire_state_context (err, dfa, nodes, context)
   hash = calc_state_hash (nodes, context);
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
 
-  if (spot->alloc == 0)
+  for (i = 0 ; i < spot->num ; i++)
     {
-      /* Currently there are only one state in this spot.  */
-      if (spot->entry.state != NULL && hash == spot->entry.state->hash
-          && re_node_set_compare (&spot->entry.state->nodes, nodes)
-          && spot->entry.state->context == context)
-        return spot->entry.state;
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+        continue;
+      if (re_node_set_compare (state->entrance_nodes, nodes)
+          && state->context == context)
+        return state;
     }
-  else
-    for (i = 0 ; i < spot->num ; i++)
-      {
-        re_dfastate_t *state = spot->entry.array[i];
-        if (hash != state->hash)
-          continue;
-        if (re_node_set_compare (state->entrance_nodes, nodes)
-            && state->context == context)
-          return state;
-      }
   /* There are no appropriate state in `dfa', create the new one.  */
   new_state = create_cd_newstate (dfa, nodes, context, hash);
-  if (new_state != NULL)
+  if (BE (new_state != NULL, 1))
     return new_state;
   else
     {
@@ -993,7 +970,7 @@ create_newstate_common (dfa, nodes, hash)
 {
   re_dfastate_t *newstate;
   newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   re_node_set_init_copy (&newstate->nodes, nodes);
   newstate->trtable = NULL;
@@ -1016,27 +993,12 @@ register_state (dfa, newstate, hash)
 
   if (spot->alloc <= spot->num)
     {
-      re_dfastate_t **new_array;
-
-      /* XXX Is spot->entry.array == NULL if spot->alloc == 0?  If yes
-	 the if can go away and only realloc is needed.  */
-      if (spot->alloc == 0)
-        {
-          spot->alloc = 4;
-          new_array = re_malloc (re_dfastate_t *, spot->alloc);
-	  if (new_array == NULL)
-            return REG_ESPACE;
-          new_array[0] = spot->entry.state;
-        }
-      else
-        {
-          spot->alloc = 2 * spot->num;
-          new_array = re_realloc (spot->entry.array, re_dfastate_t *,
-                                  spot->alloc);
-        }
-      spot->entry.array = new_array;
+      spot->alloc = 2 * spot->num + 2;
+      spot->array = re_realloc (spot->array, re_dfastate_t *, spot->alloc);
+      if (BE (spot->array == NULL, 0))
+        return REG_ESPACE;
     }
-  spot->entry.array[spot->num++] = newstate;
+  spot->array[spot->num++] = newstate;
   return REG_NOERROR;
 }
 
@@ -1053,7 +1015,7 @@ create_ci_newstate (dfa, nodes, hash)
   reg_errcode_t err;
   re_dfastate_t *newstate;
   newstate = create_newstate_common (dfa, nodes, hash);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   newstate->entrance_nodes = &newstate->nodes;
 
@@ -1098,7 +1060,7 @@ create_cd_newstate (dfa, nodes, context, hash)
   re_dfastate_t *newstate;
 
   newstate = create_newstate_common (dfa, nodes, hash);
-  if (newstate == NULL)
+  if (BE (newstate == NULL, 0))
     return NULL;
   newstate->context = context;
   newstate->entrance_nodes = &newstate->nodes;
@@ -1139,7 +1101,7 @@ create_cd_newstate (dfa, nodes, context, hash)
           if (newstate->entrance_nodes == &newstate->nodes)
             {
               newstate->entrance_nodes = re_malloc (re_node_set, 1);
-	      if (newstate->entrance_nodes == NULL)
+	      if (BE (newstate->entrance_nodes == NULL, 0))
 		return NULL;
               re_node_set_init_copy (newstate->entrance_nodes, nodes);
               nctx_nodes = 0;
diff --git a/posix/regex_internal.h b/posix/regex_internal.h
index 38d68d47c0..f3ae7e1c64 100644
--- a/posix/regex_internal.h
+++ b/posix/regex_internal.h
@@ -360,11 +360,7 @@ struct re_state_table_entry
 {
   int num;
   int alloc;
-  union
-  {
-    re_dfastate_t *state;
-    re_dfastate_t **array;
-  } entry;
+  re_dfastate_t **array;
 };
 
 struct re_dfa_t
diff --git a/posix/regexec.c b/posix/regexec.c
index dc60e50e70..a069d7d3af 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -176,18 +176,20 @@ re_match (buffer, string, length, start, regs)
     struct re_registers *regs;
 {
   reg_errcode_t result;
-  int i, nregs, rval, eflags = 0;
+  int i, tmp_nregs, nregs, rval, eflags = 0;
   regmatch_t *pmatch;
 
   eflags |= (buffer->not_bol) ? REG_NOTBOL : 0;
   eflags |= (buffer->not_eol) ? REG_NOTEOL : 0;
 
   /* We need at least 1 register.  */
-  nregs = ((regs == NULL) ? 1
-           : ((regs->num_regs > buffer->re_nsub) ? buffer->re_nsub + 1
-              : regs->num_regs + 1));
+  tmp_nregs = ((buffer->no_sub || regs == NULL || regs->num_regs < 1) ? 1
+               : regs->num_regs);
+  nregs = ((tmp_nregs < buffer->re_nsub + 1
+            && buffer->regs_allocated == REGS_FIXED) ? tmp_nregs
+           : buffer->re_nsub + 1);
   pmatch = re_malloc (regmatch_t, nregs);
-  if (pmatch == NULL)
+  if (BE (pmatch == NULL, 0))
     return -2;
   result = re_search_internal (buffer, string, length, start, 0,
                                nregs, pmatch, eflags);
@@ -200,11 +202,10 @@ re_match (buffer, string, length, start, regs)
         { /* No.  So allocate them with malloc.  We need one
              extra element beyond `num_regs' for the `-1' marker
              GNU code uses.  */
-          regs->num_regs = ((RE_NREGS > buffer->re_nsub + 1) ? RE_NREGS
-                            : buffer->re_nsub + 1);
+          regs->num_regs = buffer->re_nsub + 1;
           regs->start = re_malloc (regoff_t, regs->num_regs);
           regs->end = re_malloc (regoff_t, regs->num_regs);
-          if (regs->start == NULL || regs->end == NULL)
+          if (BE (regs->start == NULL || regs->end == NULL, 0))
             {
               re_free (pmatch);
               return -2;
@@ -220,7 +221,7 @@ re_match (buffer, string, length, start, regs)
               regs->num_regs = buffer->re_nsub + 1;
               regs->start = re_realloc (regs->start, regoff_t, regs->num_regs);
               regs->end = re_realloc (regs->end, regoff_t, regs->num_regs);
-              if (regs->start == NULL || regs->end == NULL)
+              if (BE (regs->start == NULL || regs->end == NULL, 0))
                 {
                   re_free (pmatch);
                   return -2;
@@ -238,7 +239,9 @@ re_match (buffer, string, length, start, regs)
   /* Restore registers.  */
   if (regs != NULL)
     {
-      for (i = 0; i <= nregs; ++i)
+      int max_regs = ((regs->num_regs < buffer->re_nsub + 1) ? regs->num_regs
+                      : buffer->re_nsub + 1);
+      for (i = 0; i < max_regs; ++i)
         {
           regs->start[i] = pmatch[i].rm_so;
           regs->end[i] = pmatch[i].rm_eo;
@@ -279,7 +282,7 @@ re_match_2 (buffer, string1, length1, string2, length2, start, regs, stop)
 {
   int len, ret;
   char *str = re_malloc (char, length1 + length2);
-  if (str == NULL)
+  if (BE (str == NULL, 0))
     return -2;
   memcpy (str, string1, length1);
   memcpy (str + length1, string2, length2);
@@ -303,21 +306,25 @@ re_search (bufp, string, size, startpos, range, regs)
      struct re_registers *regs;
 {
   reg_errcode_t result;
-  int i, nregs, real_range, rval, eflags = 0;
+  int i, tmp_nregs, nregs, real_range, rval, eflags = 0;
   regmatch_t *pmatch;
 
   eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
   eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
 
   /* Check for out-of-range.  */
-  if (startpos < 0 || startpos > size)
+  if (BE (startpos < 0 || startpos > size, 0))
     return -1;
 
   /* We need at least 1 register.  */
-  nregs = ((regs == NULL) ? 1
-           : ((regs->num_regs > bufp->re_nsub) ? bufp->re_nsub + 1
-              : regs->num_regs + 1));
+  tmp_nregs = ((bufp->no_sub || regs == NULL || regs->num_regs < 1) ? 1
+               : regs->num_regs);
+  nregs = ((tmp_nregs < bufp->re_nsub + 1
+            && bufp->regs_allocated == REGS_FIXED) ? tmp_nregs
+           : bufp->re_nsub + 1);
   pmatch = re_malloc (regmatch_t, nregs);
+  if (BE (pmatch == NULL, 0))
+    return -2;
 
   /* Correct range if we need.  */
   real_range = ((startpos + range > size) ? size - startpos
@@ -338,11 +345,10 @@ re_search (bufp, string, size, startpos, range, regs)
         { /* No.  So allocate them with malloc.  We need one
              extra element beyond `num_regs' for the `-1' marker
              GNU code uses.  */
-          regs->num_regs = ((RE_NREGS > bufp->re_nsub + 1) ? RE_NREGS
-                            : bufp->re_nsub + 1);
+          regs->num_regs = bufp->re_nsub + 1;
           regs->start = re_malloc (regoff_t, regs->num_regs);
           regs->end = re_malloc (regoff_t, regs->num_regs);
-          if (regs->start == NULL || regs->end == NULL)
+          if (BE (regs->start == NULL || regs->end == NULL, 0))
             {
               re_free (pmatch);
               return -2;
@@ -358,7 +364,7 @@ re_search (bufp, string, size, startpos, range, regs)
               regs->num_regs = bufp->re_nsub + 1;
               regs->start = re_realloc (regs->start, regoff_t, regs->num_regs);
               regs->end = re_realloc (regs->end, regoff_t, regs->num_regs);
-              if (regs->start == NULL || regs->end == NULL)
+              if (BE (regs->start == NULL || regs->end == NULL, 0))
                 {
                   re_free (pmatch);
                   return -2;
@@ -376,7 +382,9 @@ re_search (bufp, string, size, startpos, range, regs)
   /* Restore registers.  */
   if (regs != NULL)
     {
-      for (i = 0; i <= bufp->re_nsub; ++i)
+      int max_regs = ((regs->num_regs < bufp->re_nsub + 1) ? regs->num_regs
+                      : bufp->re_nsub + 1);
+      for (i = 0; i < max_regs; ++i)
         {
           regs->start[i] = pmatch[i].rm_so;
           regs->end[i] = pmatch[i].rm_eo;
@@ -522,9 +530,9 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
                    ? preg->fastmap : NULL);
 
   /* Check if the DFA haven't been compiled.  */
-  if (preg->used == 0 || dfa->init_state == NULL
-      || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-      || dfa->init_state_begbuf == NULL)
+  if (BE (preg->used == 0 || dfa->init_state == NULL
+          || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+          || dfa->init_state_begbuf == NULL, 0))
     return REG_NOMATCH;
 
   re_node_set_init_empty (&empty_set);
@@ -539,7 +547,7 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
   if (nmatch > 1 || dfa->has_mb_node)
     {
       state_log = re_malloc (re_dfastate_t *, length + 1);
-      if (state_log == NULL)
+      if (BE (state_log == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -549,11 +557,11 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
     err = re_string_construct_toupper (&input, string, length, preg->translate);
   else
     err = re_string_construct (&input, string, length, preg->translate);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
 #ifdef DEBUG
@@ -581,7 +589,7 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
                                            match_first, 0, fl_longest_match);
               if (match_last != -1)
                 {
-                  if (match_last == -2)
+                  if (BE (match_last == -2, 0))
                     return REG_ESPACE;
                   else
                     break; /* We found a matching.  */
@@ -627,11 +635,11 @@ re_search_internal (preg, string, length, start, range, nmatch, pmatch, eflags)
           halt_node = check_halt_state_context (preg, pstate, &input,
                                                 match_last, eflags);
           err = sift_states_backward (preg, state_log, &mctx, &input, halt_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
           err = set_regs (preg, state_log, &mctx, &input, nmatch, pmatch,
                           halt_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
     }
@@ -707,7 +715,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
   cur_state = acquire_init_state_context (&err, preg, input, start_idx,
                                           mctx->eflags);
   /* An initial state must not be NULL(invalid state).  */
-  if (cur_state == NULL)
+  if (BE (cur_state == NULL, 0))
     return -2;
   if (state_log != NULL)
     state_log[start_idx] = cur_state;
@@ -735,7 +743,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
       if (cur_state == NULL) /* Reached at the invalid state or an error.  */
         {
           int cur_str_idx = re_string_cur_idx (input);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return -2;
           if (fl_search && !match)
             {
@@ -747,7 +755,7 @@ check_matching (preg, input, mctx, state_log, start_idx, fl_search,
                 cur_state = acquire_init_state_context (&err, preg, input,
                                                         cur_str_idx,
                                                         mctx->eflags);
-              if (cur_state == NULL && err != REG_NOERROR)
+              if (BE (cur_state == NULL && err != REG_NOERROR, 0))
                 return -2;
               if (state_log != NULL)
                 state_log[cur_str_idx] = cur_state;
@@ -853,7 +861,7 @@ proceed_next_node (preg, state_log, mctx, input, pidx, node, eps_via_nodes)
   if (IS_EPSILON_NODE (dfa->nodes[node].type))
     {
       err = re_node_set_insert (eps_via_nodes, node);
-      if (err < 0)
+      if (BE (err < 0, 0))
         return -1;
       for (i = 0; i < state_log[*pidx]->nodes.nelem; ++i)
         {
@@ -896,7 +904,7 @@ proceed_next_node (preg, state_log, mctx, input, pidx, node, eps_via_nodes)
           if (naccepted == 0)
             {
               err = re_node_set_insert (eps_via_nodes, node);
-              if (err < 0)
+              if (BE (err < 0, 0))
                 return -1;
               dest_node = dfa->nexts[node];
               if (re_node_set_contains (&state_log[*pidx]->nodes, dest_node))
@@ -996,7 +1004,7 @@ set_regs (preg, state_log, mctx, input, nmatch, pmatch, last_node)
       /* Proceed to next node.  */
       cur_node = proceed_next_node (preg, state_log, mctx, input, &idx,
                                     cur_node, &eps_via_nodes);
-      if (cur_node < 0)
+      if (BE (cur_node < 0, 0))
         return REG_ESPACE;
     }
   re_node_set_free (&eps_via_nodes);
@@ -1046,26 +1054,26 @@ sift_states_backward (preg, state_log, mctx, input, last_node)
   assert (state_log != NULL && state_log[str_idx] != NULL);
 #endif
   err = re_node_set_alloc (&state_buf, NUMBER_OF_STATE);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
   plog = &state_log[str_idx]->nodes;
 
   /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
      transit to the last_node and the last_node itself.  */
   err = re_node_set_intersect (&state_buf, plog, dfa->inveclosures + last_node);
-  if (err != REG_NOERROR)
+  if (BE (err != REG_NOERROR, 0))
     return err;
 
   if (state_log[str_idx] != NULL && state_log[str_idx]->has_backref)
     {
       err = add_epsilon_backreference (dfa, mctx, plog, str_idx, &state_buf);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
     }
 
   /* Update state log.  */
   state_log[str_idx] = re_acquire_state (&err, dfa, &state_buf);
-  if (state_log[str_idx] == NULL && err != REG_NOERROR)
+  if (BE (state_log[str_idx] == NULL && err != REG_NOERROR, 0))
     return err;
 
   /* Then check each states in the state_log.  */
@@ -1129,19 +1137,19 @@ sift_states_backward (preg, state_log, mctx, input, last_node)
              then we use plog->elems[i] instead.  */
           err = re_node_set_add_intersect (&state_buf, plog,
                                            dfa->inveclosures + prev_node);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
       if (state_log[str_idx] != NULL && state_log[str_idx]->has_backref)
         {
           err = add_epsilon_backreference (dfa, mctx, plog, str_idx, &state_buf);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
 
       /* Update state_log.  */
       state_log[str_idx] = re_acquire_state (&err, dfa, &state_buf);
-      if (state_log[str_idx] == NULL && err != REG_NOERROR)
+      if (BE (state_log[str_idx] == NULL && err != REG_NOERROR, 0))
         return err;
     }
 
@@ -1241,7 +1249,7 @@ add_epsilon_backreference (dfa, mctx, plog, idx, state_buf)
               reg_errcode_t err;
               err = re_node_set_add_intersect (state_buf, plog,
                                                dfa->inveclosures + node_idx);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return err;
               i = 0;
             }
@@ -1282,7 +1290,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
       if (state->accept_mb)
         {
           *err = transit_state_mb (preg, state, input, state_log, mctx);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
 
@@ -1307,7 +1315,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
           /* don't use transition table  */
           next_state = transit_state_sb (err, preg, state, input, fl_search,
                                          mctx);
-          if (next_state == NULL && err != REG_NOERROR)
+          if (BE (next_state == NULL && err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1341,7 +1349,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
               table_nodes = next_state->entrance_nodes;
               *err = re_node_set_init_union (&next_nodes, table_nodes,
                                              log_nodes);
-              if (*err != REG_NOERROR)
+              if (BE (*err != REG_NOERROR, 0))
                 return NULL;
             }
           else
@@ -1363,7 +1371,7 @@ transit_state (err, preg, state, input, fl_search, state_log, mctx)
       if (next_state != NULL && next_state->has_backref)
         {
           *err = transit_state_bkref (preg, next_state, input, state_log, mctx);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
           next_state = state_log[cur_idx];
         }
@@ -1392,7 +1400,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
   unsigned int context;
 
   *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
-  if (*err != REG_NOERROR)
+  if (BE (*err != REG_NOERROR, 0))
     return NULL;
   for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
     {
@@ -1402,7 +1410,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
         {
           *err = re_node_set_merge (&next_nodes,
                                     dfa->eclosures + dfa->nexts[cur_node]);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1422,7 +1430,7 @@ transit_state_sb (err, preg, state, input, fl_search, mctx)
         {
           *err = re_node_set_merge (&next_nodes,
                                     dfa->init_state->entrance_nodes);
-          if (*err != REG_NOERROR)
+          if (BE (*err != REG_NOERROR, 0))
             return NULL;
         }
     }
@@ -1490,14 +1498,14 @@ transit_state_mb (preg, pstate, input, state_log, mctx)
         {
           err = re_node_set_init_union (&dest_nodes,
                                         dest_state->entrance_nodes, new_nodes);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
       context = re_string_context_at (input, dest_idx - 1, mctx->eflags,
                                       preg->newline_anchor);
       state_log[dest_idx] = re_acquire_state_context (&err, dfa, &dest_nodes,
                                                       context);
-      if (state_log[dest_idx] == NULL && err != REG_NOERROR)
+      if (BE (state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
         return err;
       if (dest_state != NULL)
         re_node_set_free (&dest_nodes);
@@ -1519,7 +1527,7 @@ transit_state_bkref (preg, pstate, input, state_log, mctx)
   assert (mctx->match_first != -1);
 #endif
   work_state_log = re_malloc (re_dfastate_t *, re_string_cur_idx (input) + 1);
-  if (work_state_log == NULL)
+  if (BE (work_state_log == NULL, 0))
     return REG_ESPACE;
 
   err = transit_state_bkref_loop (preg, input, &pstate->nodes, work_state_log,
@@ -1543,7 +1551,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
   int i, j;
   regmatch_t *cur_regs = re_malloc (regmatch_t, preg->re_nsub + 1);
   int cur_str_idx = re_string_cur_idx (input);
-  if (cur_regs == NULL)
+  if (BE (cur_regs == NULL, 0))
     return REG_ESPACE;
 
   for (i = 0; i < nodes->nelem; ++i)
@@ -1600,7 +1608,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
       /* Successfully matched, add a new cache entry.  */
       dest_str_idx = cur_str_idx + subexp_len;
       err = match_ctx_add_entry (mctx, node_idx, cur_str_idx, dest_str_idx);
-      if (err != REG_NOERROR)
+      if (BE (err != REG_NOERROR, 0))
         return err;
       clean_state_log_if_need (state_log, mctx, dest_str_idx);
 
@@ -1625,7 +1633,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
           state_log[dest_str_idx] = re_acquire_state_context (&err, dfa,
                                                               new_dest_nodes,
                                                               context);
-          if (state_log[dest_str_idx] == NULL && err != REG_NOERROR)
+          if (BE (state_log[dest_str_idx] == NULL && err != REG_NOERROR, 0))
             return err;
         }
       else
@@ -1633,12 +1641,12 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
           re_node_set dest_nodes;
           err = re_node_set_init_union (&dest_nodes, dest_state->entrance_nodes,
                                         new_dest_nodes);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
           state_log[dest_str_idx] = re_acquire_state_context (&err, dfa,
                                                               &dest_nodes,
                                                               context);
-          if (state_log[dest_str_idx] == NULL && err != REG_NOERROR)
+          if (BE (state_log[dest_str_idx] == NULL && err != REG_NOERROR, 0))
             return err;
           re_node_set_free (&dest_nodes);
         }
@@ -1649,7 +1657,7 @@ transit_state_bkref_loop (preg, input, nodes, work_state_log, state_log, mctx)
         {
           err = transit_state_bkref_loop (preg, input, new_dest_nodes,
                                           work_state_log, state_log, mctx);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return err;
         }
     }
@@ -1684,13 +1692,13 @@ build_trtable (preg, state, fl_search)
 
   /* Initialize transiton table.  */
   trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
-  if (dests_node == NULL || dests_ch == NULL || trtable == NULL)
+  if (BE (dests_node == NULL || dests_ch == NULL || trtable == NULL, 0))
     return NULL;
 
   /* At first, group all nodes belonging to `state' into several
      destinations.  */
   ndests = group_nodes_into_DFAstates (preg, state, dests_node, dests_ch);
-  if (ndests <= 0)
+  if (BE (ndests <= 0, 0))
     {
       re_free (dests_node);
       re_free (dests_ch);
@@ -1704,8 +1712,8 @@ build_trtable (preg, state, fl_search)
   bitset_empty (acceptable);
 
   err = re_node_set_alloc (&follows, ndests + 1);
-  if (dest_states == NULL || dest_states_word == NULL || dest_states_nl == NULL
-      || err != REG_NOERROR)
+  if (BE (dest_states == NULL || dest_states_word == NULL
+          || dest_states_nl == NULL || err != REG_NOERROR, 0))
     return NULL;
 
   /* Then build the states for all destinations.  */
@@ -1720,7 +1728,7 @@ build_trtable (preg, state, fl_search)
           if (next_node != -1)
             {
               err = re_node_set_merge (&follows, dfa->eclosures + next_node);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return NULL;
             }
         }
@@ -1740,12 +1748,12 @@ build_trtable (preg, state, fl_search)
             {
               err = re_node_set_merge (&follows,
                                        dfa->init_state->entrance_nodes);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return NULL;
             }
         }
       dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
-      if (dest_states[i] == NULL && err != REG_NOERROR)
+      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
         return NULL;
       /* If the new state has context constraint,
          build appropriate states for these contexts.  */
@@ -1753,11 +1761,11 @@ build_trtable (preg, state, fl_search)
         {
           dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
                                                           CONTEXT_WORD);
-          if (dest_states_word[i] == NULL && err != REG_NOERROR)
+          if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
             return NULL;
           dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
                                                         CONTEXT_NEWLINE);
-          if (dest_states_nl[i] == NULL && err != REG_NOERROR)
+          if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
             return NULL;
         }
       else
@@ -1915,14 +1923,14 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
               bitset_copy (dests_ch[ndests], remains);
               bitset_copy (dests_ch[j], intersec);
               err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
-              if (err != REG_NOERROR)
+              if (BE (err != REG_NOERROR, 0))
                 return -1;
               ++ndests;
             }
 
           /* Put the position in the current group. */
           err = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-          if (err < 0)
+          if (BE (err < 0, 0))
             return -1;
 
           /* If all characters are consumed, go to next node. */
@@ -1934,7 +1942,7 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
         {
           bitset_copy (dests_ch[ndests], accepts);
           err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
-          if (err != REG_NOERROR)
+          if (BE (err != REG_NOERROR, 0))
             return -1;
           ++ndests;
           bitset_empty (accepts);
@@ -2209,7 +2217,7 @@ match_ctx_init (mctx, eflags, n)
   if (n > 0)
     {
       mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
-      if (mctx->bkref_ents == NULL)
+      if (BE (mctx->bkref_ents == NULL, 0))
         return REG_ESPACE;
     }
   else
@@ -2239,7 +2247,7 @@ match_ctx_add_entry (mctx, node, from, to)
       mctx->bkref_ents = re_realloc (mctx->bkref_ents,
                                      struct re_backref_cache_entry,
                                      mctx->abkref_ents * 2);
-      if (mctx->bkref_ents == NULL)
+      if (BE (mctx->bkref_ents == NULL, 0))
         return REG_ESPACE;
       memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
              sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);