Re: Fix class type lookup from OBJ_TYPE_REF

2013-08-17 Thread Jan Hubicka
> This patch causes an ICE when building libobjc, which is part of
> normal bootstrap.
> 
> PR 58179
> 
> /nasfarm/edelsohn/src/src/libobjc/accessors.m: In function 'objc_getProperty':
> /nasfarm/edelsohn/src/src/libobjc/accessors.m:127:11: internal
> compiler error: in obj_type_ref_class, at tree.c:11876
> result = RETAIN (*(pointer_to_ivar));

Oops, sorry, I was really convinced OBJ_TYPE_REF is a C++ thing so I did not
test obj-C.  The obj-C use is produced by:
/* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression.  This
   needs to be done if we are calling a function through a cast.  */

tree
objc_rewrite_function_call (tree function, tree first_param)
{
  if (TREE_CODE (function) == NOP_EXPR
  && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
 == FUNCTION_DECL)
{
  function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
 TREE_OPERAND (function, 0),
 first_param, size_zero_node);
}

  return function;
}

so obviously it is again type of the first parameter that correspond to the
type of a pointer to the class.

I am testing 
Index: tree.c
===
--- tree.c  (revision 201814)
+++ tree.c  (working copy)
@@ -11873,7 +11873,11 @@ obj_type_ref_class (tree ref)
   ref = TREE_TYPE (ref);
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   ref = TREE_TYPE (ref);
-  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE);
+  /* Wee look for type THIS points to.  ObjC also builds
+ OBJ_TYPE_REF with non-method calls, their first parameter
+ ID however also corresponds to class type. */
+  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE
+  || TREE_CODE (ref) == FUNCTION_TYPE);
   ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   return TREE_TYPE (ref);

This obviously should get me to the same value as TREE_TYPE (TREE_TYPE
(FIRST_PARAM)) the old code will get from OBJ_REF_OBJECT generated above.  I
will go with this patch if it passes testing to unbreak bootstrap.

The question however is if we should not drop OBJ_TYPE_REF generation in objc
or if we want to somehow add the necesary bits to actually make it useful?

At least in the testcase above however there is no TYPE_BINFO attached, so
there is no way backend can actually take use of it. OBJ_TYPE_REF will just sit
there and consume memory + drag alive the parameter.

By grep, objc prouces some BINFOs but they never have VTABLE attached. So even
if sometimes binfo was there, the devirtualization machinery will be unable to
do anything useful about it.

Moreover objc apparently never produce any virtual functions/methods.

Can someone explain me in greater detail how the objc use works?

Honza


Go patch committed: Don't generate range value for sink

2013-08-17 Thread Ian Lance Taylor
This patch from Chris Manghane fixes a bug when the value in a range
clause is a sink variable.  It's fixedbugs/bug454.go in the master Go
testsuite, and will appear in the gccgo testsuite in due course.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline and 4.8 branch.

Ian

diff -r 4baad377e84a go/parse.cc
--- a/go/parse.cc	Sat Aug 17 10:56:57 2013 -0700
+++ b/go/parse.cc	Sat Aug 17 11:02:05 2013 -0700
@@ -5266,7 +5266,8 @@
 	no->var_value()->set_type_from_range_value();
   if (is_new)
 	any_new = true;
-  p_range_clause->value = Expression::make_var_reference(no, location);
+  if (!Gogo::is_sink_name(pti->name()))
+p_range_clause->value = Expression::make_var_reference(no, location);
 }
 
   if (!any_new)


Re: Fix class type lookup from OBJ_TYPE_REF

2013-08-17 Thread Jan Hubicka
Hi,
this is the patch I comitted after testing.
My apologizes for the breakage.

Honza

Index: ChangeLog
===
--- ChangeLog   (revision 201816)
+++ ChangeLog   (working copy)
@@ -1,3 +1,8 @@
+2013-08-16  Jan Hubicka  
+
+   PR middle-end/58179
+   * tree.c (obj_type_ref_class): Do not ICE on non-method calls.
+
 2013-08-16  David Edelsohn  
 
* config/rs6000/rs6000.md (rs6000_get_timebase_ppc32): Add length
Index: tree.c
===
--- tree.c  (revision 201814)
+++ tree.c  (working copy)
@@ -11873,7 +11873,11 @@ obj_type_ref_class (tree ref)
   ref = TREE_TYPE (ref);
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   ref = TREE_TYPE (ref);
-  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE);
+  /* We look for type THIS points to.  ObjC also builds
+ OBJ_TYPE_REF with non-method calls, Their first parameter
+ ID however also corresponds to class type. */
+  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE
+  || TREE_CODE (ref) == FUNCTION_TYPE);
   ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   return TREE_TYPE (ref);


