diff mbox

[C++] PR 58664

Message ID 537B160B.8080109@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 20, 2014, 8:44 a.m. UTC
Hi,

On 05/20/2014 04:50 AM, Jason Merrill wrote:
> On 05/19/2014 06:43 PM, Paolo Carlini wrote:
>>           if (unqualified_id)
>> -          error ("field %qD has incomplete type %qT",
>> -             unqualified_id, type);
>> +          cxx_incomplete_type_error (unqualified_id, type);
>>           else
>>             error ("name %qT has incomplete type", type);
>
> Why not use cxx_incomplete_type_error in both cases?
In fact, my patch has a rather serious issue: the use of 
cxx_incomplete_type_error means that we don't print anymore the name of 
the field in the non-template case because we don't have yet a 
FIELD_DECL yet, we have an IDENTIFIER_NODE. I think this is a 
regression, in particular as long as our locations aren't always perfect 
or the user decides to disable the caret.

Then, about your specific point, I don't think the additional inform 
facility automatically provided by cxx_incomplete_type_error is normally 
useful in the !unqualified_id case: if you consider, for example, 
parse/crash31.C below, clang++ also doesn't print any notes in such 
cases. Then I think we can as well leave that error alone (and 
consistent with the other error)

Thanks,
Paolo.

PS: note that initialized doesn't play any role in the unqualified_id 
case: either we don't have an array at all or its element-type is 
incomplete, eg:

struct S
{
   int a[];
};

is simply accepted of course (COMPLETE_TYPE_P (complete_type (type)) is 
true).

//////////////////////
/cp
2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58664
	* typeck2.c (cxx_incomplete_type_inform): New.
	(cxx_incomplete_type_diagnostic): Use it.
	* decl.c (grokdeclarator): Check the element type of an
	incomplete array type; call the above.

/testsuite
2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58664
	* g++.dg/cpp0x/nsdmi-union6.C: New.
	* g++.dg/parse/pr58664.C: Likewise.
	* g++.dg/cpp0x/nsdmi6.C: Tweak.
	* g++.dg/parse/crash31.C: Likewise.
	* g++.dg/template/error2.C: Likewise.
	* g++.dg/template/inherit8.C: Likewise.
	* g++.dg/template/offsetof2.C: Likewise.

Comments

