[gcc/devel/c++-coroutines] c++: Poor diagnostic for dynamic_cast in constexpr context [PR93414]

Iain D Sandoe iains@gcc.gnu.org
Sat Jan 25 20:20:00 GMT 2020


https://gcc.gnu.org/g:de0684bf3f72c1e7a29704bce215ab40bcb84bb6

commit de0684bf3f72c1e7a29704bce215ab40bcb84bb6
Author: Marek Polacek <polacek@redhat.com>
Date:   Fri Jan 24 18:08:58 2020 -0500

    c++: Poor diagnostic for dynamic_cast in constexpr context [PR93414]
    
    I neglected to add a proper diagnostic for the reference dynamic_cast
    case when the operand of a dynamic_cast doesn't refer to a public base
    of Derived, resulting in suboptimal error message
    
       error: call to non-'constexpr' function 'void* __cxa_bad_cast()'
    
    2020-01-25  Marek Polacek  <polacek@redhat.com>
    
    	PR c++/93414 - poor diagnostic for dynamic_cast in constexpr context.
    	* constexpr.c (cxx_eval_dynamic_cast_fn): Add a reference
    	dynamic_cast diagnostic.
    
    	* g++.dg/cpp2a/constexpr-dynamic18.C: New test.

Diff:
---
 gcc/cp/ChangeLog                                 |  6 ++++++
 gcc/cp/constexpr.c                               | 15 ++++++++++++++-
 gcc/testsuite/ChangeLog                          |  5 +++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic18.C | 22 ++++++++++++++++++++++
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ca56766..0dc1ad2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-25  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/93414 - poor diagnostic for dynamic_cast in constexpr context.
+	* constexpr.c (cxx_eval_dynamic_cast_fn): Add a reference
+	dynamic_cast diagnostic.
+
 2020-01-24  Jason Merrill  <jason@redhat.com>
 
 	PR c++/93400 - ICE with constrained friend.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 8e880634..577022e 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1888,7 +1888,20 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
   if (tree t = (TREE_CODE (obj) == COMPONENT_REF
 		? TREE_OPERAND (obj, 1) : obj))
     if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
-      return integer_zero_node;
+      {
+	if (reference_p)
+	  {
+	    if (!ctx->quiet)
+	      {
+		error_at (loc, "reference %<dynamic_cast%> failed");
+		inform (loc, "dynamic type %qT of its operand does "
+			"not have a base class of type %qT",
+			objtype, type);
+	      }
+	    *non_constant_p = true;
+	  }
+	return integer_zero_node;
+      }
 
   /* [class.cdtor] When a dynamic_cast is used in a constructor ...
      or in a destructor ... if the operand of the dynamic_cast refers
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6795839..587603f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-25  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/93414 - poor diagnostic for dynamic_cast in constexpr context.
+	* g++.dg/cpp2a/constexpr-dynamic18.C: New test.
+
 2020-01-25  Feng Xue  <fxue@os.amperecomputing.com>
 
 	PR ipa/93166
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic18.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic18.C
new file mode 100644
index 0000000..346f9f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic18.C
@@ -0,0 +1,22 @@
+// PR c++/93414 - poor diagnostic for dynamic_cast in constexpr context.
+// { dg-do compile { target c++2a } }
+// Here 'b' doesn't point/refer to a public base of Derived.
+
+struct Base {
+    constexpr virtual ~Base(){}
+};
+
+struct Derived: Base {
+    constexpr ~Derived(){}
+};
+
+constexpr const Derived& cast(const Base& b) {
+    return dynamic_cast<const Derived&>(b); // { dg-error "reference .dynamic_cast. failed" }
+// { dg-message "dynamic type .const Base. of its operand does not have a base class of type .Derived." "" { target *-*-* } .-1 }
+}
+
+auto test() {
+    static constexpr Base b;
+    constexpr auto res = cast(b);
+    return res;
+}



More information about the Gcc-cvs mailing list