Skip to content

Commit 746e5d0

Browse files
authored
[clang][bytecode] Don't outright reject dynamic casts (#167517)
Just delegate to the subexpr instead for now.
1 parent 778b85a commit 746e5d0

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,11 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
773773
case CK_ToVoid:
774774
return discard(SubExpr);
775775

776+
case CK_Dynamic:
777+
// This initially goes through VisitCXXDynamicCastExpr, where we emit
778+
// a diagnostic if appropriate.
779+
return this->delegate(SubExpr);
780+
776781
default:
777782
return this->emitInvalid(CE);
778783
}

clang/test/AST/ByteCode/cxx20.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,3 +1201,13 @@ namespace NonPureVirtualCall {
12011201

12021202
int main() { check(); }
12031203
}
1204+
1205+
namespace DyamicCast {
1206+
struct X {
1207+
virtual constexpr ~X() {}
1208+
};
1209+
struct Y : X {};
1210+
constexpr Y y;
1211+
constexpr const X *p = &y;
1212+
constexpr const Y *q = dynamic_cast<const Y*>(p);
1213+
}

clang/test/SemaCXX/constant-expression-p2280r4.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,13 @@ namespace dropped_note {
278278
namespace dynamic {
279279
struct A {virtual ~A();};
280280
struct B : A {};
281-
void f(A& a) {
281+
void f(A& a) { // interpreter-note 2{{declared here}}
282282
constexpr B* b = dynamic_cast<B*>(&a); // expected-error {{must be initialized by a constant expression}} \
283-
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}}
283+
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}} \
284+
// interpreter-note {{pointer to 'a' is not a constant expression}}
284285
constexpr void* b2 = dynamic_cast<void*>(&a); // expected-error {{must be initialized by a constant expression}} \
285-
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}}
286+
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}} \
287+
// interpreter-note {{pointer to 'a' is not a constant expression}}
286288
}
287289
}
288290

@@ -415,9 +417,7 @@ namespace InvalidConstexprFn {
415417
};
416418
constexpr int virtual_call(const PolyBase& b) { return b.get(); }
417419
constexpr auto* type(const PolyBase& b) { return &typeid(b); }
418-
// FIXME: Intepreter doesn't support constexpr dynamic_cast yet.
419-
constexpr const void* dyncast(const PolyBase& b) { return dynamic_cast<const void*>(&b); } // interpreter-error {{constexpr function never produces a constant expression}} \
420-
// interpreter-note 2 {{subexpression not valid in a constant expression}}
420+
constexpr const void* dyncast(const PolyBase& b) { return dynamic_cast<const void*>(&b); }
421421
constexpr int sub(const int (&a)[], const int (&b)[]) { return a-b; }
422422
constexpr const int* add(const int &a) { return &a+3; }
423423

@@ -427,7 +427,7 @@ namespace InvalidConstexprFn {
427427
static_assert(get_derived_member(Derived{}) == 0);
428428
static_assert(virtual_call(PolyDerived{}) == 1);
429429
static_assert(type(PolyDerived{}) != nullptr);
430-
static_assert(dyncast(PolyDerived{}) != nullptr); // interpreter-error {{static assertion expression is not an integral constant expression}} interpreter-note {{in call}}
430+
static_assert(dyncast(PolyDerived{}) != nullptr);
431431
static_assert(sub(arr, arr) == 0);
432432
static_assert(add(arr[0]) == &arr[3]);
433433
}

0 commit comments

Comments
 (0)