With the patch :)

On 07/29/2013 06:47 PM, Arnaud A. de Grandmaison wrote:
> On 07/29/2013 06:17 PM, Jean-Daniel Dupas wrote:
>> Le 29 juil. 2013 à 17:52, Arnaud A. de Grandmaison <[email protected]> 
>> a écrit :
>>
>>> 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 ?
>> If we want to support dynamic_cast without rtti when possible (as you do in 
>> your patch), you may add such case in the test to make sure clang accepts it.
> Good point. I added a test for the 2 cases we accept (upcast, and cast
> to same type).
>
>> -- Jean-Daniel
>>
>>
>>
>>
>


-- 
Arnaud A. de Grandmaison

>From 64f1420f41a9b8d43eb6b5ae5f78696e7d2846bc Mon Sep 17 00:00:00 2001
From: "Arnaud A. de Grandmaison" <[email protected]>
Date: Mon, 29 Jul 2013 18:43:27 +0200
Subject: [PATCH] Check dynamic_cast is not used with -fno-rtti, unless it is a
 noop or can be resolved statically.

---
 include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 lib/Sema/SemaCast.cpp                      |  7 +++++++
 test/SemaCXX/dynamic_cast-no-rtti.cpp      | 22 ++++++++++++++++++++++
 test/SemaCXX/no-rtti.cpp                   | 14 ++++++++++++++
 4 files changed, 45 insertions(+)
 create mode 100644 test/SemaCXX/dynamic_cast-no-rtti.cpp

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/dynamic_cast-no-rtti.cpp b/test/SemaCXX/dynamic_cast-no-rtti.cpp
new file mode 100644
index 0000000..03f7b42
--- /dev/null
+++ b/test/SemaCXX/dynamic_cast-no-rtti.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fno-rtti %s
+// expected-no-diagnostics
+
+namespace {
+struct A {
+  virtual ~A(){};
+};
+
+struct B : public A {
+  B() : A() {}
+};
+}
+
+// Upcasts are resolved statically and will not require runtime support.
+A *upcast(B *b) {
+  return dynamic_cast<A *>(b);
+}
+
+// The dynamic_cast is a NoOp here and will not require runtime support.
+B *samecast(B *b) {
+  return dynamic_cast<B *>(b);
+}
diff --git a/test/SemaCXX/no-rtti.cpp b/test/SemaCXX/no-rtti.cpp
index 75167050..3d6e109 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