[clang] [clang][ExprConst] Add diagnostics for invalid binary arithmetic (PR #118475)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 4 21:45:12 PST 2024


Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>,
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/118475 at github.com>


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/118475

>From ce52d3d0c04fc53b814debdcd2c5019f488eddc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 3 Dec 2024 11:54:07 +0100
Subject: [PATCH 1/3] [clang][ExprConst] Add diagnostics for invalid binary
 arithmetic

... between unrelated declarations or literals.
---
 clang/include/clang/Basic/DiagnosticASTKinds.td |  4 ++++
 clang/lib/AST/ExprConstant.cpp                  | 17 +++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index f630698757c5fb..4d078fc9ca6bb7 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -91,11 +91,15 @@ def note_constexpr_pointer_subtraction_zero_size : Note<
   "subtraction of pointers to type %0 of zero size">;
 def note_constexpr_pointer_comparison_unspecified : Note<
   "comparison between '%0' and '%1' has unspecified value">;
+def note_constexpr_pointer_arith_unspecified : Note<
+  "arithmetic involving '%0' and '%1' has unspecified value">;
 def note_constexpr_pointer_constant_comparison : Note<
   "comparison of numeric address '%0' with pointer '%1' can only be performed "
   "at runtime">;
 def note_constexpr_literal_comparison : Note<
   "comparison of addresses of literals has unspecified value">;
+def note_constexpr_literal_arith : Note<
+  "arithmetic on addresses of literals has unspecified value">;
 def note_constexpr_opaque_call_comparison : Note<
   "comparison against opaque constant address '%0' can only be performed at "
   "runtime">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6b5b95aee35522..2aefcd870ebaf8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14548,8 +14548,21 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
         return Error(E);
       const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr *>();
       const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr *>();
-      if (!LHSExpr || !RHSExpr)
-        return Error(E);
+      if (!LHSExpr || !RHSExpr) {
+        std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
+        std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
+        Info.FFDiag(E, diag::note_constexpr_pointer_arith_unspecified)
+            << LHS << RHS;
+        return false;
+      }
+
+      if (ArePotentiallyOverlappingStringLiterals(Info, LHSValue, RHSValue)) {
+        std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
+        std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
+        Info.FFDiag(E, diag::note_constexpr_literal_arith) << LHS << RHS;
+        return false;
+      }
+
       const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
       const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
       if (!LHSAddrExpr || !RHSAddrExpr)

>From e59b74fe979a17898096e0039dd4572241124bc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 4 Dec 2024 16:04:25 +0100
Subject: [PATCH 2/3] Address review comments

---
 .../include/clang/Basic/DiagnosticASTKinds.td | 10 ++++---
 clang/lib/AST/ExprConstant.cpp                | 27 ++++++++++---------
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 4d078fc9ca6bb7..ab432606edbc4c 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -90,16 +90,18 @@ def note_constexpr_pointer_subtraction_not_same_array : Note<
 def note_constexpr_pointer_subtraction_zero_size : Note<
   "subtraction of pointers to type %0 of zero size">;
 def note_constexpr_pointer_comparison_unspecified : Note<
-  "comparison between '%0' and '%1' has unspecified value">;
+  "comparison between pointers to unrelated objects '%0' and '%1' has unspecified value">;
 def note_constexpr_pointer_arith_unspecified : Note<
-  "arithmetic involving '%0' and '%1' has unspecified value">;
+  "arithmetic involving unrelated objects '%0' and '%1' has unspecified value">;
 def note_constexpr_pointer_constant_comparison : Note<
   "comparison of numeric address '%0' with pointer '%1' can only be performed "
   "at runtime">;
 def note_constexpr_literal_comparison : Note<
-  "comparison of addresses of literals has unspecified value">;
+  "comparison of addresses of potentially overlapping literals has unspecified value">;
 def note_constexpr_literal_arith : Note<
-  "arithmetic on addresses of literals has unspecified value">;
+  "arithmetic on addresses of potentially overlapping literals has unspecified value">;
+def note_constexpr_repeated_literal_eval : Note<
+  "repeated evaluation of the same literal expression can produce different objects">;
 def note_constexpr_opaque_call_comparison : Note<
   "comparison against opaque constant address '%0' can only be performed at "
   "runtime">;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2aefcd870ebaf8..eed33a45e12c8a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14548,20 +14548,23 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
         return Error(E);
       const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr *>();
       const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr *>();
-      if (!LHSExpr || !RHSExpr) {
-        std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
-        std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
-        Info.FFDiag(E, diag::note_constexpr_pointer_arith_unspecified)
-            << LHS << RHS;
-        return false;
-      }
 
-      if (ArePotentiallyOverlappingStringLiterals(Info, LHSValue, RHSValue)) {
-        std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
-        std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
-        Info.FFDiag(E, diag::note_constexpr_literal_arith) << LHS << RHS;
+      auto DiagArith = [&](unsigned DiagID) {
+        std::string LHS = LHSValue.toString(Info.Ctx, LHSExpr->getType());
+        std::string RHS = RHSValue.toString(Info.Ctx, RHSExpr->getType());
+        Info.FFDiag(E, DiagID) << LHS << RHS;
+        if (LHSExpr && LHSExpr == RHSExpr)
+          Info.Note(LHSExpr->getExprLoc(),
+                    diag::note_constexpr_repeated_literal_eval)
+              << LHSExpr->getSourceRange();
         return false;
-      }
+      };
+
+      if (!LHSExpr || !RHSExpr)
+        return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
+
+      if (ArePotentiallyOverlappingStringLiterals(Info, LHSValue, RHSValue))
+        return DiagArith(diag::note_constexpr_literal_arith);
 
       const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
       const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);

