This is the mail archive of the
mailing list for the GCC project.
Re: [C++ Patch] [PR c++/88146] do not crash synthesizing inherited ctor(...)
- From: Jason Merrill <jason at redhat dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 14 Dec 2018 15:42:22 -0500
- Subject: Re: [C++ Patch] [PR c++/88146] do not crash synthesizing inherited ctor(...)
- References: <email@example.com>
On 12/6/18 7:23 PM, Alexandre Oliva wrote:
This patch started out from the testcase in PR88146, that attempted to
synthesize an inherited ctor without any args before a varargs
ellipsis and crashed while at that, because of the unguarded
dereferencing of the parm type list, that usually contains a
terminator. The terminator is not there for varargs functions,
however, and without any other args, we ended up dereferencing a NULL
Guarding the accesses there was easy, but I missed the sorry message
we got in other testcases that passed arguments through the ellipsis
in inherited ctors. I put a check in, and noticed the inherited ctors
were synthesized with the location assigned to the class name,
although they were initially assigned the location of the using
declaration. I decided the latter was better, and arranged for the
better location to be retained.
Further investigation revealed the lack of a sorry message had to do
with the call being in a non-evaluated context, in this case, a
noexcept expression. The sorry would be correctly reported in other
contexts, so I rolled back the check I'd added, but retained the
source location improvement.
I was still concerned about issuing sorry messages while instantiating
template ctors even in non-evaluated contexts, e.g., if a template
ctor had a base initializer that used an inherited ctor with enough
arguments that they'd go through an ellipsis. I wanted to defer the
instantiation of such template ctors, but that would have been wrong
for constexpr template ctors, and already done for non-constexpr ones.
So, I just consolidated multiple test variants into a single testcase
that explores and explains various of the possibilities I thought of.
Regstrapped on x86_64- and i686-linux-gnu, mistakenly along with a patch
with a known regression, and got only that known regression. Retesting
without it. Ok to install?
* method.c (do_build_copy_constructor): Do not crash with
ellipsis-only parm list.
(synthesize_method): Retain location of inherited ctor.
* g++.dg/cpp0x/inh-ctor32.C: New.
gcc/cp/method.c | 9 +
gcc/testsuite/g++.dg/cpp0x/inh-ctor32.C | 229 +++++++++++++++++++++++++++++++
2 files changed, 234 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/inh-ctor32.C
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index fd023e200538..41d609fb1de6 100644
@@ -643,7 +643,7 @@ do_build_copy_constructor (tree fndecl)
bool trivial = trivial_fn_p (fndecl);
tree inh = DECL_INHERITED_CTOR (fndecl);
- if (!inh)
+ if (parm && !inh)
parm = convert_from_reference (parm);
If inh is false, we're a copy constructor, which always has a parm, so
this hunk seems unnecessary.
@@ -677,7 +677,7 @@ do_build_copy_constructor (tree fndecl)
tree fields = TYPE_FIELDS (current_class_type);
tree member_init_list = NULL_TREE;
- int cvquals = cp_type_quals (TREE_TYPE (parm));
+ int cvquals = parm ? cp_type_quals (TREE_TYPE (parm)) : 0;
This could also check !inh.