Author: Timm Bäder Date: 2024-03-01T15:40:45+01:00 New Revision: e59681d96327e2ed1963ec1c0f2bc3d40df26443
URL: https://github.com/llvm/llvm-project/commit/e59681d96327e2ed1963ec1c0f2bc3d40df26443 DIFF: https://github.com/llvm/llvm-project/commit/e59681d96327e2ed1963ec1c0f2bc3d40df26443.diff LOG: [clang][Interp] Allow inc/dec on boolean values The warnings or errors are emitted in Sema, but we still need to do the operation and provide a reasonable result. Added: Modified: clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/literals.cpp clang/test/SemaCXX/bool.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index f379c9869d8d8e..677c699efc2ab2 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -199,6 +199,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, llvm::ArrayRef<int64_t> ArrayIndices, int64_t &Result); +inline bool Invalid(InterpState &S, CodePtr OpPC); + enum class ArithOp { Add, Sub }; //===----------------------------------------------------------------------===// @@ -522,6 +524,11 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (Ptr.isDummy()) return false; + if constexpr (std::is_same_v<T, Boolean>) { + if (!S.getLangOpts().CPlusPlus14) + return Invalid(S, OpPC); + } + const T &Value = Ptr.deref<T>(); T Result; diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 3e3ba1b163e339..ffc54646f0279e 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -563,10 +563,10 @@ def Inv: Opcode { } // Increment and decrement. -def Inc: IntegerOpcode; -def IncPop : IntegerOpcode; -def Dec: IntegerOpcode; -def DecPop: IntegerOpcode; +def Inc: AluOpcode; +def IncPop : AluOpcode; +def Dec: AluOpcode; +def DecPop: AluOpcode; // Float increment and decrement. def Incf: FloatOpcode; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 8ea1c1155143e9..10b687c1408ac3 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1131,3 +1131,40 @@ namespace nullptrsub { f = (char *)((char *)0 - (char *)0); } } + +namespace incdecbool { +#if __cplusplus >= 201402L + constexpr bool incb(bool c) { + if (!c) + ++c; + else {++c; c++; } +#if __cplusplus >= 202002L + // both-error@-3 {{ISO C++17 does not allow incrementing expression of type bool}} + // both-error@-3 2{{ISO C++17 does not allow incrementing expression of type bool}} +#else + // both-warning@-6 {{incrementing expression of type bool is deprecated and incompatible with C++17}} +#endif + return c; + } + static_assert(incb(false), ""); + static_assert(incb(true), ""); + static_assert(incb(true) == 1, ""); +#endif + + +#if __cplusplus == 201103L + constexpr bool foo() { // both-error {{never produces a constant expression}} + bool b = true; // both-warning {{variable declaration in a constexpr function is a C++14 extension}} + b++; // both-warning {{incrementing expression of type bool is deprecated and incompatible with C++17}} \ + // both-warning {{use of this statement in a constexpr function is a C++14 extension}} \ + // both-note 2{{subexpression not valid in a constant expression}} + + return b; + } + static_assert(foo() == 1, ""); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} +#endif + + + +} diff --git a/clang/test/SemaCXX/bool.cpp b/clang/test/SemaCXX/bool.cpp index 33e22c8f6d36f7..57cdba1b1a830d 100644 --- a/clang/test/SemaCXX/bool.cpp +++ b/clang/test/SemaCXX/bool.cpp @@ -2,6 +2,11 @@ // RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s // RUN: %clang_cc1 %std_cxx17- -fsyntax-only -verify=expected,cxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s +// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 %std_cxx17- -fsyntax-only -verify=expected,cxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s -fexperimental-new-constant-interpreter + + // Bool literals can be enum values. enum { ReadWrite = false, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits