Skip to content

Commit c4779ea

Browse files
authored
[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.
1 parent 0a9c6be commit c4779ea

10 files changed

+64
-38
lines changed

libcxxabi/src/abort_message.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,15 @@
1414
extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
1515
abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
1616

17+
#ifndef _LIBCXXABI_ASSERT
18+
# define _LIBCXXABI_ASSERT(expr, msg) \
19+
do { \
20+
if (!(expr)) { \
21+
char const* __msg = (msg); \
22+
::abort_message("%s:%d: %s", __FILE__, __LINE__, __msg); \
23+
} \
24+
} while (false)
25+
1726
#endif
27+
28+
#endif // __ABORT_MESSAGE_H_

libcxxabi/src/cxa_demangle.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
// file does not yet support:
1111
// - C++ modules TS
1212

13+
#include "abort_message.h"
14+
#define DEMANGLE_ASSERT(expr, msg) _LIBCXXABI_ASSERT(expr, msg)
15+
1316
#include "demangle/DemangleConfig.h"
1417
#include "demangle/ItaniumDemangle.h"
1518
#include "__cxxabi_config.h"
16-
#include <cassert>
1719
#include <cctype>
1820
#include <cstdio>
1921
#include <cstdlib>
@@ -395,7 +397,7 @@ __cxa_demangle(const char *MangledName, char *Buf, size_t *N, int *Status) {
395397
InternalStatus = demangle_invalid_mangled_name;
396398
else {
397399
OutputBuffer O(Buf, N);
398-
assert(Parser.ForwardTemplateRefs.empty());
400+
DEMANGLE_ASSERT(Parser.ForwardTemplateRefs.empty(), "");
399401
AST->print(O);
400402
O += '\0';
401403
if (N != nullptr)

libcxxabi/src/demangle/DemangleConfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@
9999
#define DEMANGLE_FALLTHROUGH
100100
#endif
101101

102+
#ifndef DEMANGLE_ASSERT
103+
#include <cassert>
104+
#define DEMANGLE_ASSERT(__expr, __msg) assert((__expr) && (__msg))
105+
#endif
106+
102107
#define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle {
103108
#define DEMANGLE_NAMESPACE_END } }
104109

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "Utility.h"
2222
#include <__cxxabi_config.h>
2323
#include <algorithm>
24-
#include <cassert>
2524
#include <cctype>
2625
#include <cstdio>
2726
#include <cstdlib>
@@ -129,12 +128,12 @@ template <class T, size_t N> class PODSmallVector {
129128

130129
// NOLINTNEXTLINE(readability-identifier-naming)
131130
void pop_back() {
132-
assert(Last != First && "Popping empty vector!");
131+
DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
133132
--Last;
134133
}
135134

136135
void shrinkToSize(size_t Index) {
137-
assert(Index <= size() && "shrinkToSize() can't expand!");
136+
DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
138137
Last = First + Index;
139138
}
140139

@@ -144,11 +143,11 @@ template <class T, size_t N> class PODSmallVector {
144143
bool empty() const { return First == Last; }
145144
size_t size() const { return static_cast<size_t>(Last - First); }
146145
T &back() {
147-
assert(Last != First && "Calling back() on empty vector!");
146+
DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
148147
return *(Last - 1);
149148
}
150149
T &operator[](size_t Index) {
151-
assert(Index < size() && "Invalid access!");
150+
DEMANGLE_ASSERT(Index < size(), "Invalid access!");
152151
return *(begin() + Index);
153152
}
154153
void clear() { Last = First; }
@@ -1678,7 +1677,7 @@ class SpecialSubstitution final : public ExpandedSpecialSubstitution {
16781677
std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
16791678
if (isInstantiation()) {
16801679
// The instantiations are typedefs that drop the "basic_" prefix.
1681-
assert(starts_with(SV, "basic_"));
1680+
DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
16821681
SV.remove_prefix(sizeof("basic_") - 1);
16831682
}
16841683
return SV;
@@ -2569,7 +2568,7 @@ void Node::visit(Fn F) const {
25692568
return F(static_cast<const X *>(this));
25702569
#include "ItaniumNodes.def"
25712570
}
2572-
assert(0 && "unknown mangling node kind");
2571+
DEMANGLE_ASSERT(0, "unknown mangling node kind");
25732572
}
25742573

25752574
/// Determine the kind of a node from its type.
@@ -2611,7 +2610,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
26112610
Parser->TemplateParams.push_back(&Params);
26122611
}
26132612
~ScopedTemplateParamList() {
2614-
assert(Parser->TemplateParams.size() >= OldNumTemplateParamLists);
2613+
DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2614+
"");
26152615
Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
26162616
}
26172617
TemplateParamList *params() { return &Params; }
@@ -2692,7 +2692,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
26922692
}
26932693

26942694
NodeArray popTrailingNodeArray(size_t FromPosition) {
2695-
assert(FromPosition <= Names.size());
2695+
DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
26962696
NodeArray res =
26972697
makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
26982698
Names.shrinkToSize(FromPosition);
@@ -2859,8 +2859,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
28592859
std::string_view getSymbol() const {
28602860
std::string_view Res = Name;
28612861
if (Kind < Unnameable) {
2862-
assert(starts_with(Res, "operator") &&
2863-
"operator name does not start with 'operator'");
2862+
DEMANGLE_ASSERT(starts_with(Res, "operator"),
2863+
"operator name does not start with 'operator'");
28642864
Res.remove_prefix(sizeof("operator") - 1);
28652865
if (starts_with(Res, ' '))
28662866
Res.remove_prefix(1);
@@ -3694,7 +3694,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
36943694
}
36953695
}
36963696

3697-
assert(SoFar != nullptr);
3697+
DEMANGLE_ASSERT(SoFar != nullptr, "");
36983698

36993699
Node *Base = getDerived().parseBaseUnresolvedName();
37003700
if (Base == nullptr)
@@ -5635,7 +5635,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
56355635
Node *ForwardRef = make<ForwardTemplateReference>(Index);
56365636
if (!ForwardRef)
56375637
return nullptr;
5638-
assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
5638+
DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5639+
"");
56395640
ForwardTemplateRefs.push_back(
56405641
static_cast<ForwardTemplateReference *>(ForwardRef));
56415642
return ForwardRef;

libcxxabi/src/demangle/Utility.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "DemangleConfig.h"
2020

2121
#include <array>
22-
#include <cassert>
2322
#include <cstdint>
2423
#include <cstdlib>
2524
#include <cstring>
@@ -159,7 +158,7 @@ class OutputBuffer {
159158
}
160159

161160
void insert(size_t Pos, const char *S, size_t N) {
162-
assert(Pos <= CurrentPosition);
161+
DEMANGLE_ASSERT(Pos <= CurrentPosition, "");
163162
if (N == 0)
164163
return;
165164
grow(N);
@@ -172,7 +171,7 @@ class OutputBuffer {
172171
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
173172

174173
char back() const {
175-
assert(CurrentPosition);
174+
DEMANGLE_ASSERT(CurrentPosition, "");
176175
return Buffer[CurrentPosition - 1];
177176
}
178177

libcxxabi/src/fallback_malloc.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "fallback_malloc.h"
10+
#include "abort_message.h"
1011

1112
#include <__threading_support>
1213
#ifndef _LIBCXXABI_HAS_NO_THREADS
@@ -16,7 +17,7 @@
1617
#endif
1718

1819
#include <__memory/aligned_alloc.h>
19-
#include <assert.h>
20+
#include <__assert>
2021
#include <stdlib.h> // for malloc, calloc, free
2122
#include <string.h> // for memset
2223

@@ -142,7 +143,7 @@ void* fallback_malloc(size_t len) {
142143

143144
// Check the invariant that all heap_nodes pointers 'p' are aligned
144145
// so that 'p + 1' has an alignment of at least RequiredAlignment
145-
assert(reinterpret_cast<size_t>(p + 1) % RequiredAlignment == 0);
146+
_LIBCXXABI_ASSERT(reinterpret_cast<size_t>(p + 1) % RequiredAlignment == 0, "");
146147

147148
// Calculate the number of extra padding elements needed in order
148149
// to split 'p' and create a properly aligned heap_node from the tail
@@ -163,7 +164,7 @@ void* fallback_malloc(size_t len) {
163164
q->next_node = 0;
164165
q->len = static_cast<heap_size>(aligned_nelems);
165166
void* ptr = q + 1;
166-
assert(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0);
167+
_LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
167168
return ptr;
168169
}
169170

@@ -176,7 +177,7 @@ void* fallback_malloc(size_t len) {
176177
prev->next_node = p->next_node;
177178
p->next_node = 0;
178179
void* ptr = p + 1;
179-
assert(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0);
180+
_LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
180181
return ptr;
181182
}
182183
}

libcxxabi/test/test_fallback_malloc.pass.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ typedef std::deque<void *> container;
2727

2828
TEST_DIAGNOSTIC_PUSH
2929
TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
30+
#define _LIBCXXABI_ASSERT(expr, msg) assert((expr) && (msg))
31+
3032
// #define DEBUG_FALLBACK_MALLOC
3133
#define INSTRUMENT_FALLBACK_MALLOC
3234
#include "../src/fallback_malloc.cpp"

llvm/include/llvm/Demangle/DemangleConfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@
8686
#define DEMANGLE_FALLTHROUGH
8787
#endif
8888

89+
#ifndef DEMANGLE_ASSERT
90+
#include <cassert>
91+
#define DEMANGLE_ASSERT(__expr, __msg) assert((__expr) && (__msg))
92+
#endif
93+
8994
#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle {
9095
#define DEMANGLE_NAMESPACE_END } }
9196

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "StringViewExtras.h"
2121
#include "Utility.h"
2222
#include <algorithm>
23-
#include <cassert>
2423
#include <cctype>
2524
#include <cstdio>
2625
#include <cstdlib>
@@ -128,12 +127,12 @@ template <class T, size_t N> class PODSmallVector {
128127

129128
// NOLINTNEXTLINE(readability-identifier-naming)
130129
void pop_back() {
131-
assert(Last != First && "Popping empty vector!");
130+
DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
132131
--Last;
133132
}
134133

135134
void shrinkToSize(size_t Index) {
136-
assert(Index <= size() && "shrinkToSize() can't expand!");
135+
DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
137136
Last = First + Index;
138137
}
139138

@@ -143,11 +142,11 @@ template <class T, size_t N> class PODSmallVector {
143142
bool empty() const { return First == Last; }
144143
size_t size() const { return static_cast<size_t>(Last - First); }
145144
T &back() {
146-
assert(Last != First && "Calling back() on empty vector!");
145+
DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
147146
return *(Last - 1);
148147
}
149148
T &operator[](size_t Index) {
150-
assert(Index < size() && "Invalid access!");
149+
DEMANGLE_ASSERT(Index < size(), "Invalid access!");
151150
return *(begin() + Index);
152151
}
153152
void clear() { Last = First; }
@@ -1677,7 +1676,7 @@ class SpecialSubstitution final : public ExpandedSpecialSubstitution {
16771676
std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
16781677
if (isInstantiation()) {
16791678
// The instantiations are typedefs that drop the "basic_" prefix.
1680-
assert(starts_with(SV, "basic_"));
1679+
DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
16811680
SV.remove_prefix(sizeof("basic_") - 1);
16821681
}
16831682
return SV;
@@ -2568,7 +2567,7 @@ void Node::visit(Fn F) const {
25682567
return F(static_cast<const X *>(this));
25692568
#include "ItaniumNodes.def"
25702569
}
2571-
assert(0 && "unknown mangling node kind");
2570+
DEMANGLE_ASSERT(0, "unknown mangling node kind");
25722571
}
25732572

25742573
/// Determine the kind of a node from its type.
@@ -2610,7 +2609,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
26102609
Parser->TemplateParams.push_back(&Params);
26112610
}
26122611
~ScopedTemplateParamList() {
2613-
assert(Parser->TemplateParams.size() >= OldNumTemplateParamLists);
2612+
DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2613+
"");
26142614
Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
26152615
}
26162616
TemplateParamList *params() { return &Params; }
@@ -2691,7 +2691,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
26912691
}
26922692

26932693
NodeArray popTrailingNodeArray(size_t FromPosition) {
2694-
assert(FromPosition <= Names.size());
2694+
DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
26952695
NodeArray res =
26962696
makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
26972697
Names.shrinkToSize(FromPosition);
@@ -2858,8 +2858,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
28582858
std::string_view getSymbol() const {
28592859
std::string_view Res = Name;
28602860
if (Kind < Unnameable) {
2861-
assert(starts_with(Res, "operator") &&
2862-
"operator name does not start with 'operator'");
2861+
DEMANGLE_ASSERT(starts_with(Res, "operator"),
2862+
"operator name does not start with 'operator'");
28632863
Res.remove_prefix(sizeof("operator") - 1);
28642864
if (starts_with(Res, ' '))
28652865
Res.remove_prefix(1);
@@ -3693,7 +3693,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
36933693
}
36943694
}
36953695

3696-
assert(SoFar != nullptr);
3696+
DEMANGLE_ASSERT(SoFar != nullptr, "");
36973697

36983698
Node *Base = getDerived().parseBaseUnresolvedName();
36993699
if (Base == nullptr)
@@ -5634,7 +5634,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
56345634
Node *ForwardRef = make<ForwardTemplateReference>(Index);
56355635
if (!ForwardRef)
56365636
return nullptr;
5637-
assert(ForwardRef->getKind() == Node::KForwardTemplateReference);
5637+
DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5638+
"");
56385639
ForwardTemplateRefs.push_back(
56395640
static_cast<ForwardTemplateReference *>(ForwardRef));
56405641
return ForwardRef;

llvm/include/llvm/Demangle/Utility.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "DemangleConfig.h"
2020

2121
#include <array>
22-
#include <cassert>
2322
#include <cstdint>
2423
#include <cstdlib>
2524
#include <cstring>
@@ -159,7 +158,7 @@ class OutputBuffer {
159158
}
160159

161160
void insert(size_t Pos, const char *S, size_t N) {
162-
assert(Pos <= CurrentPosition);
161+
DEMANGLE_ASSERT(Pos <= CurrentPosition, "");
163162
if (N == 0)
164163
return;
165164
grow(N);
@@ -172,7 +171,7 @@ class OutputBuffer {
172171
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
173172

174173
char back() const {
175-
assert(CurrentPosition);
174+
DEMANGLE_ASSERT(CurrentPosition, "");
176175
return Buffer[CurrentPosition - 1];
177176
}
178177

0 commit comments

Comments
 (0)