This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [v2 of PATCH 03/14] C++: add location_t wrapper nodes during parsing (minimal impl)
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Nathan Sidwell <nathan at acm dot org>, Jakub Jelinek <jakub at redhat dot com>, Richard Biener <richard dot guenther at gmail dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 05 Jan 2018 17:20:08 -0500
- Subject: Re: [v2 of PATCH 03/14] C++: add location_t wrapper nodes during parsing (minimal impl)
- Authentication-results: sourceware.org; auth=none
- References: <CADzB+2mPVCyX1izR9d4X+P9LjJtmM8XbxvZiGXXQX7zcNoabvw@mail.gmail.com> <1514567206-13093-1-git-send-email-dmalcolm@redhat.com> <1a3db854-830d-516c-61ed-ef503b47b946@redhat.com>
On Fri, 2018-01-05 at 15:29 -0500, Jason Merrill wrote:
> On 12/29/2017 12:06 PM, David Malcolm wrote:
> > One issue I ran into was that fold_for_warn doesn't eliminate
> > location wrappers when processing_template_decl, leading to
> > failures of the template-based cases in
> > g++.dg/warn/Wmemset-transposed-args-1.C.
> >
> > This is due to the early bailout when processing_template_decl
> > within cp_fold:
> >
> > 2078 if (processing_template_decl
> > 2079 || (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE
> > (x) == error_mark_node)))
> > 2080 return x;
> >
> > which dates back to the merger of the C++ delayed folding branch.
> >
> > I've fixed that in this version of the patch by removing that
> > "processing_template_decl ||" condition from that cp_fold early
> > bailout.
>
> Hmm, that makes me nervous. We might want to fold in templates when
> called from fold_for_warn, but not for other occurrences. But I see
> that we check processing_template_decl in cp_fully_fold and in the
> call
> to cp_fold_function, so I guess this is fine.
(I wondered if it would be possible to add a new flag to the various
fold* calls to request folding in templates, but given that the API is
partially shared with C doing so doesn't seem to make sense)
> > + case VIEW_CONVERT_EXPR:
> > + case NON_LVALUE_EXPR:
> > case CAST_EXPR:
> > case REINTERPRET_CAST_EXPR:
> > case CONST_CAST_EXPR:
> > @@ -14937,6 +14940,15 @@ tsubst_copy (tree t, tree args,
> > tsubst_flags_t complain, tree in_decl)
> > case CONVERT_EXPR:
> > case NOP_EXPR:
> > {
> > + if (location_wrapper_p (t))
> > + {
> > + /* Handle location wrappers by substituting the
> > wrapped node
> > + first, *then* reusing the resulting type. Doing
> > the type
> > + first ensures that we handle template parameters
> > and
> > + parameter pack expansions. */
> > + tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args,
> > complain, in_decl);
> > + return build1 (code, TREE_TYPE (op0), op0);
> > + }
>
> I'd rather handle location wrappers separately, and abort if
> VIEW_CONVERT_EXPR or NON_LVALUE_EXPR appear other than as wrappers.
OK. I'm testing an updated version which does so.
> > @@ -24998,6 +25018,8 @@ build_non_dependent_expr (tree expr)
> > && !expanding_concept ())
> > fold_non_dependent_expr (expr);
> >
> > + STRIP_ANY_LOCATION_WRAPPER (expr);
>
> Why is this needed?
I added this to fix a failure:
template argument deduction/substitution failed:
note: cannot convert ‘0’ (type ‘int’) to type ‘char**’
seen building the precompiled header, where build_non_dependent_expr
adds a NON_DEPENDENT_EXPR around a location wrapper around an
INTEGER_CST, whereas without location wrappers we'd just have an
INTEGER_CST.
build_non_dependent_expr performs various tests for exact TREE_CODEs,
special-casing constants; without the stripping these TREE_CODE tests
don't match when the constants have location wrappers, leading to the
failure.
Here are the gory details:
In file included from ./src/libstdc++-
v3/include/precompiled/extc++.h:82:
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h: In member function ‘virtual
std::codecvt_base::result std::codecvt<_InternT, _ExternT,
__gnu_cxx::__cxx11::encoding_state>::do_unshift(std::codecvt<_InternT,
_ExternT, __gnu_cxx::__cxx11::encoding_state>::state_type&,
std::codecvt<_InternT, _ExternT,
__gnu_cxx::__cxx11::encoding_state>::extern_type*,
std::codecvt<_InternT, _ExternT,
__gnu_cxx::__cxx11::encoding_state>::extern_type*,
std::codecvt<_InternT, _ExternT,
__gnu_cxx::__cxx11::encoding_state>::extern_type*&) const’:
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:392:58: error: no matching
function for call to ‘__iconv_adaptor(size_t (&)(iconv_t, char**,
size_t*, char**, size_t*), void* const&, int, int, char**,
std::size_t*)’
&__cto, &__tlen);
^
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:301:5: note: candidate:
‘template<class _Tp> std::size_t std::__iconv_adaptor(std::size_t
(*)(iconv_t, _Tp, std::size_t*, char**, std::size_t*), iconv_t, char**,
std::size_t*, char**, std::size_t*)’
__iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**,
size_t*),
^~~~~~~~~~~~~~~
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:301:5: note: template
argument deduction/substitution failed:
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:392:58: note: cannot convert
‘0’ (type ‘int’) to type ‘char**’
&__cto, &__tlen);
^
(gdb) call debug_tree (arg)
<non_dependent_expr 0x7fffe7402820
type <integer_type 0x7ffff0e4f5e8 int asm_written public type_6 SI
size <integer_cst 0x7ffff0e520c0 constant 32>
unit-size <integer_cst 0x7ffff0e520d8 constant 4>
align:32 warn_if_not_align:0 symtab:-291372496 alias-set -1
canonical-type 0x7ffff0e4f5e8 precision:32 min <integer_cst
0x7ffff0e52078 -2147483648> max <integer_cst 0x7ffff0e52090 2147483647>
pointer_to_this <pointer_type 0x7ffff0e57a80> reference_to_this
<reference_type 0x7fffee916e70>>
arg:0 <non_lvalue_expr 0x7fffe7402720 type <integer_type
0x7ffff0e4f5e8 int>
constant
arg:0 <integer_cst 0x7ffff0e52210 constant 0>
./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:391:50 start: ./build/x86_64-
pc-linux-gnu/libstdc++-v3/include/ext/codecvt_specializations.h:391:50
finish: ./build/x86_64-pc-linux-gnu/libstdc++-
v3/include/ext/codecvt_specializations.h:391:50>>
...when for a unpatched build we'd just have an INTEGER_CST.
Given the various TREE_CODE comparisons, using the
STRIP_ANY_LOCATION_WRAPPER macro seemed most appropriate; I put it
before the first TREE_CODE test.
I also added selftest::test_build_non_dependent_expr for this, to
verify that location wrappers don't affect the result of
build_non_dependent_expr (for integer constants and on string
literals).
Thanks
Dave