Skip to content

Commit c5a0344

Browse files
author
git apple-llvm automerger
committed
Merge commit '92d2b9c39800' from llvm.org/main into experimental/cas/main
2 parents 01d99ea + 92d2b9c commit c5a0344

File tree

32 files changed

+585
-79
lines changed

32 files changed

+585
-79
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,40 @@ static internal::Matcher<Stmt>
163163
isInUnspecifiedPointerContext(internal::Matcher<Stmt> InnerMatcher) {
164164
// A UPC can be
165165
// 1. an argument of a function call (except the callee has [[unsafe_...]]
166-
// attribute), or
167-
// 2. the operand of a cast operation; or
166+
// attribute), or
167+
// 2. the operand of a pointer-to-(integer or bool) cast operation; or
168168
// 3. the operand of a comparator operation; or
169+
// 4. the operand of a pointer subtraction operation
170+
// (i.e., computing the distance between two pointers); or ...
171+
169172
auto CallArgMatcher =
170173
callExpr(forEachArgumentWithParam(InnerMatcher,
171174
hasPointerType() /* array also decays to pointer type*/),
172175
unless(callee(functionDecl(hasAttr(attr::UnsafeBufferUsage)))));
173176

174177
auto CastOperandMatcher =
175-
explicitCastExpr(hasCastKind(CastKind::CK_PointerToIntegral),
176-
castSubExpr(allOf(hasPointerType(), InnerMatcher)));
178+
castExpr(anyOf(hasCastKind(CastKind::CK_PointerToIntegral),
179+
hasCastKind(CastKind::CK_PointerToBoolean)),
180+
castSubExpr(allOf(hasPointerType(), InnerMatcher)));
177181

178182
auto CompOperandMatcher =
179183
binaryOperator(hasAnyOperatorName("!=", "==", "<", "<=", ">", ">="),
180184
eachOf(hasLHS(allOf(hasPointerType(), InnerMatcher)),
181185
hasRHS(allOf(hasPointerType(), InnerMatcher))));
182186

183-
return stmt(anyOf(CallArgMatcher, CastOperandMatcher, CompOperandMatcher));
187+
// A matcher that matches pointer subtractions:
188+
auto PtrSubtractionMatcher =
189+
binaryOperator(hasOperatorName("-"),
190+
// Note that here we need both LHS and RHS to be
191+
// pointer. Then the inner matcher can match any of
192+
// them:
193+
allOf(hasLHS(hasPointerType()),
194+
hasRHS(hasPointerType())),
195+
eachOf(hasLHS(InnerMatcher),
196+
hasRHS(InnerMatcher)));
197+
198+
return stmt(anyOf(CallArgMatcher, CastOperandMatcher, CompOperandMatcher,
199+
PtrSubtractionMatcher));
184200
// FIXME: any more cases? (UPC excludes the RHS of an assignment. For now we
185201
// don't have to check that.)
186202
}

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,7 @@ class AnnotatingParser {
18191819
Previous && Previous->Previous &&
18201820
!Previous->Previous->isOneOf(tok::comma, tok::semi);
18211821
Previous = Previous->Previous) {
1822-
if (Previous->isOneOf(tok::r_square, tok::r_paren)) {
1822+
if (Previous->isOneOf(tok::r_square, tok::r_paren, tok::greater)) {
18231823
Previous = Previous->MatchingParen;
18241824
if (!Previous)
18251825
break;

clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-addressof-arraysubscript.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,30 @@ void address_to_integer(int x) {
1313
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:37-[[@LINE-1]]:42}:"&p.data()[x]"
1414
}
1515

16+
void address_to_bool(int x) {
17+
int * p = new int[10];
18+
bool a = (bool) &p[5];
19+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:24}:"&p.data()[5]"
20+
bool b = (bool) &p[x];
21+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:24}:"&p.data()[x]"
22+
23+
bool a1 = &p[5];
24+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:18}:"&p.data()[5]"
25+
bool b1 = &p[x];
26+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:18}:"&p.data()[x]"
27+
28+
if (&p[5]) {
29+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:12}:"&p.data()[5]"
30+
return;
31+
}
32+
}
33+
1634
void call_argument(int x) {
1735
int * p = new int[10];
1836

1937
f((unsigned long) &p[5], &p[x]);
20-
// CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-1]]:21-[[@LINE-1]]:26}:"&p.data()[5]"
21-
// CHECK-DAG: fix-it:"{{.*}}":{[[@LINE-2]]:28-[[@LINE-2]]:33}:"&p.data()[x]"
38+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:21-[[@LINE-1]]:26}:"&p.data()[5]"
39+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:28-[[@LINE-2]]:33}:"&p.data()[x]"
2240
}
2341

2442
void ignore_unsafe_calls(int x) {
@@ -55,18 +73,36 @@ void index_is_zero() {
5573
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:5-[[@LINE-1]]:10}:"p.data()"
5674
}
5775

