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