Jason Merrill May 20, 2014, 1:02 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 210625)
+++ cp/cp-tree.h	(working copy)
@@ -6158,6 +6158,7 @@  extern void cxx_incomplete_type_diagnostic	(const_
 extern void cxx_incomplete_type_error		(const_tree, const_tree);
 #define cxx_incomplete_type_error(V,T) \
   (cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
+extern void cxx_incomplete_type_inform 	        (const_tree);
 extern tree error_not_base_type			(tree, tree);
 extern tree binfo_or_else			(tree, tree);
 extern void cxx_readonly_error			(tree, enum lvalue_use);
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 210622)
+++ cp/decl.c	(working copy)
@@ -10586,11 +10586,16 @@  grokdeclarator (const cp_declarator *declarator,
 	  }
 	else if (!staticp && !dependent_type_p (type)
 		 && !COMPLETE_TYPE_P (complete_type (type))
-		 && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
+		 && (TREE_CODE (type) != ARRAY_TYPE
+		     || !COMPLETE_TYPE_P (TREE_TYPE (type))
+		     || initialized == 0))
 	  {
 	    if (unqualified_id)
-	      error ("field %qD has incomplete type %qT",
-		     unqualified_id, type);
+	      {
+		error ("field %qD has incomplete type %qT",
+		       unqualified_id, type);
+		cxx_incomplete_type_inform (strip_array_types (type));
+	      }
 	    else
 	      error ("name %qT has incomplete type", type);
 
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c	(revision 210623)
+++ cp/typeck2.c	(working copy)
@@ -429,6 +429,25 @@  abstract_virtuals_error (abstract_class_use use, t
   return abstract_virtuals_error_sfinae (use, type, tf_warning_or_error);
 }
 
+/* Print an inform about the declaration of the incomplete type TYPE.  */
+
+void
+cxx_incomplete_type_inform (const_tree type)
+{
+  location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
+  tree ptype = strip_top_quals (CONST_CAST_TREE (type));
+
+  if (current_class_type
+      && TYPE_BEING_DEFINED (current_class_type)
+      && same_type_p (ptype, current_class_type))
+    inform (loc, "definition of %q#T is not complete until "
+	    "the closing brace", ptype);
+  else if (!TYPE_TEMPLATE_INFO (ptype))
+    inform (loc, "forward declaration of %q#T", ptype);
+  else
+    inform (loc, "declaration of %q#T", ptype);
+}
+
 /* Print an error message for invalid use of an incomplete type.
    VALUE is the expression that was used (or 0 if that isn't known)
    and TYPE is the type that was invalid.  DIAG_KIND indicates the
@@ -469,14 +488,7 @@  cxx_incomplete_type_diagnostic (const_tree value,
 				      "invalid use of incomplete type %q#T",
 				      type);
       if (complained)
-	{
-      	  if (!TYPE_TEMPLATE_INFO (type))
-	    inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
-		    "forward declaration of %q#T", type);
-	  else
-	    inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
-		    "declaration of %q#T", type);
-	}
+	cxx_incomplete_type_inform (type);
       break;
 
     case VOID_TYPE:
Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-union6.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-union6.C	(working copy)
@@ -0,0 +1,56 @@ 
+// PR c++/58664
+// { dg-do compile { target c++11 } }
+
+struct F;          // { dg-message "forward declaration" }
+
+union U            // { dg-message "not complete" }
+{
+  U u[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UT           // { dg-message "not complete" }
+{
+  UT u[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template union UT<int>;
+
+union UF
+{
+  F u[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UFT
+{
+  F u[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template union UFT<int>;
+
+struct S           // { dg-message "not complete" }
+{
+  S s[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct ST          // { dg-message "not complete" }
+{
+  ST s[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template class ST<int>;
+
+struct SF
+{
+  F s[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct SFT
+{
+  F s[1] = { 0 };  // { dg-error "incomplete type" }
+};
+
+template class SFT<int>;
Index: testsuite/g++.dg/cpp0x/nsdmi6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi6.C	(revision 210622)
+++ testsuite/g++.dg/cpp0x/nsdmi6.C	(working copy)
@@ -4,5 +4,5 @@ 
 struct A
 {
     typedef int int T; // { dg-error "two or more data types in declaration" }
-    struct T x[1] = { 0 }; // { dg-error "invalid|forward" }
+    struct T x[1] = { 0 }; // { dg-error "incomplete type|forward" }
 };
Index: testsuite/g++.dg/parse/crash31.C
===================================================================
--- testsuite/g++.dg/parse/crash31.C	(revision 210624)
+++ testsuite/g++.dg/parse/crash31.C	(working copy)
@@ -1,4 +1,4 @@ 
-struct A // { dg-message "forward declaration" }
+struct A // { dg-message "not complete" }
 {
   A : A; // { dg-error "expected|incomplete" }
   A : B; // { dg-error "not declared|incomplete" }
Index: testsuite/g++.dg/parse/pr58664.C
===================================================================
--- testsuite/g++.dg/parse/pr58664.C	(revision 0)
+++ testsuite/g++.dg/parse/pr58664.C	(working copy)
@@ -0,0 +1,66 @@ 
+// PR c++/58664
+// { dg-do compile { target c++11 } }
+
+struct F;          // { dg-message "forward declaration" }
+
+union U            // { dg-message "not complete" }
+{
+  U u;             // { dg-error "field 'u' has incomplete type 'U'" }
+};
+
+union CU           // { dg-message "not complete" }
+{
+  const CU u;      // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UT           // { dg-message "not complete" }
+{
+  UT u;            // { dg-error "incomplete type" }
+};
+
+template union UT<int>;
+
+union UF
+{
+  F u;             // { dg-error "field 'u' has incomplete type 'F'" }
+};
+
+template<typename T>
+union UFT
+{
+  F u;             // { dg-error "incomplete type" }
+};
+
+template union UFT<int>;
+
+struct S           // { dg-message "not complete" }
+{
+  S s;             // { dg-error "field 's' has incomplete type 'S'" }
+};
+
+struct VS          // { dg-message "not complete" }
+{
+  volatile VS s;   // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct ST          // { dg-message "not complete" }
+{
+  ST s;            // { dg-error "incomplete type" }
+};
+
+template class ST<int>;
+
+struct SF
+{
+  F s;             // { dg-error "field 's' has incomplete type 'F'" }
+};
+
+template<typename T>
+struct SFT
+{
+  F s;             // { dg-error "incomplete type" }
+};
+
+template class SFT<int>;
Index: testsuite/g++.dg/template/error2.C
===================================================================
--- testsuite/g++.dg/template/error2.C	(revision 210624)
+++ testsuite/g++.dg/template/error2.C	(working copy)
@@ -7,8 +7,7 @@ 
 
 template<class T> struct X
 {
-  T m;	// { dg-error "void" "void" }
-	// { dg-error "incomplete type" "incomplete" { target *-*-* } 10 }
+  T m;	// { dg-error "incomplete type|invalid use" }
 };
 
 template<class T >
Index: testsuite/g++.dg/template/inherit8.C
===================================================================
--- testsuite/g++.dg/template/inherit8.C	(revision 210624)
+++ testsuite/g++.dg/template/inherit8.C	(working copy)
@@ -4,7 +4,7 @@  template <typename T>
 struct A
 {
   template <typename U>
-  struct B : public A <B<U> >	// { dg-message "declaration" }
+  struct B : public A <B<U> >	// { dg-message "not complete" }
   {
     struct C : public B<U>	// { dg-error "incomplete" }
     {
Index: testsuite/g++.dg/template/offsetof2.C
===================================================================
--- testsuite/g++.dg/template/offsetof2.C	(revision 210624)
+++ testsuite/g++.dg/template/offsetof2.C	(working copy)
@@ -1,7 +1,7 @@ 
 // PR c++/49085
 
 template <class T>
-struct A			// { dg-message "declaration" }
+struct A			// { dg-message "not complete" }
 {
   int i, j;
   int ar[__builtin_offsetof(A,j)]; // { dg-error "incomplete type" }