[clang] 7bd92f5 - [AST] Pick last tentative definition as the acting definition

Benson Chu via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 26 14:53:07 PDT 2021


Author: Benson Chu
Date: 2021-08-26T16:49:54-05:00
New Revision: 7bd92f5911dc7ec54200d37552d364f87ad03dfb

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

LOG: [AST] Pick last tentative definition as the acting definition

Clang currently picks the second tentative definition when
VarDecl::getActingDefinition is called.

This can lead to attributes being dropped if they are attached to
tentative definitions that appear after the second one. This is
because VarDecl::getActingDefinition loops through VarDecl::redecls
assuming that the last tentative definition is the last element in the
iterator. However, it is the second element that would be the last
tentative definition.

This changeset modifies getActingDefinition to iterate through the
declaration chain in reverse, so that it can immediately return when
it encounters a tentative definition.

Originally the unit test for this changeset did not have a -triple
flag for the clang invocation, leading to this test being broken on
MacOS, since Mach-O does not support the section attribute.

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

Added: 
    clang/test/CodeGen/attr-tentative-definition.c

Modified: 
    clang/lib/AST/Decl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index aa9fba519642a..835e28c0bc9fc 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2216,14 +2216,18 @@ VarDecl *VarDecl::getActingDefinition() {
     return nullptr;
 
   VarDecl *LastTentative = nullptr;
-  VarDecl *First = getFirstDecl();
-  for (auto I : First->redecls()) {
-    Kind = I->isThisDeclarationADefinition();
+
+  // Loop through the declaration chain, starting with the most recent.
+  for (VarDecl *Decl = getMostRecentDecl(); Decl;
+       Decl = Decl->getPreviousDecl()) {
+    Kind = Decl->isThisDeclarationADefinition();
     if (Kind == Definition)
       return nullptr;
-    if (Kind == TentativeDefinition)
-      LastTentative = I;
+    // Record the first (most recent) TentativeDefinition that is encountered.
+    if (Kind == TentativeDefinition && !LastTentative)
+      LastTentative = Decl;
   }
+
   return LastTentative;
 }
 

diff  --git a/clang/test/CodeGen/attr-tentative-definition.c b/clang/test/CodeGen/attr-tentative-definition.c
new file mode 100644
index 0000000000000..0c49894e9bbc0
--- /dev/null
+++ b/clang/test/CodeGen/attr-tentative-definition.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-unknown < %s | FileCheck %s
+
+char arr[10];
+char arr[10] __attribute__((section("datadata")));
+char arr[10] __attribute__((aligned(16)));
+
+// CHECK: @arr ={{.*}}section "datadata", align 16


        


More information about the cfe-commits mailing list