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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits