Skip to content

Commit a47e40b

Browse files
committed
[clang][Interp] Disallow ptr-to-int casts on dummy pointers
1 parent 87cedbe commit a47e40b

File tree

3 files changed

+11
-10
lines changed

3 files changed

+11
-10
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,6 +1937,9 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
19371937
bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
19381938
const Pointer &Ptr = S.Stk.pop<Pointer>();
19391939

1940+
if (Ptr.isDummy())
1941+
return false;
1942+
19401943
const SourceInfo &E = S.Current->getSource(OpPC);
19411944
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
19421945
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
@@ -1949,6 +1952,9 @@ static inline bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC,
19491952
uint32_t BitWidth) {
19501953
const Pointer &Ptr = S.Stk.pop<Pointer>();
19511954

1955+
if (Ptr.isDummy())
1956+
return false;
1957+
19521958
const SourceInfo &E = S.Current->getSource(OpPC);
19531959
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
19541960
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
@@ -1962,6 +1968,9 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
19621968
uint32_t BitWidth) {
19631969
const Pointer &Ptr = S.Stk.pop<Pointer>();
19641970

1971+
if (Ptr.isDummy())
1972+
return false;
1973+
19651974
const SourceInfo &E = S.Current->getSource(OpPC);
19661975
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
19671976
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);

clang/test/AST/Interp/builtin-align-cxx.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,7 @@ static_assert(__builtin_align_down(&align32array[7], 4) == &align32array[4], "")
202202
static_assert(__builtin_align_down(&align32array[8], 4) == &align32array[8], "");
203203

204204
// Achieving the same thing using casts to uintptr_t is not allowed:
205-
static_assert((char *)((__UINTPTR_TYPE__)&align32array[7] & ~3) == &align32array[4], ""); // both-error{{not an integral constant expression}} \
206-
// expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
205+
static_assert((char *)((__UINTPTR_TYPE__)&align32array[7] & ~3) == &align32array[4], ""); // both-error{{not an integral constant expression}}
207206

208207
static_assert(__builtin_align_down(&align32array[1], 4) == &align32array[0], "");
209208
static_assert(__builtin_align_down(&align32array[1], 64) == &align32array[0], ""); // both-error{{not an integral constant expression}}

clang/test/AST/Interp/const-eval.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,8 @@ EVAL_EXPR(47, &x < &x + 1 ? 1 : -1)
140140
EVAL_EXPR(48, &x != &x - 1 ? 1 : -1)
141141
EVAL_EXPR(49, &x < &x - 100 ? 1 : -1) // ref-error {{not an integer constant expression}}
142142

143-
/// FIXME: Rejecting this is correct, BUT when converting the innermost pointer
144-
/// to an integer, we do not preserve the information where it came from. So when we later
145-
/// create a pointer from it, it also doesn't have that information, which means
146-
/// hasSameBase() for those two pointers will return false. And in those cases, we emit
147-
/// the diagnostic:
148-
/// comparison between '&Test50' and '&(631578)' has unspecified value
149143
extern struct Test50S Test50;
150-
EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // both-error {{not an integer constant expression}} \
151-
// expected-note {{comparison between}}
144+
EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned long)&Test50 + 10)) // both-error {{not an integer constant expression}}
152145

153146
EVAL_EXPR(51, 0 != (float)1e99)
154147

0 commit comments

Comments
 (0)