[clang] bcaa806 - [Clang] Fix BZ47169, loader_uninitialized on incomplete types

Jon Chesterfield via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 19 10:12:03 PDT 2020


Author: Jon Chesterfield
Date: 2020-08-19T18:11:50+01:00
New Revision: bcaa806a4747595116b538e8b75b12966e6607f6

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

LOG: [Clang] Fix BZ47169, loader_uninitialized on incomplete types

[Clang] Fix BZ47169, loader_uninitialized on incomplete types

Reported by @erichkeane. Fix proposed by @erichkeane works, tests included.
Bug introduced in D74361. Crash was on querying a CXXRecordDecl for
hasTrivialDefaultConstructor on an incomplete type. Fixed by calling
RequireCompleteType in the right place.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D85990

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/CodeGenCXX/attr-loader-uninitialized.cpp
    clang/test/Sema/attr-loader-uninitialized.c
    clang/test/Sema/attr-loader-uninitialized.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ab1496337210..566a2f9da681 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12476,6 +12476,17 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
     }
 
     if (!Var->isInvalidDecl() && RealDecl->hasAttr<LoaderUninitializedAttr>()) {
+      if (Var->getStorageClass() == SC_Extern) {
+        Diag(Var->getLocation(), diag::err_loader_uninitialized_extern_decl)
+            << Var;
+        Var->setInvalidDecl();
+        return;
+      }
+      if (RequireCompleteType(Var->getLocation(), Var->getType(),
+                              diag::err_typecheck_decl_incomplete_type)) {
+        Var->setInvalidDecl();
+        return;
+      }
       if (CXXRecordDecl *RD = Var->getType()->getAsCXXRecordDecl()) {
         if (!RD->hasTrivialDefaultConstructor()) {
           Diag(Var->getLocation(), diag::err_loader_uninitialized_trivial_ctor);
@@ -12483,12 +12494,6 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
           return;
         }
       }
-      if (Var->getStorageClass() == SC_Extern) {
-        Diag(Var->getLocation(), diag::err_loader_uninitialized_extern_decl)
-            << Var;
-        Var->setInvalidDecl();
-        return;
-      }
     }
 
     VarDecl::DefinitionKind DefKind = Var->isThisDeclarationADefinition();

diff  --git a/clang/test/CodeGenCXX/attr-loader-uninitialized.cpp b/clang/test/CodeGenCXX/attr-loader-uninitialized.cpp
index e82ae47e9f16..6501a25bf5bc 100644
--- a/clang/test/CodeGenCXX/attr-loader-uninitialized.cpp
+++ b/clang/test/CodeGenCXX/attr-loader-uninitialized.cpp
@@ -28,3 +28,15 @@ double arr[32] __attribute__((loader_uninitialized));
 // Defining as arr2[] [[clang..]] raises the error: attribute cannot be applied to types
 // CHECK: @arr2 = global [4 x double] undef
 double arr2 [[clang::loader_uninitialized]] [4];
+
+template<typename T> struct templ{T * t;};
+
+// CHECK: @templ_int = global %struct.templ undef, align 8
+templ<int> templ_int [[clang::loader_uninitialized]];
+
+// CHECK: @templ_trivial = global %struct.templ.0 undef, align 8
+templ<trivial> templ_trivial [[clang::loader_uninitialized]];
+
+// CHECK: @templ_incomplete = global %struct.templ.1 undef, align 8
+struct incomplete;
+templ<incomplete> templ_incomplete [[clang::loader_uninitialized]];

diff  --git a/clang/test/Sema/attr-loader-uninitialized.c b/clang/test/Sema/attr-loader-uninitialized.c
index f2e78d981580..a1edd858e27f 100644
--- a/clang/test/Sema/attr-loader-uninitialized.c
+++ b/clang/test/Sema/attr-loader-uninitialized.c
@@ -10,6 +10,10 @@ const int can_still_be_const __attribute__((loader_uninitialized));
 extern int external_rejected __attribute__((loader_uninitialized));
 // expected-error at -1 {{variable 'external_rejected' cannot be declared both 'extern' and with the 'loader_uninitialized' attribute}}
 
+struct S;
+extern struct S incomplete_external_rejected __attribute__((loader_uninitialized));
+// expected-error at -1 {{variable 'incomplete_external_rejected' cannot be declared both 'extern' and with the 'loader_uninitialized' attribute}}
+
 int noargs __attribute__((loader_uninitialized(0)));
 // expected-error at -1 {{'loader_uninitialized' attribute takes no arguments}}
 
@@ -35,3 +39,8 @@ __private_extern__ int initialized_private_extern_rejected __attribute__((loader
 
 extern __attribute__((visibility("hidden"))) int extern_hidden __attribute__((loader_uninitialized));
 // expected-error at -1 {{variable 'extern_hidden' cannot be declared both 'extern' and with the 'loader_uninitialized' attribute}}
+
+struct Incomplete;
+struct Incomplete incomplete __attribute__((loader_uninitialized));
+// expected-error at -1 {{variable has incomplete type 'struct Incomplete'}}
+// expected-note at -3 {{forward declaration of 'struct Incomplete'}}

diff  --git a/clang/test/Sema/attr-loader-uninitialized.cpp b/clang/test/Sema/attr-loader-uninitialized.cpp
index 3a330b3d5965..54b018fd91eb 100644
--- a/clang/test/Sema/attr-loader-uninitialized.cpp
+++ b/clang/test/Sema/attr-loader-uninitialized.cpp
@@ -9,6 +9,10 @@ const int still_cant_be_const __attribute__((loader_uninitialized));
 extern int external_rejected __attribute__((loader_uninitialized));
 // expected-error at -1 {{variable 'external_rejected' cannot be declared both 'extern' and with the 'loader_uninitialized' attribute}}
 
+struct S;
+extern S incomplete_external_rejected __attribute__((loader_uninitialized));
+// expected-error at -1 {{variable 'incomplete_external_rejected' cannot be declared both 'extern' and with the 'loader_uninitialized' attribute}}
+
 int noargs __attribute__((loader_uninitialized(0)));
 // expected-error at -1 {{'loader_uninitialized' attribute takes no arguments}}
 
@@ -58,3 +62,12 @@ struct nontrivial
 
 nontrivial needs_trivial_ctor __attribute__((loader_uninitialized));
 // expected-error at -1 {{variable with 'loader_uninitialized' attribute must have a trivial default constructor}}
+
+struct Incomplete;
+Incomplete incomplete __attribute__((loader_uninitialized));
+// expected-error at -1 {{variable has incomplete type 'Incomplete'}}
+// expected-note at -3 {{forward declaration of 'Incomplete'}}
+
+struct Incomplete s_incomplete __attribute__((loader_uninitialized));
+// expected-error at -1 {{variable has incomplete type 'struct Incomplete'}}
+// expected-note at -7 {{forward declaration of 'Incomplete'}}


        


More information about the cfe-commits mailing list