Skip to content

Commit b3392c4

Browse files
authored
[clang] Reject incomplete type arguments for __builtin_dump_struct (#72749)
We used to assume that the CXXRecordDecl passed to the 1st argument always had a definition. This is not true since a pointer to an incomplete type was not excluded. Fixes #63506
1 parent a8874cf commit b3392c4

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2821,7 +2821,7 @@ Example output:
28212821
28222822
The ``__builtin_dump_struct`` function is used to print the fields of a simple
28232823
structure and their values for debugging purposes. The first argument of the
2824-
builtin should be a pointer to the struct to dump. The second argument ``f``
2824+
builtin should be a pointer to a complete record type to dump. The second argument ``f``
28252825
should be some callable expression, and can be a function object or an overload
28262826
set. The builtin calls ``f``, passing any further arguments ``args...``
28272827
followed by a ``printf``-compatible format string and the corresponding

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,9 @@ Bug Fixes to C++ Support
794794
Fixes:
795795
(`#68769 <https://github.com/llvm/llvm-project/issues/68769>`_)
796796

797+
- Clang now rejects incomplete types for ``__builtin_dump_struct``. Fixes:
798+
(`#63506 <https://github.com/llvm/llvm-project/issues/63506>`_)
799+
797800
- Fixed a crash for C++98/03 while checking an ill-formed ``_Static_assert`` expression.
798801
Fixes: (`#72025 <https://github.com/llvm/llvm-project/issues/72025>`_)
799802

clang/lib/Sema/SemaChecking.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,13 @@ static ExprResult SemaBuiltinDumpStruct(Sema &S, CallExpr *TheCall) {
712712
<< 1 << TheCall->getDirectCallee() << PtrArgType;
713713
return ExprError();
714714
}
715-
const RecordDecl *RD = PtrArgType->getPointeeType()->getAsRecordDecl();
716-
715+
QualType Pointee = PtrArgType->getPointeeType();
716+
const RecordDecl *RD = Pointee->getAsRecordDecl();
717+
// Try to instantiate the class template as appropriate; otherwise, access to
718+
// its data() may lead to a crash.
719+
if (S.RequireCompleteType(PtrArgResult.get()->getBeginLoc(), Pointee,
720+
diag::err_incomplete_type))
721+
return ExprError();
717722
// Second argument is a callable, but we can't fully validate it until we try
718723
// calling it.
719724
QualType FnArgType = TheCall->getArg(1)->getType();

clang/test/SemaCXX/builtin-dump-struct.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,26 @@ B {
149149
}
150150
)"[1]);
151151

152+
class Incomplete; // #incomplete-type
153+
154+
template <class T>
155+
class Class {
156+
T value = {};
157+
};
158+
152159
void errors(B b) {
160+
ConstexprString cs;
153161
__builtin_dump_struct(); // expected-error {{too few arguments to function call, expected 2, have 0}}
154162
__builtin_dump_struct(1); // expected-error {{too few arguments to function call, expected 2, have 1}}
155163
__builtin_dump_struct(1, 2); // expected-error {{expected pointer to struct as 1st argument to '__builtin_dump_struct', found 'int'}}
156164
__builtin_dump_struct(&b, 2); // expected-error {{expected a callable expression as 2nd argument to '__builtin_dump_struct', found 'int'}}
157165
__builtin_dump_struct(&b, Format, 0); // expected-error {{no matching function for call to 'Format'}}
158166
// expected-note@-1 {{in call to printing function with arguments '(0, "%s", "B")' while dumping struct}}
159167
// expected-note@#Format {{no known conversion from 'int' to 'ConstexprString &' for 1st argument}}
168+
__builtin_dump_struct((Incomplete *)nullptr, Format, cs); // expected-error {{incomplete type 'Incomplete' where a complete type is required}}
169+
// expected-note@#incomplete-type {{forward declaration of 'Incomplete'}}
170+
// Ensure the Class<int> gets instantiated; otherwise crash happens.
171+
__builtin_dump_struct((Class<int> *)nullptr, Format, cs);
160172
}
161173
#endif
162174

0 commit comments

Comments
 (0)