Skip to content

Commit de1af6b

Browse files
authored
Eval string one past end reland (#137091)
Relands #137078 after updating clang/test/AST/ByteCode/cxx20.cpp to account for diagnostic outputs that differ between Linux and macOS.
1 parent ea0dbee commit de1af6b

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,10 +2232,15 @@ static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info,
22322232
// within RHS. We don't need to look at the characters of one string that
22332233
// would appear before the start of the other string if they were merged.
22342234
CharUnits Offset = RHS.Offset - LHS.Offset;
2235-
if (Offset.isNegative())
2235+
if (Offset.isNegative()) {
2236+
if (LHSString.Bytes.size() < (size_t)-Offset.getQuantity())
2237+
return false;
22362238
LHSString.Bytes = LHSString.Bytes.drop_front(-Offset.getQuantity());
2237-
else
2239+
} else {
2240+
if (RHSString.Bytes.size() < (size_t)Offset.getQuantity())
2241+
return false;
22382242
RHSString.Bytes = RHSString.Bytes.drop_front(Offset.getQuantity());
2243+
}
22392244

22402245
bool LHSIsLonger = LHSString.Bytes.size() > RHSString.Bytes.size();
22412246
StringRef Longer = LHSIsLonger ? LHSString.Bytes : RHSString.Bytes;

clang/test/AST/ByteCode/cxx20.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ constexpr auto b3 = name1() == name1(); // ref-error {{must be initialized by a
119119
constexpr auto b4 = name1() == name2();
120120
static_assert(!b4);
121121

122+
constexpr auto bar(const char *p) { return p + __builtin_strlen(p); }
123+
constexpr auto b5 = bar(p1) == p1;
124+
static_assert(!b5);
125+
constexpr auto b6 = bar(p1) == ""; // ref-error {{must be initialized by a constant expression}} \
126+
// ref-note {{comparison of addresses of potentially overlapping literals}}
127+
constexpr auto b7 = bar(p1) + 1 == ""; // both-error {{must be initialized by a constant expression}} \
128+
// both-note {{comparison against pointer '&"test1"[6]' that points past the end of a complete object has unspecified value}}
129+
122130
namespace UninitializedFields {
123131
class A {
124132
public:

clang/test/SemaCXX/constant-expression-cxx11.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,8 @@ namespace BuiltinStrlen {
22032203
static_assert(__builtin_strlen("foo") == 3, "");
22042204
static_assert(__builtin_strlen("foo\0quux") == 3, "");
22052205
static_assert(__builtin_strlen("foo\0quux" + 4) == 4, "");
2206+
static_assert(__builtin_strlen("foo") + 1 + "foo" == "foo", ""); // expected-error {{static assertion expression is not an integral constant expression}}
2207+
// expected-note@-1 {{comparison against pointer '&"foo"[4]' that points past the end of a complete object has unspecified value}}
22062208

22072209
constexpr bool check(const char *p) {
22082210
return __builtin_strlen(p) == 3 &&

0 commit comments

Comments
 (0)