From 2dd68de1bf29993c8c8d7e20a3f230fc9a5a40e8 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Tue, 8 Oct 2013 00:19:09 +0000 Subject: [PATCH] Sema: Only merge typedef attributes if the previous decl is a typedef In r186373, we started merging attributes on typedefs, but this causes us to try to merge attributes even if the previous declaration was not a typedef. Only merge the attributes if the previous decl was also a typedef. Fixes rdar://problem/15044218 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192146 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 10 +++++----- test/SemaCXX/attr-aligned.cpp | 16 ++++++++++++++++ test/SemaCXX/attr-deprecated.cpp | 6 ++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 test/SemaCXX/attr-aligned.cpp diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4d5d559ed5..f2f203531f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1712,12 +1712,12 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { if (isIncompatibleTypedef(Old, New)) return; - // The types match. Link up the redeclaration chain if the old - // declaration was a typedef. - if (TypedefNameDecl *Typedef = dyn_cast(Old)) + // The types match. Link up the redeclaration chain and merge attributes if + // the old declaration was a typedef. + if (TypedefNameDecl *Typedef = dyn_cast(Old)) { New->setPreviousDeclaration(Typedef); - - mergeDeclAttributes(New, Old); + mergeDeclAttributes(New, Old); + } if (getLangOpts().MicrosoftExt) return; diff --git a/test/SemaCXX/attr-aligned.cpp b/test/SemaCXX/attr-aligned.cpp new file mode 100644 index 0000000000..4b9c55f4c7 --- /dev/null +++ b/test/SemaCXX/attr-aligned.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// expected-no-diagnostics + +typedef struct S1 { char c; } S1 __attribute__((aligned(8))); +static_assert(alignof(S1) == 8, "attribute ignored"); +static_assert(alignof(struct S1) == 1, "attribute applied to original type"); + +typedef struct __attribute__((aligned(8))) S2 { char c; } AS; +static_assert(alignof(S2) == 8, "attribute not propagated"); +static_assert(alignof(struct S2) == 8, "attribute ignored"); + +typedef struct __attribute__((aligned(4))) S3 { + char c; +} S3 __attribute__((aligned(8))); +static_assert(alignof(S3) == 8, "attribute ignored"); +static_assert(alignof(struct S3) == 4, "attribute clobbered"); diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp index d09faf34d7..b3223f3997 100644 --- a/test/SemaCXX/attr-deprecated.cpp +++ b/test/SemaCXX/attr-deprecated.cpp @@ -244,3 +244,9 @@ namespace test7 { X *x = new X; // expected-warning{{'operator new' is deprecated}} expected-warning{{'operator delete' is deprecated}} } } + +// rdar://problem/15044218 +typedef struct TDS { +} TDS __attribute__((deprecated)); // expected-note {{'TDS' declared here}} +TDS tds; // expected-warning {{'TDS' is deprecated}} +struct TDS tds2; // no warning, attribute only applies to the typedef. -- 2.40.0