[clang] [clang][bytecode] Prefer ParmVarDecls as function parameters (PR #153952)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 16 06:09:28 PDT 2025
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/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.
>From bbf6cd50e1f41838605cfca1817dff43c08e3827 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sat, 16 Aug 2025 15:07:58 +0200
Subject: [PATCH] [clang][bytecode] Prefer ParmVarDecls as function parameters
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.
---
clang/lib/AST/ByteCode/Compiler.cpp | 30 ++++++++++++++-------------
clang/test/AST/ByteCode/functions.cpp | 19 +++++++++++++++++
2 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 8e651cf060620..6c6c8d41d3b93 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -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 {
diff --git a/clang/test/AST/ByteCode/functions.cpp b/clang/test/AST/ByteCode/functions.cpp
index 3c00de0102e5a..5272bedd037d1 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -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);
+ }
+ consteval int foo() {
+ return bar(Iter(), false);
+ }
+ static_assert(foo());
+}
More information about the cfe-commits
mailing list