diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -109,6 +109,10 @@ bounds memory accesses. It emits warnings at call sites to such functions when the flag ``-Wunsafe-buffer-usage`` is enabled. +``__declspec`` attributes can now be used together with the using keyword. Before +the attributes on ``__declspec`` was ignored, while now it will be forwarded to the +point where the alias is used. + Windows Support --------------- diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -56,6 +56,18 @@ if (OwnedType) *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr; + // Move declspec attributes to ParsedAttributes + if (Attrs) { + llvm::SmallVector ToBeMoved; + for (ParsedAttr &AL : DS.getAttributes()) { + if (AL.isDeclspecAttribute()) + ToBeMoved.push_back(&AL); + } + + for (ParsedAttr *AL : ToBeMoved) + Attrs->takeOneFrom(DS.getAttributes(), AL); + } + // Parse the abstract-declarator, if present. Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), Context); ParseDeclarator(DeclaratorInfo); diff --git a/clang/test/SemaCXX/using-declspec.cpp b/clang/test/SemaCXX/using-declspec.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/using-declspec.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s + +// This should ignore the alignment and issue a warning about +// align not being used +auto func() -> __declspec(align(16)) int; // expected-warning{{attribute ignored when parsing type}} +static_assert(alignof(decltype(func())) == alignof(int)); + +// The following should NOT assert since alignment should +// follow the type +struct Test { int a; }; +using AlignedTest = __declspec(align(16)) const Test; +static_assert(alignof(AlignedTest) == 16, "error"); + +// Same here, no declaration to shift to +int i = (__declspec(align(16))int)12; // expected-warning{{attribute ignored when parsing type}} + +// But there is a declaration here! +typedef __declspec(align(16)) int Foo; +static_assert(alignof(Foo) == 16);