Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4191,6 +4191,31 @@ template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
return this->Visit(E);
}

static const Expr *stripCheckedDerivedToBaseCasts(const Expr *E) {
if (const auto *PE = dyn_cast<ParenExpr>(E))
return stripCheckedDerivedToBaseCasts(PE->getSubExpr());

if (const auto *CE = dyn_cast<CastExpr>(E);
CE &&
(CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
return stripCheckedDerivedToBaseCasts(CE->getSubExpr());

return E;
}

static const Expr *stripDerivedToBaseCasts(const Expr *E) {
if (const auto *PE = dyn_cast<ParenExpr>(E))
return stripDerivedToBaseCasts(PE->getSubExpr());

if (const auto *CE = dyn_cast<CastExpr>(E);
CE && (CE->getCastKind() == CK_DerivedToBase ||
CE->getCastKind() == CK_UncheckedDerivedToBase ||
CE->getCastKind() == CK_NoOp))
return stripDerivedToBaseCasts(CE->getSubExpr());

return E;
}

template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
if (E->getType().isNull())
return false;
Expand All @@ -4200,7 +4225,7 @@ template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {

// Create local variable to hold the return value.
if (!E->isGLValue() && !canClassify(E->getType())) {
UnsignedOrNone LocalIndex = allocateLocal(E);
UnsignedOrNone LocalIndex = allocateLocal(stripDerivedToBaseCasts(E));
if (!LocalIndex)
return false;

Expand Down Expand Up @@ -5078,18 +5103,6 @@ bool Compiler<Emitter>::VisitBuiltinCallExpr(const CallExpr *E,
return true;
}

static const Expr *stripDerivedToBaseCasts(const Expr *E) {
if (const auto *PE = dyn_cast<ParenExpr>(E))
return stripDerivedToBaseCasts(PE->getSubExpr());

if (const auto *CE = dyn_cast<CastExpr>(E);
CE &&
(CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
return stripDerivedToBaseCasts(CE->getSubExpr());

return E;
}

template <class Emitter>
bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
const FunctionDecl *FuncDecl = E->getDirectCallee();
Expand Down Expand Up @@ -5194,7 +5207,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
const auto *InstancePtr = MC->getImplicitObjectArgument();
if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) ||
isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) {
const auto *Stripped = stripDerivedToBaseCasts(InstancePtr);
const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr);
if (isa<CXXThisExpr>(Stripped)) {
FuncDecl =
cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass(
Expand Down
11 changes: 11 additions & 0 deletions clang/test/AST/ByteCode/cxx03.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,14 @@ void LambdaAccessingADummy() {
int d;
int a9[1] = {[d = 0] = 1}; // both-error {{is not an integral constant expression}}
}

const int p = 10;
struct B {
int a;
void *p;
};
struct B2 : B {
void *q;
};
_Static_assert(&(B2().a) == &p, ""); // both-error {{taking the address of a temporary object of type 'int'}} \
// both-error {{not an integral constant expression}}