>From 4f58533b354ed2002aed167d93e78c882466cf6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 5 Dec 2024 06:44:55 +0100
Subject: [PATCH 3/3] Fix tests

---
 clang/lib/AST/ExprConstant.cpp                |  4 +--
 clang/test/AST/ByteCode/builtin-functions.cpp |  2 +-
 clang/test/AST/ByteCode/cxx20.cpp             |  2 +-
 clang/test/AST/ByteCode/functions.cpp         |  4 +--
 clang/test/AST/ByteCode/literals.cpp          |  4 +--
 clang/test/CXX/expr/expr.const/p2-0x.cpp      | 30 +++++++++----------
 .../SemaCXX/constant-expression-cxx11.cpp     | 12 ++++----
 .../SemaCXX/constant-expression-cxx14.cpp     |  2 +-
 8 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index eed33a45e12c8a..0a5a1ca6fe0704 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14550,8 +14550,8 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
       const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr *>();
 
       auto DiagArith = [&](unsigned DiagID) {
-        std::string LHS = LHSValue.toString(Info.Ctx, LHSExpr->getType());
-        std::string RHS = RHSValue.toString(Info.Ctx, RHSExpr->getType());
+        std::string LHS = LHSValue.toString(Info.Ctx, E->getLHS()->getType());
+        std::string RHS = RHSValue.toString(Info.Ctx, E->getRHS()->getType());
         Info.FFDiag(E, DiagID) << LHS << RHS;
         if (LHSExpr && LHSExpr == RHSExpr)
           Info.Note(LHSExpr->getExprLoc(),
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index b951c04dde5980..5bd8840a624649 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1001,7 +1001,7 @@ namespace FunctionStart {
   void a(void) {}
   static_assert(__builtin_function_start(a) == a, ""); // both-error {{not an integral constant expression}} \
                                                        // ref-note {{comparison against opaque constant address '&__builtin_function_start(a)'}} \
-                                                       // expected-note {{comparison of addresses of literals has unspecified value}}
+                                                       // expected-note {{comparison of addresses of potentially overlapping literals has unspecified value}}
 }
 
 namespace BuiltinInImplicitCtor {
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index dea4055c531d23..268362ceff635b 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -115,7 +115,7 @@ constexpr auto name1() { return "name1"; }
 constexpr auto name2() { return "name2"; }
 
 constexpr auto b3 = name1() == name1(); // ref-error {{must be initialized by a constant expression}} \
-                                        // ref-note {{comparison of addresses of literals}}
+                                        // ref-note {{comparison of addresses of potentially overlapping literals}}
 constexpr auto b4 = name1() == name2();
 static_assert(!b4);
 
diff --git a/clang/test/AST/ByteCode/functions.cpp b/clang/test/AST/ByteCode/functions.cpp
index b00f59a8d8d433..85f290f5e5d646 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -208,11 +208,11 @@ namespace Comparison {
 
   constexpr bool u13 = pf < pg; // both-warning {{ordered comparison of function pointers}} \
                                 // both-error {{must be initialized by a constant expression}} \
-                                // both-note {{comparison between '&f' and '&g' has unspecified value}}
+                                // both-note {{comparison between pointers to unrelated objects '&f' and '&g' has unspecified value}}
 
   constexpr bool u14 = pf < (void(*)())nullptr; // both-warning {{ordered comparison of function pointers}} \
                                                 // both-error {{must be initialized by a constant expression}} \
-                                                // both-note {{comparison between '&f' and 'nullptr' has unspecified value}}
+                                                // both-note {{comparison between pointers to unrelated objects '&f' and 'nullptr' has unspecified value}}
 
 
 
diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp
index 13d6c4feb35002..cc4ae16b279a66 100644
--- a/clang/test/AST/ByteCode/literals.cpp
+++ b/clang/test/AST/ByteCode/literals.cpp
@@ -194,7 +194,7 @@ namespace PointerComparison {
   constexpr void *qv = (void*)&s.b;
   constexpr bool v1 = null < (int*)0;
   constexpr bool v2 = null < pv; // both-error {{must be initialized by a constant expression}} \
-                                 // both-note {{comparison between 'nullptr' and '&s.a' has unspecified value}}
+                                 // both-note {{comparison between pointers to unrelated objects 'nullptr' and '&s.a' has unspecified value}}
 
   constexpr bool v3 = null == pv; // ok
   constexpr bool v4 = qv == pv; // ok
@@ -202,7 +202,7 @@ namespace PointerComparison {
   constexpr bool v5 = qv >= pv;
   constexpr bool v8 = qv > (void*)&s.a;
   constexpr bool v6 = qv > null; // both-error {{must be initialized by a constant expression}} \
-                                 // both-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
+                                 // both-note {{comparison between pointers to unrelated objects '&s.b' and 'nullptr' has unspecified value}}
 
   constexpr bool v7 = qv <= (void*)&s.b; // ok
 
diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp
index 67160ba571f33c..df5ce108aca82e 100644
--- a/clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -510,22 +510,22 @@ namespace UnspecifiedRelations {
   // different objects that are not members of the same array or to different
   // functions, or if only one of them is null, the results of p<q, p>q, p<=q,
   // and p>=q are unspecified.
-  constexpr bool u1 = p < q; // expected-error {{constant expression}} expected-note {{comparison between '&a' and '&b' has unspecified value}}
-  constexpr bool u2 = p > q; // expected-error {{constant expression}} expected-note {{comparison between '&a' and '&b' has unspecified value}}
-  constexpr bool u3 = p <= q; // expected-error {{constant expression}} expected-note {{comparison between '&a' and '&b' has unspecified value}}
-  constexpr bool u4 = p >= q; // expected-error {{constant expression}} expected-note {{comparison between '&a' and '&b' has unspecified value}}
-  constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}} expected-note {{comparison between '&a' and 'nullptr' has unspecified value}}
-  constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}} expected-note {{comparison between '&a' and 'nullptr' has unspecified value}}
-  constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}} expected-note {{comparison between '&a' and 'nullptr' has unspecified value}}
-  constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}} expected-note {{comparison between '&a' and 'nullptr' has unspecified value}}
-  constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&b' has unspecified value}}
-  constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&b' has unspecified value}}
-  constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&b' has unspecified value}}
-  constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&b' has unspecified value}}
+  constexpr bool u1 = p < q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and '&b' has unspecified value}}
+  constexpr bool u2 = p > q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and '&b' has unspecified value}}
+  constexpr bool u3 = p <= q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and '&b' has unspecified value}}
+  constexpr bool u4 = p >= q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and '&b' has unspecified value}}
+  constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and 'nullptr' has unspecified value}}
+  constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and 'nullptr' has unspecified value}}
+  constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and 'nullptr' has unspecified value}}
+  constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&a' and 'nullptr' has unspecified value}}
+  constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects 'nullptr' and '&b' has unspecified value}}
+  constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects 'nullptr' and '&b' has unspecified value}}
+  constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects 'nullptr' and '&b' has unspecified value}}
+  constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects 'nullptr' and '&b' has unspecified value}}
   void f(), g();
 
   constexpr void (*pf)() = &f, (*pg)() = &g;
