[clang] 373206d - [clang][bytecode] Prefer ParmVarDecls as function parameters (#153952)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 16 08:22:17 PDT 2025
Author: Timm Baeder
Date: 2025-08-16T17:22:14+02:00
New Revision: 373206d5e0591896477f988e4194f59eee7981e1
URL: https://github.com/llvm/llvm-project/commit/373206d5e0591896477f988e4194f59eee7981e1
DIFF: https://github.com/llvm/llvm-project/commit/373206d5e0591896477f988e4194f59eee7981e1.diff
LOG: [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.
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/test/AST/ByteCode/functions.cpp
Removed:
################################################################################
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..4f090842510e0 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);
+ }
+ constexpr int foo() {
+ return bar(Iter(), false);
+ }
+ static_assert(foo(), "");
+}
More information about the cfe-commits
mailing list