diff mbox

[C++] PR 44625

Message ID 4E031E9C.8090502@oracle.com
State New
Headers show

Commit Message

Paolo Carlini June 23, 2011, 11:08 a.m. UTC
Hi,

a patchlet for a pretty old ice-on-invalid regression. Tested x86_64-linux.

Ok for mainline?

Thanks,
Paolo.

////////////////
/cp
2011-06-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/44625
	* pt.c (tsubst_copy_and_build): Do not use BASELINK_P on a NULL_TREE.

/testsuite
2011-06-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/44625
	* g++.dg/template/crash107.C: New.

Comments

Jason Merrill June 23, 2011, 2:51 p.m. UTC | #1
Why are we creating a COMPONENT_REF with a null op1 in the first place?

Jason
Paolo Carlini June 23, 2011, 3:30 p.m. UTC | #2
Hi,
> Why are we creating a COMPONENT_REF with a null op1 in the first place?
For now, what I figured out is the following: build_anon_union_vars 
calls build_min_nt (COMPONENT_REF, object, DECL_NAME (field), NULL_TREE) 
with a null third argument, which becomes the null op1.

As a matter of fact, the possibility that DECL_NAME (field) could be 
null is considered in build_anon_union_vars itself, because right after 
the above mentioned build_min_nt call, there is a conditional 'if 
(DECL_NAME (field)) ...'

I don't know if the above is enough for you to suggest the way we should 
go...

Paolo.
Jason Merrill June 23, 2011, 3:47 p.m. UTC | #3
On 06/23/2011 11:30 AM, Paolo Carlini wrote:
>> Why are we creating a COMPONENT_REF with a null op1 in the first place?

> As a matter of fact, the possibility that DECL_NAME (field) could be
> null is considered in build_anon_union_vars itself, because right after
> the above mentioned build_min_nt call, there is a conditional 'if
> (DECL_NAME (field)) ...'

Indeed.  The code is using DECL_NAME in templates so that tsubst can 
look them up again by name, but as we see in this PR that can't work if 
the field has no name.  We need a different strategy for handling 
anonymous aggregates nested in other anonymous aggregates in templates.

Jason
Paolo Carlini June 23, 2011, 3:52 p.m. UTC | #4
On 06/23/2011 05:47 PM, Jason Merrill wrote:
> Indeed.  The code is using DECL_NAME in templates so that tsubst can 
> look them up again by name, but as we see in this PR that can't work 
> if the field has no name.  We need a different strategy for handling 
> anonymous aggregates nested in other anonymous aggregates in templates.
Ok, then, from what you saying I understand that it should be possible 
to actually construct a reject-valid or an ice-on-valid in this area, 
isn't just about improving the diagnostic, that is only the tip of the 
iceberg, so to speak. I guess it's not for me, at this time...

Paolo.
Jason Merrill June 23, 2011, 4:01 p.m. UTC | #5
On 06/23/2011 11:52 AM, Paolo Carlini wrote:
> Ok, then, from what you saying I understand that it should be possible
> to actually construct a reject-valid or an ice-on-valid in this area,
> isn't just about improving the diagnostic, that is only the tip of the
> iceberg, so to speak. I guess it's not for me, at this time...

For the time being you could improve the diagnostic by adding a sorry 
for the case of null DECL_NAME in a template in build_anon_union_vars.

Jason
Jason Merrill June 23, 2011, 4:05 p.m. UTC | #6
Actually, 9.5 says

A union of the form
   union { member-specification } ;
is called an anonymous union; it defines an unnamed object of unnamed 
type. The member-specification of an anonymous union shall only define 
non-static data members. [ Note: Nested types and functions cannot
be declared within an anonymous union. — end note ]

So we should be able to just reject nested anonymous aggregates and not 
worry about how to make them work.

