diff options
author | Marek Polacek <polacek@redhat.com> | 2020-01-24 18:08:58 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2020-01-25 14:26:07 -0500 |
commit | de0684bf3f72c1e7a29704bce215ab40bcb84bb6 (patch) | |
tree | 0c6b84992dd87dd390731bee7c92d1c38438af14 /gcc | |
parent | 10be08aa276916b4dc286abc269ed0a175f033dd (diff) | |
download | gcc-de0684bf3f72c1e7a29704bce215ab40bcb84bb6.zip gcc-de0684bf3f72c1e7a29704bce215ab40bcb84bb6.tar.gz gcc-de0684bf3f72c1e7a29704bce215ab40bcb84bb6.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic18.C | 22 |
4 files changed, 47 insertions, 1 deletions
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; +} |