Skip to content

Commit

Permalink
[clang][Interp] Allow inc/dec on boolean values
Browse files Browse the repository at this point in the history
The warnings or errors are emitted in Sema, but we still need to
do the operation and provide a reasonable result.
  • Loading branch information
tbaederr committed Mar 1, 2024
1 parent 3fc277f commit e59681d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
7 changes: 7 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -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;

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/AST/Interp/Opcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
37 changes: 37 additions & 0 deletions clang/test/AST/Interp/literals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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



}
5 changes: 5 additions & 0 deletions clang/test/SemaCXX/bool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e59681d

Please sign in to comment.