[clang] [Clang] Produce determenistic hash for anonymous namespaces. (PR #194542)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 22:11:49 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vladimir Vereschaka (vvereschaka)

<details>
<summary>Changes</summary>

This change adds a path substitution for the main module file during anonymous namespace hash generation using the prefix map specified by -fmacro-prefix-map option. That ensures deterministic symbol mangling for reproducible builds.

---
Full diff: https://github.com/llvm/llvm-project/pull/194542.diff


2 Files Affected:

- (modified) clang/lib/AST/MicrosoftMangle.cpp (+7-1) 
- (added) clang/test/AST/anon-ns-determ-hash.cpp (+9) 


``````````diff
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 20c52969d7024..7d0c60d57253c 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -29,6 +29,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CRC.h"
@@ -503,8 +504,13 @@ MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,
   // which are something like "?A0x01234567@".
   SourceManager &SM = Context.getSourceManager();
   if (OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getMainFileID())) {
+    SmallString<256> Path(FE->getName());
+    // Do a path substitution from the MacroPrefixMap if needed.
+    clang::Preprocessor::processPathForFileMacro(Path, Context.getLangOpts(),
+                                                 Context.getTargetInfo());
+
     // Truncate the hash so we get 8 characters of hexadecimal.
-    uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));
+    uint32_t TruncatedHash = uint32_t(xxh3_64bits(Path));
     AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);
   } else {
     // If we don't have a path to the main file, we'll just use 0.
diff --git a/clang/test/AST/anon-ns-determ-hash.cpp b/clang/test/AST/anon-ns-determ-hash.cpp
new file mode 100644
index 0000000000000..aa16455d80154
--- /dev/null
+++ b/clang/test/AST/anon-ns-determ-hash.cpp
@@ -0,0 +1,9 @@
+// Check anonymous namespace deterministic hash generation.
+// RUN: %clang_cc1 -std=c++2a -ast-dump=json -fmacro-prefix-map=%p=/static-path %s | FileCheck %s
+
+namespace {
+    int internal_ns_var = 0;
+} 
+
+// The 0xA110234F hash value must be identical on any system with proper path substitution.
+// CHECK: "mangledName": "?internal_ns_var@?A0xA110234F@@3HA",

``````````

</details>


https://github.com/llvm/llvm-project/pull/194542


More information about the cfe-commits mailing list