[clang] b7cc3c5 - [C++20][Modules] Do not apply `getAdjustedOffset` to file-internal byte offset. (#184956)

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 6 08:44:45 PST 2026


Author: Michael Park
Date: 2026-03-06T08:44:39-08:00
New Revision: b7cc3c5682f9eca27b836dcb13cab97dbb5db626

URL: https://github.com/llvm/llvm-project/commit/b7cc3c5682f9eca27b836dcb13cab97dbb5db626
DIFF: https://github.com/llvm/llvm-project/commit/b7cc3c5682f9eca27b836dcb13cab97dbb5db626.diff

LOG: [C++20][Modules] Do not apply `getAdjustedOffset` to file-internal byte offset. (#184956)

In https://reviews.llvm.org/D137214 and
https://reviews.llvm.org/D136624, offset adjustment logic was added to
account for the non-affecting module map files that are removed. While
the adjustment logic applies to global source location offsets, they do
not apply to file-internal offsets (relative within the file).

In `ASTWriter::WritePragmaDiagnosticMappings`, the adjustment is applied
to `StatePoint.Offset`s in `StateTransitions`. However, these offsets
are file-internal offsets, not global source location offsets. As such,
applying adjustment to these offsets result in incorrect diagnostic
behavior from the module.

Specifically, wrapping a piece of code in `pragma clang diagnostic
push/pop`, inside of a module is not applied correctly. A new test case
`diag-pragma-nonaffecting.cpp` was added to verify the broken behavior
as well as the corrected behavior with this commit.

Assisted-by: Claude Opus 4.6

Added: 
    clang/test/Modules/diag-pragma-nonaffecting.cpp

Modified: 
    clang/lib/Serialization/ASTWriter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 814f4e42e9c9b..ec718169550aa 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3357,7 +3357,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
 
     Record.push_back(FileIDAndFile.second.StateTransitions.size());
     for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
-      Record.push_back(getAdjustedOffset(StatePoint.Offset));
+      Record.push_back(StatePoint.Offset);
       AddDiagState(StatePoint.State, false);
     }
   }

diff  --git a/clang/test/Modules/diag-pragma-nonaffecting.cpp b/clang/test/Modules/diag-pragma-nonaffecting.cpp
new file mode 100644
index 0000000000000..e6d70a5040775
--- /dev/null
+++ b/clang/test/Modules/diag-pragma-nonaffecting.cpp
@@ -0,0 +1,50 @@
+// Test that pragma diagnostic mappings from an explicit module are not
+// corrupted by the presence of non-affecting module map files.
+//
+// When non-affecting module map files are pruned, NonAffectingRanges becomes
+// non-empty. Ensure that getAdjustedOffset is not incorrectly applied to
+// file-internal byte offsets in WritePragmaDiagnosticMappings, corrupting the
+// serialized diagnostic state transition offsets.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Build the module with a non-affecting module map present.
+// RUN: %clang_cc1 -std=c++20 -fmodules \
+// RUN:   -fmodule-map-file=%t/nonaffecting/module.modulemap \
+// RUN:   -emit-module -fmodule-name=diag_pragma \
+// RUN:   -x c++ %t/module.modulemap -o %t/diag_pragma.pcm
+
+// Use the module and verify the warning is suppressed.
+// RUN: %clang_cc1 -std=c++20 -fmodules \
+// RUN:   -fmodule-file=%t/diag_pragma.pcm \
+// RUN:   -I %t -verify %t/main.cpp
+
+//--- module.modulemap
+module diag_pragma { header "header.h" }
+
+//--- header.h
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+template<typename T> const char *suppressed(T t) {
+  return "foo" + t;
+}
+#pragma clang diagnostic pop
+
+template<typename T> const char *unsuppressed(T t) {
+  return "bar" + t;
+}
+
+//--- nonaffecting/module.modulemap
+module nonaffecting {}
+
+//--- main.cpp
+#include "header.h"
+
+void test() {
+  suppressed(0);   // no warning expected - suppressed by pragma in module
+
+  // expected-warning at header.h:9 {{adding 'int' to a string}}
+  // expected-note at header.h:9 {{use array indexing}}
+  unsuppressed(0); // expected-note {{in instantiation of}}
+}


        


More information about the cfe-commits mailing list