llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Henrik G. Olsson (hnrklssn)

<details>
<summary>Changes</summary>

When `ArePotentiallyOverlappingStringLiterals`, added in 
https://github.com/llvm/llvm-project/pull/109208, compares string literals it 
drops the front of the string with the greatest offset from its base pointer. 
The number of characters dropped is equal to the difference between the two 
strings' offsets from their base pointers. This would trigger an assert when 
the resulting offset is past the end of the object. Not only are 
one-past-the-end pointers legal constructs, the compiler should not crash even 
when faced with illegal constructs.

rdar://149865910

---
Full diff: https://github.com/llvm/llvm-project/pull/137078.diff


3 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+7-2) 
- (modified) clang/test/AST/ByteCode/cxx20.cpp (+9) 
- (modified) clang/test/SemaCXX/constant-expression-cxx11.cpp (+2) 


``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 80ece3c4ed7e1..262c78458b78f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2234,10 +2234,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 c35f3a5632a05..ec154517949cc 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2199,6 +2199,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 &&

``````````

</details>


https://github.com/llvm/llvm-project/pull/137078
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to