diff options
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 11 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.h | 1 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.h | 5 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/PrimType.h | 4 | ||||
-rw-r--r-- | clang/test/AST/ByteCode/cxx11-pedantic.cpp | 13 |
5 files changed, 32 insertions, 2 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index fd306c0..58fe2c1 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -3012,6 +3012,17 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr( } template <class Emitter> +bool Compiler<Emitter>::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) { + + if (!Ctx.getLangOpts().CPlusPlus20) { + if (!this->emitInvalidCast(CastKind::Dynamic, /*Fatal=*/false, E)) + return false; + } + + return this->VisitCastExpr(E); +} + +template <class Emitter> bool Compiler<Emitter>::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { assert(E->getType()->isBooleanType()); diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index a3090a8..0febbac 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -180,6 +180,7 @@ public: bool VisitPredefinedExpr(const PredefinedExpr *E); bool VisitCXXThrowExpr(const CXXThrowExpr *E); bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E); + bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E); bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E); bool VisitCXXConstructExpr(const CXXConstructExpr *E); bool VisitSourceLocExpr(const SourceLocExpr *E); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 91864ba..e2f2e73 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -2935,6 +2935,11 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind, S.FFDiag(E); return false; + } else if (Kind == CastKind::Dynamic) { + assert(!S.getLangOpts().CPlusPlus20); + S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast) + << diag::ConstexprInvalidCastKind::Dynamic; + return true; } return false; diff --git a/clang/lib/AST/ByteCode/PrimType.h b/clang/lib/AST/ByteCode/PrimType.h index c6145d4..6152fbf 100644 --- a/clang/lib/AST/ByteCode/PrimType.h +++ b/clang/lib/AST/ByteCode/PrimType.h @@ -56,6 +56,7 @@ inline constexpr bool isPtrType(PrimType T) { enum class CastKind : uint8_t { Reinterpret, Volatile, + Dynamic, }; inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, @@ -67,6 +68,9 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, case interp::CastKind::Volatile: OS << "volatile"; break; + case interp::CastKind::Dynamic: + OS << "dynamic"; + break; } return OS; } diff --git a/clang/test/AST/ByteCode/cxx11-pedantic.cpp b/clang/test/AST/ByteCode/cxx11-pedantic.cpp index 8779a28..a73f20e 100644 --- a/clang/test/AST/ByteCode/cxx11-pedantic.cpp +++ b/clang/test/AST/ByteCode/cxx11-pedantic.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 -triple x86_64-linux -pedantic %s -// RUN: %clang_cc1 -verify=both,ref -std=c++11 -triple x86_64-linux -pedantic %s +// RUN: %clang_cc1 -verify=both,expected -std=c++11 -triple x86_64-linux -pedantic %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -verify=both,ref -std=c++11 -triple x86_64-linux -pedantic %s struct T { int n; }; const T t = { 42 }; // both-note 2{{declared here}} @@ -11,3 +11,12 @@ struct S { static_assert(t.n == 42, ""); // both-error {{expression is not an integral constant expression}} \ // both-note {{read of non-constexpr variable 't' is not allowed}} + +namespace DynamicCast { + struct S { int n; }; + constexpr S s { 16 }; + struct T { + int n : dynamic_cast<const S*>(&s)->n; // both-warning {{constant expression}} \ + // both-note {{dynamic_cast}} + }; +} |