[clang][bytecode] Prefer ParmVarDecls as function parameters (#153952)

We might create a local temporary variable for a ParmVarDecl, in which
case a DeclRefExpr for that ParmVarDecl should _still_ result in us
choosing the parameter, not that local.
This commit is contained in:
Timm Baeder 2025-08-16 17:22:14 +02:00 committed by GitHub
parent 0b1b567d9f
commit 373206d5e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 14 deletions

View File

@ -6745,6 +6745,22 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
// value.
bool IsReference = D->getType()->isReferenceType();
// Function parameters.
// Note that it's important to check them first since we might have a local
// variable created for a ParmVarDecl as well.
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
!D->getType()->isIntegralOrEnumerationType()) {
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
/*InitializerFailed=*/false, E);
}
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
if (IsReference || !It->second.IsPtr)
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
return this->emitGetPtrParam(It->second.Offset, E);
}
}
// Local variables.
if (auto It = Locals.find(D); It != Locals.end()) {
const unsigned Offset = It->second.Offset;
@ -6762,20 +6778,6 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
return this->emitGetPtrGlobal(*GlobalIndex, E);
}
// Function parameters.
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
!D->getType()->isIntegralOrEnumerationType()) {
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
/*InitializerFailed=*/false, E);
}
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
if (IsReference || !It->second.IsPtr)
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
return this->emitGetPtrParam(It->second.Offset, E);
}
}
// In case we need to re-visit a declaration.
auto revisit = [&](const VarDecl *VD) -> bool {

View File

@ -713,3 +713,22 @@ namespace EnableIfWithTemporary {
struct A { ~A(); };
int &h() __attribute__((enable_if((A(), true), ""))); // both-warning {{clang extension}}
}
namespace LocalVarForParmVarDecl {
struct Iter {
void *p;
};
constexpr bool bar2(Iter A) {
return true;
}
constexpr bool bar(Iter A, bool b) {
if (b)
return true;
return bar(A, true);
}
constexpr int foo() {
return bar(Iter(), false);
}
static_assert(foo(), "");
}