Skip to content

Conversation

@tbaederr
Copy link
Contributor

Emit a CCE diagnostic.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Apr 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 26, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

Emit a CCE diagnostic.


Full diff: https://github.com/llvm/llvm-project/pull/137442.diff

5 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+11)
  • (modified) clang/lib/AST/ByteCode/Compiler.h (+1)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+5)
  • (modified) clang/lib/AST/ByteCode/PrimType.h (+4)
  • (modified) clang/test/AST/ByteCode/cxx11-pedantic.cpp (+11-2)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index fd306c0669d6c..58fe2c184cf3f 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3011,6 +3011,17 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
   return this->VisitCastExpr(E);
 }
 
+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 a3090a8a31189..0febbac9c2043 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -180,6 +180,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
   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 c1970f064cef5..e6f88b310a1ac 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2933,6 +2933,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 c6145d4823a0c..6152fbfbe3a74 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 8779a2826c50d..a73f20ead1092 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}}
+  };
+}

@tbaederr tbaederr merged commit a50269e into llvm:main Apr 26, 2025
15 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants