Skip to content

Commit 36b0707

Browse files
authored
[clang][bytecode] Return an lvalue path for dummy pointers (#111862)
Not doing this is wrong in general and we need to reject expressions where it would matter differently.
1 parent 59b2945 commit 36b0707

File tree

3 files changed

+13
-11
lines changed

3 files changed

+13
-11
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6006,6 +6006,9 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
60066006

60076007
return this->emitGetPtrParam(It->second.Offset, E);
60086008
}
6009+
6010+
if (D->getType()->isReferenceType())
6011+
return false; // FIXME: Do we need to emit InvalidDeclRef?
60096012
}
60106013

60116014
// In case we need to re-visit a declaration.
@@ -6042,9 +6045,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
60426045
const auto typeShouldBeVisited = [&](QualType T) -> bool {
60436046
if (T.isConstant(Ctx.getASTContext()))
60446047
return true;
6045-
if (const auto *RT = T->getAs<ReferenceType>())
6046-
return RT->getPointeeType().isConstQualified();
6047-
return false;
6048+
return T->isReferenceType();
60486049
};
60496050

60506051
// DecompositionDecls are just proxies for us.
@@ -6060,9 +6061,12 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
60606061
// other words, we're evaluating the initializer, just to know if we can
60616062
// evaluate the initializer.
60626063
if (VD->isLocalVarDecl() && typeShouldBeVisited(VD->getType()) &&
6063-
VD->getInit() && !VD->getInit()->isValueDependent() &&
6064-
VD->evaluateValue())
6065-
return revisit(VD);
6064+
VD->getInit() && !VD->getInit()->isValueDependent()) {
6065+
6066+
if (VD->evaluateValue())
6067+
return revisit(VD);
6068+
return this->emitInvalidDeclRef(cast<DeclRefExpr>(E), E);
6069+
}
60666070
}
60676071
} else {
60686072
if (const auto *VD = dyn_cast<VarDecl>(D);

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,6 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
253253
}
254254
}
255255

256-
// FIXME(perf): We compute the lvalue path above, but we can't supply it
257-
// for dummy pointers (that causes crashes later in CheckConstantExpression).
258-
if (isDummy())
259-
Path.clear();
260-
261256
// We assemble the LValuePath starting from the innermost pointer to the
262257
// outermost one. SO in a.b.c, the first element in Path will refer to
263258
// the field 'c', while later code expects it to refer to 'a'.

clang/test/AST/ByteCode/cxx1z.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ namespace Temp {
1010
A<int &, addr({}).n> c; // both-error {{reference to subobject of temporary object}}
1111
A<int *, &addr({}).n> d; // both-error {{pointer to subobject of temporary object}}
1212
}
13+
14+
char arr[3];
15+
A<const char*, &arr[1]> d; // both-error {{refers to subobject '&arr[1]'}}

0 commit comments

Comments
 (0)