[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:
parent
0b1b567d9f
commit
373206d5e0
@ -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 {
|
||||
|
@ -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(), "");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user