tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, shafik, cor3ntin.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D158702
Files:
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/literals.cpp
Index: clang/test/AST/Interp/literals.cpp
===================================================================
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -523,36 +523,72 @@
}
static_assert(incBool(), "");
- template<typename T, bool Inc>
+ /// FIXME: The diagnostics for pre-inc/dec of pointers doesn't match the
+ /// current interpreter. But they are stil OK.
+ template<typename T, bool Inc, bool Pre>
constexpr int uninit() {
T a;
- if constexpr (Inc)
- ++a; // ref-note 2{{increment of uninitialized}} \
- // expected-note 2{{increment of uninitialized}}
- else
- --a; // ref-note 2{{decrement of uninitialized}} \
- // expected-note 2{{decrement of uninitialized}}
+ if constexpr (Inc) {
+ if (Pre)
+ ++a; // ref-note 3{{increment of uninitialized}} \
+ // expected-note 2{{increment of uninitialized}} \
+ // expected-note {{read of uninitialized}}
+ else
+ a++; // ref-note 2{{increment of uninitialized}} \
+ // expected-note 2{{increment of uninitialized}}
+ } else {
+ if (Pre)
+ --a; // ref-note 3{{decrement of uninitialized}} \
+ // expected-note 2{{decrement of uninitialized}} \
+ // expected-note {{read of uninitialized}}
+ else
+ a--; // ref-note 2{{decrement of uninitialized}} \
+ // expected-note 2{{decrement of uninitialized}}
+ }
return 1;
}
- static_assert(uninit<int, true>(), ""); // ref-error {{not an integral constant expression}} \
- // ref-note {{in call to 'uninit<int, true>()'}} \
- // expected-error {{not an integral constant expression}} \
- // expected-note {{in call to 'uninit()'}}
-
- static_assert(uninit<int, false>(), ""); // ref-error {{not an integral constant expression}} \
- // ref-note {{in call to 'uninit<int, false>()'}} \
- // expected-error {{not an integral constant expression}} \
- // expected-note {{in call to 'uninit()'}}
-
- static_assert(uninit<float, true>(), ""); // ref-error {{not an integral constant expression}} \
- // ref-note {{in call to 'uninit<float, true>()'}} \
- // expected-error {{not an integral constant expression}} \
- // expected-note {{in call to 'uninit()'}}
-
- static_assert(uninit<float, false>(), ""); // ref-error {{not an integral constant expression}} \
- // ref-note {{in call to 'uninit<float, false>()'}} \
- // expected-error {{not an integral constant expression}} \
- // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<int, true, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int, true, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<int, false, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int, false, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+
+ static_assert(uninit<float, true, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<float, true, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<float, false, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<float, false, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<float, true, false>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<float, true, false>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<float, false, false>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<float, false, false>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+
+ static_assert(uninit<int*, true, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int *, true, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<int*, false, true>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int *, false, true>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<int*, true, false>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int *, true, false>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
+ static_assert(uninit<int*, false, false>(), ""); // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'uninit<int *, false, false>()'}} \
+ // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'uninit()'}}
constexpr int OverFlow() { // ref-error {{never produces a constant expression}} \
// expected-error {{never produces a constant expression}}
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1467,9 +1467,9 @@
}
template <ArithOp Op>
-static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC) {
+static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,
+ const Pointer &Ptr) {
using OneT = Integral<8, false>;
- const Pointer &Ptr = S.Stk.pop<Pointer>();
// Get the current value on the stack.
S.Stk.push<Pointer>(Ptr.deref<Pointer>());
@@ -1486,11 +1486,21 @@
}
static inline bool IncPtr(InterpState &S, CodePtr OpPC) {
- return IncDecPtrHelper<ArithOp::Add>(S, OpPC);
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
+
+ if (!CheckInitialized(S, OpPC, Ptr, AK_Increment))
+ return false;
+
+ return IncDecPtrHelper<ArithOp::Add>(S, OpPC, Ptr);
}
static inline bool DecPtr(InterpState &S, CodePtr OpPC) {
- return IncDecPtrHelper<ArithOp::Sub>(S, OpPC);
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
+
+ if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement))
+ return false;
+
+ return IncDecPtrHelper<ArithOp::Sub>(S, OpPC, Ptr);
}
/// 1) Pops a Pointer from the stack.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits