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
5 changes: 5 additions & 0 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,11 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
case CK_ToVoid:
return discard(SubExpr);

case CK_Dynamic:
// This initially goes through VisitCXXDynamicCastExpr, where we emit
// a diagnostic if appropriate.
return this->delegate(SubExpr);

default:
return this->emitInvalid(CE);
}
Expand Down
10 changes: 10 additions & 0 deletions clang/test/AST/ByteCode/cxx20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1201,3 +1201,13 @@ namespace NonPureVirtualCall {

int main() { check(); }
}

namespace DyamicCast {
struct X {
virtual constexpr ~X() {}
};
struct Y : X {};
constexpr Y y;
constexpr const X *p = &y;
constexpr const Y *q = dynamic_cast<const Y*>(p);
}
14 changes: 7 additions & 7 deletions clang/test/SemaCXX/constant-expression-p2280r4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,13 @@ namespace dropped_note {
namespace dynamic {
struct A {virtual ~A();};
struct B : A {};
void f(A& a) {
void f(A& a) { // interpreter-note 2{{declared here}}
constexpr B* b = dynamic_cast<B*>(&a); // expected-error {{must be initialized by a constant expression}} \
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}}
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}} \
// interpreter-note {{pointer to 'a' is not a constant expression}}
constexpr void* b2 = dynamic_cast<void*>(&a); // expected-error {{must be initialized by a constant expression}} \
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}}
// nointerpreter-note {{dynamic_cast applied to object 'a' whose dynamic type is not constant}} \
// interpreter-note {{pointer to 'a' is not a constant expression}}
}
}

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

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