[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-09-05 Thread Timm Bäder via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa13f036949b0: [clang][Interp] Check one-past-the-end 
pointers in GetPtrField (authored by tbaeder).

Changed prior to commit:
  https://reviews.llvm.org/D149149?vs=516763=555834#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

Files:
  clang/lib/AST/Interp/Interp.cpp
  clang/lib/AST/Interp/Interp.h
  clang/test/AST/Interp/records.cpp

Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -531,6 +531,29 @@
   //static_assert(b.a.f == 100, "");
 }
 
+namespace PointerArith {
+  struct A {};
+  struct B : A { int n; };
+
+  B b = {};
+  constexpr A *a1 = 
+  constexpr B *b1 =  + 1;
+  constexpr B *b2 =  + 0;
+
+#if 0
+  constexpr A *a2 =  + 1; // expected-error {{must be initialized by a constant expression}} \
+// expected-note {{cannot access base class of pointer past the end of object}} \
+// ref-error {{must be initialized by a constant expression}} \
+// ref-note {{cannot access base class of pointer past the end of object}}
+
+#endif
+  constexpr const int *pn = &( + 1)->n; // expected-error {{must be initialized by a constant expression}} \
+  // expected-note {{cannot access field of pointer past the end of object}} \
+  // ref-error {{must be initialized by a constant expression}} \
+  // ref-note {{cannot access field of pointer past the end of object}}
+
+}
+
 #if __cplusplus >= 202002L
 namespace VirtualCalls {
 namespace Obvious {
Index: clang/lib/AST/Interp/Interp.h
===
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -67,9 +67,9 @@
 bool CheckRange(InterpState , CodePtr OpPC, const Pointer ,
 CheckSubobjectKind CSK);
 
-/// Checks if accessing a base or derived record of the given pointer is valid.
-bool CheckBaseDerived(InterpState , CodePtr OpPC, const Pointer ,
-  CheckSubobjectKind CSK);
+/// Checks if Ptr is a one-past-the-end pointer.
+bool CheckSubobject(InterpState , CodePtr OpPC, const Pointer ,
+CheckSubobjectKind CSK);
 
 /// Checks if a pointer points to const storage.
 bool CheckConst(InterpState , CodePtr OpPC, const Pointer );
@@ -1121,6 +1121,9 @@
 return false;
   if (!CheckRange(S, OpPC, Ptr, CSK_Field))
 return false;
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
+return false;
+
   S.Stk.push(Ptr.atField(Off));
   return true;
 }
@@ -1165,7 +1168,7 @@
   const Pointer  = S.Stk.pop();
   if (!CheckNull(S, OpPC, Ptr, CSK_Derived))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Derived))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived))
 return false;
   S.Stk.push(Ptr.atFieldSub(Off));
   return true;
@@ -1175,7 +1178,7 @@
   const Pointer  = S.Stk.peek();
   if (!CheckNull(S, OpPC, Ptr, CSK_Base))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
 return false;
   S.Stk.push(Ptr.atField(Off));
   return true;
@@ -1185,7 +1188,7 @@
   const Pointer  = S.Stk.pop();
   if (!CheckNull(S, OpPC, Ptr, CSK_Base))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
 return false;
   S.Stk.push(Ptr.atField(Off));
   return true;
Index: clang/lib/AST/Interp/Interp.cpp
===
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -213,8 +213,8 @@
   return false;
 }
 
-bool CheckBaseDerived(InterpState , CodePtr OpPC, const Pointer ,
-  CheckSubobjectKind CSK) {
+bool CheckSubobject(InterpState , CodePtr OpPC, const Pointer ,
+CheckSubobjectKind CSK) {
   if (!Ptr.isOnePastEnd())
 return true;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-05-03 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a subscriber: rsmith.
shafik added inline comments.



Comment at: clang/test/AST/Interp/records.cpp:509
 
   constexpr A *a2 =  + 1; // expected-error {{must be initialized by a 
constant expression}} \
 // expected-note {{cannot access base class of 
pointer past the end of object}} \

