diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 7dd415d6e4605..c5ee720d5a29d 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1453,7 +1453,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, DiagInvalidOffset(); } - if (Invalid && !Ptr.isDummy()) + if (Invalid && !Ptr.isDummy() && S.getLangOpts().CPlusPlus) return false; // Offset is valid - compute it on unsigned. @@ -1531,7 +1531,7 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) { const Pointer &LHS = S.Stk.pop(); const Pointer &RHS = S.Stk.pop(); - if (!Pointer::hasSameArray(LHS, RHS)) { + if (!Pointer::hasSameBase(LHS, RHS) && S.getLangOpts().CPlusPlus) { // TODO: Diagnose. return false; } diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index 6bfcded0a7864..2bc3d906bcc5e 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -4,6 +4,7 @@ // RUN: %clang_cc1 -pedantic -verify=pedantic-ref -std=c11 %s typedef __INTPTR_TYPE__ intptr_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; _Static_assert(1, ""); _Static_assert(0 != 1, ""); @@ -81,3 +82,6 @@ const intptr_t L = (intptr_t)(&(yy->y)); // expected-error {{not a compile-time // pedantic-expected-error {{not a compile-time constant}} \ // ref-error {{not a compile-time constant}} \ // pedantic-ref-error {{not a compile-time constant}} +const ptrdiff_t m = &m + 137 - &m; +_Static_assert(m == 137, ""); // pedantic-ref-warning {{GNU extension}} \ + // pedantic-expected-warning {{GNU extension}} diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index ba24955d14503..92b467da3e884 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -7,6 +7,7 @@ #define INT_MAX __INT_MAX__ typedef __INTPTR_TYPE__ intptr_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; static_assert(true, ""); @@ -198,6 +199,20 @@ namespace PointerComparison { // ref-note {{comparison between '&s.b' and 'nullptr' has unspecified value}} constexpr bool v7 = qv <= (void*)&s.b; // ok + + constexpr ptrdiff_t m = &m - &m; + static_assert(m == 0, ""); + + constexpr ptrdiff_t m2 = (&m2 + 1) - (&m2 + 1); + static_assert(m2 == 0, ""); + + constexpr long m3 = (&m3 + 1) - (&m3); + static_assert(m3 == 1, ""); + + constexpr long m4 = &m4 + 2 - &m4; // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{cannot refer to element 2 of non-array object}} \ + // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{cannot refer to element 2 of non-array object}} } namespace SizeOf {