From ea379c9ec3776b9d4f72d5d8c8987e2e43c7baae Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Mon, 20 Aug 2018 13:52:29 +0000 Subject: [PATCH 1/8] [debug] Fix handling of vlas in lto Atm, when running vla-1.c with -O0 -flto, we have: ... FAIL: gcc.dg/guality/vla-1.c -O0 -flto -fuse-linker-plugin \ -fno-fat-lto-objects line 17 sizeof (a) == 6 ... The vla a[i + 1] in f1 is gimplified into: ... f1 (int i) { char a[0:D.1922] [value-expr: *a.0]; char[0:D.1922] * a.0; D.1921 = i + 1; D.1926 = (sizetype) D.1921; a.0 = __builtin_alloca_with_align (D.1926, 8); ... The early debug info for the upper bound of the type of vla a that we stream out is: ... DIE 0: DW_TAG_subrange_type (0x7f85029a90f0) DW_AT_upper_bound: location descriptor: (0x7f85029a9230) DW_OP_GNU_variable_value die -> 0 (0x7f85029a94b0), 0 DIE 0: DW_TAG_variable (0x7f85029a94b0) DW_AT_name: "D.1922" DW_AT_type: die -> 0 (0x7f85029a3d70) DW_AT_artificial: 1 ... and in ltrans we have for that same upper bound: ... DIE 0: DW_TAG_subrange_type (0x7f5183b57d70) DW_AT_upper_bound: die -> 0 (0x7f5183b576e0) DIE 0: DW_TAG_variable (0x7f5183b576e0) DW_AT_name: "D.4278" DW_AT_abstract_origin: die -> label: vla_1.c.6719312a + 193 (0x7f5183b57730) ... where D.4278 has abstract origin D.1922. The D.4278 die has no DW_AT_location, so when evaluting "sizeof (a)" in the debugger, we can't find the information to get the value of D.4278, and the debugger prints "". This patch fixes that by either: - adding DW_AT_location to the referenced variable die, or - instead of using a ref for the upper bound, using an exprloc. When changing gcc.dg/guality/guality.exp to run the usual flto flavours "-fno-use-linker-plugin -flto-partition=none" and "-fuse-linker-plugin -fno-fat-lto-objects" in combination with O0, Og, O1, O2, O3 and Os, this patch fixes all (20) failures in vla-1.c, leaving only: ... No symbol "i" in current context. UNSUPPORTED: gcc.dg/guality/vla-1.c -O3 -flto -fno-use-linker-plugin \ -flto-partition=none line 17 i == 5 'a' has unknown type; cast it to its declared type UNSUPPORTED: gcc.dg/guality/vla-1.c -O3 -flto -fno-use-linker-plugin \ -flto-partition=none line 17 sizeof (a) == 6 ... Bootstrapped and reg-tested on x86_64. 2018-08-20 Tom de Vries * dwarf2out.c (add_scalar_info): Don't add reference to existing die unless the referenced die describes the added property using DW_AT_location or DW_AT_const_value. Fall back to exprloc case. Otherwise, add a DW_AT_location to the referenced die. From-SVN: r263660 --- gcc/ChangeLog | 7 +++++++ gcc/dwarf2out.c | 32 ++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec1fb242c239..3dbcd1c82dbb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-08-20 Tom de Vries + + * dwarf2out.c (add_scalar_info): Don't add reference to existing die + unless the referenced die describes the added property using + DW_AT_location or DW_AT_const_value. Fall back to exprloc case. + Otherwise, add a DW_AT_location to the referenced die. + 2018-08-19 Uros Bizjak PR target/86994 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 236f199afcf0..b80c909e1fc6 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -20598,7 +20598,7 @@ static void add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, int forms, struct loc_descr_context *context) { - dw_die_ref context_die, decl_die; + dw_die_ref context_die, decl_die = NULL; dw_loc_list_ref list; bool strip_conversions = true; bool placeholder_seen = false; @@ -20675,7 +20675,7 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, if (decl != NULL_TREE) { - dw_die_ref decl_die = lookup_decl_die (decl); + decl_die = lookup_decl_die (decl); /* ??? Can this happen, or should the variable have been bound first? Probably it can, since I imagine that we try to create @@ -20684,8 +20684,12 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, later parameter. */ if (decl_die != NULL) { - add_AT_die_ref (die, attr, decl_die); - return; + if (get_AT (decl_die, DW_AT_location) + || get_AT (decl_die, DW_AT_const_value)) + { + add_AT_die_ref (die, attr, decl_die); + return; + } } } } @@ -20729,15 +20733,19 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, || placeholder_seen) return; - if (current_function_decl == 0) - context_die = comp_unit_die (); - else - context_die = lookup_decl_die (current_function_decl); + if (!decl_die) + { + if (current_function_decl == 0) + context_die = comp_unit_die (); + else + context_die = lookup_decl_die (current_function_decl); + + decl_die = new_die (DW_TAG_variable, context_die, value); + add_AT_flag (decl_die, DW_AT_artificial, 1); + add_type_attribute (decl_die, TREE_TYPE (value), TYPE_QUAL_CONST, false, + context_die); + } - decl_die = new_die (DW_TAG_variable, context_die, value); - add_AT_flag (decl_die, DW_AT_artificial, 1); - add_type_attribute (decl_die, TREE_TYPE (value), TYPE_QUAL_CONST, false, - context_die); add_AT_location_description (decl_die, DW_AT_location, list); add_AT_die_ref (die, attr, decl_die); } From a2c5e1ae5988cef25799a569f3255ac14c8ba41a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 20 Aug 2018 14:53:56 +0100 Subject: [PATCH 2/8] PR libstdc++/86963 Remove use of __tuple_base in std::tuple The _Tuple_impl base class can be used to disable copy/move assignment, without requiring an extra base class. Exception specifications on std::tuple assignment and swap functions can be defined directly using is_nothrow_swappable, instead of querying the base classes. PR libstdc++/86963 * include/std/tuple (_Tuple_impl::operator=): Define as deleted. (_Tuple_impl::_M_assign): New functions to perform assignment instead of assignment operators. (_Tuple_impl::_M_swap): Remove exception specification. (_Tuple_impl<_Idx, _Head>): Likewise. (_TC::_NonNestedTuple, _TC::_NotSameTuple): Use __remove_cvref_t. (__tuple_base): Remove. (tuple, tuple<_T1, _T2>): Remove inheritance from __tuple_base. (tuple::operator=, tuple<_T1, _T2>::operator=): Call _M_assign. (tuple::swap, tuple<_T1, _T2>::swap): Define exception specification using __is_nothrow_swappable. (tuple<_T1, _T2>::tuple(_U1&&, _U2&&)): Use __remove_cvref_t. From-SVN: r263661 --- libstdc++-v3/ChangeLog | 14 ++++ libstdc++-v3/include/std/tuple | 133 +++++++++++---------------------- 2 files changed, 57 insertions(+), 90 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 39855d9b6918..48455953db8e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,19 @@ 2018-08-20 Jonathan Wakely + PR libstdc++/86963 + * include/std/tuple (_Tuple_impl::operator=): Define as deleted. + (_Tuple_impl::_M_assign): New functions to perform assignment instead + of assignment operators. + (_Tuple_impl::_M_swap): Remove exception specification. + (_Tuple_impl<_Idx, _Head>): Likewise. + (_TC::_NonNestedTuple, _TC::_NotSameTuple): Use __remove_cvref_t. + (__tuple_base): Remove. + (tuple, tuple<_T1, _T2>): Remove inheritance from __tuple_base. + (tuple::operator=, tuple<_T1, _T2>::operator=): Call _M_assign. + (tuple::swap, tuple<_T1, _T2>::swap): Define exception specification + using __is_nothrow_swappable. + (tuple<_T1, _T2>::tuple(_U1&&, _U2&&)): Use __remove_cvref_t. + * include/std/optional (_Optional_payload): Use variable templates for conditions in default template arguments and exception specifications. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 955b853066f9..56b97c25eed4 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -219,6 +219,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2729. Missing SFINAE on std::pair::operator= + _Tuple_impl& operator=(const _Tuple_impl&) = delete; + constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_, @@ -288,49 +292,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } - _Tuple_impl& - operator=(const _Tuple_impl& __in) - { - _M_head(*this) = _M_head(__in); - _M_tail(*this) = _M_tail(__in); - return *this; - } - - _Tuple_impl& - operator=(_Tuple_impl&& __in) - noexcept(__and_, - is_nothrow_move_assignable<_Inherited>>::value) - { - _M_head(*this) = std::forward<_Head>(_M_head(__in)); - _M_tail(*this) = std::move(_M_tail(__in)); - return *this; - } - template - _Tuple_impl& - operator=(const _Tuple_impl<_Idx, _UElements...>& __in) + void + _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); - _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); - return *this; + _M_tail(*this)._M_assign( + _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)); } template - _Tuple_impl& - operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) + void + _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { _M_head(*this) = std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); - _M_tail(*this) = std::move - (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); - return *this; + _M_tail(*this)._M_assign( + std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); } protected: void _M_swap(_Tuple_impl& __in) - noexcept(__is_nothrow_swappable<_Head>::value - && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; swap(_M_head(*this), _M_head(__in)); @@ -367,6 +350,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2729. Missing SFINAE on std::pair::operator= + _Tuple_impl& operator=(const _Tuple_impl&) = delete; + constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(is_nothrow_move_constructible<_Head>::value) @@ -420,42 +407,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } - _Tuple_impl& - operator=(const _Tuple_impl& __in) - { - _M_head(*this) = _M_head(__in); - return *this; - } - - _Tuple_impl& - operator=(_Tuple_impl&& __in) - noexcept(is_nothrow_move_assignable<_Head>::value) - { - _M_head(*this) = std::forward<_Head>(_M_head(__in)); - return *this; - } - template - _Tuple_impl& - operator=(const _Tuple_impl<_Idx, _UHead>& __in) + void + _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); - return *this; } template - _Tuple_impl& - operator=(_Tuple_impl<_Idx, _UHead>&& __in) + void + _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) { _M_head(*this) = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); - return *this; } protected: void _M_swap(_Tuple_impl& __in) - noexcept(__is_nothrow_swappable<_Head>::value) { using std::swap; swap(_M_head(*this), _M_head(__in)); @@ -495,20 +464,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static constexpr bool _NonNestedTuple() { return __and_<__not_, - typename remove_cv< - typename remove_reference<_SrcTuple>::type - >::type>>, + __remove_cvref_t<_SrcTuple>>>, __not_>, __not_> >::value; } + template static constexpr bool _NotSameTuple() { return __not_, - typename remove_const< - typename remove_reference<_UElements...>::type - >::type>>::value; + __remove_cvref_t<_UElements>...>>::value; } }; @@ -544,30 +510,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } + template static constexpr bool _NotSameTuple() { - return true; + return true; } }; - // The tag parameter ensures that in nested tuples each __tuple_base - // is a different type and can use the empty base-class optimisation. - template - class __tuple_base - { - template friend struct tuple; - __tuple_base() = default; - ~__tuple_base() = default; - __tuple_base(const __tuple_base&) = default; - __tuple_base& operator=(const __tuple_base&) = delete; - }; - /// Primary class template, tuple template - class tuple - : public _Tuple_impl<0, _Elements...>, - private __tuple_base> + class tuple : public _Tuple_impl<0, _Elements...> { typedef _Tuple_impl<0, _Elements...> _Inherited; @@ -858,13 +811,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } + // tuple assignment + tuple& operator=(typename conditional<__assignable(), const tuple&, const __nonesuch_no_braces&>::type __in) noexcept(__nothrow_assignable()) { - static_cast<_Inherited&>(*this) = __in; + this->_M_assign(__in); return *this; } @@ -874,7 +829,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __nonesuch_no_braces&&>::type __in) noexcept(__nothrow_assignable<_Elements...>()) { - static_cast<_Inherited&>(*this) = std::move(__in); + this->_M_assign(std::move(__in)); return *this; } @@ -883,7 +838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(const tuple<_UElements...>& __in) noexcept(__nothrow_assignable()) { - static_cast<_Inherited&>(*this) = __in; + this->_M_assign(__in); return *this; } @@ -892,13 +847,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(tuple<_UElements...>&& __in) noexcept(__nothrow_assignable<_UElements...>()) { - static_cast<_Inherited&>(*this) = std::move(__in); + this->_M_assign(std::move(__in)); return *this; } + // tuple swap void swap(tuple& __in) - noexcept(noexcept(__in._M_swap(__in))) + noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) { _Inherited::_M_swap(__in); } }; @@ -934,9 +890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Partial specialization, 2-element tuple. /// Includes construction and assignment from a pair. template - class tuple<_T1, _T2> - : public _Tuple_impl<0, _T1, _T2>, - private __tuple_base> + class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> { typedef _Tuple_impl<0, _T1, _T2> _Inherited; @@ -1009,8 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() - && !is_same::type, - allocator_arg_t>::value, + && !is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value, bool>::type = true> constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } @@ -1020,8 +973,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() - && !is_same::type, - allocator_arg_t>::value, + && !is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value, bool>::type = false> explicit constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } @@ -1255,7 +1207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const __nonesuch_no_braces&>::type __in) noexcept(__nothrow_assignable()) { - static_cast<_Inherited&>(*this) = __in; + this->_M_assign(__in); return *this; } @@ -1265,7 +1217,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __nonesuch_no_braces&&>::type __in) noexcept(__nothrow_assignable<_T1, _T2>()) { - static_cast<_Inherited&>(*this) = std::move(__in); + this->_M_assign(std::move(__in)); return *this; } @@ -1274,7 +1226,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(const tuple<_U1, _U2>& __in) noexcept(__nothrow_assignable()) { - static_cast<_Inherited&>(*this) = __in; + this->_M_assign(__in); return *this; } @@ -1283,7 +1235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(tuple<_U1, _U2>&& __in) noexcept(__nothrow_assignable<_U1, _U2>()) { - static_cast<_Inherited&>(*this) = std::move(__in); + this->_M_assign(std::move(__in)); return *this; } @@ -1309,7 +1261,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(tuple& __in) - noexcept(noexcept(__in._M_swap(__in))) + noexcept(__and_<__is_nothrow_swappable<_T1>, + __is_nothrow_swappable<_T2>>::value) { _Inherited::_M_swap(__in); } }; From 4864297f7858617a5fe406d3651a46446b41db7a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 20 Aug 2018 14:01:05 +0000 Subject: [PATCH 3/8] re PR c++/78655 (gcc doesn't exploit the fact that the result of pointer addition can not be nullptr) 2018-08-20 Richard Biener PR tree-optimization/78655 * tree-vrp.c (extract_range_from_binary_expr_1): Make pointer + offset nonnull if either operand is nonnull work. * gcc.dg/tree-ssa/evrp11.c: New testcase. From-SVN: r263662 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/evrp11.c | 23 +++++++++++++++++++++++ gcc/tree-vrp.c | 7 ++++++- 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/evrp11.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dbcd1c82dbb..6cf673c73829 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-08-20 Richard Biener + + PR tree-optimization/78655 + * tree-vrp.c (extract_range_from_binary_expr_1): Make + pointer + offset nonnull if either operand is nonnull work. + 2018-08-20 Tom de Vries * dwarf2out.c (add_scalar_info): Don't add reference to existing die diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e89f4a4c093b..1eaec9008da9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-20 Richard Biener + + PR tree-optimization/78655 + * gcc.dg/tree-ssa/evrp11.c: New testcase. + 2018-08-18 Iain Sandoe * gcc.dg/debug/dwarf2/pr80263.c: Suppress pubtypes output diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c new file mode 100644 index 000000000000..f1373bd8683c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +extern void link_error (); + +void foo (int *x) +{ + int *p = x + 1; + if (p == 0) + link_error (); +} + +void bar (char *x, int a) +{ + if (a != 0) + { + char *p = x + a; + if (p == 0) + link_error (); + } +} + +/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index d553a254878a..2ddb0c2c197e 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1437,6 +1437,7 @@ extract_range_from_binary_expr_1 (value_range *vr, && code != PLUS_EXPR && code != MINUS_EXPR && code != RSHIFT_EXPR + && code != POINTER_PLUS_EXPR && (vr0.type == VR_VARYING || vr1.type == VR_VARYING || vr0.type != vr1.type @@ -1467,7 +1468,11 @@ extract_range_from_binary_expr_1 (value_range *vr, { /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ - if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) + if (range_is_nonnull (&vr0) + || range_is_nonnull (&vr1) + || (vr1.type == VR_RANGE + && !symbolic_range_p (&vr1) + && !range_includes_zero_p (vr1.min, vr1.max))) set_value_range_to_nonnull (vr, expr_type); else if (range_is_null (&vr0) && range_is_null (&vr1)) set_value_range_to_null (vr, expr_type); From abcd1775e067600918da69330f8ff3f1f6734b4c Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 20 Aug 2018 14:20:04 +0000 Subject: [PATCH 4/8] [PATCH] Kill cpp-id-data.h https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01149.html libcpp/ * Makefile.in (TAGS_SOURCES): Remove cpp-id-data.h. * include/cpp-id-data.h: Delete. * internal.h: Include cpplib.h not cpp-id-data.h. gcc/ * Makefile.in (CPP_ID_DATA_H): Delete. (CPP_INTERNAL_H): Don't add it. (GTFILES): Replace CPP_ID_DATA_H with CPPLIB_H. * gengtype.c (open_base_files): Replace cpp-id-data.h with cpplib.h From-SVN: r263663 --- gcc/ChangeLog | 7 +++++++ gcc/Makefile.in | 5 ++--- gcc/gengtype.c | 2 +- libcpp/ChangeLog | 4 ++++ libcpp/Makefile.in | 5 ++--- libcpp/include/cpp-id-data.h | 19 ------------------- libcpp/internal.h | 2 +- 7 files changed, 17 insertions(+), 27 deletions(-) delete mode 100644 libcpp/include/cpp-id-data.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6cf673c73829..868d28338dfc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-08-20 Nathan Sidwell + + * Makefile.in (CPP_ID_DATA_H): Delete. + (CPP_INTERNAL_H): Don't add it. + (GTFILES): Replace CPP_ID_DATA_H with CPPLIB_H. + * gengtype.c (open_base_files): Replace cpp-id-data.h with cpplib.h + 2018-08-20 Richard Biener PR tree-optimization/78655 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d8d2b885f6d9..e008f63b2ea4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -978,8 +978,7 @@ CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h OPTS_H = $(INPUT_H) $(VEC_H) opts.h $(OBSTACK_H) SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h $(OBSTACK_H) -CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h -CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H) +CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) $(DUMPFILE_H) TREE_PASS_H = tree-pass.h $(TIMEVAR_H) $(DUMPFILE_H) TREE_SSA_H = tree-ssa.h tree-ssa-operands.h \ @@ -2522,7 +2521,7 @@ s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd generic-match.c $(STAMP) s-match -GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ +GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(host_xm_file_list) \ $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \ $(srcdir)/wide-int.h $(srcdir)/alias.h \ diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 0db5528e6323..4339456e9c67 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -1721,7 +1721,7 @@ open_base_files (void) "tree-vrp.h", "tree-phinodes.h", "ssa-iterators.h", "stringpool.h", "tree-ssanames.h", "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h", "tree-ssa-loop-niter.h", "tree-into-ssa.h", - "tree-dfa.h", "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h", + "tree-dfa.h", "tree-ssa.h", "reload.h", "cpplib.h", "tree-chrec.h", "except.h", "output.h", "cfgloop.h", "target.h", "lto-streamer.h", "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h", "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-offload.h", NULL diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 2e347db4556b..19d89b172271 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,9 @@ 2018-08-20 Nathan Sidwell + * Makefile.in (TAGS_SOURCES): Remove cpp-id-data.h. + * include/cpp-id-data.h: Delete. + * internal.h: Include cpplib.h not cpp-id-data.h. + * include/cpp-id-data.h (struct answer): Delete. * include/cpplib.h (struct answer): Don't forward-declare. (enum cpp_macro_kind): Add cmk_assert. diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in index bfd6069c2506..835c835183fe 100644 --- a/libcpp/Makefile.in +++ b/libcpp/Makefile.in @@ -261,9 +261,8 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES) sed 's:$(srcdir)/::g' po/$(PACKAGE).pot rm po/$(PACKAGE).pot.tmp -TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h ucnid.h \ - include/line-map.h include/symtab.h include/cpp-id-data.h \ - include/cpplib.h include/mkdeps.h system.h +TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h system.h ucnid.h \ + include/cpplib.h include/line-map.h include/mkdeps.h include/symtab.h TAGS: $(TAGS_SOURCES) cd $(srcdir) && etags $(TAGS_SOURCES) diff --git a/libcpp/include/cpp-id-data.h b/libcpp/include/cpp-id-data.h deleted file mode 100644 index 909f8286a093..000000000000 --- a/libcpp/include/cpp-id-data.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Structures that hang off cpp_identifier, for PCH. - Copyright (C) 1986-2018 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -. */ - -#include "cpplib.h" - diff --git a/libcpp/internal.h b/libcpp/internal.h index e40b20f267ce..59f830c6a8e5 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -23,7 +23,7 @@ along with this program; see the file COPYING3. If not see #define LIBCPP_INTERNAL_H #include "symtab.h" -#include "cpp-id-data.h" +#include "cpplib.h" #if HAVE_ICONV #include From be3cfb9da549517523d9ee9177d327481dc788de Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 20 Aug 2018 14:20:59 +0000 Subject: [PATCH 5/8] re PR target/86984 (invalid relocation accessing a const char array) PR target/86984 * expr.c (expand_assignment): Assert that bitpos is positive. (store_field): Likewise (expand_expr_real_1): Make sure that bitpos is positive. * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed integer overflow. PR target/86984 * gcc.target/alpha/pr86984.c: New test. From-SVN: r263664 --- gcc/ChangeLog | 9 +++ gcc/config/alpha/alpha.h | 2 +- gcc/expr.c | 11 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/alpha/pr86984.c | 96 ++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/alpha/pr86984.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 868d28338dfc..feee8a29e3a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-08-20 Bernd Edlinger + + PR target/86984 + * expr.c (expand_assignment): Assert that bitpos is positive. + (store_field): Likewise + (expand_expr_real_1): Make sure that bitpos is positive. + * config/alpha/alpha.h (CONSTANT_ADDRESS_P): Avoid signed + integer overflow. + 2018-08-20 Nathan Sidwell * Makefile.in (CPP_ID_DATA_H): Delete. diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 6802ef386ede..aa1de8a797a6 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -678,7 +678,7 @@ enum reg_class { #define CONSTANT_ADDRESS_P(X) \ (CONST_INT_P (X) \ - && (unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000) + && (UINTVAL (X) + 0x8000) < 0x10000) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. diff --git a/gcc/expr.c b/gcc/expr.c index c071be677839..0d79d0896336 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5270,6 +5270,7 @@ expand_assignment (tree to, tree from, bool nontemporal) MEM_VOLATILE_P (to_rtx) = 1; } + gcc_checking_assert (known_ge (bitpos, 0)); if (optimize_bitfield_assignment_op (bitsize, bitpos, bitregion_start, bitregion_end, mode1, to_rtx, to, from, @@ -7046,6 +7047,7 @@ store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos, } /* Store the value in the bitfield. */ + gcc_assert (known_ge (bitpos, 0)); store_bit_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode, temp, reverse); @@ -10545,6 +10547,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, mode2 = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0); + /* Make sure bitpos is not negative, it can wreak havoc later. */ + if (maybe_lt (bitpos, 0)) + { + gcc_checking_assert (offset == NULL_TREE); + offset = size_int (bits_to_bytes_round_down (bitpos)); + bitpos = num_trailing_bits (bitpos); + } + /* If we have either an offset, a BLKmode result, or a reference outside the underlying object, we must force it to memory. Such a case can occur in Ada if we have unchecked conversion @@ -10795,6 +10805,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && GET_MODE_CLASS (ext_mode) == MODE_INT) reversep = TYPE_REVERSE_STORAGE_ORDER (type); + gcc_checking_assert (known_ge (bitpos, 0)); op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, (modifier == EXPAND_STACK_PARM ? NULL_RTX : target), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1eaec9008da9..a0620b1b802b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-20 Bernd Edlinger + + PR target/86984 + * gcc.target/alpha/pr86984.c: New test. + 2018-08-20 Richard Biener PR tree-optimization/78655 diff --git a/gcc/testsuite/gcc.target/alpha/pr86984.c b/gcc/testsuite/gcc.target/alpha/pr86984.c new file mode 100644 index 000000000000..f6a98d4ed9c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/alpha/pr86984.c @@ -0,0 +1,96 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -Wwrite-strings -Werror -fmerge-all-constants -fno-stack-protector -mieee -fdump-rtl-expand" } */ + +struct expression { + unsigned long int num; +}; +union YYSTYPE { + unsigned long int num; + struct expression *exp; +}; + +typedef union YYSTYPE YYSTYPE; + +struct expression * new_exp_0 (int); + +union yyalloc { + short yyss_alloc; +}; + +static const signed char yypact[] = { + -9, -9, -10, -10, -9, 8, 36, -10, 13, -10, -9, -9, -9, -9, -9, -9, -9, -10, 26, 41, 45, 18, -2, 14, -10, -9, 36 }; +static const unsigned char yydefact[] = { + 0, 0, 12, 11, 0, 0, 2, 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 5, 6, 7, 8, 9, 0, 3 }; + +static const signed char yypgoto[3] = "\366\366\377"; +static const signed char yydefgoto[3] = "\377\005\006"; + +static const unsigned char yytable[] = { + 7, 1, 2, 8, 3, 4, 15, 16, 9, 18, 19, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 15, 16, 16, 26, 14, 15, 16, 17, 10, 11, 12, 13, 14, 15, 16, 0, 0, 25, 10, 11, 12, 13, 14, 15, 16, 12, 13, 14, 15, 16, 13, 14, 15, 16 }; + +static const signed char yycheck[] = { + 1, 10, 11, 4, 13, 14, 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 3, 4, 5, 6, 7, 8, 9, 9, 25, 7, 8, 9, 15, 3, 4, 5, 6, 7, 8, 9, -1, -1, 12, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 6, 7, 8, 9 }; + +static const unsigned char yyr1[] = { + 0, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; + +static const unsigned char yyr2[] = { + 0, 2, 1, 5, 3, 3, 3, 3, 3, 3, 2, 1, 1, 3 }; + +int __gettextparse (void) +{ + int yystate = 0; + short yyssa[200]; + short *yyss = yyss; + short *yyssp = yyssa; + YYSTYPE yyvsa[200]; + YYSTYPE *yyvsp = yyvsa; + enum { yystacksize = 200 }; + int yylen = 0; + goto yysetstate; + yynewstate: yyssp++; + yysetstate: *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + long unsigned int yysize = yyssp - yyss + 1; + { + short *yyss1 = yyss; + union yyalloc *yyptr = (union yyalloc *) __builtin_malloc ((yystacksize * (sizeof (short) + sizeof (YYSTYPE)) + (sizeof (union yyalloc) - 1))); + if (!yyptr) return 0; + __builtin_memcpy (&yyptr->yyss_alloc, yyss, yysize * sizeof *(yyss)); + yyss = &yyptr->yyss_alloc; + if (yyss1 != yyssa) __builtin_free (yyss1); + } + if (yyss + yystacksize - 1 <= yyssp) + return 0; + } + + int yyn = yypact[yystate]; + if (yyn == -10) + goto yydefault; + + yyn = yytable[yyn]; + if (yyn <= 0) + goto yyreduce; + + yydefault: yyn = yydefact[yystate]; + yyreduce: yylen = yyr2[yyn]; + + YYSTYPE yyval; + if (yyn == 12 && (yyval.exp = new_exp_0 (0)) != 0) + (yyval.exp)->num = (yyvsp[0].num); + + (yyvsp -= yylen, yyssp -= yylen); + yyn = yyr1[yyn]; + yystate = yypgoto[yyn - 16] + *yyssp; + if (0 <= yystate && yystate <= 54 && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - 16]; + + goto yynewstate; +} + +/* { dg-final { scan-rtl-dump-not "const_int 230584300921" "expand" } } */ +/* { dg-final { scan-assembler-not "yypgoto\\+230584300921" } } */ From e11b709d2107a504c185d75d7e1a2b0b2a2dc6fe Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 20 Aug 2018 15:01:04 +0000 Subject: [PATCH 6/8] expr.c (store_field): Change gcc_assert to gcc_checking_assert. 2018-08-20 Bernd Edlinger * expr.c (store_field): Change gcc_assert to gcc_checking_assert. From-SVN: r263665 --- gcc/ChangeLog | 4 ++++ gcc/expr.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index feee8a29e3a1..b1d08897f22e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2018-08-20 Bernd Edlinger + + * expr.c (store_field): Change gcc_assert to gcc_checking_assert. + 2018-08-20 Bernd Edlinger PR target/86984 diff --git a/gcc/expr.c b/gcc/expr.c index 0d79d0896336..58574bafbf30 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7047,7 +7047,7 @@ store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos, } /* Store the value in the bitfield. */ - gcc_assert (known_ge (bitpos, 0)); + gcc_checking_assert (known_ge (bitpos, 0)); store_bit_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode, temp, reverse); From 7692e253ee0bdab40fb896991f9208112ebfff61 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 20 Aug 2018 15:28:15 +0000 Subject: [PATCH 7/8] [CPP PATCH] Fix warning & other cleanups. https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01162.html * directives.c (do_undef): Use cpp_macro_p & cpp_builtin_macro_p. * include/cpplib.h (enum cpp_macro_kind): Remove trailing comma. (cpp_fun_like_macro_p): Make inline, define. * macro.c (cpp_define_lazily): Use UCHAR_MAX. (cpp_fun_like_macro_p): Delete. From-SVN: r263666 --- libcpp/ChangeLog | 6 ++++++ libcpp/directives.c | 4 ++-- libcpp/include/cpplib.h | 7 +++++-- libcpp/macro.c | 11 +---------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 19d89b172271..01cc25086782 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,11 @@ 2018-08-20 Nathan Sidwell + * directives.c (do_undef): Use cpp_macro_p & cpp_builtin_macro_p. + * include/cpplib.h (enum cpp_macro_kind): Remove trailing comma. + (cpp_fun_like_macro_p): Make inline, define. + * macro.c (cpp_define_lazily): Use UCHAR_MAX. + (cpp_fun_like_macro_p): Delete. + * Makefile.in (TAGS_SOURCES): Remove cpp-id-data.h. * include/cpp-id-data.h: Delete. * internal.h: Include cpplib.h not cpp-id-data.h. diff --git a/libcpp/directives.c b/libcpp/directives.c index e75462f1c0d6..f04ed7cf2c1f 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -665,12 +665,12 @@ do_undef (cpp_reader *pfile) /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier is not currently defined as a macro name. */ - if (node->type == NT_MACRO) + if (cpp_macro_p (node)) { if (node->flags & NODE_WARN) cpp_error (pfile, CPP_DL_WARNING, "undefining \"%s\"", NODE_NAME (node)); - else if ((node->flags & NODE_BUILTIN) + else if (cpp_builtin_macro_p (node) && CPP_OPTION (pfile, warn_builtin_macro_redefined)) cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED, pfile->directive_line, 0, diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index d446fb1e48c1..b784e0facd07 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -674,7 +674,7 @@ struct cpp_dir enum cpp_macro_kind { cmk_macro, /* An ISO macro (token expansion). */ cmk_assert, /* An assertion. */ - cmk_traditional, /* A traditional macro (text expansion). */ + cmk_traditional /* A traditional macro (text expansion). */ }; /* Each macro definition is recorded in a cpp_macro structure. @@ -972,7 +972,10 @@ inline bool cpp_macro_p (const cpp_hashnode *node) return node->type == NT_MACRO; } /* Returns true if NODE is a function-like user macro. */ -extern bool cpp_fun_like_macro_p (cpp_hashnode *node); +inline bool cpp_fun_like_macro_p (cpp_hashnode *node) +{ + return cpp_user_macro_p (node) && node->value.macro->fun_like; +} extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *); diff --git a/libcpp/macro.c b/libcpp/macro.c index 0f9e25d3b98f..123f63d11771 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -3551,7 +3551,7 @@ cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num) { cpp_macro *macro = node->value.macro; - gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < 255); + gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < UCHAR_MAX); macro->lazy = num + 1; } @@ -3632,15 +3632,6 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, } } -/* Returns true of NODE is a function-like macro. */ -bool -cpp_fun_like_macro_p (cpp_hashnode *node) -{ - return (node->type == NT_MACRO - && (node->flags & (NODE_BUILTIN | NODE_MACRO_ARG)) == 0 - && node->value.macro->fun_like); -} - /* Returns the name, arguments and expansion of a macro, in a format suitable to be read back in again, and therefore also for DWARF 2 debugging info. e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION". From a570d97f5b8612ad2756333e5f21098be64057df Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 20 Aug 2018 16:32:29 +0000 Subject: [PATCH 8/8] [CPP PATCH] node type https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01164.html * include/cpplib.h (NODE_BUILTIN, NODE_MACRO_ARG): Delete. Renumber others. (enum node_type): Replace NT_MACRO with NT_USER_MACRO, NT_BUILTIN_MACRO, NT_MACRO_ARG. Delete NT_ASSERTION. (NTV_MACRO, NTV_ANSWER, NTV_BUILTIN, NTV_ARGUMENT, NTV_NONE): Delete. (CPP_HASHNODE_VALUE_IDX): Delete. (union _cpp_hashnode_value): GTY tag from enum node_type directly. (struct cpp_hashnode): Adjust GTY desc for value field. (cpp_user_macro_p, cpp_builtin_macro_p, cpp_macro_p): Adjust. * directives.c (undefine_macros): Clear value.anwers, adjust flag clearing. (_cpp_test_assertion): No need to check NT_ASSERTION. (do_assert, do_unassert): Likewise. * init.c (cpp_init_special_builtins): Set type not flags. * macro.c (struct macro_arg_saved_data): Add type field. (cpp_get_token_1): Check type not NT_VOID. (_cpp_free_definition): Adjust flag clearing. Nullify value.answers. (_cpp_save_parameter, _cpp_unsave_parameters): Save and restore type. (lex_expansion_token): Check type not flags. (_cpp_create_definition): Set type to NT_USER_MACRO. (_cpp_notify_macro_use): Adjust type checking. * pch.c (write_macdef, count_defs, write_defs, cpp_valid_state) (save_macros): Adjust node type/flag handling. * traditional.c (_cpp_scan_out_logical_line): Check type not flags. From-SVN: r263667 --- libcpp/ChangeLog | 28 ++++++++++ libcpp/directives.c | 29 ++++------ libcpp/include/cpplib.h | 71 +++++++++--------------- libcpp/init.c | 3 +- libcpp/macro.c | 44 ++++++++------- libcpp/pch.c | 118 +++++++++++++++++----------------------- libcpp/traditional.c | 2 +- 7 files changed, 141 insertions(+), 154 deletions(-) diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 01cc25086782..8998c0dace93 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,33 @@ 2018-08-20 Nathan Sidwell + * include/cpplib.h (NODE_BUILTIN, NODE_MACRO_ARG): Delete. + Renumber others. + (enum node_type): Replace NT_MACRO with NT_USER_MACRO, + NT_BUILTIN_MACRO, NT_MACRO_ARG. Delete NT_ASSERTION. + (NTV_MACRO, NTV_ANSWER, NTV_BUILTIN, NTV_ARGUMENT, NTV_NONE): + Delete. + (CPP_HASHNODE_VALUE_IDX): Delete. + (union _cpp_hashnode_value): GTY tag from enum node_type directly. + (struct cpp_hashnode): Adjust GTY desc for value field. + (cpp_user_macro_p, cpp_builtin_macro_p, cpp_macro_p): Adjust. + * directives.c (undefine_macros): Clear value.anwers, adjust flag + clearing. + (_cpp_test_assertion): No need to check NT_ASSERTION. + (do_assert, do_unassert): Likewise. + * init.c (cpp_init_special_builtins): Set type not flags. + * macro.c (struct macro_arg_saved_data): Add type field. + (cpp_get_token_1): Check type not NT_VOID. + (_cpp_free_definition): Adjust flag clearing. Nullify + value.answers. + (_cpp_save_parameter, _cpp_unsave_parameters): Save and restore + type. + (lex_expansion_token): Check type not flags. + (_cpp_create_definition): Set type to NT_USER_MACRO. + (_cpp_notify_macro_use): Adjust type checking. + * pch.c (write_macdef, count_defs, write_defs, cpp_valid_state) + (save_macros): Adjust node type/flag handling. + * traditional.c (_cpp_scan_out_logical_line): Check type not flags. + * directives.c (do_undef): Use cpp_macro_p & cpp_builtin_macro_p. * include/cpplib.h (enum cpp_macro_kind): Remove trailing comma. (cpp_fun_like_macro_p): Make inline, define. diff --git a/libcpp/directives.c b/libcpp/directives.c index f04ed7cf2c1f..f7c460d2f83b 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -695,7 +695,8 @@ undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, /* Body of _cpp_free_definition inlined here for speed. Macros and assertions no longer have anything to free. */ h->type = NT_VOID; - h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED); + h->value.answers = NULL; + h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED); return 1; } @@ -2217,9 +2218,10 @@ parse_answer (cpp_reader *pfile, int type, source_location pred_loc, } /* Parses an assertion directive of type TYPE, returning a pointer to - the hash node of the predicate, or 0 on error. If an answer was - supplied, it is placed in EXP_PTR & EXP_COUNT, which is otherwise - set to 0. */ + the hash node of the predicate, or 0 on error. The node is + guaranteed to be disjoint from the macro namespace, so can only + have type 'NT_VOID'. If an answer was supplied, it is placed in + *ANSWER_PTR, which is otherwise set to 0. */ static cpp_hashnode * parse_assertion (cpp_reader *pfile, int type, cpp_macro **answer_ptr) { @@ -2294,7 +2296,7 @@ _cpp_test_assertion (cpp_reader *pfile, unsigned int *value) if (node) { - if (node->type == NT_ASSERTION) + if (node->value.answers) *value = !answer || *find_answer (node, answer); } else if (pfile->cur_token[-1].type == CPP_EOF) @@ -2315,7 +2317,7 @@ do_assert (cpp_reader *pfile) { /* Place the new answer in the answer list. First check there is not a duplicate. */ - if (node->type == NT_ASSERTION && *find_answer (node, answer)) + if (*find_answer (node, answer)) { cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", NODE_NAME (node) + 1); @@ -2327,10 +2329,8 @@ do_assert (cpp_reader *pfile) (pfile, sizeof (cpp_macro) - sizeof (cpp_token) + sizeof (cpp_token) * answer->count); - if (node->type == NT_ASSERTION) - answer->parm.next = node->value.answers; - - node->type = NT_ASSERTION; + /* Chain into the list. */ + answer->parm.next = node->value.answers; node->value.answers = answer; check_eol (pfile, false); @@ -2345,7 +2345,7 @@ do_unassert (cpp_reader *pfile) cpp_hashnode *node = parse_assertion (pfile, T_UNASSERT, &answer); /* It isn't an error to #unassert something that isn't asserted. */ - if (node && node->type == NT_ASSERTION) + if (node) { if (answer) { @@ -2353,12 +2353,7 @@ do_unassert (cpp_reader *pfile) /* Remove the assert from the list. */ if (cpp_macro *temp = *p) - { - *p = temp->parm.next; - /* Did we free the last answer? */ - if (!*p) - node->type = NT_VOID; - } + *p = temp->parm.next; check_eol (pfile, false); } diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index b784e0facd07..e7a933b1787d 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -742,14 +742,9 @@ struct GTY(()) cpp_macro { } GTY ((desc ("%1.kind == cmk_traditional"))) exp; }; -/* The structure of a node in the hash table. The hash table has - entries for all identifiers: either macros defined by #define - commands (type NT_MACRO), assertions created with #assert - (NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros - like __LINE__ are flagged NODE_BUILTIN. Poisoned identifiers are - flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an - identifier that behaves like an operator such as "xor". - NODE_DIAGNOSTIC is for speed in lex_token: it indicates a +/* Poisoned identifiers are flagged NODE_POISONED. NODE_OPERATOR (C++ + only) indicates an identifier that behaves like an operator such as + "xor". NODE_DIAGNOSTIC is for speed in lex_token: it indicates a diagnostic may be required for this node. Currently this only applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat warnings about NODE_OPERATOR. */ @@ -757,21 +752,21 @@ struct GTY(()) cpp_macro { /* Hash node flags. */ #define NODE_OPERATOR (1 << 0) /* C++ named operator. */ #define NODE_POISONED (1 << 1) /* Poisoned identifier. */ -#define NODE_BUILTIN (1 << 2) /* Builtin macro. */ -#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */ -#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */ -#define NODE_DISABLED (1 << 5) /* A disabled macro. */ -#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ -#define NODE_USED (1 << 7) /* Dumped with -dU. */ -#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */ -#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */ +#define NODE_DIAGNOSTIC (1 << 2) /* Possible diagnostic when lexed. */ +#define NODE_WARN (1 << 3) /* Warn if redefined or undefined. */ +#define NODE_DISABLED (1 << 4) /* A disabled macro. */ +#define NODE_USED (1 << 5) /* Dumped with -dU. */ +#define NODE_CONDITIONAL (1 << 6) /* Conditional macro */ +#define NODE_WARN_OPERATOR (1 << 7) /* Warn about C++ named operator. */ /* Different flavors of hash node. */ enum node_type { - NT_VOID = 0, /* No definition yet. */ - NT_MACRO, /* A macro of some form. */ - NT_ASSERTION /* Predicate for #assert. */ + NT_VOID = 0, /* Maybe an assert? */ + NT_MACRO_ARG, /* A macro arg. */ + NT_USER_MACRO, /* A user macro. */ + NT_BUILTIN_MACRO, /* A builtin macro. */ + NT_MACRO_MASK = NT_USER_MACRO /* Mask for either macro kind. */ }; /* Different flavors of builtin macro. _Pragma is an operator, but we @@ -796,36 +791,19 @@ enum cpp_builtin_type #define NODE_LEN(NODE) HT_LEN (&(NODE)->ident) #define NODE_NAME(NODE) HT_STR (&(NODE)->ident) -/* Specify which field, if any, of the union is used. */ - -enum { - NTV_MACRO, - NTV_ANSWER, - NTV_BUILTIN, - NTV_ARGUMENT, - NTV_NONE -}; - -#define CPP_HASHNODE_VALUE_IDX(HNODE) \ - ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ - : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ - ? NTV_BUILTIN : NTV_MACRO) \ - : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ - : NTV_NONE) - /* The common part of an identifier node shared amongst all 3 C front ends. Also used to store CPP identifiers, which are a superset of identifiers in the grammatical sense. */ union GTY(()) _cpp_hashnode_value { - /* If a macro. */ - cpp_macro * GTY((tag ("NTV_MACRO"))) macro; - /* Answers to an assertion. */ - cpp_macro * GTY ((tag ("NTV_ANSWER"))) answers; + /* Assert (maybe NULL) */ + cpp_macro * GTY((tag ("NT_VOID"))) answers; + /* Macro (never NULL) */ + cpp_macro * GTY((tag ("NT_USER_MACRO"))) macro; /* Code for a builtin macro. */ - enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin; + enum cpp_builtin_type GTY ((tag ("NT_BUILTIN_MACRO"))) builtin; /* Macro argument index. */ - unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index; + unsigned short GTY ((tag ("NT_MACRO_ARG"))) arg_index; }; struct GTY(()) cpp_hashnode { @@ -838,7 +816,7 @@ struct GTY(()) cpp_hashnode { ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */ unsigned int flags : 10; /* CPP flags. */ - union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value; + union _cpp_hashnode_value GTY ((desc ("%1.type"))) value; }; /* A class for iterating through the source locations within a @@ -961,15 +939,16 @@ extern const cpp_token *cpp_get_token_with_location (cpp_reader *, source_location *); inline bool cpp_user_macro_p (const cpp_hashnode *node) { - return node->type == NT_MACRO && !(node->flags & NODE_BUILTIN); + return node->type == NT_USER_MACRO; + } inline bool cpp_builtin_macro_p (const cpp_hashnode *node) { - return node->flags & NODE_BUILTIN; + return node->type == NT_BUILTIN_MACRO; } inline bool cpp_macro_p (const cpp_hashnode *node) { - return node->type == NT_MACRO; + return node->type & NT_MACRO_MASK; } /* Returns true if NODE is a function-like user macro. */ inline bool cpp_fun_like_macro_p (cpp_hashnode *node) diff --git a/libcpp/init.c b/libcpp/init.c index d1697fdec1c4..32a595651743 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -480,8 +480,7 @@ cpp_init_special_builtins (cpp_reader *pfile) || pfile->cb.has_attribute == NULL)) continue; cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); - hp->type = NT_MACRO; - hp->flags |= NODE_BUILTIN; + hp->type = NT_BUILTIN_MACRO; if (b->always_warn_if_redefined) hp->flags |= NODE_WARN; hp->value.builtin = (enum cpp_builtin_type) b->value; diff --git a/libcpp/macro.c b/libcpp/macro.c index 123f63d11771..3629e83cecfd 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -85,8 +85,9 @@ struct macro_arg_token_iter struct macro_arg_saved_data { /* The canonical (UTF-8) spelling of this identifier. */ cpp_hashnode *canonical_node; - /* The previous value of this identifier. */ + /* The previous value & type of this identifier. */ union _cpp_hashnode_value value; + node_type type; }; static const char *vaopt_paste_error = @@ -2730,7 +2731,7 @@ cpp_get_token_1 (cpp_reader *pfile, source_location *location) node = result->val.node.node; - if (node->type != NT_MACRO || (result->flags & NO_EXPAND)) + if (node->type == NT_VOID || (result->flags & NO_EXPAND)) break; if (!(node->flags & NODE_DISABLED)) @@ -3040,8 +3041,8 @@ _cpp_free_definition (cpp_hashnode *h) { /* Macros and assertions no longer have anything to free. */ h->type = NT_VOID; - /* Clear builtin flag in case of redefinition. */ - h->flags &= ~(NODE_BUILTIN | NODE_DISABLED | NODE_USED); + h->value.answers = NULL; + h->flags &= ~(NODE_DISABLED | NODE_USED); } /* Save parameter NODE (spelling SPELLING) to the parameter list of @@ -3051,7 +3052,7 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node, cpp_hashnode *spelling) { /* Constraint 6.10.3.6 - duplicate parameter names. */ - if (node->flags & NODE_MACRO_ARG) + if (node->type == NT_MACRO_ARG) { cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", NODE_NAME (node)); @@ -3069,13 +3070,14 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node, macro_arg_saved_data *saved = (macro_arg_saved_data *)pfile->macro_buffer; saved[n].canonical_node = node; saved[n].value = node->value; + saved[n].type = node->type; void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *), sizeof (cpp_hashnode *)); ((cpp_hashnode **)base)[n] = spelling; /* Morph into a macro arg. */ - node->flags |= NODE_MACRO_ARG; + node->type = NT_MACRO_ARG; /* Index is 1 based. */ node->value.arg_index = n + 1; @@ -3093,8 +3095,8 @@ _cpp_unsave_parameters (cpp_reader *pfile, unsigned n) &((struct macro_arg_saved_data *) pfile->macro_buffer)[n]; struct cpp_hashnode *node = save->canonical_node; + node->type = save->type; node->value = save->value; - node->flags &= ~NODE_MACRO_ARG; } } @@ -3109,6 +3111,7 @@ _cpp_unsave_parameters (cpp_reader *pfile, unsigned n) | name '...' | '...' */ + static bool parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr) { @@ -3232,9 +3235,9 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) pfile->cur_token = saved_cur_token; /* Is this a parameter? */ - if (token->type == CPP_NAME - && (token->val.node.node->flags & NODE_MACRO_ARG) != 0) + if (token->type == CPP_NAME && token->val.node.node->type == NT_MACRO_ARG) { + /* Morph into a parameter reference. */ cpp_hashnode *spelling = token->val.node.spelling; token->type = CPP_MACRO_ARG; token->val.macro_arg.arg_no = token->val.node.node->value.arg_index; @@ -3527,7 +3530,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) } /* Enter definition in hash table. */ - node->type = NT_MACRO; + node->type = NT_USER_MACRO; node->value.macro = macro; if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")) && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS") @@ -3565,17 +3568,18 @@ _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node) node->flags |= NODE_USED; switch (node->type) { - case NT_MACRO: - if (!(node->flags & NODE_BUILTIN)) - { - cpp_macro *macro = node->value.macro; - if (macro->lazy) - { - pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1); - macro->lazy = 0; - } - } + case NT_USER_MACRO: + { + cpp_macro *macro = node->value.macro; + if (macro->lazy) + { + pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1); + macro->lazy = 0; + } + } + /* FALLTHROUGH. */ + case NT_BUILTIN_MACRO: if (pfile->cb.used_define) pfile->cb.used_define (pfile, pfile->directive_line, node); break; diff --git a/libcpp/pch.c b/libcpp/pch.c index 47b99c119815..04d7094b068f 100644 --- a/libcpp/pch.c +++ b/libcpp/pch.c @@ -50,48 +50,47 @@ static int write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) { FILE *f = (FILE *) file_p; + bool is_void = false; switch (hn->type) { case NT_VOID: if (! (hn->flags & NODE_POISONED)) return 1; - /* XXX Really fallthru? */ - /* FALLTHRU */ + is_void = true; + goto poisoned; - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) - return 1; - - { - struct macrodef_struct s; - const unsigned char *defn; - - s.name_length = NODE_LEN (hn); - s.flags = hn->flags & NODE_POISONED; - - if (hn->type == NT_MACRO) - { - defn = cpp_macro_definition (pfile, hn); - s.definition_length = ustrlen (defn); - } - else - { - defn = NODE_NAME (hn); - s.definition_length = s.name_length; - } - - if (fwrite (&s, sizeof (s), 1, f) != 1 - || fwrite (defn, 1, s.definition_length, f) != s.definition_length) - { - cpp_errno (pfile, CPP_DL_ERROR, - "while writing precompiled header"); - return 0; - } - } + case NT_BUILTIN_MACRO: return 1; - case NT_ASSERTION: - /* Not currently implemented. */ + case NT_USER_MACRO: + if (hn->value.macro->kind != cmk_assert) + { + poisoned: + struct macrodef_struct s; + const unsigned char *defn; + + s.name_length = NODE_LEN (hn); + s.flags = hn->flags & NODE_POISONED; + + if (is_void) + { + defn = NODE_NAME (hn); + s.definition_length = s.name_length; + } + else + { + defn = cpp_macro_definition (pfile, hn); + s.definition_length = ustrlen (defn); + } + + if (fwrite (&s, sizeof (s), 1, f) != 1 + || fwrite (defn, 1, s.definition_length, f) != s.definition_length) + { + cpp_errno (pfile, CPP_DL_ERROR, + "while writing precompiled header"); + return 0; + } + } return 1; default: @@ -226,8 +225,11 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) switch (hn->type) { - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) return 1; /* fall through. */ @@ -248,10 +250,6 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) } return 1; - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; - default: abort (); } @@ -265,8 +263,11 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) switch (hn->type) { - case NT_MACRO: - if (hn->flags & NODE_BUILTIN) + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) return 1; /* fall through. */ @@ -287,10 +288,6 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) } return 1; - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; - default: abort (); } @@ -621,7 +618,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd) goto fail; } - if (h->type != NT_MACRO) + if (h->type == NT_VOID) { /* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined, as in, when the PCH file is created with -g and we're @@ -758,8 +755,7 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) { struct save_macro_data *data = (struct save_macro_data *)data_p; - if (h->type != NT_VOID - && (h->flags & NODE_BUILTIN) == 0) + if (cpp_user_macro_p (h)) { if (data->count == data->array_size) { @@ -767,28 +763,14 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); } - switch (h->type) - { - case NT_ASSERTION: - /* Not currently implemented. */ - return 1; + const uchar * defn = cpp_macro_definition (r, h); + size_t defnlen = ustrlen (defn); - case NT_MACRO: - { - const uchar * defn = cpp_macro_definition (r, h); - size_t defnlen = ustrlen (defn); - - data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, - defnlen + 2); - data->defns[data->count][defnlen] = '\n'; - } - break; - - default: - abort (); - } + data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, defnlen + 2); + data->defns[data->count][defnlen] = '\n'; data->count++; } + return 1; } diff --git a/libcpp/traditional.c b/libcpp/traditional.c index 0c42b25d1992..51c3e3522e26 100644 --- a/libcpp/traditional.c +++ b/libcpp/traditional.c @@ -545,7 +545,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, goto new_context; } } - else if (macro && (node->flags & NODE_MACRO_ARG) != 0) + else if (macro && node->type == NT_MACRO_ARG) { /* Found a parameter in the replacement text of a #define. Remove its name from the output. */