Type inheritance graph analysis & speculative devirtualization, part 1/6

2013-08-17 Thread Jan Hubicka
Hi,
I have got the ipa-devirt implementation into shape it seems actually useful
and working as expected.  The main selling point of it for the moment is
compile time of C++ programs (especially with LTO) and verification facilities.

Currently we keep all virtual functions in the callgraph until after inlining
in hope that the type based devirtualization will find use of them.  This does
not happen in wast majorty of cases (currently about 400 times for Firefox).
Removing them early, at compile time, reduces tons of streaming and thus
linktime speed and memory use.  For firefox the callgraph node count
goes down from over 3 million functions, to hundred of thousdands.

Martin Liska did statistic for me with a recent Firefox tree (rev 201708).
Without the patch the overall build time is 33m real, 180m user.  LTO link time
is 8m real, 26m user.  Peaking over 15GB of memory use (combined GCC+linker),

With the patch it goes down to 26m real, 149m user and the linking
is 6m real, 24m user. Memory use is peaking at 4GB for WPA, parallel
part runs to 9GB, but that can be controlled by an parallelism (plus
I have independent patch to cut it to half).

Memory use graphs can be seen at
http://kam.mff.cuni.cz/~hubicka/build1.pdf
http://kam.mff.cuni.cz/~hubicka/build2.pdf

I think we thus arrived to shape LTO is practically useful for firefox.
I still hope to cut WPA in approx half in 4.9 timeframe and we need to address
issues with command line options merging at least.

Some of the improvements are seen w/o LTO, too.  We save running early opts
on all those functions, but I did not made any detailed stats.

Since the whole area of devirtualization in middle end seems to have very
little documentation and number of latent bugs and moreover I am by no means
expert on C++ type hiearchy a virtual calls, I decided to break up the change
into small patches and try to write an detailed description for each, so
hopefully it will be easier to eyeball the changes and hopefully identify
issues + get things more sane.

