Richard Smith <[email protected]> writes:
> On Mon, Oct 7, 2013 at 3:09 PM, Justin Bogner <[email protected]> wrote:
>
>     Richard Smith <[email protected]> writes:
>     > This doesn't look right in the case where the attribute is on a typedef
>     > defined inside a class in C++. Instead, I think we should only perform
>     the
>     > merging if Old was a TypedefNameDecl.
>    
>     I think you meant to say "if old was a CXXRecordDecl"? This would mean I
>     should put the [dcl.typedef] logic back where it was before and handle
>     this separately. I think you're right.
>
> I meant what I said: we only want to merge attributes if the old declaration
> was also a typedef (that is, the redeclaration chain of typedefs has its own
> set of attributes that is independent of the attributes on the redeclaration
> chain for the record, and we shouldn't merge between them).

Ah, that makes way more sense. New patch attached.

>From 0741a8ac244281d2678dc2f48ad058278ebed61b Mon Sep 17 00:00:00 2001
From: Justin Bogner <[email protected]>
Date: Fri, 4 Oct 2013 11:53:18 -0700
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
---
 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 4d5d559..f2f2035 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<TypedefNameDecl>(Old))
+  // The types match.  Link up the redeclaration chain and merge attributes if
+  // the old declaration was a typedef.
+  if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(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 0000000..cf4caf0
--- /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 d09faf3..b3223f3 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.
-- 
1.8.3.4 (Apple Git-47)

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to