Skip to content

Commit e2f8ec7

Browse files
authored
[clang][Interp] Fix variables referring to their own address (#70587)
This was a combination of issues: 1) We can subtract pointers that don't point into arrays. 2) In C, everything is possible.
1 parent 51c351f commit e2f8ec7

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
14531453
DiagInvalidOffset();
14541454
}
14551455

1456-
if (Invalid && !Ptr.isDummy())
1456+
if (Invalid && !Ptr.isDummy() && S.getLangOpts().CPlusPlus)
14571457
return false;
14581458

14591459
// Offset is valid - compute it on unsigned.
@@ -1531,7 +1531,7 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
15311531
const Pointer &LHS = S.Stk.pop<Pointer>();
15321532
const Pointer &RHS = S.Stk.pop<Pointer>();
15331533

1534-
if (!Pointer::hasSameArray(LHS, RHS)) {
1534+
if (!Pointer::hasSameBase(LHS, RHS) && S.getLangOpts().CPlusPlus) {
15351535
// TODO: Diagnose.
15361536
return false;
15371537
}

clang/test/AST/Interp/c.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// RUN: %clang_cc1 -pedantic -verify=pedantic-ref -std=c11 %s
55

66
typedef __INTPTR_TYPE__ intptr_t;
7+
typedef __PTRDIFF_TYPE__ ptrdiff_t;
78

89
_Static_assert(1, "");
910
_Static_assert(0 != 1, "");
@@ -81,3 +82,6 @@ const intptr_t L = (intptr_t)(&(yy->y)); // expected-error {{not a compile-time
8182
// pedantic-expected-error {{not a compile-time constant}} \
8283
// ref-error {{not a compile-time constant}} \
8384
// pedantic-ref-error {{not a compile-time constant}}
85+
const ptrdiff_t m = &m + 137 - &m;
86+
_Static_assert(m == 137, ""); // pedantic-ref-warning {{GNU extension}} \
87+
// pedantic-expected-warning {{GNU extension}}

clang/test/AST/Interp/literals.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define INT_MAX __INT_MAX__
88

99
typedef __INTPTR_TYPE__ intptr_t;
10+
typedef __PTRDIFF_TYPE__ ptrdiff_t;
1011

1112

1213
static_assert(true, "");
@@ -198,6 +199,20 @@ namespace PointerComparison {
198199
// ref-note {{comparison between '&s.b' and 'nullptr' has unspecified value}}
199200

200201
constexpr bool v7 = qv <= (void*)&s.b; // ok
202+
203+
constexpr ptrdiff_t m = &m - &m;
204+
static_assert(m == 0, "");
205+
206+
constexpr ptrdiff_t m2 = (&m2 + 1) - (&m2 + 1);
207+
static_assert(m2 == 0, "");
208+
209+
constexpr long m3 = (&m3 + 1) - (&m3);
210+
static_assert(m3 == 1, "");
211+
212+
constexpr long m4 = &m4 + 2 - &m4; // ref-error {{must be initialized by a constant expression}} \
213+
// ref-note {{cannot refer to element 2 of non-array object}} \
214+
// expected-error {{must be initialized by a constant expression}} \
215+
// expected-note {{cannot refer to element 2 of non-array object}}
201216
}
202217

203218
namespace SizeOf {

0 commit comments

Comments
 (0)