The plan is as follows
part 1: tracking of all polymorphic calls in indirect_info
(until now we track
part 2: basic ipa-devirt type inheritance graph construction code,
debugging dumps, function to get possible targets of given
virtual function call and its use at callgraph construction
time.

This is the part bringing important improvements on compile time,
especially with firefox LTO because we get rid of unreachable
function calls comming from headers quickly without having them
to bubble through early optimization, LTO streaming and merging.
part 4: verifier that all devirtualization decisions are in the list of
possible targets + user warning when this is not true for virtual
table access folding machinery. Ignoring GCC bugs it can happen only in
programs with undefined effect. Falss warnings are useful to detect
changes where type inheritance graph is broken.
part 3: support for One Definition Rule matching at LTO time.
This needs fix to types_same_for_odr I posted to the original
thread.
It also adds logic to match multiple different tree types together,
detect some ODR violations, eliminate external vtables when internal
are around and other bit subtle details.
part 4: Use of ipa-devirt in unreachable function removal (that is done at
LTO time, too)
part 5: Do devirtualization for types in local namespaces where there is
only one candidate.
part 6: Do speculative devirtualization when there is only one candidate.
This will handle Firefox's addref.

All these changes are conceptually very easy. I found number of weird things
and little improvements in the current devirt code I will send independently.
I am also trying to keep code flexible so it allows further development:
such as tracking of multiple type variants with same targets thorough
ipa-cp and folding and such.  The dynamic type changes seems somewhat
scary so I want to keep code simple at start to be sure it won't produce
wrong code. (in the plan above only part 5 risks bad code).

This is part 1 of the series. Nothing really fancy is going on here.
It adds code to cgraph.c to notice all polymorphic calls and
record the info.  

I also added virtual_method_call_p that disables the devirtualization
code path from trying to do something on the OBJ-C OBJ_TYPE_REF use
because it can not work as currently written.  If we remove it, we can
use test for OBJ_TYPE_REF again instead.

Boostrapped/regtested x86_64-linux, testing ppc64-linux and will
commit it if passes and there are no objections.

Honza

* cgraph.c (cgraph_create_indirect_edge): Discover
polymorphic calls and record basic info into indirect_info.
* gimple-fold.c (gimple_fold_call): When doing BINFO based
devirtualization, ignore objc function calls.
* ipa-cp.c (initialize_node_lattices): Be 

Re: [PATCH] Sanitize block partitioning under -freorder-blocks-and-partition

2013-08-17 Thread Jan Hubicka
> 
> I added both of these and ran into issues due to profile maintenance.
> For example, there were non-zero blocks in the cold section because
> pro_and_epilogue split a simple return block that was previously reach
> by both hot and cold paths. The new return block that was then only
> reached via the cold path did not have its count properly updated to
> reflect this, and since with this patch, blocks dominated by cold
> blocks are remarked cold, we ended up with a non-zero count block in
> the cold section. And there were 0 count blocks reached by non-zero
> edges because copyprop did not clean up edge weights after removing
> some branches and blocks, leading to non-zero edge weights that had
> previously targeted a branch that was removed, now targeting a 0 count
> block that the removed branch always branched around.

I see, can you please send fixes for the problems you identified?
Thanks for owrking on this!
> 
> In any case, the good news is in that the cases I looked at, the
> splitting code is doing the right thing and these blocks that were
> marked cold really were cold. It would be great to fix the profile
> maintenance issues, but that in the meantime the above sanity checks
> are too aggressive.

We can keep them and output info into dump file - it is what most of
the profile sanity checking does anyway.

Did you try to use Martin's linker script to turn text.unlikely
section unexecutable?  I think that way we will easily find what really
causes us to use it during startup of trained application (just like
Martin does for gimp).
> 
> I think it makes sense to commit the current patch if possible, as it
> is making the splitting more sane.

My only concern about the patch is that I am not convinced the dominator
based code has chance to work reliably enough so we won't see too many
accesses into the cold section.
We can commit it and work on better solution incrementally but it will
probably mean replacing it later.  If you think it makes things easier
to work on it incrementally, I think the patch is OK.
> 
> > - I'll try building and profiling gimp myself to see if I can
> > reproduce the issue with code executing out of the cold section.
> 
> I have spent some time this week trying to get the latest gimp Martin
> pointed me to configured and built, but it took awhile to track down
> and configure/build all of the required versions of dependent
> packages. I'm still hitting some issues trying to get it compiled, so
> it may not yet be configured properly. I'll take a look again early
> next week.

I do not think there is anything special about gimp.  You can probably
take any other bigger app, like GCC itself. With profiledbootstrap
and linker script to lock unlikely section you should get ICEs where
we jump into cold secton and should not.
> 
> Teresa
> 
> patch for updating counts based on estimated frequencies to address
> inlined comdats with 0 profile counts:
> 
> 013-08-16  Teresa Johnson  
> 
> * tree-inline.c (copy_bb): Compute count based on frequency.
> (copy_edges_for_bb): Ditto.
> (copy_cfg_body): Ditto.
> (copy_body): Pass down frequency.
> (expand_call_inline): Ditto.
> (tree_function_versioning): Ditto.
> * predict.c (init_and_estimate_bb_frequencies): New function.
> (rebuild_frequencies): Invoke init_and_estimate_bb_frequencies.
> * predict.h (init_and_estimate_bb_frequencies): Declare.
> * profile.c (branch_prob): Invoke init_and_estimate_bb_frequencies.
> * ipa-inline-transform.c (update_noncloned_frequencies): Scale edge
> counts.
> (clone_inlined_nodes): Compute edge count scale if needed.

I do not see why inliner needs to care about scaling more than it does right
now.  So you have init_and_estimate_bb_frequencies that force profile guessing
on a given function body. In addition to that I thing you need something like
freqs_to_counts that will compute counts based on freqs with given scale
(actually you can do that as part of propagation before frequencies are scalled
to the usual 0...FREQ_MAX scale and precision is lost).

Because offline COMDAT functoin will be porduced for every COMDAT used, I think
it is bad to porduce any COMDAT (or any reachable function via calls with non-0
count) that has empty profile (either because it got lost by COMDAT merging
or because of reading mismatch). 

So I guess you can just check functions with 0 count and non-0 count callers
and initialize their guessed profile.
Some capping will probably be needed to not propagate insanely large numbers..

Since new direct calls can be discovered later, inline may want to do that
again each time it inlines non-0 count call of COMDAT with 0 count...

Honza
> 
> Index: tree-inline.c
> ===
> --- tree-inline.c   (revision 201644)
> +++ tree-inline.c   (working copy)
> @@ -1502,7 +1502,7 @@ remap_gimple_stmt (gimple stmt, 

Re: Fix class type lookup from OBJ_TYPE_REF

2013-08-17 Thread Gerald Pfeifer
On Sat, 17 Aug 2013, Jan Hubicka wrote:
> this is the patch I comitted after testing.
> My apologizes for the breakage.
> 
> +2013-08-16  Jan Hubicka  
> +
> + PR middle-end/58179
> + * tree.c (obj_type_ref_class): Do not ICE on non-method calls.

This fixes my bootstraps on {amd64,i386}-unknown-freebsd*, too.  Thanks.

Gerald


[RFC] Issues with intraprocedural devirtualization

2013-08-17 Thread Jan Hubicka
Hi,
this patch tries to make gimple_extract_devirt_binfo_from_cst little bit more
sane and make it match bit more cases.  Currently we seem to be able to
devirtualize only if the type in question has no basetypes (not even some not
having virtual methods at all) and it is the initial type implementing the
given virtual method (i.e. we even refuse any derivation not giving new
implementation of the virtual method in question).  This is bit silly.

What the current implemntation does
===

gimple_extract_devirt_binfo_from_cst looks for address expression that object
used for virtual method comes from.  It sees something like

 &var + 10;

It looks at the type of VAR and tries to look for a field at offset 10.  If it
suceeds it verify that the field is not artificial (i.e. it is not base of some
outer type present in var) and that its BINFO has no derived types (it basically
has to be the original type defining the virtual method and the type can not
be derived at all).

After this happen the caller proceeds by calling get_binfo_at_offset and by
lookup of virtual call from vtable found.

Why it does so
==

I was always confused on why gimple_extract_devirt_binfo_from_cst apparently
duplicates logic of get_binfo_at_offset and why it has the limitations.
Disussing this with Martin, it is about dynamic type changes.  My understanding
is that

 1) we want the type to not have base because we may have inlined the 
constructor.
During construction the vtables are filled by base's vtable and thus we can
not simply devirtualize based on the final virtual table without proving 
that
constructor was not (partially) inlined.

This is ensured by the exisitng code refusing artifical types and
by the check for number of bases being 0.
 2) apparently the code is supposed to refuse non-0 offset 
