Commit 3e86c6a8 by Jan Hubicka Committed by Jan Hubicka

re PR ipa/60659 (ICE in get_polymorphic_call_info, at ipa-devirt.c:1292)


	PR ipa/60659
	* ipa-devirt.c (get_polymorphic_call_info): Do not ICE on type inconsistent
	code and instead mark the context inconsistent.
	(possible_polymorphic_call_targets): For inconsistent contexts
	return empty complete list.
	* testsuite/g++.dg/torture/pr60659.C: New testcase.

From-SVN: r209048
parent 2b9912aa
2014-04-02 Jan Hubicka <hubicka@ucw.cz>
PR ipa/60659
* ipa-devirt.c (get_polymorphic_call_info): Do not ICE on type inconsistent
code and instead mark the context inconsistent.
(possible_polymorphic_call_targets): For inconsistent contexts
return empty complete list.
2014-04-02 Anthony Green <green@moxielogic.com> 2014-04-02 Anthony Green <green@moxielogic.com>
* config/moxie/moxie.md (zero_extendqisi2, zero_extendhisi2) * config/moxie/moxie.md (zero_extendqisi2, zero_extendhisi2)
......
...@@ -1214,7 +1214,13 @@ get_polymorphic_call_info (tree fndecl, ...@@ -1214,7 +1214,13 @@ get_polymorphic_call_info (tree fndecl,
not part of outer type. */ not part of outer type. */
if (!contains_type_p (TREE_TYPE (base), if (!contains_type_p (TREE_TYPE (base),
context->offset + offset2, *otr_type)) context->offset + offset2, *otr_type))
return base_pointer; {
/* Use OTR_TOKEN = INT_MAX as a marker of probably type inconsistent
code sequences; we arrange the calls to be builtin_unreachable
later. */
*otr_token = INT_MAX;
return base_pointer;
}
get_polymorphic_call_info_for_decl (context, base, get_polymorphic_call_info_for_decl (context, base,
context->offset + offset2); context->offset + offset2);
return NULL; return NULL;
...@@ -1288,8 +1294,10 @@ get_polymorphic_call_info (tree fndecl, ...@@ -1288,8 +1294,10 @@ get_polymorphic_call_info (tree fndecl,
if (!contains_type_p (context->outer_type, context->offset, if (!contains_type_p (context->outer_type, context->offset,
*otr_type)) *otr_type))
{ {
context->outer_type = NULL; /* Use OTR_TOKEN = INT_MAX as a marker of probably type inconsistent
gcc_unreachable (); code sequences; we arrange the calls to be builtin_unreachable
later. */
*otr_token = INT_MAX;
return base_pointer; return base_pointer;
} }
context->maybe_derived_type = false; context->maybe_derived_type = false;
...@@ -1389,6 +1397,9 @@ devirt_variable_node_removal_hook (varpool_node *n, ...@@ -1389,6 +1397,9 @@ devirt_variable_node_removal_hook (varpool_node *n,
temporarily change to one of base types. INCLUDE_DERIVER_TYPES make temporarily change to one of base types. INCLUDE_DERIVER_TYPES make
us to walk the inheritance graph for all derivations. us to walk the inheritance graph for all derivations.
OTR_TOKEN == INT_MAX is used to mark calls that are provably
undefined and should be redirected to unreachable.
If COMPLETEP is non-NULL, store true if the list is complete. If COMPLETEP is non-NULL, store true if the list is complete.
CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
in the target cache. If user needs to visit every target list in the target cache. If user needs to visit every target list
...@@ -1422,6 +1433,7 @@ possible_polymorphic_call_targets (tree otr_type, ...@@ -1422,6 +1433,7 @@ possible_polymorphic_call_targets (tree otr_type,
bool complete; bool complete;
bool can_refer; bool can_refer;
/* If ODR is not initialized, return empty incomplete list. */
if (!odr_hash.is_created ()) if (!odr_hash.is_created ())
{ {
if (completep) if (completep)
...@@ -1431,11 +1443,28 @@ possible_polymorphic_call_targets (tree otr_type, ...@@ -1431,11 +1443,28 @@ possible_polymorphic_call_targets (tree otr_type,
return nodes; return nodes;
} }
/* If we hit type inconsistency, just return empty list of targets. */
if (otr_token == INT_MAX)
{
if (completep)
*completep = true;
if (nonconstruction_targetsp)
*nonconstruction_targetsp = 0;
return nodes;
}
type = get_odr_type (otr_type, true); type = get_odr_type (otr_type, true);
/* Lookup the outer class type we want to walk. */ /* Lookup the outer class type we want to walk. */
if (context.outer_type) if (context.outer_type
get_class_context (&context, otr_type); && !get_class_context (&context, otr_type))
{
if (completep)
*completep = false;
if (nonconstruction_targetsp)
*nonconstruction_targetsp = 0;
return nodes;
}
/* We canonicalize our query, so we do not need extra hashtable entries. */ /* We canonicalize our query, so we do not need extra hashtable entries. */
......
2014-04-02 Jan Hubicka <hubicka@ucw.cz>
PR ipa/60659
* testsuite/g++.dg/torture/pr60659.C: New testcase.
2014-04-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> 2014-04-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/60733 PR tree-optimization/60733
......
// { dg-do compile }
template <typename _InputIterator> void __distance (_InputIterator);
template <typename _InputIterator>
void distance (_InputIterator, _InputIterator p2)
{
__distance (p2);
}
namespace boost
{
template <class Iterator> struct A
{
typedef typename Iterator::difference_type type;
};
template <class T> typename T::const_iterator end (T &);
template <class T> typename T::const_iterator begin (T &);
template <class T> struct D : A<typename T::const_iterator>
{
};
template <class T> typename D<T>::type distance (const T &p1)
{
distance (boost::begin (p1), boost::end (p1));
return 0;
}
template <class IteratorT> class B
{
public:
typedef B type;
typedef IteratorT const_iterator;
};
}
typedef int storage_t[];
struct F;
template <template <typename> class> struct G
{
G (const G &p1) { p1.m_fn1 ().m_fn1 (0); }
const F &m_fn1 () const
{
const void *a;
a = &data_m;
return *static_cast<const F *>(a);
}
storage_t *data_m;
};
struct F
{
virtual F *m_fn1 (void *) const;
};
template <typename> struct H;
struct C : G<H>
{
typedef int difference_type;
};
boost::B<C> AllTransVideos ();
int b = boost::distance (AllTransVideos ());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment