================
@@ -2940,18 +2940,28 @@ bool QualType::isBitwiseCloneableType(const ASTContext 
&Context) const {
   if (RD->mayInsertExtraPadding())
     return false;
 
+  auto isCycleBackToRD = [RD](QualType T) {
+    return !T.isNull() && !T->containsErrors() &&
+           T.getCanonicalType()->getAsRecordDecl() == RD;
----------------
Xinlong-Chen wrote:

Thanks for the insightful review! You're right — I was overthinking it. 
Checking for incomplete or invalid types is indeed sufficient.

Case 1: Forward-declared type — caught by isIncompleteType().
```
struct Bar;
struct Foo {
    Bar bar;
};
static_assert(__is_bitwise_cloneable(Bar)
```

Case 2: Infinite recursion. After error recovery, the RecordDecl is marked 
invalid, so we bail out early via RD->isInvalidDecl().

```
struct ABC {
  ABCD ptr;
};

static_assert(__is_bitwise_cloneable(ABC) == true);
```

So the fix is simply adding:
```
  if (RD->isInvalidDecl())
    return false;
```

output:
```
/tmp/test_cycle2.cpp:2:3: error: unknown type name 'ABCD'; did you mean 'ABC'?
    2 |   ABCD ptr;
      |   ^~~~
      |   ABC
/tmp/test_cycle2.cpp:1:8: note: 'ABC' declared here
    1 | struct ABC {
      |        ^
/tmp/test_cycle2.cpp:2:8: error: field has incomplete type 'ABC'
    2 |   ABCD ptr;
      |        ^
/tmp/test_cycle2.cpp:1:8: note: definition of 'ABC' is not complete until the 
closing '}'
    1 | struct ABC {
      |        ^
/tmp/test_cycle2.cpp:5:15: error: static assertion failed due to requirement 
'__is_bitwise_cloneable(ABC) == true'
    5 | static_assert(__is_bitwise_cloneable(ABC) == true);
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
```

https://github.com/llvm/llvm-project/pull/183707
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to