because ipa-prop is tracking possibly dynamic type changes only for
beggining of the objects.

What is wrong with 1


I think 1) is unnecesarily restrictive.
  a) when tyhe bases of type found define no virtual methods (or do not
 define virtual method in question) then partially constructed types
 are not harmful.
  b) when the type found has a base type that defines given method, but do
 not overwrite it, we are safe too.

Less conservative solution for 1


I think 1) can be also ignored in gimple_extract_devirt_binfo_from_cst pushing
the need to check for effects of partial construction into users.  I think I can
track constructors inlined into given function, but I am not doing it right now.
Intead I do two lookups - I find the method by the mechanizm above and I compare
it with the first definition of the method.  If they are same, I devirtualize.

What seems worng with 2
===

For 2) i actually found no code checking it. All I can notice that current
implementation will always fail to find anything in ipa-prop when
indirect_info->offset is non-0.  This is because the conditions implementing 1)
prevents gimple_extract_devirt_binfo_from_cst to return anything than the final
type and it will never match on any derived type (making the whole thing bit
pointless, since devirtualization is mostly about derived types I think).

Solution for 2
==

It does not seem to break the testcases, but if check_stmt_for_type_change 
really
can not detect changes outside the main object, then I think all the code above
is wrong anyway and it needs to test for zero the combined offset (i.e. offset
given by get_ref_base_and_extent on the constant as well as offset of the
basetype given by indirect_info->offset).  This can be done easily and will
disable any transformations on derived types, but I suppose I can extend it
incrementally.

I am also confused why ipa-prop needs to track dynamic changes, while
gimple-fold is happy without doing so.  I do not know if one can do
something like having automatic variable of class A and use placement new
to change it to class B.  I tried to change devirt-6.C testcase to do so
but did not suceed in producing anything that would seem to have sane
construction and destruction order.  The local variable is destructed
at the end of sope block, so I would at least need to placement new it to
something class B, do somethjing and then placement new it back so the
destructor can be called.  I would hope this is invalid.  Is there any
sane summary of restriction of placement new use?

If such changing of dyanmic type is possible, we will need to track in
gimple-fold the changes, too.

