[llvm] 61e1c3d - [Demangle] convert itaniumDemangle and nonMicrosoftDemangle to use std::string_view

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 2 15:03:01 PDT 2023


Author: Nick Desaulniers
Date: 2023-06-02T14:53:49-07:00
New Revision: 61e1c3d80db6e94e8b5b83b3819afefeec4d357b

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

LOG: [Demangle] convert itaniumDemangle and nonMicrosoftDemangle to use std::string_view

D149104 converted llvm::demangle to use std::string_view. Enabling
"expensive checks" (via -DLLVM_ENABLE_EXPENSIVE_CHECKS=ON) causes
lld/test/wasm/why-extract.s to fail. The reason for this is obscure:

Reason #10007 why std::string_view is dangerous:
Consider the following pattern:

  std::string_view s = ...;
  const char *c = s.data();
  std::strlen(c);

Is c a NUL-terminated C style string? It depends; but if it's not then
it's not safe to call std::strlen on the std::string_view::data().
std::string_view::length() should be used instead.

Fixing this fixes the one lone test that caught this.

microsoftDemangle, rustDemangle, and dlangDemangle should get this same
treatment, too. I will do that next.

Reviewed By: MaskRay, efriedma

Differential Revision: https://reviews.llvm.org/D149675

Added: 
    

Modified: 
    llvm/include/llvm/Demangle/Demangle.h
    llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
    llvm/lib/Demangle/Demangle.cpp
    llvm/lib/Demangle/ItaniumDemangle.cpp
    llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
    llvm/tools/llvm-nm/llvm-nm.cpp
    llvm/tools/llvm-opt-report/OptReport.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h
