On 10/23/2017 11:00 AM, Richard Sandiford wrote:
+#if NUM_POLY_INT_COEFFS == 1 +extern inline __attribute__ ((__gnu_inline__)) poly_int64 +tree_to_poly_int64 (const_tree t)
I'm curious about the extern inline and __gnu_inline__ here and not in poly_int_tree_p below. Am I correct in assuming that the combination is a holdover from the days when GCC was compiled using a C compiler, and that the way to write the same definition in C++ 98 is simply: inline poly_int64 tree_to_poly_int64 (const_tree t)
+{ + gcc_assert (tree_fits_poly_int64_p (t)); + return TREE_INT_CST_LOW (t); +}
If yes, I would suggest to use the C++ form (and at some point, changing the existing uses of the GCC/C idiom to the C++ form as well). Otherwise, if something requires the use of the C form I would suggest to add a brief comment explaining it. ...
+ +inline bool +poly_int_tree_p (const_tree t, poly_int64_pod *value) +{
...
/* The tree and const_tree overload templates. */ namespace wi { + class unextended_tree + { + private: + const_tree m_t; + + public: + unextended_tree () {}
Defining no-op ctors is quite dangerous and error-prone. I suggest to instead default initialize the member(s): unextended_tree (): m_t () {} Ditto everywhere else, such as in: ...
template <int N> class extended_tree { @@ -5139,11 +5225,13 @@ extern bool anon_aggrname_p (const_tree) const_tree m_t; public: + extended_tree () {} extended_tree (const_tree);
...
Index: gcc/tree.c ===================================================================
...
+ +/* Return true if T holds a polynomial pointer difference, storing it in + *VALUE if so. A true return means that T's precision is no greater + than 64 bits, which is the largest address space we support, so *VALUE + never loses precision. However, the signedness of the result is + somewhat arbitrary, since if B lives near the end of a 64-bit address + range and A lives near the beginning, B - A is a large positive value + outside the range of int64_t. A - B is likewise a large negative value + outside the range of int64_t. All the pointer difference really + gives is a raw pointer-sized bitstring that can be added to the first + pointer value to get the second. */
I'm not sure I understand the comment about the sign correctly, but if I do, I don't think it's correct. Because their difference wouldn't representable in any basic integer type (i.,e., in ptrdiff_t) the pointers described above could never point to the same object (or array), and so their difference is not meaningful. C/C++ only define the semantics of a difference between pointers to the same object. That restricts the size of the largest possible object typically to SIZE_MAX / 2, or at most SIZE_MAX on the handful of targets where ptrdiff_t has greater precision than size_t. But even on those targets, the difference between any two pointers to the same object must be representable in ptrdiff_t, including the sign.
+bool +ptrdiff_tree_p (const_tree t, poly_int64_pod *value) +{
Martin