[SV 31155] Parse order-only tokens in second expansion results.
diff --git a/ChangeLog b/ChangeLog
index 816a2ad..e96feef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2013-09-22  Paul Smith  <psmith@gnu.org>
 
+	* implicit.c (pattern_search): After second expansion be sure to
+	handle order-only markers inside the expansion properly.
+	Fixes Savannah bug #31155.
+
 	* guile.c (guile_define_module): Technically a void* cannot
 	contain a pointer-to-function and some compilers warn about this.
 	Cast the function pointers.
diff --git a/implicit.c b/implicit.c
index f0bb385..5fedec0 100644
--- a/implicit.c
+++ b/implicit.c
@@ -574,6 +574,7 @@
                 {
                   int add_dir = 0;
                   unsigned int len;
+                  struct dep **dptr;
 
                   nptr = get_next_word (nptr, &len);
                   if (nptr == 0)
@@ -616,6 +617,9 @@
                         add_dir = 1;
                     }
 
+                  /* Set up for the next word.  */
+                  nptr += len;
+
                   /* Initialize and set file variables if we haven't already
                      done so. */
                   if (!file_vars_initialized)
@@ -634,20 +638,33 @@
 
                   /* Perform the 2nd expansion.  */
                   p = variable_expand_for_file (depname, file);
+                  dptr = &dl;
 
-                  /* Parse the expanded string. */
-                  dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE,
-                                       add_dir ? dir : NULL, PARSEFS_NONE);
-
-                  for (d = dl; d != NULL; d = d->next)
+                  /* Parse the results into a deps list.  */
+                  do
                     {
-                      ++deps_found;
-                      if (order_only)
-                        d->ignore_mtime = 1;
-                    }
+                      /* Parse the expanded string. */
+                      struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
+                                                       order_only ? MAP_NUL : MAP_PIPE,
+                                                       add_dir ? dir : NULL, PARSEFS_NONE);
+                      *dptr = dp;
 
-                  /* Set up for the next word.  */
-                  nptr += len;
+                      for (d = dp; d != NULL; d = d->next)
+                        {
+                          ++deps_found;
+                          if (order_only)
+                            d->ignore_mtime = 1;
+                          dptr = &d->next;
+                        }
+
+                      /* If we stopped due to an order-only token, note it.  */
+                      if (*p == '|')
+                        {
+                          order_only = 1;
+                          ++p;
+                        }
+                    }
+                  while (*p != '\0');
                 }
 
               /* If there are more than max_pattern_deps prerequisites (due to
diff --git a/tests/ChangeLog b/tests/ChangeLog
index ad746d2..eaeb7c0 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,9 @@
 2013-09-22  Paul Smith  <psmith@gnu.org>
 
+	* scripts/features/se_implicit: Verify that order-only tokens
+	inside second expansion are parsed correctly.
+	Test for Savannah bug #31155.
+
 	* run_make_tests.pl (set_more_defaults): If we can't find
 	gnumake.h based on the make program we might be running from a
 	remote build directory.  Parse the Makefile for the right path.
diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit
index 0a31948..ec09d8d 100644
--- a/tests/scripts/features/se_implicit
+++ b/tests/scripts/features/se_implicit
@@ -244,5 +244,17 @@
 
 unlink('a');
 
+# Ensure that order-only tokens embedded in second expansions are parsed
+run_make_test(q!
+.SECONDEXPANSION:
+PREREQS=p1|p2
+P2=p2
+all : foo bar
+f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
+b%r: p1|$$(P2)   ; @echo '$@' from '$^' and '$|'
+p% : ; : $@
+!,
+              "", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
+
 # This tells the test driver that the perl test script executed properly.
 1;