aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDecl.cpp24
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.cpp3
-rw-r--r--test/CodeGenCXX/visibility.cpp2
-rw-r--r--test/Sema/attr-declspec-ignored.c12
-rw-r--r--test/Sema/attr-deprecated.c4
-rw-r--r--test/Sema/warn-cast-align.c2
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp2
-rw-r--r--test/SemaCXX/attr-declspec-ignored.cpp19
10 files changed, 61 insertions, 10 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index e69312e37a..d9c078f880 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -186,6 +186,7 @@ def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
def UnknownAttributes : DiagGroup<"attributes">;
+def IgnoredAttributes : DiagGroup<"ignored-attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
[CXX98CompatUnnamedTypeTemplateArgs]>;
def UnusedArgument : DiagGroup<"unused-argument">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index aa6fe86081..c0676dd3e1 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1465,6 +1465,8 @@ def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_declspec_attribute_ignored : Warning<
+ "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function_method : Warning<
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5edeab416d..a0291afeed 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2367,8 +2367,6 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
bool emittedWarning = false;
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
-
if (!Record->getDeclName() && Record->isCompleteDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
if (getLangOptions().CPlusPlus ||
@@ -2463,7 +2461,27 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
<< Tag->getTagKind()
<< FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc());
- // FIXME: Warn on useless attributes
+ // Warn about ignored type attributes, for example:
+ // __attribute__((aligned)) struct A;
+ // Attributes should be placed after tag to apply to type declaration.
+ if (!DS.getAttributes().empty()) {
+ DeclSpec::TST TypeSpecType = DS.getTypeSpecType();
+ if (TypeSpecType == DeclSpec::TST_class ||
+ TypeSpecType == DeclSpec::TST_struct ||
+ TypeSpecType == DeclSpec::TST_union ||
+ TypeSpecType == DeclSpec::TST_enum) {
+ AttributeList* attrs = DS.getAttributes().getList();
+ while (attrs) {
+ Diag(attrs->getScopeLoc(),
+ diag::warn_declspec_attribute_ignored)
+ << attrs->getName()
+ << (TypeSpecType == DeclSpec::TST_class ? 0 :
+ TypeSpecType == DeclSpec::TST_struct ? 1 :
+ TypeSpecType == DeclSpec::TST_union ? 2 : 3);
+ attrs = attrs->getNext();
+ }
+ }
+ }
return TagD;
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index a0b55804b9..bbdf489796 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -162,8 +162,7 @@ struct TestUnexpandedTTP {
// Test for unexpanded parameter packs in declarations.
template<typename T, typename... Types>
// FIXME: this should test that the diagnostic reads "type contains..."
-alignas(Types) // expected-error{{expression contains unexpanded parameter pack 'Types'}}
-struct TestUnexpandedDecls : T{
+struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}
void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 0f36a6a753..0da55c63d6 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -156,7 +156,7 @@ namespace Test9 {
namespace Test10 {
struct A;
- DEFAULT class B {
+ class DEFAULT B {
void foo(A*);
};
diff --git a/test/Sema/attr-declspec-ignored.c b/test/Sema/attr-declspec-ignored.c
new file mode 100644
index 0000000000..e1bce4726e
--- /dev/null
+++ b/test/Sema/attr-declspec-ignored.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+__attribute__((visibility("hidden"))) __attribute__((aligned)) struct A; // expected-warning{{attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration}} \
+// expected-warning{{attribute 'aligned' is ignored, place it after "struct" to apply attribute to type declaration}}
+__attribute__((visibility("hidden"))) __attribute__((aligned)) union B; // expected-warning{{attribute 'visibility' is ignored, place it after "union" to apply attribute to type declaration}} \
+// expected-warning{{attribute 'aligned' is ignored, place it after "union" to apply attribute to type declaration}}
+__attribute__((visibility("hidden"))) __attribute__((aligned)) enum C {C}; // expected-warning{{attribute 'visibility' is ignored, place it after "enum" to apply attribute to type declaration}} \
+// expected-warning{{attribute 'aligned' is ignored, place it after "enum" to apply attribute to type declaration}}
+
+__attribute__((visibility("hidden"))) __attribute__((aligned)) struct D {} d;
+__attribute__((visibility("hidden"))) __attribute__((aligned)) union E {} e;
+__attribute__((visibility("hidden"))) __attribute__((aligned)) enum F {F} f;
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index 86ee80ef06..4760dabc4c 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -44,8 +44,8 @@ void test1(struct foo *F) {
typedef struct foo foo_dep __attribute__((deprecated));
foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}}
-struct bar_dep __attribute__((deprecated,
- invalid_attribute)); // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+struct __attribute__((deprecated,
+ invalid_attribute)) bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}}
diff --git a/test/Sema/warn-cast-align.c b/test/Sema/warn-cast-align.c
index 93352c253a..9d64699bb5 100644
--- a/test/Sema/warn-cast-align.c
+++ b/test/Sema/warn-cast-align.c
@@ -28,7 +28,7 @@ void test1(void *P) {
}
// Aligned struct.
-__attribute__((aligned(16))) struct A {
+struct __attribute__((aligned(16))) A {
char buffer[16];
};
void test2(char *P) {
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index c697a7d152..4281895f40 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -9,7 +9,7 @@ struct align_member {
int member alignas(8);
};
-template <unsigned A> alignas(A) struct align_class_template {};
+template <unsigned A> struct alignas(A) align_class_template {};
// FIXME: these should not error
template <typename... T> alignas(T...) struct align_class_temp_pack_type {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}}
diff --git a/test/SemaCXX/attr-declspec-ignored.cpp b/test/SemaCXX/attr-declspec-ignored.cpp
new file mode 100644
index 0000000000..c6745c4e64
--- /dev/null
+++ b/test/SemaCXX/attr-declspec-ignored.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+namespace test1 {
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) class A; // expected-warning{{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}} \
+ // expected-warning{{attribute 'aligned' is ignored, place it after "class" to apply attribute to type declaration}}
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) struct B; // expected-warning{{attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration}} \
+ // expected-warning{{attribute 'aligned' is ignored, place it after "struct" to apply attribute to type declaration}}
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) union C; // expected-warning{{attribute 'visibility' is ignored, place it after "union" to apply attribute to type declaration}} \
+ // expected-warning{{attribute 'aligned' is ignored, place it after "union" to apply attribute to type declaration}}
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) enum D {D}; // expected-warning{{attribute 'visibility' is ignored, place it after "enum" to apply attribute to type declaration}} \
+ // expected-warning{{attribute 'aligned' is ignored, place it after "enum" to apply attribute to type declaration}}
+}
+
+namespace test2 {
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) class A {} a;
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) struct B {} b;
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) union C {} c;
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) enum D {D} d;
+}