Jason
Paolo Carlini June 23, 2011, 4:06 p.m. UTC | #7
On 06/23/2011 06:01 PM, Jason Merrill wrote:
> On 06/23/2011 11:52 AM, Paolo Carlini wrote:
>> Ok, then, from what you saying I understand that it should be possible
>> to actually construct a reject-valid or an ice-on-valid in this area,
>> isn't just about improving the diagnostic, that is only the tip of the
>> iceberg, so to speak. I guess it's not for me, at this time...
> For the time being you could improve the diagnostic by adding a sorry 
> for the case of null DECL_NAME in a template in build_anon_union_vars.
Indeed. Let me try then...

Paolo.
Paolo Carlini June 23, 2011, 4:11 p.m. UTC | #8
On 06/23/2011 06:05 PM, Jason Merrill wrote:
> Actually, 9.5 says
>
> A union of the form
>   union { member-specification } ;
> is called an anonymous union; it defines an unnamed object of unnamed 
> type. The member-specification of an anonymous union shall only define 
> non-static data members. [ Note: Nested types and functions cannot
> be declared within an anonymous union. — end note ]
>
> So we should be able to just reject nested anonymous aggregates and 
> not worry about how to make them work.
Yes, but we are accepting already some of that as an extension. If I 
compile the testcase with -pedantic-errors I get:

44625.C:8:31: error: ISO C++ prohibits anonymous structs [-pedantic]
44625.C:9:9: error: anonymous struct not inside named type

thus, it's not clear to me where we should stop, exactly.

Paolo.
Paolo Carlini June 23, 2011, 4:15 p.m. UTC | #9
On 06/23/2011 06:11 PM, Paolo Carlini wrote:
> On 06/23/2011 06:05 PM, Jason Merrill wrote:
>> Actually, 9.5 says
>>
>> A union of the form
>>   union { member-specification } ;
>> is called an anonymous union; it defines an unnamed object of unnamed 
>> type. The member-specification of an anonymous union shall only 
>> define non-static data members. [ Note: Nested types and functions 
>> cannot
>> be declared within an anonymous union. — end note ]
>>
>> So we should be able to just reject nested anonymous aggregates and 
>> not worry about how to make them work.
> Yes, but we are accepting already some of that as an extension. If I 
> compile the testcase with -pedantic-errors I get:
>
> 44625.C:8:31: error: ISO C++ prohibits anonymous structs [-pedantic]
> 44625.C:9:9: error: anonymous struct not inside named type
Of course only the first message is new with -pedantic-errors.

Thus, the idea would be rejecting *nested* anonymous, now I see. Uhmm.

Paolo.
diff mbox

Patch

Index: testsuite/g++.dg/template/crash107.C
===================================================================
--- testsuite/g++.dg/template/crash107.C	(revision 0)
+++ testsuite/g++.dg/template/crash107.C	(revision 0)
@@ -0,0 +1,20 @@ 
+// PR c++/44625
+// { dg-do compile }
+// { dg-options "" }
+
+template<typename FP_> struct Vec { // { dg-message "note" }
+    Vec& operator^=(Vec& rhs)     {
+        union {
+            struct {FP_ x,y,z;};
+        }; // { dg-error "anonymous struct" }
+        X = y*rhs.z() - z*rhs.y(); // { dg-error "not declared|no member" }
+    }
+    Vec& operator^(Vec& rhs) {
+        return Vec(*this)^=rhs; // { dg-message "required" }
+    }
+};
+Vec<double> v(3,4,12); // { dg-error "no matching" }
+// { dg-message "note" { target *-*-* } 16 }
+Vec<double> V(12,4,3);  // { dg-error "no matching" }
+// { dg-message "note" { target *-*-* } 18 }
+Vec<double> c = v^V;   // { dg-message "required" }
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 175328)
+++ cp/pt.c	(working copy)
@@ -13252,6 +13252,9 @@  tsubst_copy_and_build (tree t,
 	object_type = TREE_TYPE (object);
 
 	member = TREE_OPERAND (t, 1);
+	if (!member)
+	  return error_mark_node;
+
 	if (BASELINK_P (member))
 	  member = tsubst_baselink (member,
 				    non_reference (TREE_TYPE (object)),