index 7dfe609f7b400..1fd286bfad4c0 100644
--- a/llvm/include/llvm/Demangle/Demangle.h
+++ b/llvm/include/llvm/Demangle/Demangle.h
@@ -31,7 +31,7 @@ enum : int {
 /// Returns a non-NULL pointer to a NUL-terminated C style string
 /// that should be explicitly freed, if successful. Otherwise, may return
 /// nullptr if mangled_name is not a valid mangling or is nullptr.
-char *itaniumDemangle(const char *mangled_name);
+char *itaniumDemangle(std::string_view mangled_name);
 
 enum MSDemangleFlags {
   MSDF_None = 0,
@@ -66,7 +66,7 @@ char *dlangDemangle(const char *MangledName);
 /// demangling occurred.
 std::string demangle(const std::string &MangledName);
 
-bool nonMicrosoftDemangle(const char *MangledName, std::string &Result);
+bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result);
 
 /// "Partial" demangler. This supports demangling a string into an AST
 /// (typically an intermediate stage in itaniumDemangle) and querying certain

diff  --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index c5c53baa9c55b..aaee4f11af446 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -679,7 +679,7 @@ std::string
 LLVMSymbolizer::DemangleName(const std::string &Name,
                              const SymbolizableModule *DbiModuleDescriptor) {
   std::string Result;
-  if (nonMicrosoftDemangle(Name.c_str(), Result))
+  if (nonMicrosoftDemangle(Name, Result))
     return Result;
 
   if (!Name.empty() && Name.front() == '?') {
@@ -700,7 +700,7 @@ LLVMSymbolizer::DemangleName(const std::string &Name,
     std::string DemangledCName(demanglePE32ExternCFunc(Name));
     // On i386 Windows, the C name mangling for 
diff erent calling conventions
     // may also be applied on top of the Itanium or Rust name mangling.
-    if (nonMicrosoftDemangle(DemangledCName.c_str(), Result))
+    if (nonMicrosoftDemangle(DemangledCName, Result))
       return Result;
     return DemangledCName;
   }

diff  --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp
index 87603603cb4ac..f83117f3b7e05 100644
--- a/llvm/lib/Demangle/Demangle.cpp
+++ b/llvm/lib/Demangle/Demangle.cpp
@@ -30,10 +30,10 @@ std::string llvm::demangle(const std::string &MangledName) {
   std::string Result;
   const char *S = MangledName.c_str();
 
-  if (nonMicrosoftDemangle(S, Result))
+  if (nonMicrosoftDemangle(MangledName, Result))
     return Result;
 
-  if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
+  if (S[0] == '_' && nonMicrosoftDemangle(MangledName.substr(1), Result))
     return Result;
 
   if (char *Demangled = microsoftDemangle(S, nullptr, nullptr)) {
@@ -45,14 +45,15 @@ std::string llvm::demangle(const std::string &MangledName) {
   return MangledName;
 }
 
-bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
+bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
+                                std::string &Result) {
   char *Demangled = nullptr;
-  if (isItaniumEncoding(MangledName))
+  if (isItaniumEncoding(MangledName.data()))
     Demangled = itaniumDemangle(MangledName);
-  else if (isRustEncoding(MangledName))
-    Demangled = rustDemangle(MangledName);
-  else if (isDLangEncoding(MangledName))
-    Demangled = dlangDemangle(MangledName);
+  else if (isRustEncoding(MangledName.data()))
+    Demangled = rustDemangle(MangledName.data());
+  else if (isDLangEncoding(MangledName.data()))
+    Demangled = dlangDemangle(MangledName.data());
 
   if (!Demangled)
     return false;

diff  --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp
index b1a8832f1b32a..f2ce6ebc13132 100644
--- a/llvm/lib/Demangle/ItaniumDemangle.cpp
+++ b/llvm/lib/Demangle/ItaniumDemangle.cpp
@@ -365,11 +365,12 @@ class DefaultAllocator {
 
 using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
 
-char *llvm::itaniumDemangle(const char *MangledName) {
-  if (!MangledName)
+char *llvm::itaniumDemangle(std::string_view MangledName) {
+  if (MangledName.empty())
     return nullptr;
 
-  Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
+  Demangler Parser(MangledName.data(),
+                   MangledName.data() + MangledName.length());
   Node *AST = Parser.parse();
   if (!AST)
     return nullptr;

diff  --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
index 109c1b27e5872..2bbd57f14d998 100644
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Demangle/Demangle.h"
+#include "llvm/Demangle/StringViewExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -71,10 +72,11 @@ static void error(const Twine &Message) {
 }
 
 static std::string demangle(const std::string &Mangled) {
-  const char *DecoratedStr = Mangled.c_str();
+  using llvm::itanium_demangle::starts_with;
+  std::string_view DecoratedStr = Mangled;
   if (StripUnderscore)
     if (DecoratedStr[0] == '_')
-      ++DecoratedStr;
+      DecoratedStr.remove_prefix(1);
 
   std::string Result;
   if (nonMicrosoftDemangle(DecoratedStr, Result))
@@ -86,9 +88,9 @@ static std::string demangle(const std::string &Mangled) {
   if (Types)
     Undecorated = itaniumDemangle(DecoratedStr);
 
-  if (!Undecorated && strncmp(DecoratedStr, "__imp_", 6) == 0) {
+  if (!Undecorated && starts_with(DecoratedStr, "__imp_")) {
     Prefix = "import thunk for ";
-    Undecorated = itaniumDemangle(DecoratedStr + 6);
+    Undecorated = itaniumDemangle(DecoratedStr.substr(6));
   }
 
   Result = Undecorated ? Prefix + Undecorated : Mangled;

diff  --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index 96baca5476ba6..473f5fd32aa8f 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -639,7 +639,7 @@ static void darwinPrintStab(MachOObjectFile *MachO, const NMSymbol &S) {
 
 static std::optional<std::string> demangle(StringRef Name) {
   std::string Demangled;
-  if (nonMicrosoftDemangle(Name.str().c_str(), Demangled))
+  if (nonMicrosoftDemangle(Name, Demangled))
     return Demangled;
   return std::nullopt;
 }

diff  --git a/llvm/tools/llvm-opt-report/OptReport.cpp b/llvm/tools/llvm-opt-report/OptReport.cpp
index aa7a33d0af839..1a2493857ed15 100644
--- a/llvm/tools/llvm-opt-report/OptReport.cpp
+++ b/llvm/tools/llvm-opt-report/OptReport.cpp
@@ -338,7 +338,7 @@ static bool writeReport(LocationInfoTy &LocationInfo) {
 
             bool Printed = false;
             if (!NoDemangle) {
-              if (char *Demangled = itaniumDemangle(FuncName.c_str())) {
+              if (char *Demangled = itaniumDemangle(FuncName)) {
                 OS << Demangled;
                 Printed = true;
                 std::free(Demangled);


        


More information about the llvm-commits mailing list