From 9a59bcd8e8ad4c5e47968ffa267a77f9d2f78e31 Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Fri, 7 Aug 2026 22:52:26 -0700 Subject: [PATCH] Type switch scrutinee bindings by their enumeration type Clang applies the integral promotions to a switch condition, so the translated condition carries the promoted integer type. An enumeration is modeled by its underlying integer type, which makes that promotion the identity, so the rvalue translation elides it. The scrutinee binding was still annotated with the promoted type, leaving the declared type and the bound value syntactically distinct. The Pulse dereference tactic compares types syntactically and rejected the binding. Annotate the binding with the enumeration's own type when the unpromoted condition is an enumeration. Other promotions remain genuine casts that the rvalue translation preserves, so their promoted type is still correct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 981f7d3c-6a91-47ad-84d7-7aadf747123d (cherry picked from commit 588982d07b110a144f8b72b7a5189831b6900978) --- cpp/impl.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cpp/impl.cpp b/cpp/impl.cpp index 63a7b7a3..7894ffde 100644 --- a/cpp/impl.cpp +++ b/cpp/impl.cpp @@ -1891,8 +1891,20 @@ class PALConsumer : public ASTConsumer { // Evaluate scrutinee auto scrutRval = trRValue(sw->getCond()); - auto scrutTy = - trQualType(sw->getCond()->getType(), sw->getCond()->getSourceRange()); + // Clang applies the integral promotions to the switch condition. An + // enumeration is modeled by its underlying integer type, so that + // promotion translates to the identity and is elided from the rvalue. + // Annotating the binding with the promoted type would then leave the + // declared type and the translated value syntactically distinct, which + // the Pulse dereference tactic rejects. Use the enumeration's own type + // so the two agree; other promotions are genuine casts that trRValue + // preserves, so their promoted type remains correct. + auto *scrutExpr = sw->getCond(); + auto scrutQualTy = scrutExpr->getType(); + if (scrutExpr->IgnoreImpCasts()->getType()->isEnumeralType()) { + scrutQualTy = scrutExpr->IgnoreImpCasts()->getType(); + } + auto scrutTy = trQualType(scrutQualTy, scrutExpr->getSourceRange()); // Bind the scrutinee once as an immutable value. static int switchCounter = 0;