Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLANG] Enable alignas after GNU attributes #133107

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
@@ -428,6 +428,7 @@ Bug Fixes to C++ Support
- Clang no longer crashes when establishing subsumption between some constraint expressions. (#GH122581)
- Clang now issues an error when placement new is used to modify a const-qualified variable
in a ``constexpr`` function. (#GH131432)
- Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107)
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)

Bug Fixes to AST Handling
5 changes: 4 additions & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
@@ -3062,13 +3062,16 @@ class Parser : public CodeCompletionHandler {
bool CouldBeBitField = false);
Decl *ParseHLSLBuffer(SourceLocation &DeclEnd);

void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) {
bool MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) {
bool AttrsParsed = false;
if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) &&
Tok.is(tok::l_square)) {
ParsedAttributes AttrsWithRange(AttrFactory);
ParseMicrosoftAttributes(AttrsWithRange);
AttrsParsed = AttrsWithRange.size();
Attrs.takeAllFrom(AttrsWithRange);
}
return AttrsParsed;
}
void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
void ParseMicrosoftAttributes(ParsedAttributes &Attrs);
7 changes: 5 additions & 2 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
@@ -3035,11 +3035,14 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
}

ParsedAttributes DeclSpecAttrs(AttrFactory);
MaybeParseMicrosoftAttributes(DeclSpecAttrs);

// Hold late-parsed attributes so we can attach a Decl to them later.
LateParsedAttrList CommonLateParsedAttrs;

while (MaybeParseCXX11Attributes(DeclAttrs) ||
MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs) ||
MaybeParseMicrosoftAttributes(DeclSpecAttrs))
;

// decl-specifier-seq:
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this, TemplateDiags);
13 changes: 8 additions & 5 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
@@ -235,6 +235,9 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
}

default: {
if (getLangOpts().CPlusPlus && MaybeParseCXX11Attributes(CXX11Attrs, true))
goto Retry;

bool HaveAttrs = !CXX11Attrs.empty() || !GNUAttrs.empty();
auto IsStmtAttr = [](ParsedAttr &Attr) { return Attr.isStmtAttr(); };
bool AllAttrsAreStmtAttrs = llvm::all_of(CXX11Attrs, IsStmtAttr) &&
@@ -260,11 +263,11 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
GNUAttrs);
}
if (CXX11Attrs.Range.getBegin().isValid()) {
// The caller must guarantee that the CXX11Attrs appear before the
// GNUAttrs, and we rely on that here.
assert(GNUAttrs.Range.getBegin().isInvalid() ||
GNUAttrs.Range.getBegin() > CXX11Attrs.Range.getBegin());
DeclStart = CXX11Attrs.Range.getBegin();
// Order of C++11 and GNU attributes is may be arbitrary.
DeclStart = GNUAttrs.Range.getBegin().isInvalid()
? CXX11Attrs.Range.getBegin()
: std::min(CXX11Attrs.Range.getBegin(),
GNUAttrs.Range.getBegin());
} else if (GNUAttrs.Range.getBegin().isValid())
DeclStart = GNUAttrs.Range.getBegin();
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
2 changes: 1 addition & 1 deletion clang/test/AST/ast-dump-color.cpp
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ struct Invalid {
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]] non_odr_use_unevaluated{{$}}
//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit referenced struct[[CYAN]] Invalid[[RESET]]
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]]
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:29[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]]
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]]
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]>
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit used constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void () noexcept'[[RESET]] inline
2 changes: 1 addition & 1 deletion clang/test/Index/annotate-attribute.cpp
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ int templateFunction(T value) __attribute__((annotate("works")));

// CHECK: ClassDecl=Test:3:7 (Definition) Extent=[3:1 - 17:2]
// CHECK-NEXT: CXXAccessSpecifier=:4:1 (Definition) Extent=[4:1 - 4:8]
// CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:3 - 5:60]
// CHECK-NEXT: CXXMethod=aMethod:5:51 Extent=[5:46 - 5:60]
// CHECK-NEXT: attribute(annotate)=spiffy_method Extent=[5:18 - 5:43]
// CHECK-NEXT: CXXAccessSpecifier=:7:1 (Definition) Extent=[7:1 - 7:43]
// CHECK-NEXT: attribute(annotate)=works Extent=[7:23 - 7:40]
23 changes: 23 additions & 0 deletions clang/test/Parser/c2x-alignas.c
Original file line number Diff line number Diff line change
@@ -2,3 +2,26 @@

