diff --git a/src/commands.c b/src/commands.c
index ee9c5367..644fe43b 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -58,10 +58,13 @@ dep_hash_cmp (const void *x, const void *y)
   return strcmp (dep_name (dx), dep_name (dy));
 }
 
-/* Set FILE's automatic variables up.  */
+/* Set FILE's automatic variables up.
+ * Use STEM to set $*.
+ * If STEM is 0, then set FILE->STEM and $* to the target name with any
+ * suffix in the .SUFFIXES list stripped off.  */
 
 void
-set_file_variables (struct file *file)
+set_file_variables (struct file *file, const char *stem)
 {
   struct dep *d;
   const char *at, *percent, *star, *less;
@@ -95,7 +98,7 @@ set_file_variables (struct file *file)
     }
 
   /* $* is the stem from an implicit or static pattern rule.  */
-  if (file->stem == 0)
+  if (stem == 0)
     {
       /* In Unix make, $* is set to the target name with
          any suffix in the .SUFFIXES list stripped off for
@@ -121,14 +124,14 @@ set_file_variables (struct file *file)
           size_t slen = strlen (dep_name (d));
           if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
             {
-              file->stem = strcache_add_len (name, len - slen);
+              file->stem = stem = strcache_add_len (name, len - slen);
               break;
             }
         }
       if (d == 0)
-        file->stem = "";
+        file->stem = stem = "";
     }
-  star = file->stem;
+  star = stem;
 
   /* $< is the first not order-only dependency.  */
   less = "";
@@ -464,7 +467,7 @@ execute_file_commands (struct file *file)
 
   initialize_file_variables (file, 0);
 
-  set_file_variables (file);
+  set_file_variables (file, file->stem);
 
   /* If this is a loaded dynamic object, unload it before remaking.
      Some systems don't support overwriting a loaded object.  */
diff --git a/src/commands.h b/src/commands.h
index 055624ba..c10f42d9 100644
--- a/src/commands.h
+++ b/src/commands.h
@@ -39,4 +39,4 @@ void execute_file_commands (struct file *file);
 void print_commands (const struct commands *cmds);
 void delete_child_targets (struct child *child);
 void chop_commands (struct commands *cmds);
-void set_file_variables (struct file *file);
+void set_file_variables (struct file *file, const char *stem);
diff --git a/src/file.c b/src/file.c
index 2afad872..cf5842ed 100644
--- a/src/file.c
+++ b/src/file.c
@@ -571,7 +571,6 @@ expand_deps (struct file *f)
 {
   struct dep *d;
   struct dep **dp;
-  const char *file_stem = f->stem;
   int initialized = 0;
 
   f->updating = 0;
@@ -614,16 +613,10 @@ expand_deps (struct file *f)
           initialized = 1;
         }
 
-      if (d->stem != 0)
-        f->stem = d->stem;
-
-      set_file_variables (f);
+      set_file_variables (f, d->stem ? d->stem : f->stem);
 
       p = variable_expand_for_file (d->name, f);
 
-      if (d->stem != 0)
-        f->stem = file_stem;
-
       /* At this point we don't need the name anymore: free it.  */
       free (name);
 
diff --git a/src/implicit.c b/src/implicit.c
index b7f5d9ce..a6fd222c 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -521,10 +521,6 @@ pattern_search (struct file *file, int archive,
           if (rule->deps == 0)
             break;
 
-          /* Temporary assign STEM to file->stem (needed to set file
-             variables below).   */
-          file->stem = stem_str;
-
           /* Mark this rule as in use so a recursive pattern_search won't try
              to use it.  */
           rule->in_use = 1;
@@ -666,14 +662,14 @@ pattern_search (struct file *file, int archive,
                   if (!file_vars_initialized)
                     {
                       initialize_file_variables (file, 0);
-                      set_file_variables (file);
+                      set_file_variables (file, stem_str);
                       file_vars_initialized = 1;
                     }
                   /* Update the stem value in $* for this rule.  */
                   else if (!file_variables_set)
                     {
                       define_variable_for_file (
-                        "*", 1, file->stem, o_automatic, 0, file);
+                        "*", 1, stem_str, o_automatic, 0, file);
                       file_variables_set = 1;
                     }
 
@@ -913,10 +909,6 @@ pattern_search (struct file *file, int archive,
                 break;
             }
 
-          /* Reset the stem in FILE. */
-
-          file->stem = 0;
-
           /* This rule is no longer 'in use' for recursive searches.  */
           rule->in_use = 0;
 
