Skip to content

Commit

Permalink
[clang] Reject incomplete type arguments for __builtin_dump_struct (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
zyn0217 committed Dec 5, 2023
1 parent a8874cf commit b3392c4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 3 deletions.
2 changes: 1 addition & 1 deletion clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2821,7 +2821,7 @@ Example output:
The ``__builtin_dump_struct`` function is used to print the fields of a simple
structure and their values for debugging purposes. The first argument of the
builtin should be a pointer to the struct to dump. The second argument ``f``
builtin should be a pointer to a complete record type to dump. The second argument ``f``
should be some callable expression, and can be a function object or an overload
set. The builtin calls ``f``, passing any further arguments ``args...``
followed by a ``printf``-compatible format string and the corresponding
Expand Down
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,9 @@ Bug Fixes to C++ Support
Fixes:
(`#68769 <https://github.com/llvm/llvm-project/issues/68769>`_)

- Clang now rejects incomplete types for ``__builtin_dump_struct``. Fixes:
(`#63506 <https://github.com/llvm/llvm-project/issues/63506>`_)

- Fixed a crash for C++98/03 while checking an ill-formed ``_Static_assert`` expression.
Fixes: (`#72025 <https://github.com/llvm/llvm-project/issues/72025>`_)

Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,13 @@ static ExprResult SemaBuiltinDumpStruct(Sema &S, CallExpr *TheCall) {
<< 1 << TheCall->getDirectCallee() << PtrArgType;
return ExprError();
}
const RecordDecl *RD = PtrArgType->getPointeeType()->getAsRecordDecl();

QualType Pointee = PtrArgType->getPointeeType();
const RecordDecl *RD = Pointee->getAsRecordDecl();
// Try to instantiate the class template as appropriate; otherwise, access to
// its data() may lead to a crash.
if (S.RequireCompleteType(PtrArgResult.get()->getBeginLoc(), Pointee,
diag::err_incomplete_type))
return ExprError();
// Second argument is a callable, but we can't fully validate it until we try
// calling it.
QualType FnArgType = TheCall->getArg(1)->getType();
Expand Down
12 changes: 12 additions & 0 deletions clang/test/SemaCXX/builtin-dump-struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,26 @@ B {
}
)"[1]);

class Incomplete; // #incomplete-type

template <class T>
class Class {
T value = {};
};

void errors(B b) {
ConstexprString cs;
__builtin_dump_struct(); // expected-error {{too few arguments to function call, expected 2, have 0}}
__builtin_dump_struct(1); // expected-error {{too few arguments to function call, expected 2, have 1}}
__builtin_dump_struct(1, 2); // expected-error {{expected pointer to struct as 1st argument to '__builtin_dump_struct', found 'int'}}
__builtin_dump_struct(&b, 2); // expected-error {{expected a callable expression as 2nd argument to '__builtin_dump_struct', found 'int'}}
__builtin_dump_struct(&b, Format, 0); // expected-error {{no matching function for call to 'Format'}}
// expected-note@-1 {{in call to printing function with arguments '(0, "%s", "B")' while dumping struct}}
// expected-note@#Format {{no known conversion from 'int' to 'ConstexprString &' for 1st argument}}
__builtin_dump_struct((Incomplete *)nullptr, Format, cs); // expected-error {{incomplete type 'Incomplete' where a complete type is required}}
// expected-note@#incomplete-type {{forward declaration of 'Incomplete'}}
// Ensure the Class<int> gets instantiated; otherwise crash happens.
__builtin_dump_struct((Class<int> *)nullptr, Format, cs);
}
#endif

Expand Down

0 comments on commit b3392c4

Please sign in to comment.