Patchwork [C++] PR 52487

login
register
mail settings
Submitter Paolo Carlini
Date March 20, 2012, 3:11 p.m.
Message ID <4F689E3A.20805@oracle.com>
Download mbox | patch
Permalink /patch/147809/
State New
Headers show

Comments

Paolo Carlini - March 20, 2012, 3:11 p.m.
Hi,

this regression is about literal_type_p ICEing for types which cannot be 
completed. Indeed, for the testcase, complete_type cannot complete the 
type but doesn't error out either, just returns the type as-is, and the 
gcc_assert triggers. We could imagine handling such types in the caller 
- check_field_decls - but in my opinion makes more sense to just allow 
such types and return false. I also considered changing literal_type_p 
to use complete_type_or_else but then it's easy to produce duplicate 
diagnostics, for example. What do you think?

Tested x86_64-linux.

Thanks,
Paolo.

PS: eventually I guess we want to fix this in mainline and 4.7.1.

///////////////////////////
/cp
2012-03-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52487
	* semantics.c (literal_type_p): Simply return false for types
	which cannot be completed.

/testsuite
2012-03-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52487
	* g++.dg/cpp0x/lambda/lambda-ice7.C: New.
Jason Merrill - March 20, 2012, 7:22 p.m.
That assert is there to make sure that we don't try to test for 
literality of an incomplete type.  We should check for completeness 
before trying to check for literality.

Jason
Paolo Carlini - March 20, 2012, 8:13 p.m.
On 03/20/2012 08:22 PM, Jason Merrill wrote:
> That assert is there to make sure that we don't try to test for 
> literality of an incomplete type.  We should check for completeness 
> before trying to check for literality.
You mean, in the relevant caller, here in check_field_decls:

       /* If at least one non-static data member is non-literal, the whole
          class becomes non-literal.  */
       if (!literal_type_p (type))
         CLASSTYPE_LITERAL_P (t) = false;

essentially setting CLASSTYPE_LITERAL_P (t) = false; also when 
CLASS_TYPE_P (type) && !COMPLETE_TYPE_P (complete_type (type) or maybe 
just CLASS_TYPE_P (type) && !COMPLETE_TYPE_P (type) ?

Thanks,
Paolo.

Patch

Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C	(revision 0)
@@ -0,0 +1,9 @@ 
+// PR c++/52487
+// { dg-options "-std=c++0x" }
+
+struct A;         // { dg-error "forward declaration" }
+
+void foo(A& a)
+{
+  [=](){a;};      // { dg-error "invalid use of incomplete type" }
+}
Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 185571)
+++ cp/semantics.c	(working copy)
@@ -5610,8 +5610,7 @@  literal_type_p (tree t)
   if (CLASS_TYPE_P (t))
     {
       t = complete_type (t);
-      gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
-      return CLASSTYPE_LITERAL_P (t);
+      return COMPLETE_TYPE_P (t) && CLASSTYPE_LITERAL_P (t);
     }
   if (TREE_CODE (t) == ARRAY_TYPE)
     return literal_type_p (strip_array_types (t));