mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-01 15:54:17 +08:00
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
This commit is contained in:
parent
2b9912aa3c
commit
3e86c6a8e1
@ -1,3 +1,11 @@
|
||||
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>
|
||||
|
||||
* config/moxie/moxie.md (zero_extendqisi2, zero_extendhisi2)
|
||||
|
@ -1214,7 +1214,13 @@ get_polymorphic_call_info (tree fndecl,
|
||||
not part of outer type. */
|
||||
if (!contains_type_p (TREE_TYPE (base),
|
||||
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,
|
||||
context->offset + offset2);
|
||||
return NULL;
|
||||
@ -1288,8 +1294,10 @@ get_polymorphic_call_info (tree fndecl,
|
||||
if (!contains_type_p (context->outer_type, context->offset,
|
||||
*otr_type))
|
||||
{
|
||||
context->outer_type = NULL;
|
||||
gcc_unreachable ();
|
||||
/* 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;
|
||||
}
|
||||
context->maybe_derived_type = false;
|
||||
@ -1389,6 +1397,9 @@ devirt_variable_node_removal_hook (varpool_node *n,
|
||||
temporarily change to one of base types. INCLUDE_DERIVER_TYPES make
|
||||
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.
|
||||
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
|
||||
@ -1422,6 +1433,7 @@ possible_polymorphic_call_targets (tree otr_type,
|
||||
bool complete;
|
||||
bool can_refer;
|
||||
|
||||
/* If ODR is not initialized, return empty incomplete list. */
|
||||
if (!odr_hash.is_created ())
|
||||
{
|
||||
if (completep)
|
||||
@ -1431,11 +1443,28 @@ possible_polymorphic_call_targets (tree otr_type,
|
||||
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);
|
||||
|
||||
/* Lookup the outer class type we want to walk. */
|
||||
if (context.outer_type)
|
||||
get_class_context (&context, otr_type);
|
||||
if (context.outer_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. */
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR tree-optimization/60733
|
||||
|
58
gcc/testsuite/g++.dg/torture/pr60659.C
Normal file
58
gcc/testsuite/g++.dg/torture/pr60659.C
Normal file
@ -0,0 +1,58 @@
|
||||
// { 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 ());
|
||||
|
Loading…
Reference in New Issue
Block a user