-  constexpr bool u13 = pf < pg; // expected-error {{constant expression}} expected-note {{comparison between '&f' and '&g' has unspecified value}}
+  constexpr bool u13 = pf < pg; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&f' and '&g' has unspecified value}}
                                 // expected-warning at -1 {{ordered comparison of function pointers}}
   constexpr bool u14 = pf == pg;
 
@@ -578,11 +578,11 @@ namespace UnspecifiedRelations {
   constexpr void *pv = (void*)&s.a;
   constexpr void *qv = (void*)&s.b;
   constexpr bool v1 = null < (int*)0;
-  constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison between 'nullptr' and '&s.a' has unspecified value}}
+  constexpr bool v2 = null < pv; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects 'nullptr' and '&s.a' has unspecified value}}
   constexpr bool v3 = null == pv;
   constexpr bool v4 = qv == pv;
   constexpr bool v5 = qv >= pv;
-  constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
+  constexpr bool v6 = qv > null; // expected-error {{constant expression}} expected-note {{comparison between pointers to unrelated objects '&s.b' and 'nullptr' has unspecified value}}
   constexpr bool v7 = qv <= (void*)&s.b;
   constexpr bool v8 = qv > (void*)&s.a;
 }
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 0c349333d89d44..594c5183272794 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -380,17 +380,17 @@ static_assert(string == string, "");
 static_assert(string == also_string, "");
 
 // These strings may overlap, and so the result of the comparison is unknown.
-constexpr bool may_overlap_1 = +"foo" == +"foo"; // expected-error {{}} expected-note {{addresses of literals}}
-constexpr bool may_overlap_2 = +"foo" == +"foo\0bar"; // expected-error {{}} expected-note {{addresses of literals}}
-constexpr bool may_overlap_3 = +"foo" == "bar\0foo" + 4; // expected-error {{}} expected-note {{addresses of literals}}
-constexpr bool may_overlap_4 = "xfoo" + 1 == "xfoo" + 1; // expected-error {{}} expected-note {{addresses of literals}}
+constexpr bool may_overlap_1 = +"foo" == +"foo"; // expected-error {{}} expected-note {{addresses of potentially overlapping literals}}
+constexpr bool may_overlap_2 = +"foo" == +"foo\0bar"; // expected-error {{}} expected-note {{addresses of potentially overlapping literals}}
+constexpr bool may_overlap_3 = +"foo" == "bar\0foo" + 4; // expected-error {{}} expected-note {{addresses of potentially overlapping literals}}
+constexpr bool may_overlap_4 = "xfoo" + 1 == "xfoo" + 1; // expected-error {{}} expected-note {{addresses of potentially overlapping literals}}
 
 // These may overlap even though they have different encodings.
 // One of these two comparisons is non-constant, but due to endianness we don't
 // know which one.
 constexpr bool may_overlap_different_encoding[] =
   {fold((const char*)u"A" != (const char*)"xA\0\0\0x" + 1), fold((const char*)u"A" != (const char*)"x\0A\0\0x" + 1)};
-  // expected-error at -2 {{}} expected-note at -1 {{addresses of literals}}
+  // expected-error at -2 {{}} expected-note at -1 {{addresses of potentially overlapping literals}}
 
 }
 
@@ -942,7 +942,7 @@ Base *nullB5 = ((0ULL));
 Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Base *' with an rvalue of type 'double'}}
 enum Null { kNull };
 Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Base *' with an rvalue of type 'Class::Null'}}
-static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}
+static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointers to unrelated objects pointer and integer}}
 
 
 
diff --git a/clang/test/SemaCXX/constant-expression-cxx14.cpp b/clang/test/SemaCXX/constant-expression-cxx14.cpp
index 936d3600953b9a..579883ae52ccee 100644
--- a/clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -1315,7 +1315,7 @@ constexpr bool different_in_loop(bool b = false) {
   const char *p[2] = {};
   for (const char *&r : p)
     r = "hello";
-  return p[0] == p[1]; // expected-note {{addresses of literals}}
+  return p[0] == p[1]; // expected-note {{addresses of potentially overlapping literals}}
 }
 constexpr bool check = different_in_loop();
   // expected-error at -1 {{}} expected-note at -1 {{in call}}



More information about the cfe-commits mailing list