Author: Tobias Hieta Date: 2023-02-13T15:43:08+01:00 New Revision: 877859a09bda29fe9a7f1a9016b06cf80661a032
URL: https://github.com/llvm/llvm-project/commit/877859a09bda29fe9a7f1a9016b06cf80661a032 DIFF: https://github.com/llvm/llvm-project/commit/877859a09bda29fe9a7f1a9016b06cf80661a032.diff LOG: [clang] Handle __declspec() attributes in using This patch fixes so that declspec attributes are forwarded to the alias declaration. Before this patch this would assert: class Test { int a; }; using AlignedTest = __declspec(align(16)) const Test; static_assert(alignof(AlignedTest) == 16, "error"); But afterwards it behaves the same as MSVC does and doesn't assert. Fixes: llvm/llvm-project#60513 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D143632 Added: clang/test/SemaCXX/using-declspec.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Parse/ParseDecl.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4fef5f883655..06f0bdcc796d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -109,6 +109,10 @@ to be worn by functions containing buffer operations that could cause out of 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 index 96c25ba0c853..d32f26b9c32e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -56,6 +56,18 @@ TypeResult Parser::ParseTypeName(SourceRange *Range, DeclaratorContext Context, if (OwnedType) *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr; + // Move declspec attributes to ParsedAttributes + if (Attrs) { + llvm::SmallVector<ParsedAttr *, 1> 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 index 000000000000..a903bc93c9b4 --- /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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits