Skip to content

Commit 373206d

Browse files
authored
[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.
1 parent 0b1b567 commit 373206d

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6745,6 +6745,22 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
67456745
// value.
67466746
bool IsReference = D->getType()->isReferenceType();
67476747

6748+
// Function parameters.
6749+
// Note that it's important to check them first since we might have a local
6750+
// variable created for a ParmVarDecl as well.
6751+
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6752+
if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
6753+
!D->getType()->isIntegralOrEnumerationType()) {
6754+
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
6755+
/*InitializerFailed=*/false, E);
6756+
}
6757+
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
6758+
if (IsReference || !It->second.IsPtr)
6759+
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
6760+
6761+
return this->emitGetPtrParam(It->second.Offset, E);
6762+
}
6763+
}
67486764
// Local variables.
67496765
if (auto It = Locals.find(D); It != Locals.end()) {
67506766
const unsigned Offset = It->second.Offset;
@@ -6762,20 +6778,6 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
67626778

67636779
return this->emitGetPtrGlobal(*GlobalIndex, E);
67646780
}
6765-
// Function parameters.
6766-
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
6767-
if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().CPlusPlus11 &&
6768-
!D->getType()->isIntegralOrEnumerationType()) {
6769-
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
6770-
/*InitializerFailed=*/false, E);
6771-
}
6772-
if (auto It = this->Params.find(PVD); It != this->Params.end()) {
6773-
if (IsReference || !It->second.IsPtr)
6774-
return this->emitGetParam(classifyPrim(E), It->second.Offset, E);
6775-
6776-
return this->emitGetPtrParam(It->second.Offset, E);
6777-
}
6778-
}
67796781

67806782
// In case we need to re-visit a declaration.
67816783
auto revisit = [&](const VarDecl *VD) -> bool {

clang/test/AST/ByteCode/functions.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,3 +713,22 @@ namespace EnableIfWithTemporary {
713713
struct A { ~A(); };
714714
int &h() __attribute__((enable_if((A(), true), ""))); // both-warning {{clang extension}}
715715
}
716+
717+
namespace LocalVarForParmVarDecl {
718+
struct Iter {
719+
void *p;
720+
};
721+
constexpr bool bar2(Iter A) {
722+
return true;
723+
}
724+
constexpr bool bar(Iter A, bool b) {
725+
if (b)
726+
return true;
727+
728+
return bar(A, true);
729+
}
730+
constexpr int foo() {
731+
return bar(Iter(), false);
732+
}
733+
static_assert(foo(), "");
734+
}

0 commit comments

Comments
 (0)