Skip to content

Commit e59681d

Browse files
committed
[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.
1 parent 3fc277f commit e59681d

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
199199
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
200200
llvm::ArrayRef<int64_t> ArrayIndices, int64_t &Result);
201201

202+
inline bool Invalid(InterpState &S, CodePtr OpPC);
203+
202204
enum class ArithOp { Add, Sub };
203205

204206
//===----------------------------------------------------------------------===//
@@ -522,6 +524,11 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
522524
if (Ptr.isDummy())
523525
return false;
524526

527+
if constexpr (std::is_same_v<T, Boolean>) {
528+
if (!S.getLangOpts().CPlusPlus14)
529+
return Invalid(S, OpPC);
530+
}
531+
525532
const T &Value = Ptr.deref<T>();
526533
T Result;
527534

clang/lib/AST/Interp/Opcodes.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,10 @@ def Inv: Opcode {
563563
}
564564

565565
// Increment and decrement.
566-
def Inc: IntegerOpcode;
567-
def IncPop : IntegerOpcode;
568-
def Dec: IntegerOpcode;
569-
def DecPop: IntegerOpcode;
566+
def Inc: AluOpcode;
567+
def IncPop : AluOpcode;
568+
def Dec: AluOpcode;
569+
def DecPop: AluOpcode;
570570

571571
// Float increment and decrement.
572572
def Incf: FloatOpcode;

clang/test/AST/Interp/literals.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,3 +1131,40 @@ namespace nullptrsub {
11311131
f = (char *)((char *)0 - (char *)0);
11321132
}
11331133
}
1134+
1135+
namespace incdecbool {
1136+
#if __cplusplus >= 201402L
1137+
constexpr bool incb(bool c) {
1138+
if (!c)
1139+
++c;
1140+
else {++c; c++; }
1141+
#if __cplusplus >= 202002L
1142+
// both-error@-3 {{ISO C++17 does not allow incrementing expression of type bool}}
1143+
// both-error@-3 2{{ISO C++17 does not allow incrementing expression of type bool}}
1144+
#else
1145+
// both-warning@-6 {{incrementing expression of type bool is deprecated and incompatible with C++17}}
1146+
#endif
1147+
return c;
1148+
}
1149+
static_assert(incb(false), "");
1150+
static_assert(incb(true), "");
1151+
static_assert(incb(true) == 1, "");
1152+
#endif
1153+
1154+
1155+
#if __cplusplus == 201103L
1156+
constexpr bool foo() { // both-error {{never produces a constant expression}}
1157+
bool b = true; // both-warning {{variable declaration in a constexpr function is a C++14 extension}}
1158+
b++; // both-warning {{incrementing expression of type bool is deprecated and incompatible with C++17}} \
1159+
// both-warning {{use of this statement in a constexpr function is a C++14 extension}} \
1160+
// both-note 2{{subexpression not valid in a constant expression}}
1161+
1162+
return b;
1163+
}
1164+
static_assert(foo() == 1, ""); // both-error {{not an integral constant expression}} \
1165+
// both-note {{in call to}}
1166+
#endif
1167+
1168+
1169+
1170+
}

clang/test/SemaCXX/bool.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s
33
// RUN: %clang_cc1 %std_cxx17- -fsyntax-only -verify=expected,cxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s
44

5+
// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion %s -fexperimental-new-constant-interpreter
6+
// RUN: %clang_cc1 %std_cxx98-14 -fsyntax-only -verify=expected,precxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s -fexperimental-new-constant-interpreter
7+
// RUN: %clang_cc1 %std_cxx17- -fsyntax-only -verify=expected,cxx17 -Wno-constant-conversion -Wno-deprecated -Wdeprecated-increment-bool %s -fexperimental-new-constant-interpreter
8+
9+
510
// Bool literals can be enum values.
611
enum {
712
ReadWrite = false,

0 commit comments

Comments
 (0)