Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ related warnings within the method body.
- Clang now disallows the use of attributes applied before an
``extern template`` declaration (#GH79893).

- Clang now diagnoses unknown attribute namespaces.

Improvements to Clang's diagnostics
-----------------------------------

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/AttributeCommonInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class AttributeCommonInfo {
/// with surrounding underscores removed as appropriate (e.g.
/// __gnu__::__attr__ will be normalized to gnu::attr).
std::string getNormalizedFullName() const;
SourceRange getNormalizedRange() const;

bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ std::string AttributeCommonInfo::getNormalizedFullName() const {
normalizeName(getAttrName(), getScopeName(), getSyntax()));
}

SourceRange AttributeCommonInfo::getNormalizedRange() const {
return hasScope() ? SourceRange(ScopeLoc, AttrRange.getEnd()) : AttrRange;
}

static AttributeCommonInfo::Scope
getScopeFromNormalizedScopeName(StringRef ScopeName) {
return llvm::StringSwitch<AttributeCommonInfo::Scope>(ScopeName)
Expand Down
17 changes: 10 additions & 7 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6861,13 +6861,16 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
// though they were unknown attributes.
if (AL.getKind() == ParsedAttr::UnknownAttribute ||
!AL.existsInTarget(S.Context.getTargetInfo())) {
S.Diag(AL.getLoc(),
AL.isRegularKeywordAttribute()
? (unsigned)diag::err_keyword_not_supported_on_target
: AL.isDeclspecAttribute()
? (unsigned)diag::warn_unhandled_ms_attribute_ignored
: (unsigned)diag::warn_unknown_attribute_ignored)
<< AL << AL.getRange();
if (AL.isRegularKeywordAttribute() || AL.isDeclspecAttribute()) {
S.Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
? diag::err_keyword_not_supported_on_target
: diag::warn_unhandled_ms_attribute_ignored)
<< AL.getAttrName() << AL.getRange();
} else {
S.Diag(AL.getNormalizedRange().getBegin(),
diag::warn_unknown_attribute_ignored)
<< "'" + AL.getNormalizedFullName() + "'" << AL.getNormalizedRange();
}
return;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/module/module.interface/p3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export { // No diagnostic after P2615R1 DR
extern "C++" {} // No diagnostic after P2615R1 DR
}
export [[]]; // No diagnostic after P2615R1 DR
export [[example::attr]]; // expected-warning {{unknown attribute 'attr'}}
export [[example::attr]]; // expected-warning {{unknown attribute 'example::attr' ignored}}

// [...] shall not declare a name with internal linkage
export static int a; // expected-error {{declaration of 'a' with internal linkage cannot be exported}}
Expand Down
10 changes: 5 additions & 5 deletions clang/test/OpenMP/openmp_attribute_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
// attribute name. So this means we never hit the omp-specific parsing and
// instead handle this through the usual Sema attribute handling in
// SemaDeclAttr.cpp, which diagnoses this as an unknown attribute.
[[omp::directive]]; // expected-warning {{unknown attribute 'directive' ignored}}
[[omp::sequence]]; // expected-warning {{unknown attribute 'sequence' ignored}}
[[omp::unknown]]; // expected-warning {{unknown attribute 'unknown' ignored}}
[[omp::directive]]; // expected-warning {{unknown attribute 'omp::directive' ignored}}
[[omp::sequence]]; // expected-warning {{unknown attribute 'omp::sequence' ignored}}
[[omp::unknown]]; // expected-warning {{unknown attribute 'omp::unknown' ignored}}

[[omp::directive()]]; // expected-error {{expected an OpenMP directive}}
[[omp::sequence()]]; // expected-error {{expected an OpenMP 'directive' or 'sequence' attribute argument}}
Expand Down Expand Up @@ -49,8 +49,8 @@

// Test that we give a sensible error on an unknown attribute in the omp
// namespace that has an argument list.
[[omp::unknown()]]; // expected-warning {{unknown attribute 'unknown' ignored}}
[[using omp: unknown()]]; // expected-warning {{unknown attribute 'unknown' ignored}}
[[omp::unknown()]]; // expected-warning {{unknown attribute 'omp::unknown' ignored}}
[[using omp: unknown()]]; // expected-warning {{unknown attribute 'omp::unknown' ignored}}

// Test that unknown arguments to the omp::sequence are rejected, regardless of
// what level they're at.
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Parser/c2x-attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void f11(void) {
}

[[attr]] void f12(void); // expected-warning {{unknown attribute 'attr' ignored}}
[[vendor::attr]] void f13(void); // expected-warning {{unknown attribute 'attr' ignored}}
[[vendor::attr]] void f13(void); // expected-warning {{unknown attribute 'vendor::attr' ignored}}

// Ensure that asm statements properly handle double colons.
void test_asm(void) {
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Parser/cxx0x-attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ int & [[noreturn]] ref_attr_3 = after_attr; // expected-error {{'noreturn' attri
int && [[]] rref_attr = 0;
int array_attr [1] [[]];
alignas(8) int aligned_attr;
[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown attribute 'valid' ignored}}
[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown attribute 'test::valid' ignored}}
[[,,,static, class, namespace,, inline, constexpr, mutable,, bitand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr; // expected-warning {{unknown attribute 'static' ignored}} \
// expected-warning {{unknown attribute 'class' ignored}} \
// expected-warning {{unknown attribute 'namespace' ignored}} \
// expected-warning {{unknown attribute 'inline' ignored}} \
// expected-warning {{unknown attribute 'constexpr' ignored}} \
// expected-warning {{unknown attribute 'mutable' ignored}} \
// expected-warning {{unknown attribute 'bitand' ignored}} \
// expected-warning {{unknown attribute 'compl' ignored}}
// expected-warning {{unknown attribute 'bitor::compl' ignored}}
[[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected ']'}}
void fn_attr () [[]];
void noexcept_fn_attr () noexcept [[]];
Expand Down Expand Up @@ -269,7 +269,7 @@ template <int... Is> void variadic_nttp() {
void baz [[clang::no_sanitize(Is...)]] (); // expected-error {{expected string literal as argument of 'no_sanitize' attribute}}
void bor [[clang::annotate("A", "V" ...)]] (); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // expected-error {{'annotate' attribute requires parameter 1 to be a constant expression}} expected-note {{subexpression not valid in a constant expression}}
void boo [[unknown::foo(Is...)]] (); // expected-warning {{unknown attribute 'foo' ignored}}
void boo [[unknown::foo(Is...)]] (); // expected-warning {{unknown attribute 'unknown::foo' ignored}}
void faz [[clang::annotate("C", (Is + ...))]] (); // expected-warning {{pack fold expression is a C++17 extension}}
void far [[clang::annotate("D", Is...)]] ();
void foz [[clang::annotate("E", 1, 2, 3, Is...)]] ();
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/patchable-function-entry-attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
// silence-no-diagnostics

// AIX-error@+2 {{'patchable_function_entry' attribute is not yet supported on AIX}}
// expected-warning@+1 {{unknown attribute 'patchable_function_entry' ignored}}
// expected-warning@+1 {{unknown attribute 'gnu::patchable_function_entry' ignored}}
[[gnu::patchable_function_entry(0)]] void f();
12 changes: 12 additions & 0 deletions clang/test/Sema/unknown-attributes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 -Wunknown-attributes -fsyntax-only -verify %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -Wunknown-attributes -verify %s

[[foo::a]] // expected-warning {{unknown attribute 'foo::a' ignored}}
int f1(void) {
return 0;
}

[[clan::deprecated]] // expected-warning {{unknown attribute 'clan::deprecated' ignored}}
int f2(void) {
return 0;
}
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ struct CStructNoUniqueAddress {
struct CStructMSVCNoUniqueAddress {
int one;
[[msvc::no_unique_address]] int two;
// unsupported-warning@-1 {{unknown attribute 'no_unique_address' ignored}}
// unsupported-warning@-1 {{unknown attribute 'msvc::no_unique_address' ignored}}
};

struct CStructMSVCNoUniqueAddress2 {
int one;
[[msvc::no_unique_address]] int two;
// unsupported-warning@-1 {{unknown attribute 'no_unique_address' ignored}}
// unsupported-warning@-1 {{unknown attribute 'msvc::no_unique_address' ignored}}
};

static_assert(__has_cpp_attribute(no_unique_address) == 0);
Expand Down