Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -504,6 +504,8 @@ Improvements to Clang's diagnostics
behavior of the C99 feature as it was introduced into C++20. Fixes #GH47037
- ``-Wreserved-identifier`` now fires on reserved parameter names in a function
declaration which is not a definition.
- Clang now prints the namespace for an attribute, if any,
when emitting an unknown attribute diagnostic.

Improvements to Clang's time-trace
----------------------------------
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