It's another fallout of the scalar-storage-order merge in the form of a tree
checking failure in reverse_storage_order_for_component_p with UBSan.
The tree generated by UBSan is arguably invalid (it's a COMPONENT_REF of a
REFERENCE_TYPE) but the code already works around invalid trees generated in
Fortran (COMPONENT_REF of a VOID_TYPE) and making it more robust is trivial.
Tested on x86_64-suse-linux, applied on the mainline as obvious.
2015-11-09 Eric Botcazou <ebotca...@adacore.com>
PR middle-end/68259
* tree.h (reverse_storage_order_for_component_p) <COMPONENT_REF>:
Check that the type of the first operand is an aggregate type.
2015-11-09 Eric Botcazou <ebotca...@adacore.com>
* g++.dg/ubsan/pr68259.C: New test.
--
Eric Botcazou
Index: tree.h
===================================================================
--- tree.h (revision 230016)
+++ tree.h (working copy)
@@ -4387,8 +4387,9 @@ reverse_storage_order_for_component_p (t
{
case ARRAY_REF:
case COMPONENT_REF:
- /* ??? Fortran can take COMPONENT_REF of a void type. */
- return !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
+ /* ??? Fortran can take COMPONENT_REF of a VOID_TYPE. */
+ /* ??? UBSan can take COMPONENT_REF of a REFERENCE_TYPE. */
+ return AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
&& TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (t, 0)));
case BIT_FIELD_REF:
// PR middle-end/68259
// { dg-do compile }
// { dg-options "-fsanitize=undefined -w" }
namespace std {
template < typename _Tp > class allocator { };
template < typename _Tp, typename _Alloc
= std::allocator < _Tp >
>class vector {
public:
typedef _Tp value_type;
void push_back (const value_type & __x) { }
};
}
class Foo;
class FooBar {
public:
Foo * primitive_context;
FooBar () { }
FooBar (const FooBar & pnhp);
};
template < class KEY, class CONTENT > class AVLTreeNode { };
template < class KEY, class CONTENT > class FooTree final
{
FooBar insertPrimitive ();
public:
AVLTreeNode < KEY, CONTENT > *seek_no_lock (const KEY & key) { }
void primitive_patterns ( std::vector < FooBar > &patterns);
};
template < class KEY, class CONTENT > void FooTree < KEY,
CONTENT >::primitive_patterns ( std::vector <FooBar > &patterns)
{
patterns.push_back (insertPrimitive());
}
template < class KEY, class CONTENT >
FooBar FooTree < KEY, CONTENT >::insertPrimitive ()
{
FooBar place;
seek_no_lock (place.primitive_context);
return place;
}
class ManuverResults { };
class opc_info_t
{
public:
FooTree < Foo *, ManuverResults > *primitivecache;
};
static void
do_optical_prox_corr_tsafe (opc_info_t * opc_info)
{
std::vector < FooBar > patterns;
opc_info->primitivecache->primitive_patterns (patterns);
}