[clang] e59681d - [clang][Interp] Allow inc/dec on boolean values
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 1 07:24:52 PST 2024
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 at -3 {{ISO C++17 does not allow incrementing expression of type bool}}
+ // both-error at -3 2{{ISO C++17 does not allow incrementing expression of type bool}}
+#else
+ // both-warning at -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,
More information about the cfe-commits
mailing list