================
@@ -0,0 +1,584 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify 
%s
+
+#define __counted_by(f)  __attribute__((counted_by(f)))
+
+// 
=============================================================================
+// # Struct incomplete type with attribute in the decl position
+// 
=============================================================================
+
+// Note: This could be considered misleading. The typedef isn't actually on 
this
+// line. Also note the discrepancy in diagnostic count (27 vs 51) is due to
+// the pointer arithmetic on incomplete pointee type diagnostic always using
+// diagnostic text that refers to the underlying forward decl, even when the
+// typedef is used.
+// expected-note@+1 27{{forward declaration of 'Incomplete_t' (aka 'struct 
IncompleteTy')}}
+struct IncompleteTy; // expected-note 51{{forward declaration of 'struct 
IncompleteTy'}}
+
+typedef struct IncompleteTy Incomplete_t; 
+
+struct CBBufDeclPos {
+  int count;
+  struct IncompleteTy* buf __counted_by(count); // OK expected-note 
27{{__counted_by attribute is here}}
+  Incomplete_t* buf_typedef __counted_by(count); // OK expected-note 
27{{__counted_by attribute is here}}
+};
+
+void consume_struct_IncompleteTy(struct IncompleteTy* buf);
+
+int idx(void);
+
+
+
+void test_CBBufDeclPos(struct CBBufDeclPos* ptr) {
+  // 
===========================================================================
+  // ## Local variable initialization
+  // 
===========================================================================
+  struct CBBufDeclPos explicit_desig_init = {
+    .count = 0,
+    // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' that has type 
'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') 
because the pointee type 'struct IncompleteTy' is incomplete and the 
'__counted_by' attribute requires the pointee type be complete when 
initializing; consider providing a complete definition for 'struct 
IncompleteTy' or using the '__sized_by' attribute}}
+    .buf = 0x0,
+    // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' that 
has type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') 
because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is 
incomplete and the '__counted_by' attribute requires the pointee type be 
complete when initializing; consider providing a complete definition for 
'Incomplete_t' or using the '__sized_by' attribute}}
+    .buf_typedef = 0x0
+  };
+  // Variable is not currently marked as invalid so uses of the variable allows
+  // diagnostics to fire.
+  // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' that has type 
'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') 
because the pointee type 'struct IncompleteTy' is incomplete and the 
'__counted_by' attribute requires the pointee type be complete when assigning; 
consider providing a complete definition for 'struct IncompleteTy' or using the 
'__sized_by' attribute}}
+  explicit_desig_init.buf = 0x0;
+  // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' that has 
type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because 
the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete and 
the '__counted_by' attribute requires the pointee type be complete when 
assigning; consider providing a complete definition for 'Incomplete_t' or using 
the '__sized_by' attribute}}
+  explicit_desig_init.buf_typedef = 0x0;
+  // expected-error@+1{{cannot use 'explicit_desig_init.buf' with type 'struct 
IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the 
pointee type 'struct IncompleteTy' is incomplete and the '__counted_by' 
attribute requires the pointee type be complete in this context; consider 
providing a complete definition for 'struct IncompleteTy' or using the 
'__sized_by' attribute}}
+  void *tmp = explicit_desig_init.buf;
+  // expected-error@+1{{cannot use 'explicit_desig_init.buf_typedef' with type 
'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the 
pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete and the 
'__counted_by' attribute requires the pointee type be complete in this context; 
consider providing a complete definition for 'Incomplete_t' or using the 
'__sized_by' attribute}}
----------------
Sirraide wrote:

> This is more succinct but it looses the important piece of information that 
> is restriction comes from the `__counted_by` attribute which is really not 
> obvious.

Maybe instead of `cannot use X with type ...`, we could write `cannot use X 
with '__counted_by'-attributed type ...`? I feel like that might be as short as 
we’ll be able to make it.

Also, in addition to that, maybe we can move the ‘consider completing the 
definition or using the '__sized_by' attribute instead’ to a note that points 
to the attribute location... if we have access to that here, that is (iirc 
there were some problems w/ that, but I’m not sure anymore)?

https://github.com/llvm/llvm-project/pull/106321
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to