From 9a5f3888505630cea88f8372d3068b2d63cfb381 Mon Sep 17 00:00:00 2001 From: Benson Chu Date: Sun, 15 Aug 2021 13:12:21 -0500 Subject: [PATCH] [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. Differential Revision: https://reviews.llvm.org/D99732 --- clang/lib/AST/Decl.cpp | 14 +++++++++----- clang/test/CodeGen/attr-tentative-definition.c | 7 +++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGen/attr-tentative-definition.c diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index aa9fba519642..835e28c0bc9f 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 000000000000..7405e8079b22 --- /dev/null +++ b/clang/test/CodeGen/attr-tentative-definition.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s + +char arr[10]; +char arr[10] __attribute__((section("datadata"))); +char arr[10] __attribute__((aligned(16))); + +// CHECK: @arr ={{.*}}section "datadata", align 16