[clang][bytecode] Fix some imag/real corner cases (#174764)

Fix real/imag when taking a primitive parameter _and_ being discarded,
and fix the case where their subexpression can't be classified.

Fixes https://github.com/llvm/llvm-project/issues/174668
This commit is contained in:
Timm Baeder 2026-01-07 14:49:23 +01:00 committed by GitHub
parent 1ab7b6655d
commit 4fdbe05d6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 3 deletions

View File

@ -6792,13 +6792,17 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
case UO_Real: // __real x
assert(T);
if (!T)
return false;
return this->delegate(SubExpr);
case UO_Imag: { // __imag x
assert(T);
if (!T)
return false;
if (!this->discard(SubExpr))
return false;
return this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
return DiscardResult
? true
: this->visitZeroInitializer(*T, SubExpr->getType(), SubExpr);
}
case UO_Extension:
return this->delegate(SubExpr);

View File

@ -410,3 +410,29 @@ namespace ComplexConstexpr {
static_assert(__imag test6 == 6, "");
static_assert(&__imag test6 == &__real test6 + 1, "");
}
namespace Discard {
constexpr int test1() {
__imag(0);
__imag(0.0);
__real(0);
__real(0.0);
return 10;
}
static_assert(test1() == 10, "");
constexpr int test2() {
__imag(bar()); // both-error {{use of undeclared identifier}}
return 10;
}
static_assert(test2() == 10, ""); // both-error {{not an integral constant expression}}
constexpr int test3() {
__real(barz()); // both-error {{use of undeclared identifier}}
return 10;
}
static_assert(test3() == 10, ""); // both-error {{not an integral constant expression}}
}