58-
// CHECK-NOT: fix-it
76+
void pointer_subtraction(int x) {
77+
int * p = new int[10];
78+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"std::span<int> p"
79+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:13-[[@LINE-2]]:13}:"{"
80+
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:24-[[@LINE-3]]:24}:", 10}"
81+
82+
int n = &p[9] - &p[4];
83+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:16}:"&p.data()[9]"
84+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:19-[[@LINE-2]]:24}:"&p.data()[4]"
85+
if (&p[9] - &p[x]) {
86+
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:12}:"&p.data()[9]"
87+
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:20}:"&p.data()[x]"
88+
return;
89+
}
90+
}
91+
5992
// To test multiple function declarations, each of which carries
60-
// different incomplete informations:
93+
// different incomplete informations.
94+
// no fix-it in the rest of this test:
95+
6196
[[clang::unsafe_buffer_usage]]
6297
void unsafe_g(void*);
6398

6499
void unsafe_g(void*);
65100

66101
void multiple_unsafe_fundecls() {
67102
int * p = new int[10];
68-
103+
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
69104
unsafe_g(&p[5]);
105+
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
70106
}
71107

72108
void unsafe_h(void*);
@@ -78,6 +114,7 @@ void unsafe_h(void* p) { ((char*)p)[10]; }
78114

79115
void multiple_unsafe_fundecls2() {
80116
int * p = new int[10];
81-
117+
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
82118
unsafe_h(&p[5]);
119+
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
83120
}

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
270270
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
271271
EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
272272
EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference);
273+
274+
Tokens = annotate("Foo<A && B> a = {};");
275+
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
276+
EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_BinaryOperator);
277+
278+
Tokens = annotate("Foo<A &&> a = {};");
279+
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
280+
EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
281+
282+
Tokens = annotate("template <enable_if_t<foo && !bar>* = nullptr> void f();");
283+
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
284+
EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_BinaryOperator);
273285
}
274286

