diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f44fef28b9f17..89f96ee381999 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -308,6 +308,10 @@ Miscellaneous Bug Fixes Miscellaneous Clang Crashes Fixed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Do not attempt to dump the layout of dependent types or invalid declarations + when ``-fdump-record-layouts-complete`` is passed. + Fixes (`#83684 `_). + OpenACC Specific Changes ------------------------ diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5d6bb72a208a1..57a92357f6e5b 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5042,7 +5042,13 @@ void RecordDecl::completeDefinition() { // Layouts are dumped when computed, so if we are dumping for all complete // types, we need to force usage to get types that wouldn't be used elsewhere. - if (Ctx.getLangOpts().DumpRecordLayoutsComplete) + // + // If the type is dependent, then we can't compute its layout because there + // is no way for us to know the size or alignment of a dependent type. Also + // ignore declarations marked as invalid since 'getASTRecordLayout()' asserts + // on that. + if (Ctx.getLangOpts().DumpRecordLayoutsComplete && !isDependentType() && + !isInvalidDecl()) (void)Ctx.getASTRecordLayout(this); } diff --git a/clang/test/Layout/dump-complete-invalid.cpp b/clang/test/Layout/dump-complete-invalid.cpp new file mode 100644 index 0000000000000..d3ec1b382ce7c --- /dev/null +++ b/clang/test/Layout/dump-complete-invalid.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -fdump-record-layouts-complete %s + +struct Incomplete; // expected-note {{forward declaration}} + +// Check we don't crash on trying to print out an invalid declaration. +struct Invalid : Incomplete {}; // expected-error {{base class has incomplete type}} diff --git a/clang/test/Layout/dump-complete.cpp b/clang/test/Layout/dump-complete.cpp index 9ccbf477c7052..728f133a0eb64 100644 --- a/clang/test/Layout/dump-complete.cpp +++ b/clang/test/Layout/dump-complete.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -fdump-record-layouts-complete %s | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -fdump-record-layouts-complete %s | FileCheck %s struct a { int x; @@ -12,7 +12,62 @@ class c {}; class d; +template +struct s { + int x; +}; + +template +struct ts { + T x; +}; + +template <> +struct ts { + float f; +}; + +void f() { + ts a; + ts b; + ts c; +} + +namespace gh83671 { +template +struct integral_constant { + static constexpr const _Tp value = __v; + typedef integral_constant type; +}; + +template +using _BoolConstant = integral_constant; + +template +struct is_same : _BoolConstant<__is_same(_Tp, _Up)> {}; + +template < class _Tp > +class numeric_limits {}; + +template < class _Tp > +class numeric_limits< const _Tp > : public numeric_limits< _Tp > {}; +} + +namespace gh83684 { +template +struct AllocationResult { + Pointer ptr = nullptr; + int count = 0; +}; +} + // CHECK: 0 | struct a // CHECK: 0 | struct b // CHECK: 0 | class c +// CHECK: 0 | struct ts +// CHECK-NEXT: 0 | float +// CHECK: 0 | struct ts +// CHECK: 0 | struct ts // CHECK-NOT: 0 | class d +// CHECK-NOT: 0 | struct s +// CHECK-NOT: 0 | struct AllocationResult