@rsmith it looks like you added this diagnostic a while ago see ce1ec5e1f5620 
did you mean it to apply to this case? The rules have changed a lot since then 
so perhaps this was invalid but now is good.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

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


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-05-03 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/test/AST/Interp/records.cpp:500
 
 namespace PointerArith {
   struct A {};

shafik wrote:
> aaron.ballman wrote:
> > Neat! For the tests in this namespace, Clang and ICC agree, GCC and MSVC 
> > agree, and users get to cry: https://godbolt.org/z/7EWWrY5z6
> Yeah, unfortunate but I am pretty sure clang is correct on both of those.
I think Clang is correct on one of those, but not both of them. I think Clang 
is correct to reject `constexpr const int *pn = &( + 1)->n;` as that involves 
dereferencing the one-past-the-end pointer, but I think Clang is wrong to 
reject `constexpr A *a2 =  + 1;` as there's no dereference there.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

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


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-05-02 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/test/AST/Interp/records.cpp:500
 
 namespace PointerArith {
   struct A {};

aaron.ballman wrote:
> Neat! For the tests in this namespace, Clang and ICC agree, GCC and MSVC 
> agree, and users get to cry: https://godbolt.org/z/7EWWrY5z6
Yeah, unfortunate but I am pretty sure clang is correct on both of those.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

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


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-05-02 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM




Comment at: clang/test/AST/Interp/records.cpp:500
 
 namespace PointerArith {
   struct A {};

Neat! For the tests in this namespace, Clang and ICC agree, GCC and MSVC agree, 
and users get to cry: https://godbolt.org/z/7EWWrY5z6


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

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


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-05-01 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149149/new/

https://reviews.llvm.org/D149149

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


[PATCH] D149149: [clang][Interp] Check one-past-the-end pointers in GetPtrField

2023-04-25 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

  Rename CheckBaseDerived to something more general and call it in
  GetPtrField() as well, so we don't crash later in Pointer::toAPValue().


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149149

Files:
  clang/lib/AST/Interp/Interp.cpp
  clang/lib/AST/Interp/Interp.h
  clang/test/AST/Interp/records.cpp


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -510,6 +510,12 @@
 // expected-note {{cannot access base class of 
pointer past the end of object}} \
 // ref-error {{must be initialized by a constant 
expression}} \
 // ref-note {{cannot access base class of pointer 
past the end of object}}
+
+  constexpr const int *pn = &( + 1)->n; // expected-error {{must be 
initialized by a constant expression}} \
+  // expected-note {{cannot access 
field of pointer past the end of object}} \
+  // ref-error {{must be initialized 
by a constant expression}} \
+  // ref-note {{cannot access field of 
pointer past the end of object}}
+
 }
 
 #if __cplusplus >= 202002L
Index: clang/lib/AST/Interp/Interp.h
===
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -67,9 +67,9 @@
 bool CheckRange(InterpState , CodePtr OpPC, const Pointer ,
 CheckSubobjectKind CSK);
 
-/// Checks if accessing a base or derived record of the given pointer is valid.
-bool CheckBaseDerived(InterpState , CodePtr OpPC, const Pointer ,
-  CheckSubobjectKind CSK);
+/// Checks if Ptr is a one-past-the-end pointer.
+bool CheckSubobject(InterpState , CodePtr OpPC, const Pointer ,
+CheckSubobjectKind CSK);
 
 /// Checks if a pointer points to const storage.
 bool CheckConst(InterpState , CodePtr OpPC, const Pointer );
@@ -1039,6 +1039,8 @@
 return false;
   if (!CheckRange(S, OpPC, Ptr, CSK_Field))
 return false;
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
+return false;
   S.Stk.push(Ptr.atField(Off));
   return true;
 }
@@ -1083,7 +1085,7 @@
   const Pointer  = S.Stk.pop();
   if (!CheckNull(S, OpPC, Ptr, CSK_Derived))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Derived))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Derived))
 return false;
   S.Stk.push(Ptr.atFieldSub(Off));
   return true;
@@ -1093,7 +1095,7 @@
   const Pointer  = S.Stk.peek();
   if (!CheckNull(S, OpPC, Ptr, CSK_Base))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
 return false;
   S.Stk.push(Ptr.atField(Off));
   return true;
@@ -1103,7 +1105,7 @@
   const Pointer  = S.Stk.pop();
   if (!CheckNull(S, OpPC, Ptr, CSK_Base))
 return false;
-  if (!CheckBaseDerived(S, OpPC, Ptr, CSK_Base))
+  if (!CheckSubobject(S, OpPC, Ptr, CSK_Base))
 return false;
   S.Stk.push(Ptr.atField(Off));
   return true;
Index: clang/lib/AST/Interp/Interp.cpp
===
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -211,8 +211,8 @@
   return false;
 }
 
-bool CheckBaseDerived(InterpState , CodePtr OpPC, const Pointer ,
-  CheckSubobjectKind CSK) {
+bool CheckSubobject(InterpState , CodePtr OpPC, const Pointer ,
+CheckSubobjectKind CSK) {
   if (!Ptr.isOnePastEnd())
 return true;
 


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -510,6 +510,12 @@
 // expected-note {{cannot access base class of pointer past the end of object}} \
 // ref-error {{must be initialized by a constant expression}} \
 // ref-note {{cannot access base class of pointer past the end of object}}
+
+  constexpr const int *pn = &( + 1)->n; // expected-error {{must be initialized by a constant expression}} \
+  // expected-note {{cannot access field of pointer past the end of object}} \
+  // ref-error {{must be initialized by a constant expression}} \
+  // ref-note {{cannot access field of pointer past the end of object}}
+
 }
 
 #if __cplusplus >= 202002L
Index: clang/lib/AST/Interp/Interp.h