My secret plan is to track these cases and devirtualize speculatively - the
dynamic type changes are rare and often they can be detected by the local
constant propagation on memory locations and optimized out anyway (at least
for the inlined constructors).

Why I can not use get_binfo_at_offset
=

Finally I decided to replace the lookup of b

Re: [RFC] Issues with intraprocedural devirtualization

2013-08-17 Thread Jason Merrill

On 08/17/2013 05:44 PM, Jan Hubicka wrote:

  1) we want the type to not have base because we may have inlined the 
constructor.
 During construction the vtables are filled by base's vtable and thus we can
 not simply devirtualize based on the final virtual table without proving 
that
 constructor was not (partially) inlined.


If the constructor is inlined into the current function, then we can see 
the most recent assignment to the vptr and use that for devirtualization.



I do not know if one can do
something like having automatic variable of class A and use placement new
to change it to class B.


This is something of a grey area in the standard, with a few defect 
reports yet to be resolved.  I think it should be undefined behavior.



Finally I decided to replace the lookup of base binfo by call to
get_binfo_at_offset.  This is not possible.  For example my base
variable can be:

struct {class A a; class B b} var;

and offset 10 may point to class B.  Here I get an ICE since TYPE_BINFO
of the structure is NULL (it is not class).


I don't understand.  In C++ a struct is a class.


I wonder if we can track functions that return pointers/values of objects
exactly of given type (i.e. no derivations).


If the function returns by value, it's always a value of that exact type.


Is the dynamic type upon return from constructor always known to be of
constructor's type?


Yes.


 We may want to introduce assert_type_expr use like:

obj_ptr = assert_type_expr obj_ptr;

that can be dropped by FE for us to drive those more interesting cases, like
partial construction.


I guess we would need to be careful to insert those after vptr 
assignments within the constructor body, as well.


Jason



C++ PATCH for c++/58083 (ICE with lambda in default argument)

2013-08-17 Thread Jason Merrill
The standard says that lambdas go in the enclosing block, class or 
namespace scope, but also that default arguments aren't parsed until the 
class is complete.  So we need to accept pushing a lambda into a 
complete class.


Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
commit a3eed6be088f776afde7a9d6020a477dc04c23f2
Author: Jason Merrill 
Date:   Wed Aug 7 16:40:53 2013 -0400

	PR c++/58083
	* name-lookup.c (push_class_level_binding_1): It's OK to push a
	lambda type after the enclosing type is complete.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0fe0246..cf6c757 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3062,8 +3062,10 @@ push_class_level_binding_1 (tree name, tree x)
   if (name == error_mark_node)
 return false;
 
-  /* Check for invalid member names.  */
-  gcc_assert (TYPE_BEING_DEFINED (current_class_type));
+  /* Check for invalid member names.  But don't worry about a default
+ argument-scope lambda being pushed after the class is complete.  */
+  gcc_assert (TYPE_BEING_DEFINED (current_class_type)
+	  || LAMBDA_TYPE_P (TREE_TYPE (decl)));
   /* Check that we're pushing into the right binding level.  */
   gcc_assert (current_class_type == class_binding_level->this_entity);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C
new file mode 100644
index 000..d85918d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C
@@ -0,0 +1,30 @@
+// PR c++/58083
+// { dg-do compile { target c++11 } }
+
+namespace details {
+struct iterator_concept_checker
+{
+typedef char yes_type;
+typedef char (&no_type)[2];
+
+template 
+static no_type test(...);
+
+template 
+static yes_type test(
+int*
+	, void (*)(T) = [](T it)
+{
+auto copy = T{it};  // copy constructible
+copy = it;  // copy assignable
+copy.~T();  // destroyable
+++it;   // incrementable
+}
+  );
+};
+}
+
+int main()
+{
+  details::iterator_concept_checker::test(0);
+}


Re: [RFC] Issues with intraprocedural devirtualization

2013-08-17 Thread Gabriel Dos Reis
On Sat, Aug 17, 2013 at 7:56 PM, Jason Merrill  wrote:

>> I do not know if one can do
>> something like having automatic variable of class A and use placement new
>> to change it to class B.
>
>
> This is something of a grey area in the standard, with a few defect reports
> yet to be resolved.  I think it should be undefined behavior.

Jason, could you remind me of the CWG issue numbers for these?
It is also of interest for SG12, even if it isn't going to come withe
a different answer.

-- Gaby


C++ PATCH for c++/58119 (possibly wrong error with conversion template)

