Author: FYLGQ
Date: 2026-01-26T07:52:17+01:00
New Revision: e68eadf84968608448048ccc5d7ff8bfbff06805

URL: 
https://github.com/llvm/llvm-project/commit/e68eadf84968608448048ccc5d7ff8bfbff06805
DIFF: 
https://github.com/llvm/llvm-project/commit/e68eadf84968608448048ccc5d7ff8bfbff06805.diff

LOG: [clang][bytecode] Fix crash on discarded complex comparison (#177731)

Fixes llvm#176902: [clang][bytecode] crashes on ill-formed
_Static_assert comparing complex value

This patch resolves a crash in Clang's constant evaluation when handling
complex number comparisons in discarded expressions, such as those
involving short-circuiting logical operators. The crash occurred due to
unnecessary evaluation of the comparison in the experimental constant
interpreter.

The issue was originally observed and minimized in the following
example:

```cpp
#define EVAL(a, b) _Static_assert(a == b, "")

void foo() {
  EVAL(; + 0, 1i);
}
```

This patch ensures that such comparisons are handled correctly without
triggering assertions when the result is discarded.

Tests

A regression test has been added to verify that complex comparisons in
discarded expressions no longer cause crashes during constant
evaluation.

Local verification:


llvm-project-main/clang/lib/AST/ByteCode/constant-eval-complex-discard.c
passes.

Full ninja check-clang may fail locally due to a known GCC ICE when
building Clang unittests; this is unrelated to the change itself.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/test/AST/ByteCode/complex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 272d08f5e455c..00ff60dd825d3 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -7406,7 +7406,8 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr 
*LHS, const Expr *RHS,
                                               const BinaryOperator *E) {
   assert(E->isComparisonOp());
   assert(!Initializing);
-  assert(!DiscardResult);
+  if (DiscardResult)
+    return this->discard(LHS) && this->discard(RHS);
 
   PrimType ElemT;
   bool LHSIsComplex;

diff  --git a/clang/test/AST/ByteCode/complex.cpp 
b/clang/test/AST/ByteCode/complex.cpp
index 41e5dc0605c23..9bf000d65466c 100644
--- a/clang/test/AST/ByteCode/complex.cpp
+++ b/clang/test/AST/ByteCode/complex.cpp
@@ -439,4 +439,17 @@ namespace Discard {
   }
   static_assert((V(), true));
 
+  void test_discard_complex_comparison() {
+    _Complex int x = 1i;
+    (void)(x == 1i);
+    x == 1i;
+    (void)(x != 1i);
+  }
+
+  constexpr int test_side_effect() {
+    int k = 0;
+    (void)(1i == (++k, 1i));
+    return k;
+  }
+  static_assert(test_side_effect() == 1);
 }


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to