[clang] b3392c4 - [clang] Reject incomplete type arguments for __builtin_dump_struct (#72749)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 4 17:59:47 PST 2023


Author: Younan Zhang
Date: 2023-12-05T09:59:42+08:00
New Revision: b3392c447ad7b18a652d2ed63e8ebb7741077a98

URL: https://github.com/llvm/llvm-project/commit/b3392c447ad7b18a652d2ed63e8ebb7741077a98
DIFF: https://github.com/llvm/llvm-project/commit/b3392c447ad7b18a652d2ed63e8ebb7741077a98.diff

LOG: [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 https://github.com/llvm/llvm-project/issues/63506

Added: 
    

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaChecking.cpp
    clang/test/SemaCXX/builtin-dump-struct.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 8e01ef6cbb399..286405850900a 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -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

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 683d0026bb345..41904f4db8ef3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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>`_)
 

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 77c8334f3ca25..07ced5ffc3407 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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();

diff  --git a/clang/test/SemaCXX/builtin-dump-struct.cpp b/clang/test/SemaCXX/builtin-dump-struct.cpp
index b3d2a2d808ce2..91ffa7c8c05bd 100644
--- a/clang/test/SemaCXX/builtin-dump-struct.cpp
+++ b/clang/test/SemaCXX/builtin-dump-struct.cpp
@@ -149,7 +149,15 @@ 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'}}
@@ -157,6 +165,10 @@ void errors(B b) {
   __builtin_dump_struct(&b, Format, 0); // expected-error {{no matching function for call to 'Format'}}
                                         // expected-note at -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
 


        


More information about the cfe-commits mailing list