_Alignas(int) struct c1; // expected-warning {{'_Alignas' attribute ignored}}
alignas(int) struct c1; // expected-warning {{'alignas' attribute ignored}}


__attribute__(()) [[]] alignas(int) int a; // expected-none TODO: actually this line should be an error
__attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}}
__attribute__(()) alignas(int) int c; // expected-none
[[]] __attribute__(()) alignas(int) int d; // expected-none
alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}}

struct C1 {
__attribute__(()) [[]] alignas(int) int a; // expected-error {{an attribute list cannot appear here}}
__attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}}
__attribute__(()) alignas(int) int c; // expected-none
[[]] __attribute__(()) alignas(int) int d; // expected-none
alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}}
};

void fn_with_decl() {
__attribute__(()) [[]] alignas(int) int a; // expected-error {{an attribute list cannot appear here}}
__attribute__(()) alignas(int) [[]] int b; // expected-error {{an attribute list cannot appear here}}
__attribute__(()) alignas(int) int c; // expected-none
[[]] __attribute__(()) alignas(int) int d; // expected-none
alignas(int) [[]] __attribute__(()) int e; // expected-error {{an attribute list cannot appear here}}
}
24 changes: 24 additions & 0 deletions clang/test/Parser/cxx0x-attributes.cpp
Original file line number Diff line number Diff line change
@@ -72,6 +72,30 @@ namespace test_misplacement {
[[]] enum E2 { }; //expected-error{{misplaced attributes}}
}

__attribute__(()) alignas(int) int xx; // expected-none
__attribute__(()) alignas(int) [[]] int yy; // expected-none
[[]] __attribute__(()) alignas(int) int zz; // expected-none
alignas(int) [[]] __attribute__(()) int aa; // expected-none
[[]] alignas(int) __attribute__(()) int bb; // expected-none
__attribute__(()) [[]] alignas(int) int cc; // expected-none

class C1 {
__attribute__(()) alignas(int) int x; // expected-none
__attribute__(()) alignas(int) [[]] int y; // expected-none
[[]] __attribute__(()) alignas(int) int z; // expected-none
alignas(int) [[]] __attribute__(()) int a; // expected-none
[[]] alignas(int) __attribute__(()) int b; // expected-none
__attribute__(()) [[]] alignas(int) int c; // expected-none
};

void fn_with_decl() {
__attribute__(()) alignas(int) int x; // expected-none
__attribute__(()) alignas(int) [[]] int y; // expected-none
[[]] __attribute__(()) alignas(int) int z; // expected-none
alignas(int) [[]] __attribute__(()) int a; // expected-none
[[]] alignas(int) __attribute__(()) int b; // expected-none
__attribute__(()) [[]] alignas(int) int c; // expected-none
}
// Checks attributes placed at wrong syntactic locations of class specifiers.
class [[]] [[]]
attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}}
15 changes: 15 additions & 0 deletions clang/test/SemaCUDA/cuda-attr-order.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Verify that we can parse a simple CUDA file with different attributes order.
// RUN: %clang_cc1 "-triple" "nvptx-nvidia-cuda" -fsyntax-only -verify %s
// expected-no-diagnostics
#include "Inputs/cuda.h"

struct alignas(16) float4 {
float x, y, z, w;
};

__attribute__((device)) float func() {
__shared__ alignas(alignof(float4)) float As[4][4]; // Both combinations
alignas(alignof(float4)) __shared__ float Bs[4][4]; // must be legal

return As[0][0] + Bs[0][0];
}
8 changes: 4 additions & 4 deletions clang/test/SemaCXX/warn-thread-safety-analysis.cpp
Original file line number Diff line number Diff line change
@@ -2434,10 +2434,10 @@ class Foo {
namespace WarnNoDecl {

class Foo {
void foo(int a); __attribute__(( // \
// expected-warning {{declaration does not declare anything}}
exclusive_locks_required(a))); // \
// expected-warning {{attribute exclusive_locks_required ignored}}
void foo(int a); __attribute__((
exclusive_locks_required(a))); // expected-warning {{declaration does not declare anything}} \
// expected-warning {{attribute exclusive_locks_required ignored}}

};

} // end namespace WarnNoDecl
Loading
Oops, something went wrong.