The following is warning that "attribute declaration must precede
definition" in C++ in ToT:

typedef struct S {
  // ...
} S __attribute__((...));

This started happening in r186373. The attached patch fixes when
mergeDeclAttributes happens in MergeTypedefNameDecl to avoid this. Okay
to commit?

>From 5dcc5167eac2b25ade32311d9639097240eb47d3 Mon Sep 17 00:00:00 2001
From: Justin Bogner <[email protected]>
Date: Fri, 4 Oct 2013 11:53:18 -0700
Subject: [PATCH] Sema: When merging typedefs, handle records before merging
 attributes

In r186373, we started merging attributes on typedefs. Unfortunately,
this breaks the case where we declare and typedef a type in a single
statement, like so:

typedef struct S {
  // ...
} S __attribute__((...));

We move the check for records before the attribute merge to avoid
this.

Fixes rdar://problem/15044218
---
 lib/Sema/SemaDecl.cpp            | 14 +++++++-------
 test/SemaCXX/attr-deprecated.cpp |  5 +++++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 4d5d559..292ae06 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1717,19 +1717,19 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
   if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old))
     New->setPreviousDeclaration(Typedef);
 
+  // C++ [dcl.typedef]p2:
+  //   In a given non-class scope, a typedef specifier can be used to
+  //   redefine the name of any type declared in that scope to refer
+  //   to the type to which it already refers.
+  if (getLangOpts().CPlusPlus && !isa<CXXRecordDecl>(CurContext))
+      return;
+
   mergeDeclAttributes(New, Old);
 
   if (getLangOpts().MicrosoftExt)
     return;
 
   if (getLangOpts().CPlusPlus) {
-    // C++ [dcl.typedef]p2:
-    //   In a given non-class scope, a typedef specifier can be used to
-    //   redefine the name of any type declared in that scope to refer
-    //   to the type to which it already refers.
-    if (!isa<CXXRecordDecl>(CurContext))
-      return;
-
     // C++0x [dcl.typedef]p4:
     //   In a given class scope, a typedef specifier can be used to redefine 
     //   any class-name declared in that scope that is not also a typedef-name
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index d09faf3..f7d6b20 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -244,3 +244,8 @@ 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}}
-- 
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