]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Fix bad calculation of object hash in the depend mode
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 10 Apr 2019 20:22:24 +0000 (22:22 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 10 Apr 2019 20:22:24 +0000 (22:22 +0200)
When the depend mode is enabled, there is a code path where the direct
mode hash state is finalized and then more bytes are fed into it to
create a hash sum for the depend mode. The effect is that the last 0-63
bytes (depending on the number of previously hashed bytes) of the data
used for the depend mode will be ignored, which means that the contents
of the last 0-2 or so header files in the .d file are not accounted for
in the object hash used in the depend mode.

Fix this by making a copy of the direct mode hash state before computing
the hash result in calculate_object_hash().

Fixes #374.

doc/NEWS.adoc
src/ccache.c

index 1d84cc06f17a61458fe437e77be770592dc0fe69..4a81f2d24c0e5f2c094ac361367b3ff43b8e1ab6 100644 (file)
@@ -21,11 +21,14 @@ Changes
 * ccache now knows how to contruct the object filename if no `-o` option is
   given and the source filename does not include a `.` or ends with a `.`.
 
-* Fixed a temporary file leak when depend mode is enabled and the compiler
+* Fixed a bug in the depend mode where the last couple of include files in the
+  `.d` file was not taken into account.
+
+* Fixed a temporary file leak when the depend mode is enabled and the compiler
   produces standard error output.
 
-* Fixed a bug in the “depend mode” where a manifest hash only could be
-  associated with one set of header dependencies.
+* Fixed a bug in the depend mode where a manifest hash only could be associated
+  with one set of header dependencies.
 
 * Manifest files did not get marked as used on direct cache hits, so the LRU
   cache cleanup would incorrectly remove them eventually. This has now been
index 970497e90dc756ccd4d2b23411acdb74e10552ca..7c0427f4e07082f8818c7427a7bcd890c5e94d74 100644 (file)
@@ -2151,9 +2151,15 @@ calculate_object_hash(struct args *args, struct hash *hash, int direct_mode)
                        conf->direct_mode = false;
                        return NULL;
                }
-               char *manifest_name = hash_result(hash);
+
+               // We can't finalize hash here since its current state may be used by the
+               // depend mode code later, so make a copy.
+               struct hash *hash2 = hash_copy(hash);
+               char *manifest_name = hash_result(hash2);
+               hash_free(hash2);
                manifest_path = get_path_in_cache(manifest_name, ".manifest");
                free(manifest_name);
+
                cc_log("Looking for object file hash in %s", manifest_path);
                object_hash = manifest_get(conf, manifest_path);
                if (object_hash) {