[llvm] [llvm-debuginfo-analyzer] Fix ODR violation in llvm::logicalview::LVObject (PR #140265)

Javier Lopez-Gomez via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 13 04:40:31 PDT 2025


https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/140265

>From c62f63e2fb4d313288937cd12d7110351794c96a Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 13 Jun 2025 13:40:17 +0200
Subject: [PATCH 1/3] [llvm-debuginfo-analyzer] Make LVObject::dump()
 non-virtual (NFC)

`LVObject::dump()` does not need to be virtual as it relays to
`LVObject::print()` that is.
---
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h     | 4 ----
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h | 6 +-----
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h   | 2 +-
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h    | 4 ----
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h    | 4 ----
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h   | 4 ----
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h     | 4 ----
 7 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
index c979dc4a6be2e..3618ce7b0ecda 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLine.h
@@ -105,10 +105,6 @@ class LLVM_ABI LVLine : public LVElement {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override {}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 // Class to represent a DWARF line record object.
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
index 7b466ae206e4e..0718e33f5645b 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h
@@ -51,7 +51,7 @@ class LVOperation final {
   LLVM_ABI void print(raw_ostream &OS, bool Full = true) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() { print(dbgs()); }
+  void dump() const { print(dbgs()); }
 #endif
 };
 
@@ -159,10 +159,6 @@ class LLVM_ABI LVLocation : public LVObject {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 class LLVM_ABI LVLocationSymbol final : public LVLocation {
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
index ec02120e69b73..0ef8c78dab976 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
@@ -313,7 +313,7 @@ class LLVM_ABI LVObject {
   virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  virtual void dump() const { print(dbgs()); }
+  void dump() const { print(dbgs()); }
 #endif
 
   uint64_t getID() const {
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
index 07d5813e5b19b..b5c833330e59e 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVRange.h
@@ -87,10 +87,6 @@ class LLVM_ABI LVRange final : public LVObject {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override {}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 } // end namespace logicalview
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 0f536b5c16b96..5715a37185b2b 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -325,10 +325,6 @@ class LLVM_ABI LVScope : public LVElement {
   void printExtra(raw_ostream &OS, bool Full = true) const override;
   virtual void printWarnings(raw_ostream &OS, bool Full = true) const {}
   virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 // Class to represent a DWARF Union/Structure/Class.
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
index 93ca2a73d64dd..ec9017e16b659 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
@@ -183,10 +183,6 @@ class LLVM_ABI LVSymbol final : public LVElement {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 } // end namespace logicalview
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
index cbce9cb65c920..59e6a92be8ce6 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
@@ -146,10 +146,6 @@ class LLVM_ABI LVType : public LVElement {
 
   void print(raw_ostream &OS, bool Full = true) const override;
   void printExtra(raw_ostream &OS, bool Full = true) const override;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  void dump() const override { print(dbgs()); }
-#endif
 };
 
 // Class to represent DW_TAG_typedef_type.

>From 4e25b8935ebb606f71cffed3303008be09e8ff8b Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 13 Jun 2025 13:40:17 +0200
Subject: [PATCH 2/3] [llvm-debuginfo-analyzer][debuginfologicalview] Fix ODR
 violation in LVObject

Fix ODR violation in `LVObject` when `DebugInfoLogicalView` library
is used in a downstream project.

Depending solely on `NDEBUG` for exposing some data members may cause
trouble in downstream projects.
Enable such cases only if `LLVM_ENABLE_ABI_BREAKING_CHECKS`.
---
 llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h | 9 +++++----
 llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp        | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
index 0ef8c78dab976..645b0e79d1055 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
@@ -15,6 +15,7 @@
 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
 
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Config/abi-breaking.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
@@ -155,7 +156,7 @@ class LLVM_ABI LVObject {
   // copy constructor to create that object; it is used to print a reference
   // to another object and in the case of templates, to print its encoded args.
   LVObject(const LVObject &Object) {
-#ifndef NDEBUG
+#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
     incID();
 #endif
     Properties = Object.Properties;
@@ -166,7 +167,7 @@ class LLVM_ABI LVObject {
     Parent = Object.Parent;
   }
 
-#ifndef NDEBUG
+#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
   // This is an internal ID used for debugging logical elements. It is used
   // for cases where an unique offset within the binary input file is not
   // available.
@@ -194,7 +195,7 @@ class LLVM_ABI LVObject {
 
 public:
   LVObject() {
-#ifndef NDEBUG
+#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
     incID();
 #endif
   };
@@ -318,7 +319,7 @@ class LLVM_ABI LVObject {
 
   uint64_t getID() const {
     return
-#ifndef NDEBUG
+#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
         ID;
 #else
         0;
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
index 75acbf3225e08..3d5c2b26fef15 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
@@ -21,7 +21,7 @@ using namespace llvm::logicalview;
 
 #define DEBUG_TYPE "Object"
 
-#ifndef NDEBUG
+#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
 uint64_t LVObject::GID = 0;
 #endif
 

>From db8818da3ac8d595bfbe1060b7b387a71a7b55af Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 13 Jun 2025 13:40:17 +0200
Subject: [PATCH 3/3] [llvm-debuginfo-analyzer][debuginfologicalview] Make
 LVObject::ID unconditional

Make the `LVObject::ID` member unconditional on `NDEBUG` or
`LLVM_ENABLE_ABI_BREAKING_CHECKS`.
Changing size of `ScopeLevel` (uint16_t) and careful reorder of data members in
LVObject (avoding unneeded padding) leaves `sizeof(LVObject)` unchanged w.r.t.
a non-Debug build before.
---
 .../DebugInfo/LogicalView/Core/LVObject.h     | 31 ++++++-------------
 .../DebugInfo/LogicalView/Core/LVObject.cpp   |  4 ---
 .../DebugInfo/LogicalView/Core/LVOptions.cpp  |  2 --
 3 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
index 645b0e79d1055..8510b0703e9da 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h
@@ -37,7 +37,7 @@ namespace logicalview {
 using LVSectionIndex = uint64_t;
 using LVAddress = uint64_t;
 using LVHalf = uint16_t;
-using LVLevel = uint32_t;
+using LVLevel = uint16_t;
 using LVOffset = uint64_t;
 using LVSigned = int64_t;
 using LVUnsigned = uint64_t;
@@ -130,8 +130,6 @@ class LLVM_ABI LVObject {
     HasCodeViewLocation, // CodeView object with debug location.
     LastEntry
   };
-  // Typed bitvector with properties for this object.
-  LVProperties<Property> Properties;
 
   LVOffset Offset = 0;
   uint32_t LineNumber = 0;
@@ -141,6 +139,14 @@ class LLVM_ABI LVObject {
     dwarf::Attribute Attr;
     LVSmall Opcode;
   } TagAttrOpcode = {dwarf::DW_TAG_null};
+  // Typed bitvector with properties for this object.
+  LVProperties<Property> Properties;
+
+  // This is an internal ID used for debugging logical elements. It is used
+  // for cases where an unique offset within the binary input file is not
+  // available.
+  static uint64_t GID;
+  uint64_t ID = 0;
 
   // The parent of this object (nullptr if the root scope). For locations,
   // the parent is a symbol object; otherwise it is a scope object.
@@ -156,9 +162,7 @@ class LLVM_ABI LVObject {
   // copy constructor to create that object; it is used to print a reference
   // to another object and in the case of templates, to print its encoded args.
   LVObject(const LVObject &Object) {
-#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
     incID();
-#endif
     Properties = Object.Properties;
     Offset = Object.Offset;
     LineNumber = Object.LineNumber;
@@ -167,18 +171,10 @@ class LLVM_ABI LVObject {
     Parent = Object.Parent;
   }
 
-#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
-  // This is an internal ID used for debugging logical elements. It is used
-  // for cases where an unique offset within the binary input file is not
-  // available.
-  static uint64_t GID;
-  uint64_t ID = 0;
-
   void incID() {
     ++GID;
     ID = GID;
   }
-#endif
 
 protected:
   // Get a string representation for the given number and discriminator.
@@ -195,9 +191,7 @@ class LLVM_ABI LVObject {
 
 public:
   LVObject() {
-#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
     incID();
-#endif
   };
   LVObject &operator=(const LVObject &) = delete;
   virtual ~LVObject() = default;
@@ -318,12 +312,7 @@ class LLVM_ABI LVObject {
 #endif
 
   uint64_t getID() const {
-    return
-#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
-        ID;
-#else
-        0;
-#endif
+    return ID;
   }
 };
 
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
index 3d5c2b26fef15..dbdbff4df1914 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
@@ -21,9 +21,7 @@ using namespace llvm::logicalview;
 
 #define DEBUG_TYPE "Object"
 
-#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
 uint64_t LVObject::GID = 0;
-#endif
 
 StringRef llvm::logicalview::typeNone() { return StringRef(); }
 StringRef llvm::logicalview::typeVoid() { return "void"; }
@@ -137,10 +135,8 @@ void LVObject::printAttributes(raw_ostream &OS, bool Full, StringRef Name,
 }
 
 void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
-#ifndef NDEBUG
   if (options().getInternalID())
     OS << hexSquareString(getID());
-#endif
   if (options().getCompareExecute() &&
       (options().getAttributeAdded() || options().getAttributeMissing()))
     OS << (getIsAdded() ? '+' : getIsMissing() ? '-' : ' ');
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
index 467bb98670b40..af35e58ac0dd6 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVOptions.cpp
@@ -259,12 +259,10 @@ void LVOptions::resolveDependencies() {
 }
 
 void LVOptions::calculateIndentationSize() {
-#ifndef NDEBUG
   if (getInternalID()) {
     std::string String = hexSquareString(0);
     IndentationSize += String.length();
   }
-#endif
   if (getCompareExecute() && (getAttributeAdded() || getAttributeMissing()))
     ++IndentationSize;
   if (getAttributeOffset()) {



More information about the llvm-commits mailing list