Clang emits an error when typeid is used with -fno-rtti, but does not
perform a similar check for dynamic_cast.

The attached patch implements the check.

I have done it late in 'CastOperation::CheckDynamicCast' , as some
dynamic_cast can be resolved statically, and will thus require no
support from the runtime, but we may also want to be more paranoïd.

Any thoughts ?

-- 
Arnaud A. de Grandmaison

>From 4cb739084a6d7448dc2cd7928dc2fc61e120a142 Mon Sep 17 00:00:00 2001
From: "Arnaud A. de Grandmaison" <[email protected]>
Date: Mon, 29 Jul 2013 17:40:10 +0200
Subject: [PATCH] Check dynamic_cast is not used with -fno-rtti

---
 include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 lib/Sema/SemaCast.cpp                      |  7 +++++++
 test/SemaCXX/no-rtti.cpp                   | 14 ++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 16619d9..b84f9bb 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5037,6 +5037,8 @@ def err_not_tag_in_scope : Error<
 
 def err_no_typeid_with_fno_rtti : Error<
   "cannot use typeid with -fno-rtti">;
+def err_no_dynamic_cast_with_fno_rtti : Error<
+  "cannot use dynamic_cast with -fno-rtti">;
 
 def err_cannot_form_pointer_to_member_of_reference_type : Error<
   "cannot form a pointer-to-member to member %0 of reference type %1">;
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 1adb037..888c14e 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -667,6 +667,13 @@ void CastOperation::CheckDynamicCast() {
   Self.MarkVTableUsed(OpRange.getBegin(), 
                       cast<CXXRecordDecl>(SrcRecord->getDecl()));
 
+  // dynamic_cast is not available with fno-rtti
+  if (!Self.getLangOpts().RTTI) {
+    Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
+    SrcExpr = ExprError();
+    return;
+  }
+
   // Done. Everything else is run-time checks.
   Kind = CK_Dynamic;
 }
diff --git a/test/SemaCXX/no-rtti.cpp b/test/SemaCXX/no-rtti.cpp
index 75167050..504bef1 100644
--- a/test/SemaCXX/no-rtti.cpp
+++ b/test/SemaCXX/no-rtti.cpp
@@ -8,3 +8,17 @@ void f()
 {
   (void)typeid(int); // expected-error {{cannot use typeid with -fno-rtti}}
 }
+
+namespace {
+struct A {
+  virtual ~A();
+};
+
+struct B : public A {
+  B() : A() {}
+};
+}
+
+bool isa_B(A *a) {
+  return dynamic_cast<B *>(a) != 0; // expected-error {{cannot use dynamic_cast with -fno-rtti}}
+}
-- 
1.8.1.5

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to