Skip to content

Commit 3f98cdc

Browse files
committed
[Clang] Always constant-evaluate operands of comparisons to nullptr
even if we know what the result is going to be. There may be side effects we ought not to ignore, Fixes llvm#64923 Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D158601
1 parent 158f4f3 commit 3f98cdc

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ Bug Fixes to C++ Support
198198
- Update ``FunctionDeclBitfields.NumFunctionDeclBits``. This fixes:
199199
(`#64171 <https://github.com/llvm/llvm-project/issues/64171>`_).
200200

201+
- Expressions producing ``nullptr`` are correctly evaluated
202+
by the constant interpreter when appearing as the operand
203+
of a binary comparision.
204+
(`#64923 <https://github.com/llvm/llvm-project/issues/64923>_``)
205+
201206
Bug Fixes to AST Handling
202207
^^^^^^^^^^^^^^^^^^^^^^^^^
203208
- Fixed an import failure of recursive friend class template.

clang/lib/AST/ExprConstant.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13310,6 +13310,10 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
1331013310
// C++11 [expr.rel]p4, [expr.eq]p3: If two operands of type std::nullptr_t
1331113311
// are compared, the result is true of the operator is <=, >= or ==, and
1331213312
// false otherwise.
13313+
LValue Res;
13314+
if (!EvaluatePointer(E->getLHS(), Res, Info) ||
13315+
!EvaluatePointer(E->getRHS(), Res, Info))
13316+
return false;
1331313317
return Success(CmpResult::Equal, E);
1331413318
}
1331513319

clang/test/SemaCXX/compare-cxx2a.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,3 +461,21 @@ namespace PR52537 {
461461
template<typename T> bool f6() { return 0 < y6; } // expected-note {{instantiation of}}
462462
void g6() { f6<int>(); } // expected-note {{instantiation of}}
463463
}
464+
465+
466+
namespace GH64923 {
467+
using nullptr_t = decltype(nullptr);
468+
struct MyTask{};
469+
constexpr MyTask DoAnotherThing() {
470+
return {};
471+
}
472+
473+
constexpr nullptr_t operator++(MyTask &&T); // expected-note 2{{declared here}}
474+
void DoSomething() {
475+
if constexpr (++DoAnotherThing() != nullptr) {} // expected-error {{constexpr if condition is not a constant expression}} \
476+
// expected-note {{undefined function 'operator++' cannot be used in a constant expression}}
477+
478+
if constexpr (nullptr == ++DoAnotherThing()) {} // expected-error {{constexpr if condition is not a constant expression}} \
479+
// expected-note {{undefined function 'operator++' cannot be used in a constant expression}}
480+
}
481+
}

0 commit comments

Comments
 (0)