-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[clang][bytecode] Prefer ParmVarDecls as function parameters #153952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe 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. Full diff: https://github.com/llvm/llvm-project/pull/153952.diff 2 Files Affected:
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());
+}
|
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.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/29070 Here is the relevant piece of the build log for the reference |
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.