275287
TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {

libc/config/baremetal/arm/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2828
libc.src.string.memchr
2929
libc.src.string.memcmp
3030
libc.src.string.memcpy
31+
libc.src.string.memmem
3132
libc.src.string.memmove
3233
libc.src.string.mempcpy
3334
libc.src.string.memrchr

libc/config/darwin/arm/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2828
libc.src.string.memchr
2929
libc.src.string.memcmp
3030
libc.src.string.memcpy
31+
libc.src.string.memmem
3132
libc.src.string.memmove
3233
libc.src.string.mempcpy
3334
libc.src.string.memrchr

libc/config/darwin/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2424
libc.src.string.memchr
2525
libc.src.string.memcmp
2626
libc.src.string.memcpy
27+
libc.src.string.memmem
2728
libc.src.string.memmove
2829
libc.src.string.mempcpy
2930
libc.src.string.memrchr

libc/config/gpu/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2424
libc.src.string.memchr
2525
libc.src.string.memcmp
2626
libc.src.string.memcpy
27+
libc.src.string.memmem
2728
libc.src.string.memmove
2829
libc.src.string.mempcpy
2930
libc.src.string.memrchr

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ set(TARGET_LIBC_ENTRYPOINTS
3838
libc.src.string.memchr
3939
libc.src.string.memcmp
4040
libc.src.string.memcpy
41+
libc.src.string.memmem
4142
libc.src.string.memmove
4243
libc.src.string.mempcpy
4344
libc.src.string.memrchr

libc/config/linux/arm/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2929
libc.src.string.memchr
3030
libc.src.string.memcmp
3131
libc.src.string.memcpy
32+
libc.src.string.memmem
3233
libc.src.string.memmove
3334
libc.src.string.mempcpy
3435
libc.src.string.memrchr

libc/config/linux/riscv64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ set(TARGET_LIBC_ENTRYPOINTS
3838
libc.src.string.memchr
3939
libc.src.string.memcmp
4040
libc.src.string.memcpy
41+
libc.src.string.memmem
4142
libc.src.string.memmove
4243
libc.src.string.mempcpy
4344
libc.src.string.memrchr

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ set(TARGET_LIBC_ENTRYPOINTS
3838
libc.src.string.memchr
3939
libc.src.string.memcmp
4040
libc.src.string.memcpy
41+
libc.src.string.memmem
4142
libc.src.string.memmove
4243
libc.src.string.mempcpy
4344
libc.src.string.memrchr

libc/config/windows/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set(TARGET_LIBC_ENTRYPOINTS
2525
libc.src.string.memchr
2626
libc.src.string.memcmp
2727
libc.src.string.memcpy
28+
libc.src.string.memmem
2829
libc.src.string.memmove
2930
libc.src.string.mempcpy
3031
libc.src.string.memrchr

libc/spec/gnu_ext.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
5757
[], // Macros
5858
[], // Types
5959
[], // Enumerations
60-
[
60+
[
61+
FunctionSpec<
62+
"memmem",
63+
RetValSpec<VoidPtr>,
64+
[ArgSpec<ConstVoidPtr>, ArgSpec<SizeTType>, ArgSpec<ConstVoidPtr>, ArgSpec<SizeTType>]
65+
>,
6166
FunctionSpec<
6267
"memrchr",
6368
RetValSpec<VoidPtr>,

libc/src/string/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ add_entrypoint_object(
5959
.memory_utils.memcpy_implementation
6060
)
6161

62+
add_entrypoint_object(
63+
memmem
64+
SRCS
65+
memmem.cpp
66+
HDRS
67+
memmem.h
68+
DEPENDS
69+
.memory_utils.memmem_implementation
70+
)
71+
6272
add_entrypoint_object(
6373
memchr
6474
SRCS

libc/src/string/memmem.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Implementation of memmem ------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/string/memmem.h"
10+
#include "src/__support/common.h"
11+
#include "src/string/memory_utils/memmem_implementations.h"
12+
13+
namespace __llvm_libc {
14+
15+
LLVM_LIBC_FUNCTION(void *, memmem,
16+
(const void *haystack, size_t haystack_len,
17+
const void *needle, size_t needle_len)) {
18+
constexpr auto comp = [](unsigned char l, unsigned char r) -> int {
19+
return l - r;
20+
};
21+
return memmem_implementation(haystack, haystack_len, needle, needle_len,
22+
comp);
23+
}
24+
25+
} // namespace __llvm_libc

libc/src/string/memmem.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for memmem ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STRING_MEMMEM_H
10+
#define LLVM_LIBC_SRC_STRING_MEMMEM_H
11+
12+
#include <stddef.h> // For size_t
13+
14+
namespace __llvm_libc {
15+
16+
void *memmem(const void *haystack, size_t haystack_len, const void *needle,
17+
size_t needle_len);
18+
19+
} // namespace __llvm_libc
20+
21+
#endif // LLVM_LIBC_SRC_STRING_MEMMEM_H

libc/src/string/memory_utils/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ add_header_library(
7272
)
7373

7474
add_header_library(
75-
strstr_implementation
75+
strstr_implementation
7676
HDRS
7777
strstr_implementations.h
7878
)
79+
80+
add_header_library(
81+
memmem_implementation
82+
HDRS
83+
memmem_implementations.h
84+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//===-- memmem implementation -----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMMEM_IMPLEMENTATIONS_H
10+
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMMEM_IMPLEMENTATIONS_H
11+
12+
#include <stddef.h>
13+
14+
namespace __llvm_libc {
15+
16+
template <typename Comp>
17+
constexpr static void *
18+
memmem_implementation(const void *haystack, size_t haystack_len,
19+
const void *needle, size_t needle_len, Comp &&comp) {
20+
// TODO: simple brute force implementation. This can be
21+
// improved upon using well known string matching algorithms.
22+
if (!needle_len)
23+
return const_cast<void *>(haystack);
24+
25+
if (needle_len > haystack_len)
26+
return nullptr;
27+
28+
const unsigned char *h = static_cast<const unsigned char *>(haystack);
29+
const unsigned char *n = static_cast<const unsigned char *>(needle);
30+
for (size_t i = 0; i <= (haystack_len - needle_len); ++i) {
31+
size_t j = 0;
32+
for (; j < needle_len && !comp(h[i + j], n[j]); ++j)
33+
;
34+
if (j == needle_len)
35+
return const_cast<unsigned char *>(h + i);
36+
}
37+
return nullptr;
38+
}
39+
40+
} // namespace __llvm_libc
41+
42+
#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_MEMMEM_IMPLEMENTATIONS_H

libc/src/string/memory_utils/strstr_implementations.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,19 @@
99
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H
1010
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H
1111

12+
#include "src/string/memory_utils/memmem_implementations.h"
13+
#include "src/string/string_utils.h"
1214
#include <stddef.h>
1315

1416
namespace __llvm_libc {
1517

1618
template <typename Comp>
1719
constexpr static char *strstr_implementation(const char *haystack,
1820
const char *needle, Comp &&comp) {
19-
// TODO: This is a simple brute force implementation. This can be
20-
// improved upon using well known string matching algorithms.
21-
for (size_t i = 0; comp(haystack[i], 0); ++i) {
22-
size_t j = 0;
23-
for (; comp(haystack[i + j], 0) && !comp(haystack[i + j], needle[j]); ++j)
24-
;
25-
if (!comp(needle[j], 0))
26-
return const_cast<char *>(haystack + i);
27-
}
28-
return nullptr;
21+
void *result = memmem_implementation(
22+
static_cast<const void *>(haystack), internal::string_length(haystack),
23+
static_cast<const void *>(needle), internal::string_length(needle), comp);
24+
return static_cast<char *>(result);
2925
}
3026

3127
} // namespace __llvm_libc

0 commit comments

Comments
 (0)