aboutsummaryrefslogtreecommitdiff
path: root/libcxxabi
diff options
context:
space:
mode:
authorLouis Dionne <ldionne.2@gmail.com>2023-11-23 13:21:43 -1000
committerGitHub <noreply@github.com>2023-11-23 18:21:43 -0500
commitc4779ea8e709a7bce7288988fabf1ba50e9c9477 (patch)
tree2ede66030e077f19159ba6c187b461682e36554f /libcxxabi
parent0a9c6bea6b08538e6e910ec13dd83b8f04530835 (diff)
downloadllvm-c4779ea8e709a7bce7288988fabf1ba50e9c9477.zip
llvm-c4779ea8e709a7bce7288988fabf1ba50e9c9477.tar.gz
llvm-c4779ea8e709a7bce7288988fabf1ba50e9c9477.tar.bz2
[libc++abi] Avoid raw calls to assert() in libc++abi (#71121)
The runtimes now have a principled way of doing assertions in relation to hardening, so we should use that instead of raw calls to assert() inside libc++abi. This patch aims to maintain the behavior of the demangler code when it is used from within LLVM by introducing a simple DEMANGLE_ASSERT(...) macro that is then defined to the appropriate assertion mechanism.
Diffstat (limited to 'libcxxabi')
-rw-r--r--libcxxabi/src/abort_message.h11
-rw-r--r--libcxxabi/src/cxa_demangle.cpp6
-rw-r--r--libcxxabi/src/demangle/DemangleConfig.h5
-rw-r--r--libcxxabi/src/demangle/ItaniumDemangle.h27
-rw-r--r--libcxxabi/src/demangle/Utility.h5
-rw-r--r--libcxxabi/src/fallback_malloc.cpp9
-rw-r--r--libcxxabi/test/test_fallback_malloc.pass.cpp2
7 files changed, 43 insertions, 22 deletions
diff --git a/libcxxabi/src/abort_message.h b/libcxxabi/src/abort_message.h
index f1d5c12..9764177 100644
--- a/libcxxabi/src/abort_message.h
+++ b/libcxxabi/src/abort_message.h
@@ -14,4 +14,15 @@
extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
+#ifndef _LIBCXXABI_ASSERT
+# define _LIBCXXABI_ASSERT(expr, msg) \
+ do { \
+ if (!(expr)) { \
+ char const* __msg = (msg); \
+ ::abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
+ } \
+ } while (false)
+
#endif
+
+#endif // __ABORT_MESSAGE_H_
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp
index 6055b2a..bece33a 100644
--- a/libcxxabi/src/cxa_demangle.cpp
+++ b/libcxxabi/src/cxa_demangle.cpp
@@ -10,10 +10,12 @@
// file does not yet support:
// - C++ modules TS
+#include "abort_message.h"
+#define DEMANGLE_ASSERT(expr, msg) _LIBCXXABI_ASSERT(expr, msg)
+
#include "demangle/DemangleConfig.h"
#include "demangle/ItaniumDemangle.h"
#include "__cxxabi_config.h"
-#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
@@ -395,7 +397,7 @@ __cxa_demangle(const char *MangledName, char *Buf, size_t *N, int *Status) {
InternalStatus = demangle_invalid_mangled_name;
else {
OutputBuffer O(Buf, N);
- assert(Parser.ForwardTemplateRefs.empty());
+ DEMANGLE_ASSERT(Parser.ForwardTemplateRefs.empty(), "");
AST->print(O);
O += '\0';
if (N != nullptr)
diff --git a/libcxxabi/src/demangle/DemangleConfig.h b/libcxxabi/src/demangle/DemangleConfig.h
index d5e1143..dec382d 100644
--- a/libcxxabi/src/demangle/DemangleConfig.h
+++ b/libcxxabi/src/demangle/DemangleConfig.h
@@ -99,6 +99,11 @@
#define DEMANGLE_FALLTHROUGH
#endif
+#ifndef DEMANGLE_ASSERT
+#include <cassert>
+#define DEMANGLE_ASSERT(__expr, __msg) assert((__expr) && (__msg))
+#endif
+
#define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle {
#define DEMANGLE_NAMESPACE_END } }
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 2336b84..0ebfc0e 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -21,7 +21,6 @@
#include "Utility.h"
#include <__cxxabi_config.h>
#include <algorithm>
-#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
@@ -129,12 +128,12 @@ public:
// NOLINTNEXTLINE(readability-identifier-naming)
void pop_back() {
- assert(Last != First && "Popping empty vector!");
+ DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
--Last;
}
void shrinkToSize(size_t Index) {
- assert(Index <= size() && "shrinkToSize() can't expand!");
+ DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
Last = First + Index;
}
@@ -144,11 +143,11 @@ public:
bool empty() const { return First == Last; }
size_t size() const { return static_cast<size_t>(Last - First); }
T &back() {
- assert(Last != First && "Calling back() on empty vector!");
+ DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
return *(Last - 1);
}
T &operator[](size_t Index) {
- assert(Index < size() && "Invalid access!");
+ DEMANGLE_ASSERT(Index < size(), "Invalid access!");
return *(begin() + Index);
}
void clear() { Last = First; }
@@ -1678,7 +1677,7 @@ public:
std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
if (isInstantiation()) {
// The instantiations are typedefs that drop the "basic_" prefix.
- assert(starts_with(SV, "basic_"));
+ DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
SV.remove_prefix(sizeof("basic_") - 1);
}
return SV;
@@ -2569,7 +2568,7 @@ void Node::visit(Fn F) const {
return F(static_cast<const X *>(this));
#include "ItaniumNodes.def"
}
- assert(0 && "unknown mangling node kind");
+ DEMANGLE_ASSERT(0, "unknown mangling node kind");
}
/// Determine the kind of a node from its type.
@@ -2611,7 +2610,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
Parser->TemplateParams.push_back(&Params);
}
~ScopedTemplateParamList() {
- assert(Parser->TemplateParams.size() >= OldNumTemplateParamLists);
+ DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
+ "");
Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
}
TemplateParamList *params() { return &Params; }
@@ -2692,7 +2692,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
}
NodeArray popTrailingNodeArray(size_t FromPosition) {
- assert(FromPosition <= Names.size());
+ DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
NodeArray res =
makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
Names.shrinkToSize(FromPosition);
@@ -2859,8 +2859,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
std::string_view getSymbol() const {
std::string_view Res = Name;
if (Kind < Unnameable) {
- assert(starts_with(Res, "operator") &&
- "operator name does not start with 'operator'");
+ DEMANGLE_ASSERT(starts_with(Res, "operator"),
+ "operator name does not start with 'operator'");
Res.remove_prefix(sizeof("operator") - 1);
if (starts_with(Res, ' '))
Res.remove_prefix(1);
@@ -3694,7 +3694,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
}
}
- assert(SoFar != nullptr);
+ DEMANGLE_ASSERT(SoFar != nullptr, "");
Node *Base = getDerived().parseBaseUnresolvedName();
if (Base == nullptr)
@@ -5635,7 +5635,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
Node *ForwardRef = make<ForwardTemplateReference>(Index);
if (!ForwardRef)
return nullptr;
- assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
+ DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
+ "");
ForwardTemplateRefs.push_back(
static_cast<ForwardTemplateReference *>(ForwardRef));
return ForwardRef;
diff --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h
index f8a36f8..f1fad35 100644
--- a/libcxxabi/src/demangle/Utility.h
+++ b/libcxxabi/src/demangle/Utility.h
@@ -19,7 +19,6 @@
#include "DemangleConfig.h"
#include <array>
-#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstring>
@@ -159,7 +158,7 @@ public:
}
void insert(size_t Pos, const char *S, size_t N) {
- assert(Pos <= CurrentPosition);
+ DEMANGLE_ASSERT(Pos <= CurrentPosition, "");
if (N == 0)
return;
grow(N);
@@ -172,7 +171,7 @@ public:
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
char back() const {
- assert(CurrentPosition);
+ DEMANGLE_ASSERT(CurrentPosition, "");
return Buffer[CurrentPosition - 1];
}
diff --git a/libcxxabi/src/fallback_malloc.cpp b/libcxxabi/src/fallback_malloc.cpp
index f9fb1bc..fa802b2 100644
--- a/libcxxabi/src/fallback_malloc.cpp
+++ b/libcxxabi/src/fallback_malloc.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "fallback_malloc.h"
+#include "abort_message.h"
#include <__threading_support>
#ifndef _LIBCXXABI_HAS_NO_THREADS
@@ -16,7 +17,7 @@
#endif
#include <__memory/aligned_alloc.h>
-#include <assert.h>
+#include <__assert>
#include <stdlib.h> // for malloc, calloc, free
#include <string.h> // for memset
@@ -142,7 +143,7 @@ void* fallback_malloc(size_t len) {
// Check the invariant that all heap_nodes pointers 'p' are aligned
// so that 'p + 1' has an alignment of at least RequiredAlignment
- assert(reinterpret_cast<size_t>(p + 1) % RequiredAlignment == 0);
+ _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(p + 1) % RequiredAlignment == 0, "");
// Calculate the number of extra padding elements needed in order
// to split 'p' and create a properly aligned heap_node from the tail
@@ -163,7 +164,7 @@ void* fallback_malloc(size_t len) {
q->next_node = 0;
q->len = static_cast<heap_size>(aligned_nelems);
void* ptr = q + 1;
- assert(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0);
+ _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
return ptr;
}
@@ -176,7 +177,7 @@ void* fallback_malloc(size_t len) {
prev->next_node = p->next_node;
p->next_node = 0;
void* ptr = p + 1;
- assert(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0);
+ _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
return ptr;
}
}
diff --git a/libcxxabi/test/test_fallback_malloc.pass.cpp b/libcxxabi/test/test_fallback_malloc.pass.cpp
index ff6ef60..265a7a3 100644
--- a/libcxxabi/test/test_fallback_malloc.pass.cpp
+++ b/libcxxabi/test/test_fallback_malloc.pass.cpp
@@ -27,6 +27,8 @@ typedef std::deque<void *> container;
TEST_DIAGNOSTIC_PUSH
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
+#define _LIBCXXABI_ASSERT(expr, msg) assert((expr) && (msg))
+
// #define DEBUG_FALLBACK_MALLOC
#define INSTRUMENT_FALLBACK_MALLOC
#include "../src/fallback_malloc.cpp"