2013-08-17 Thread Jason Merrill
In this testcase, the A conversion template can't possibly produce a 
pointer type, so its presence in the overload set shouldn't cause an 
error.  The standard is unclear about the B case, but it seems 
appropriate to me to still complain there.


Tested x86_64-pc-linux-gnu, applying to trunk, 4.8, 4.7.
commit bd43671e5087c4fbee728305af02abd54bafa91e
Author: Jason Merrill 
Date:   Sat Aug 17 21:30:36 2013 -0400

	PR c++/58119
	* cvt.c (build_expr_type_conversion): Don't complain about a
	template that can't match the desired type category.

diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 532e8fd..08c026d 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1590,17 +1590,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
   if (DECL_NONCONVERTING_P (cand))
 	continue;
 
-  if (TREE_CODE (cand) == TEMPLATE_DECL)
-	{
-	  if (complain)
-	{
-	  error ("ambiguous default type conversion from %qT",
-		 basetype);
-	  error ("  candidate conversions include %qD", cand);
-	}
-	  return error_mark_node;
-	}
-
   candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
 
   switch (TREE_CODE (candidate))
@@ -1634,11 +1623,23 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
 	  break;
 
 	default:
+	  /* A wildcard could be instantiated to match any desired
+	 type, but we can't deduce the template argument.  */
+	  if (WILDCARD_TYPE_P (candidate))
+	win = true;
 	  break;
 	}
 
   if (win)
 	{
+	  if (TREE_CODE (cand) == TEMPLATE_DECL)
+	{
+	  if (complain)
+		error ("default type conversion can't deduce template"
+		   " argument for %qD", cand);
+	  return error_mark_node;
+	}
+
 	  if (winner)
 	{
 	  tree winner_type
diff --git a/gcc/testsuite/g++.dg/template/delete2.C b/gcc/testsuite/g++.dg/template/delete2.C
new file mode 100644
index 000..b6ab380
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/delete2.C
@@ -0,0 +1,26 @@
+// PR c++/58119
+
+template 
+struct A
+{
+  operator T*();
+  template 
+  operator A();
+};
+
+template 
+struct B
+{
+  operator T*();
+  template 
+  operator A*();
+};
+
+int main()
+{
+  A a;
+  delete a;
+
+  B b;
+  delete b;			// { dg-error "template|delete" }
+}


Re: [RFC] Issues with intraprocedural devirtualization

2013-08-17 Thread Richard Biener
Jason Merrill  wrote:
>On 08/17/2013 05:44 PM, Jan Hubicka wrote:
>>   1) we want the type to not have base because we may have inlined
>the constructor.
>>  During construction the vtables are filled by base's vtable and
>thus we can
>>  not simply devirtualize based on the final virtual table without
>proving that
>>  constructor was not (partially) inlined.
>
>If the constructor is inlined into the current function, then we can
>see 
>the most recent assignment to the vptr and use that for
>devirtualization.
>
>> I do not know if one can do
>> something like having automatic variable of class A and use placement
>new
>> to change it to class B.
>
>This is something of a grey area in the standard, with a few defect 
>reports yet to be resolved.  I think it should be undefined behavior.

I'm curious if special.casing the automatic non-pod type case is worth the 
trouble.  At least you need to support placement new on pod class members, in 
which case you need to be careful with which cases you can reliably detectat 
the gimple level.  As always - look at past dynamic type bugs we had with boost.

Richard.


>> Finally I decided to replace the lookup of base binfo by call to
>> get_binfo_at_offset.  This is not possible.  For example my base
>> variable can be:
>>
>> struct {class A a; class B b} var;
>>
>> and offset 10 may point to class B.  Here I get an ICE since
>TYPE_BINFO
>> of the structure is NULL (it is not class).
>
>I don't understand.  In C++ a struct is a class.
>
>> I wonder if we can track functions that return pointers/values of
>objects
>> exactly of given type (i.e. no derivations).
>
>If the function returns by value, it's always a value of that exact
>type.
>
>> Is the dynamic type upon return from constructor always known to be
>of
>> constructor's type?
>
>Yes.
>
>>  We may want to introduce assert_type_expr use like:
>>
>> obj_ptr = assert_type_expr obj_ptr;
>>
>> that can be dropped by FE for us to drive those more interesting
>cases, like
>> partial construction.
>
>I guess we would need to be careful to insert those after vptr 
>assignments within the constructor body, as well.
>
>Jason