diff mbox

[RFH,/] PR 20140

Message ID 4F01040A.8050803@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Jan. 2, 2012, 1:10 a.m. UTC
Hi,

I'm trying to do something about this old PR, which I find rather 
disturbing: I see what's going wrong - and shouldn't be too hard to fix, 
but I'd like to have help on the appropriate way to actually do it.

We have this kind of snippet:

template<typename T> void foo() {
     unsigned char s[] = "";
}

int main() {
     /* removing either of the calls below makes the error disappear */
     foo<char>();
     foo<int>();
}

and what happens is that for the *second* instantiation of foo (the 
specific types don't matter at all) we produce a bugus error message 
(about a wide-string as initializer for s).

Thus we have some sort of corruption in the data structures, otherwise 
two different instantiations cannot possibly affect each other.

Indeed, in digest_init_r we do something like, around line 910:

TREE_TYPE (init) = type;

which cannot be right when it does something useful, because init is a 
STRING_CST here which will be used also in the other instantiations!

The analysis is confirmed by the fact that the rather heavy handed 
patchlet which I'm attaching, which uses copy_node to avoid the 
corruption, "works". How do we normally handle this kind of situation?

Thanks,
Paolo.

/////////////////

Comments

Jason Merrill Jan. 2, 2012, 1:49 a.m. UTC | #1
On 01/01/2012 08:10 PM, Paolo Carlini wrote:
> The analysis is confirmed by the fact that the rather heavy handed
> patchlet which I'm attaching, which uses copy_node to avoid the
> corruption, "works". How do we normally handle this kind of situation?

In most cases, trees are unshared at instantiation time, but that 
doesn't apply to constants like this.  The patch is OK.

Jason
Paolo Carlini Jan. 2, 2012, 2:24 a.m. UTC | #2
On 01/02/2012 02:49 AM, Jason Merrill wrote:
> On 01/01/2012 08:10 PM, Paolo Carlini wrote:
>> The analysis is confirmed by the fact that the rather heavy handed
>> patchlet which I'm attaching, which uses copy_node to avoid the
>> corruption, "works". How do we normally handle this kind of situation?
> In most cases, trees are unshared at instantiation time, but that 
> doesn't apply to constants like this.  The patch is OK.
Oh I see, thanks. Then I'm going to properly test it, etc, and if 
everything goes well, I'll post what I will actually commit.

Thanks again,
Paolo.
Richard Biener Jan. 2, 2012, 12:18 p.m. UTC | #3
On Mon, Jan 2, 2012 at 3:24 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> On 01/02/2012 02:49 AM, Jason Merrill wrote:
>>
>> On 01/01/2012 08:10 PM, Paolo Carlini wrote:
>>>
>>> The analysis is confirmed by the fact that the rather heavy handed
>>> patchlet which I'm attaching, which uses copy_node to avoid the
>>> corruption, "works". How do we normally handle this kind of situation?
>>
>> In most cases, trees are unshared at instantiation time, but that doesn't
>> apply to constants like this.  The patch is OK.
>
> Oh I see, thanks. Then I'm going to properly test it, etc, and if everything
> goes well, I'll post what I will actually commit.

I think it's enough to call copy_node for CONSTANT_CLASS_P objects.

> Thanks again,
> Paolo.
diff mbox

Patch

Index: typeck2.c
===================================================================
--- typeck2.c	(revision 182776)
+++ typeck2.c	(working copy)
@@ -902,7 +902,11 @@  digest_init_r (tree type, tree init, bool nested,
 		}
 	    }
 
-	  TREE_TYPE (init) = type;
+	  if (type != TREE_TYPE (init))
+	    {
+	      init = copy_node (init);
+	      TREE_TYPE (init) = type;
+	    }
 	  if (TYPE_DOMAIN (type) != 0 && TREE_CONSTANT (TYPE_SIZE (type)))
 	    {
 	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));