This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG459f495f49a1: [clang][Interp] Check inc/dec family of ops for initialization (authored by tbaeder).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D149846/new/ https://reviews.llvm.org/D149846 Files: clang/lib/AST/Interp/Interp.cpp 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 @@ -462,14 +462,36 @@ } static_assert(incBool(), ""); + template<typename T, bool Inc> constexpr int uninit() { - int a; - ++a; // ref-note {{increment of uninitialized}} \ - // FIXME: Should also be rejected by new interpreter + T a; + if constexpr (Inc) + ++a; // ref-note 2{{increment of uninitialized}} \ + // expected-note 2{{increment of object outside its lifetime}} + else + --a; // ref-note 2{{decrement of uninitialized}} \ + // expected-note 2{{decrement of object outside its lifetime}} return 1; } - static_assert(uninit(), ""); // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to 'uninit()'}} + static_assert(uninit<int, true>(), ""); // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'uninit()'}} \ + // 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()'}} \ + // 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()'}} \ + // 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()'}} \ + // 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 @@ -76,6 +76,9 @@ /// Checks if a value can be loaded from a block. bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr); +bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK); + /// Checks if a value can be stored in a block. bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr); @@ -501,9 +504,11 @@ /// 4) Pushes the original (pre-inc) value on the stack. template <PrimType Name, class T = typename PrimConv<Name>::T> bool Inc(InterpState &S, CodePtr OpPC) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) + return false; + return IncDecHelper<T, IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr); } @@ -512,9 +517,11 @@ /// 3) Writes the value increased by one back to the pointer template <PrimType Name, class T = typename PrimConv<Name>::T> bool IncPop(InterpState &S, CodePtr OpPC) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) + return false; + return IncDecHelper<T, IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr); } @@ -524,9 +531,11 @@ /// 4) Pushes the original (pre-dec) value on the stack. template <PrimType Name, class T = typename PrimConv<Name>::T> bool Dec(InterpState &S, CodePtr OpPC) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) + return false; + return IncDecHelper<T, IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr); } @@ -535,9 +544,11 @@ /// 3) Writes the value decreased by one back to the pointer template <PrimType Name, class T = typename PrimConv<Name>::T> bool DecPop(InterpState &S, CodePtr OpPC) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) + return false; + return IncDecHelper<T, IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr); } @@ -562,26 +573,38 @@ } inline bool Incf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + + if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) + return false; + return IncDecFloatHelper<IncDecOp::Inc, PushVal::Yes>(S, OpPC, Ptr, RM); } inline bool IncfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + + if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) + return false; + return IncDecFloatHelper<IncDecOp::Inc, PushVal::No>(S, OpPC, Ptr, RM); } inline bool Decf(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + + if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) + return false; + return IncDecFloatHelper<IncDecOp::Dec, PushVal::Yes>(S, OpPC, Ptr, RM); } inline bool DecfPop(InterpState &S, CodePtr OpPC, llvm::RoundingMode RM) { - // FIXME: Check initialization of Ptr const Pointer &Ptr = S.Stk.pop<Pointer>(); + + if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) + return false; + return IncDecFloatHelper<IncDecOp::Dec, PushVal::No>(S, OpPC, Ptr, RM); } Index: clang/lib/AST/Interp/Interp.cpp =================================================================== --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -53,17 +53,6 @@ return true; } -static bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - AccessKinds AK) { - if (Ptr.isInitialized()) - return true; - if (!S.checkingPotentialConstantExpression()) { - const SourceInfo &Loc = S.Current->getSource(OpPC); - S.FFDiag(Loc, diag::note_constexpr_access_uninit) << AK << false; - } - return false; -} - static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { if (Ptr.isActive()) @@ -243,6 +232,18 @@ return false; } +bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK) { + if (Ptr.isInitialized()) + return true; + + if (!S.checkingPotentialConstantExpression()) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_access_uninit) << AK << false; + } + return false; +} + bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckLive(S, OpPC, Ptr, AK_Read)) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits