https://github.com/hnrklssn created 
https://github.com/llvm/llvm-project/pull/137091

Relands #137078 after updating clang/test/AST/ByteCode/cxx20.cpp to account for 
diagnostic outputs that differ between Linux and macOS.

>From 92e524de8e568b47d8506f8d9156dc3f3d064aaa Mon Sep 17 00:00:00 2001
From: "Henrik G. Olsson" <h_ols...@apple.com>
Date: Wed, 23 Apr 2025 17:03:47 -0700
Subject: [PATCH 1/2] Reland "[ConstEval] Fix crash when comparing strings past
 the end" (#137088)"

This reverts commit 93705c3a76e9b00137be84fbc6ef3b4af5fcc031.
---
 clang/lib/AST/ExprConstant.cpp                   | 9 +++++++--
 clang/test/AST/ByteCode/cxx20.cpp                | 9 +++++++++
 clang/test/SemaCXX/constant-expression-cxx11.cpp | 2 ++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f598ef5929aa4..7c933f47bf7f0 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2232,10 +2232,15 @@ static bool 
ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info,
   // within RHS. We don't need to look at the characters of one string that
   // would appear before the start of the other string if they were merged.
   CharUnits Offset = RHS.Offset - LHS.Offset;
-  if (Offset.isNegative())
+  if (Offset.isNegative()) {
+    if (LHSString.Bytes.size() < (size_t)-Offset.getQuantity())
+      return false;
     LHSString.Bytes = LHSString.Bytes.drop_front(-Offset.getQuantity());
-  else
+  } else {
+    if (RHSString.Bytes.size() < (size_t)Offset.getQuantity())
+      return false;
     RHSString.Bytes = RHSString.Bytes.drop_front(Offset.getQuantity());
+  }
 
   bool LHSIsLonger = LHSString.Bytes.size() > RHSString.Bytes.size();
   StringRef Longer = LHSIsLonger ? LHSString.Bytes : RHSString.Bytes;
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 42e6ae33e92e4..4c1b1592896c9 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -119,6 +119,15 @@ constexpr auto b3 = name1() == name1(); // ref-error 
{{must be initialized by a
 constexpr auto b4 = name1() == name2();
 static_assert(!b4);
 
+constexpr auto bar(const char *p) { return p + __builtin_strlen(p); }
+constexpr auto b5 = bar(p1) == p1;
+static_assert(!b5);
+constexpr auto b6 = bar(p1) == ""; // ref-error {{must be initialized by a 
constant expression}} \
+                                   // ref-note {{comparison of addresses of 
potentially overlapping literals}}
+constexpr auto b7 = bar(p1) + 1 == ""; // both-error {{must be initialized by 
a constant expression}} \
+                                       // ref-note {{comparison against 
pointer '&"test1"[6]' that points past the end of a complete object has 
unspecified value}} \
+                                       // expected-note {{comparison against 
pointer '&"test1"[6] + 1' that points past the end of a complete object has 
unspecified value}}
+
 namespace UninitializedFields {
   class A {
   public:
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 28016da925ef9..dc8f4bf1666ee 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2203,6 +2203,8 @@ namespace BuiltinStrlen {
   static_assert(__builtin_strlen("foo") == 3, "");
   static_assert(__builtin_strlen("foo\0quux") == 3, "");
   static_assert(__builtin_strlen("foo\0quux" + 4) == 4, "");
+  static_assert(__builtin_strlen("foo") + 1 + "foo" == "foo", ""); // 
expected-error {{static assertion expression is not an integral constant 
expression}}
+  // expected-note@-1 {{comparison against pointer '&"foo"[4]' that points 
past the end of a complete object has unspecified value}}
 
   constexpr bool check(const char *p) {
     return __builtin_strlen(p) == 3 &&

>From b5f4f64348354c7b75619af7d58a0d99bb4cf8ad Mon Sep 17 00:00:00 2001
From: "Henrik G. Olsson" <h_ols...@apple.com>
Date: Wed, 23 Apr 2025 17:04:23 -0700
Subject: [PATCH 2/2] [ConstEval] Accept differing outputs in test case

Linux and macOS seem to differ in the output of one diagnostic. Accept
both for now to unblock CI and reland the fix.
---
 clang/test/AST/ByteCode/cxx20.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 4c1b1592896c9..69a53a567fa41 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -125,8 +125,7 @@ static_assert(!b5);
 constexpr auto b6 = bar(p1) == ""; // ref-error {{must be initialized by a 
constant expression}} \
                                    // ref-note {{comparison of addresses of 
potentially overlapping literals}}
 constexpr auto b7 = bar(p1) + 1 == ""; // both-error {{must be initialized by 
a constant expression}} \
-                                       // ref-note {{comparison against 
pointer '&"test1"[6]' that points past the end of a complete object has 
unspecified value}} \
-                                       // expected-note {{comparison against 
pointer '&"test1"[6] + 1' that points past the end of a complete object has 
unspecified value}}
+                                       // both-note-re {{comparison against 
pointer '&"test1"[6]{{( \+ 1)?}}' that points past the end of a complete object 
has unspecified value}}
 
 namespace UninitializedFields {
   class A {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to