https://github.com/smanna12 updated https://github.com/llvm/llvm-project/pull/70762
>From 93d46d40f46663cfa30fc01da965887508684e25 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 30 Oct 2023 21:41:00 -0700 Subject: [PATCH 01/11] [clang] Add support for new loop attribute [[clang::code_align()]] --- clang/include/clang/Basic/Attr.td | 9 ++ clang/include/clang/Basic/AttrDocs.td | 43 ++++++ .../clang/Basic/DiagnosticSemaKinds.td | 4 + clang/include/clang/Sema/Sema.h | 2 + clang/lib/CodeGen/CGLoopInfo.cpp | 29 +++- clang/lib/CodeGen/CGLoopInfo.h | 6 + clang/lib/Sema/SemaStmtAttr.cpp | 53 ++++++++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 8 +- clang/test/CodeGen/code_align.c | 61 +++++++++ clang/test/Sema/code_align.c | 124 ++++++++++++++++++ clang/test/Sema/code_align_ast.c | 91 +++++++++++++ 11 files changed, 426 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGen/code_align.c create mode 100644 clang/test/Sema/code_align.c create mode 100644 clang/test/Sema/code_align_ast.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 25231c5b82b907c..e25bea67bf9e86e 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4280,3 +4280,12 @@ def PreferredType: InheritableAttr { let Args = [TypeArgument<"Type", 1>]; let Documentation = [PreferredTypeDocumentation]; } + +def CodeAlign: StmtAttr { + let Spellings = [CXX11<"clang", "code_align">, + C23<"clang", "code_align">]; + let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], + ErrorDiag, "'for', 'while', and 'do' statements">; + let Args = [ExprArgument<"NExpr">]; + let Documentation = [CodeAlignAttrDocs]; +} diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 05703df2129f612..5ee224e117d049c 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7416,3 +7416,46 @@ that ``p->array`` must have at least ``p->count`` number of elements available: }]; } + +def CodeAlignAttrDocs : Documentation { + let Category = DocCatVariable; + let Heading = "clang::code_align"; + let Content = [{ +The ``clang::code_align(N)`` attribute applies to a loop and it specifies the +byte alignment for a loop. The attribute accepts a positive integer constant +initialization expression indicating the number of bytes for the minimum +alignment boundary. Its value must be a power of 2, between 1 and 4096, such as +1, 2, 4, 8, and so on. This attribute sets ``llvm.loop.align`` loop metadata +when it applies on a loop statement. + +.. code-block:: c++ + + void foo() { + int var = 0; + [[clang::code_align(16)]] for (int i = 0; i < 10; ++i) var++; + } + + void Array(int *array, size_t n) { + [[clang::code_align(64)]] for (int i = 0; i < n; ++i) array[i] = 0; + } + + void count () { + int a1[10], int i = 0; + [[clang::code_align(32)]] while (i < 10) { + a1[i] += 3; + } + + void check() { + int a = 10; + [[clang::code_align(8)]] do { + a = a + 1; + } while (a < 20); + } + + template<int A> + void func() { + [[clang::code_align(A)]] for(;;) { } + } + + }]; +} diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 224c0df7f1fb71f..4b0f24d25e3e902 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10026,6 +10026,10 @@ def err_duplicate_case_differing_expr : Error< def warn_case_empty_range : Warning<"empty case range specified">; def warn_missing_case_for_condition : Warning<"no case matching constant switch condition '%0'">; +def err_loop_attr_duplication : Error< + "duplicate loop attribute %0">; +def err_attribute_argument_not_power_of_two : Error< + "%0 attribute argument must be a constant power of two greater than zero">; def warn_def_missing_case : Warning<"%plural{" "1:enumeration value %1 not explicitly handled in switch|" diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1e9752345ffd173..376335e9bbe70ca 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2096,6 +2096,8 @@ class Sema final { QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace, SourceLocation AttrLoc); + CodeAlignAttr *BuildCodeAlignAttr(const AttributeCommonInfo &CI, Expr *E); + bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); bool CheckFunctionReturnType(QualType T, SourceLocation Loc); diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index e5d9db273c2d336..a7cae301ba7bfda 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -440,6 +440,14 @@ MDNode *LoopInfo::createMetadata( Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup})); } + // Setting clang::code_align attribute. + if (Attrs.CodeAlign > 0) { + Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.align"), + ConstantAsMetadata::get(ConstantInt::get( + llvm::Type::getInt32Ty(Ctx), Attrs.CodeAlign))}; + LoopProperties.push_back(MDNode::get(Ctx, Vals)); + } + LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(), AdditionalLoopProperties.end()); return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms); @@ -453,7 +461,7 @@ LoopAttributes::LoopAttributes(bool IsParallel) VectorizeScalable(LoopAttributes::Unspecified), InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0), DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false), - PipelineInitiationInterval(0), MustProgress(false) {} + PipelineInitiationInterval(0), CodeAlign(0), MustProgress(false) {} void LoopAttributes::clear() { IsParallel = false; @@ -469,6 +477,7 @@ void LoopAttributes::clear() { DistributeEnable = LoopAttributes::Unspecified; PipelineDisabled = false; PipelineInitiationInterval = 0; + CodeAlign = 0; MustProgress = false; } @@ -493,8 +502,8 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, Attrs.VectorizeEnable == LoopAttributes::Unspecified && Attrs.UnrollEnable == LoopAttributes::Unspecified && Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified && - Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc && - !EndLoc && !Attrs.MustProgress) + Attrs.DistributeEnable == LoopAttributes::Unspecified && + Attrs.CodeAlign == 0 && !StartLoc && !EndLoc && !Attrs.MustProgress) return; TempLoopID = MDNode::getTemporary(Header->getContext(), std::nullopt); @@ -788,6 +797,20 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, } } + // Translate 'loop attributes' arguments to equivalent Attr enums. + // It's being handled separately from LoopHintAttrs not to support + // legacy GNU attributes and pragma styles. + // + // For attribute code_align: + // n - 'llvm.loop.align i32 n' metadata will be emitted. + for (const auto *A : Attrs) { + if (const auto *CodeAlign = dyn_cast<CodeAlignAttr>(A)) { + const auto *CE = cast<ConstantExpr>(CodeAlign->getNExpr()); + llvm::APSInt ArgVal = CE->getResultAsAPSInt(); + setCodeAlign(ArgVal.getSExtValue()); + } + } + setMustProgress(MustProgress); if (CGOpts.OptimizationLevel > 0) diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index 856e892f712e31f..f5438d7865946ab 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -79,6 +79,9 @@ struct LoopAttributes { /// Value for llvm.loop.pipeline.iicount metadata. unsigned PipelineInitiationInterval; + /// Value for 'llvm.loop.align' loop metadata. + unsigned CodeAlign; + /// Value for whether the loop is required to make progress. bool MustProgress; }; @@ -282,6 +285,9 @@ class LoopInfoStack { StagedAttrs.PipelineInitiationInterval = C; } + /// Set the CodeAlign for the next loop pushed. + void setCodeAlign(unsigned C) { StagedAttrs.CodeAlign = C; } + /// Set no progress for the next loop pushed. void setMustProgress(bool P) { StagedAttrs.MustProgress = P; } diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index ad20bc8871f103a..7b9dd0c97e61c1e 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -322,6 +322,56 @@ static Attr *handleUnlikely(Sema &S, Stmt *St, const ParsedAttr &A, return ::new (S.Context) UnlikelyAttr(S.Context, A); } +CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, + Expr *E) { + if (!E->isValueDependent()) { + llvm::APSInt ArgVal; + ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal); + if (Res.isInvalid()) + return nullptr; + E = Res.get(); + + // This attribute requires a strictly positive value. + if (ArgVal <= 0) { + Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) + << CI << /*positive*/ 0; + return nullptr; + } + + // This attribute requires a single constant power of two greater than zero. + if (!ArgVal.isPowerOf2()) { + Diag(E->getExprLoc(), diag::err_attribute_argument_not_power_of_two) + << CI; + return nullptr; + } + } + + return new (Context) CodeAlignAttr(Context, CI, E); +} + +static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { + + Expr *E = A.getArgAsExpr(0); + return S.BuildCodeAlignAttr(A, E); +} + +// Emit duplicate error for [[clang::code_align()]] attribute. +template <typename LoopAttrT> +static void +CheckForDuplicateLoopAttribute(Sema &S, + const SmallVectorImpl<const Attr *> &Attrs) { + const LoopAttrT *LoopAttr = nullptr; + + for (const auto *I : Attrs) { + if (LoopAttr && isa<LoopAttrT>(I)) { + // Cannot specify same type of attribute twice. + S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << LoopAttr; + } + if (isa<LoopAttrT>(I)) + LoopAttr = cast<LoopAttrT>(I); + } +} + #define WANT_STMT_MERGE_LOGIC #include "clang/Sema/AttrParsedAttrImpl.inc" #undef WANT_STMT_MERGE_LOGIC @@ -523,6 +573,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, return handleLikely(S, St, A, Range); case ParsedAttr::AT_Unlikely: return handleUnlikely(S, St, A, Range); + case ParsedAttr::AT_CodeAlign: + return handleCodeAlignAttr(S, St, A); default: // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a // declaration attribute is not written on a statement, but this code is @@ -541,4 +593,5 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs, } CheckForIncompatibleAttributes(*this, OutAttrs); + CheckForDuplicateLoopAttribute<CodeAlignAttr>(*this, OutAttrs); } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index e09897318ba9883..436364cfc0a4dce 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1374,7 +1374,7 @@ namespace { const AlwaysInlineAttr * TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS, const AlwaysInlineAttr *A); - + const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA); ExprResult TransformPredefinedExpr(PredefinedExpr *E); ExprResult TransformDeclRefExpr(DeclRefExpr *E); ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -1905,6 +1905,12 @@ const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr( return A; } +const CodeAlignAttr * +TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) { + Expr *TransformedExpr = getDerived().TransformExpr(CA->getNExpr()).get(); + return getSema().BuildCodeAlignAttr(*CA, TransformedExpr); +} + ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef( Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm, SourceLocation loc, TemplateArgument arg, diff --git a/clang/test/CodeGen/code_align.c b/clang/test/CodeGen/code_align.c new file mode 100644 index 000000000000000..f1ee06ff70eef27 --- /dev/null +++ b/clang/test/CodeGen/code_align.c @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C %s +// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP + +// Add CodeGen tests for Loop attribute: [[clang::code_align)]]. + +// CHECK-C: br label %for.cond, !llvm.loop ![[MD_FP:[0-9]+]] +// CHECK-C: br label %while.cond, !llvm.loop ![[MD_FP_1:[0-9]+]] +// CHECK-C: br i1 %cmp3, label %do.body, label %do.end, !llvm.loop ![[MD_FP_2:[0-9]+]] +// CHECK-C: br label %for.cond5, !llvm.loop ![[MD_FP_3:[0-9]+]] + +// CHECK-CPP: br label %for.cond, !llvm.loop ![[MD_FP_4:[0-9]+]] +// CHECK-CPP: br label %for.cond2, !llvm.loop ![[MD_FP_5:[0-9]+]] + +void bar(int); +void code_align() { + int a[10]; + // CHECK-C: ![[MD_FP]] = distinct !{![[MD_FP]], ![[MP:[0-9]+]], ![[MD_code_align:[0-9]+]]} + // CHECK-C-NEXT: ![[MP]] = !{!"llvm.loop.mustprogress"} + // CHECK-C-NEXT: ![[MD_code_align]] = !{!"llvm.loop.align", i32 4} + [[clang::code_align(4)]] + for(int I=0; I<128; ++I) { bar(I); } + + // CHECK-C: ![[MD_FP_1]] = distinct !{![[MD_FP_1]], ![[MP]], ![[MD_code_align_1:[0-9]+]]} + // CHECK-C-NEXT: ![[MD_code_align_1]] = !{!"llvm.loop.align", i32 16} + int i = 0; + [[clang::code_align(16)]] while (i < 60) { + a[i] += 3; + } + + // CHECK-C: ![[MD_FP_2]] = distinct !{![[MD_FP_2]], ![[MP]], ![[MD_code_align_2:[0-9]+]]} + // CHECK-C-NEXT: ![[MD_code_align_2]] = !{!"llvm.loop.align", i32 8} + int b = 10; + [[clang::code_align(8)]] do { + b = b + 1; + } while (b < 20); + + // CHECK-C: ![[MD_FP_3]] = distinct !{![[MD_FP_3]], ![[MP]], ![[MD_code_align_3:[0-9]+]]} + // CHECK-C-NEXT: ![[MD_code_align_3]] = !{!"llvm.loop.align", i32 64} + [[clang::code_align(64)]] + for(int I=0; I<128; ++I) { bar(I); } +} + +#if __cplusplus >= 201103L +template <int A, int B> +void code_align_cpp() { + int a[10]; + // CHECK-CPP: ![[MD_FP_4]] = distinct !{![[MD_FP_4]], ![[MP]], ![[MD_code_align_4:[0-9]+]]} + // CHECK-CPP-NEXT: ![[MD_code_align_4]] = !{!"llvm.loop.align", i32 32} + [[clang::code_align(A)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // CHECK-CPP: ![[MD_FP_5]] = distinct !{![[MD_FP_5]], ![[MD_code_align]]} + int c[] = {0, 1, 2, 3, 4, 5}; + [[clang::code_align(B)]] for (int n : c) { n *= 2; } +} + +int main() { + code_align_cpp<32, 4>(); + return 0; +} +#endif diff --git a/clang/test/Sema/code_align.c b/clang/test/Sema/code_align.c new file mode 100644 index 000000000000000..74f39ffe23300d0 --- /dev/null +++ b/clang/test/Sema/code_align.c @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,c-local %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp-local -pedantic -x c++ -std=c++11 %s + +// Add diagnostics tests for Loop attribute: [[clang::code_align()]]. + +void foo() { + int i; + int a[10], b[10]; + + [[clang::code_align(8)]] + for (i = 0; i < 10; ++i) { // this is OK + a[i] = b[i] = 0; + } + // expected-error@+1 {{'code_align' attribute only applies to 'for', 'while', and 'do' statements}} + [[clang::code_align(4)]] + i = 7; + for (i = 0; i < 10; ++i) { + a[i] = b[i] = 0; + } + + // expected-error@+1{{'code_align' attribute cannot be applied to a declaration}} + [[clang::code_align(12)]] int n[10]; +} + +void bar(int); +#if __cplusplus >= 201103L +// cpp-local-note@+2 {{declared here}} +#endif +void foo1(int A) +{ + // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} + [[clang::code_align(0)]] + for(int I=0; I<128; ++I) { bar(I); } + + // expected-error@+1{{'code_align' attribute requires a positive integral compile time constant expression}} + [[clang::code_align(-4)]] + for(int I=0; I<128; ++I) { bar(I); } + +#if __cplusplus >= 201103L + // cpp-local-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'double'}} +#else + // c-local-error@+2 {{integer constant expression must have integer type, not 'double'}} +#endif + [[clang::code_align(64.0)]] + for(int I=0; I<128; ++I) { bar(I); } + + // expected-error@+1 {{'code_align' attribute takes one argument}} + [[clang::code_align()]] + for(int I=0; I<128; ++I) { bar(I); } + + // expected-error@+1 {{'code_align' attribute takes one argument}} + [[clang::code_align(4,8)]] + for(int I=0; I<128; ++I) { bar(I); } + + // no diagnostic is expected + [[clang::code_align(32)]] + for(int I=0; I<128; ++I) { bar(I); } + +#if __cplusplus >= 201103L + // cpp-local-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} +#else + // c-local-error@+2 {{integer constant expression must have integer type, not 'char[4]'}} +#endif + [[clang::code_align("abc")]] + for(int I=0; I<128; ++I) { bar(I); } + + [[clang::code_align(64)]] + // expected-error@+1 {{duplicate loop attribute 'code_align'}} + [[clang::code_align(64)]] + for(int I=0; I<128; ++I) { bar(I); } + + // expected-error@+1 {{'code_align' attribute argument must be a constant power of two greater than zero}} + [[clang::code_align(7)]] + for(int I=0; I<128; ++I) { bar(I); } + +#if __cplusplus >= 201103L + // cpp-local-error@+5 {{expression is not an integral constant expression}} + // cpp-local-note@+4 {{function parameter 'A' with unknown value cannot be used in a constant expression}} +#else + // c-local-error@+2 {{expression is not an integer constant expression}} +#endif + [[clang::code_align(A)]] + for(int I=0; I<128; ++I) { bar(I); } +} + +#if __cplusplus >= 201103L +void check_code_align_expression() { + int a[10]; + + // Test that checks expression is not a constant expression. + int foo2; // cpp-local-note {{declared here}} + // cpp-local-error@+2{{expression is not an integral constant expression}} + // cpp-local-note@+1{{read of non-const variable 'foo2' is not allowed in a constant expression}} + [[clang::code_align(foo2 + 1)]] + for (int i = 0; i != 10; ++i) + a[i] = 0; + + // Test that checks expression is a constant expression. + constexpr int bars = 0; + [[clang::code_align(bars + 1)]] + for (int i = 0; i != 10; ++i) + a[i] = 0; +} + +template <int A, int B, int C, int D> +void code_align_dependent() { + [[clang::code_align(C)]] + for(int I=0; I<128; ++I) { bar(I); } + + [[clang::code_align(A)]] + // cpp-local-error@+1 {{duplicate loop attribute 'code_align'}} + [[clang::code_align(B)]] + for(int I=0; I<128; ++I) { bar(I); } + + // cpp-local-error@+1{{'code_align' attribute requires a positive integral compile time constant expression}} + [[clang::code_align(D)]] + for(int I=0; I<128; ++I) { bar(I); } +} + +int main() { + code_align_dependent<8, 16, 32, -10>(); // cpp-local-note{{in instantiation of function template specialization 'code_align_dependent<8, 16, 32, -10>' requested here}} + return 0; +} +#endif diff --git a/clang/test/Sema/code_align_ast.c b/clang/test/Sema/code_align_ast.c new file mode 100644 index 000000000000000..300e55d696fd402 --- /dev/null +++ b/clang/test/Sema/code_align_ast.c @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -fsyntax-only -ast-dump -verify %s | FileCheck -check-prefix=CHECK-C %s +// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -ast-dump %s | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP + +// expected-no-diagnostics + +// Add AST tests for Loop attribute: [[clang::code_align()]]. + +void bar(int); +// CHECK-C: FunctionDecl{{.*}}code_align 'void ()' +void code_align() { + int a1[10], a2[10]; + // CHECK-C: AttributedStmt + // CHECK-C-NEXT: CodeAlignAttr + // CHECK-C-NEXT: ConstantExpr{{.*}}'int' + // CHECK-C-NEXT: value: Int 16 + // CHECK-C-NEXT: IntegerLiteral{{.*}}16{{$}} + [[clang::code_align(16)]] for (int p = 0; p < 128; ++p) { + a1[p] = a2[p] = 0; + } + + // CHECK-C: AttributedStmt + // CHECK-C-NEXT: CodeAlignAttr + // CHECK-C-NEXT: ConstantExpr{{.*}}'int' + // CHECK-C-NEXT: value: Int 4 + // CHECK-C-NEXT: IntegerLiteral{{.*}}4{{$}} + int i = 0; + [[clang::code_align(4)]] while (i < 30) { + a1[i] += 3; + } + + // CHECK-C: AttributedStmt + // CHECK-C-NEXT: CodeAlignAttr + // CHECK-C-NEXT: ConstantExpr{{.*}}'int' + // CHECK-C-NEXT: value: Int 32 + // CHECK-C-NEXT: IntegerLiteral{{.*}}32{{$}} + for (int i = 0; i < 128; ++i) { + [[clang::code_align(32)]] for (int j = 0; j < 128; ++j) { + a1[i] += a1[j]; + } + } + + // CHECK-C: AttributedStmt + // CHECK-C-NEXT: CodeAlignAttr + // CHECK-C-NEXT: ConstantExpr{{.*}}'int' + // CHECK-C-NEXT: value: Int 64 + // CHECK-C-NEXT: IntegerLiteral{{.*}}64{{$}} + [[clang::code_align(64)]] + for(int I=0; I<128; ++I) { bar(I); } + + // CHECK-C: AttributedStmt + // CHECK-C-NEXT: CodeAlignAttr + // CHECK-C-NEXT: ConstantExpr{{.*}}'int' + // CHECK-C-NEXT: value: Int 4 + // CHECK-C-NEXT: IntegerLiteral{{.*}}4{{$}} + int b = 10; + [[clang::code_align(4)]] do { + b = b + 1; + } while (b < 20); +} + +#if __cplusplus >= 201103L +//CHECK-CPP: FunctionDecl{{.*}}used code_align_cpp 'void ()' implicit_instantiation +template <int A, int B> +void code_align_cpp() { + int a[10]; + // CHECK-CPP: AttributedStmt + // CHECK-CPP-NEXT: CodeAlignAttr + // CHECK-CPP-NEXT: ConstantExpr{{.*}}'int' + // CHECK-CPP-NEXT: value: Int 32 + // CHECK-CPP-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'int' + // CHECK-CPP-NEXT: NonTypeTemplateParmDecl{{.*}}referenced 'int' depth 0 index 0 A + // CHECK-CPP-NEXT: IntegerLiteral{{.*}}32{{$}} + [[clang::code_align(A)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // CHECK-CPP: AttributedStmt + // CHECK-CPP-NEXT: CodeAlignAttr + // CHECK-CPP-NEXT: ConstantExpr{{.*}}'int' + // CHECK-CPP-NEXT: value: Int 4 + // CHECK-CPP-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'int' + // CHECK-CPP-NEXT: NonTypeTemplateParmDecl{{.*}}referenced 'int' depth 0 index 1 B + // CHECK-CPP-NEXT: IntegerLiteral{{.*}}4{{$}} + int c[] = {0, 1, 2, 3, 4, 5}; + [[clang::code_align(B)]] for (int n : c) { n *= 2; } +} + +int main() { + code_align_cpp<32, 4>(); + return 0; +} +#endif >From d049dc9997bdb78ff7e7cbf9b04aa42b9274cfd9 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Wed, 1 Nov 2023 20:24:51 -0700 Subject: [PATCH 02/11] Address review comments --- clang/include/clang/Basic/Attr.td | 13 ++++++-- clang/include/clang/Basic/AttrDocs.td | 9 +++--- .../clang/Basic/DiagnosticSemaKinds.td | 4 +-- clang/lib/CodeGen/CGLoopInfo.cpp | 7 ++-- clang/lib/CodeGen/CGLoopInfo.h | 4 +-- clang/lib/Sema/SemaStmtAttr.cpp | 32 ++++++++----------- clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +- clang/test/CodeGen/code_align.c | 6 ++-- clang/test/Sema/code_align.c | 21 ++++++------ clang/test/Sema/code_align_ast.c | 8 ++--- 10 files changed, 51 insertions(+), 55 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index e25bea67bf9e86e..88d232f4aba0163 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4282,10 +4282,17 @@ def PreferredType: InheritableAttr { } def CodeAlign: StmtAttr { - let Spellings = [CXX11<"clang", "code_align">, - C23<"clang", "code_align">]; + let Spellings = [Clang<"code_align">]; let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], ErrorDiag, "'for', 'while', and 'do' statements">; - let Args = [ExprArgument<"NExpr">]; + let Args = [ExprArgument<"Alignment">]; let Documentation = [CodeAlignAttrDocs]; + let AdditionalMembers = [{ + static int getMinValue() { + return 1; + } + static int getMaxValue() { + return 4096; + } + }]; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5ee224e117d049c..099c7dc547cfa81 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7421,12 +7421,11 @@ def CodeAlignAttrDocs : Documentation { let Category = DocCatVariable; let Heading = "clang::code_align"; let Content = [{ -The ``clang::code_align(N)`` attribute applies to a loop and it specifies the -byte alignment for a loop. The attribute accepts a positive integer constant +The ``clang::code_align(N)`` attribute applies to a loop and specifies the byte +alignment for a loop. The attribute accepts a positive integer constant initialization expression indicating the number of bytes for the minimum -alignment boundary. Its value must be a power of 2, between 1 and 4096, such as -1, 2, 4, 8, and so on. This attribute sets ``llvm.loop.align`` loop metadata -when it applies on a loop statement. +alignment boundary. Its value must be a power of 2, between 1 and 4096 +(inclusive). .. code-block:: c++ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 4b0f24d25e3e902..5d9aaba57131445 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10028,8 +10028,8 @@ def warn_missing_case_for_condition : Warning<"no case matching constant switch condition '%0'">; def err_loop_attr_duplication : Error< "duplicate loop attribute %0">; -def err_attribute_argument_not_power_of_two : Error< - "%0 attribute argument must be a constant power of two greater than zero">; +def err_attribute_power_of_two_in_range : Error< + "%0 attribute must be a constant power of two between %1 and %2 inclusive">; def warn_def_missing_case : Warning<"%plural{" "1:enumeration value %1 not explicitly handled in switch|" diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index a7cae301ba7bfda..a951198b925a513 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -797,15 +797,12 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, } } - // Translate 'loop attributes' arguments to equivalent Attr enums. - // It's being handled separately from LoopHintAttrs not to support - // legacy GNU attributes and pragma styles. - // + // Identify loop attribute 'code_align' from Attrs. // For attribute code_align: // n - 'llvm.loop.align i32 n' metadata will be emitted. for (const auto *A : Attrs) { if (const auto *CodeAlign = dyn_cast<CodeAlignAttr>(A)) { - const auto *CE = cast<ConstantExpr>(CodeAlign->getNExpr()); + const auto *CE = cast<ConstantExpr>(CodeAlign->getAlignment()); llvm::APSInt ArgVal = CE->getResultAsAPSInt(); setCodeAlign(ArgVal.getSExtValue()); } diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index f5438d7865946ab..a1c8c7e5307fd9c 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -79,7 +79,7 @@ struct LoopAttributes { /// Value for llvm.loop.pipeline.iicount metadata. unsigned PipelineInitiationInterval; - /// Value for 'llvm.loop.align' loop metadata. + /// Value for 'llvm.loop.align' metadata. unsigned CodeAlign; /// Value for whether the loop is required to make progress. @@ -285,7 +285,7 @@ class LoopInfoStack { StagedAttrs.PipelineInitiationInterval = C; } - /// Set the CodeAlign for the next loop pushed. + /// Set value of code align for the next loop pushed. void setCodeAlign(unsigned C) { StagedAttrs.CodeAlign = C; } /// Set no progress for the next loop pushed. diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 7b9dd0c97e61c1e..c34fc4de5b0c670 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -331,17 +331,13 @@ CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, return nullptr; E = Res.get(); - // This attribute requires a strictly positive value. - if (ArgVal <= 0) { - Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) - << CI << /*positive*/ 0; - return nullptr; - } - - // This attribute requires a single constant power of two greater than zero. - if (!ArgVal.isPowerOf2()) { - Diag(E->getExprLoc(), diag::err_attribute_argument_not_power_of_two) - << CI; + int align_value = ArgVal.getSExtValue(); + if (align_value < CodeAlignAttr::getMinValue() || + align_value > CodeAlignAttr::getMaxValue() || + !ArgVal.isPowerOf2()) { + Diag(CI.getLoc(), diag:: err_attribute_power_of_two_in_range) + << CI << CodeAlignAttr::getMinValue() + << CodeAlignAttr::getMaxValue(); return nullptr; } } @@ -360,15 +356,15 @@ template <typename LoopAttrT> static void CheckForDuplicateLoopAttribute(Sema &S, const SmallVectorImpl<const Attr *> &Attrs) { - const LoopAttrT *LoopAttr = nullptr; - + const Attr *A = nullptr; for (const auto *I : Attrs) { - if (LoopAttr && isa<LoopAttrT>(I)) { - // Cannot specify same type of attribute twice. - S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << LoopAttr; + if (isa<LoopAttrT>(I)) { + if (A) { + // Cannot specify same type of attribute twice. + S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << A; + } + A = I; } - if (isa<LoopAttrT>(I)) - LoopAttr = cast<LoopAttrT>(I); } } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 436364cfc0a4dce..cd679d9a1f83529 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1907,7 +1907,7 @@ const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr( const CodeAlignAttr * TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) { - Expr *TransformedExpr = getDerived().TransformExpr(CA->getNExpr()).get(); + Expr *TransformedExpr = getDerived().TransformExpr(CA->getAlignment()).get(); return getSema().BuildCodeAlignAttr(*CA, TransformedExpr); } diff --git a/clang/test/CodeGen/code_align.c b/clang/test/CodeGen/code_align.c index f1ee06ff70eef27..f6d86ec969ae5f6 100644 --- a/clang/test/CodeGen/code_align.c +++ b/clang/test/CodeGen/code_align.c @@ -1,7 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-C %s -// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP - -// Add CodeGen tests for Loop attribute: [[clang::code_align)]]. +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -x c %s %s -o - | FileCheck -check-prefix=CHECK-C %s +// RUN: %clang_cc1 -fsyntax-only -emit-llvm -x c++ -std=c++11 %s -o - | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP // CHECK-C: br label %for.cond, !llvm.loop ![[MD_FP:[0-9]+]] // CHECK-C: br label %while.cond, !llvm.loop ![[MD_FP_1:[0-9]+]] diff --git a/clang/test/Sema/code_align.c b/clang/test/Sema/code_align.c index 74f39ffe23300d0..f4f977dbf65767d 100644 --- a/clang/test/Sema/code_align.c +++ b/clang/test/Sema/code_align.c @@ -1,7 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify=expected,c-local %s -// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp-local -pedantic -x c++ -std=c++11 %s - -// Add diagnostics tests for Loop attribute: [[clang::code_align()]]. +// RUN: %clang_cc1 -fsyntax-only -verify=expected,c-local -x c %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp-local -pedantic -x c++ -std=c++11 %s void foo() { int i; @@ -28,11 +26,11 @@ void bar(int); #endif void foo1(int A) { - // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} + // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} [[clang::code_align(0)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1{{'code_align' attribute requires a positive integral compile time constant expression}} + // expected-error@+1{{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} [[clang::code_align(-4)]] for(int I=0; I<128; ++I) { bar(I); } @@ -69,10 +67,14 @@ void foo1(int A) [[clang::code_align(64)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute argument must be a constant power of two greater than zero}} + // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} [[clang::code_align(7)]] for(int I=0; I<128; ++I) { bar(I); } + // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + [[clang::code_align(5000)]] + for(int I=0; I<128; ++I) { bar(I); } + #if __cplusplus >= 201103L // cpp-local-error@+5 {{expression is not an integral constant expression}} // cpp-local-note@+4 {{function parameter 'A' with unknown value cannot be used in a constant expression}} @@ -112,13 +114,14 @@ void code_align_dependent() { [[clang::code_align(B)]] for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+1{{'code_align' attribute requires a positive integral compile time constant expression}} + // cpp-local-error@+2{{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // cpp-local-note@#neg-instantiation {{in instantiation of function template specialization}} [[clang::code_align(D)]] for(int I=0; I<128; ++I) { bar(I); } } int main() { - code_align_dependent<8, 16, 32, -10>(); // cpp-local-note{{in instantiation of function template specialization 'code_align_dependent<8, 16, 32, -10>' requested here}} + code_align_dependent<8, 16, 32, -10>(); // #neg-instantiation return 0; } #endif diff --git a/clang/test/Sema/code_align_ast.c b/clang/test/Sema/code_align_ast.c index 300e55d696fd402..962cfa09c539216 100644 --- a/clang/test/Sema/code_align_ast.c +++ b/clang/test/Sema/code_align_ast.c @@ -1,9 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -ast-dump -verify %s | FileCheck -check-prefix=CHECK-C %s -// RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -ast-dump %s | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP - -// expected-no-diagnostics - -// Add AST tests for Loop attribute: [[clang::code_align()]]. +// RUN: %clang_cc1 -fsyntax-only -ast-dump -verify -x c %s | FileCheck -check-prefix=CHECK-C %s +// RUN: %clang_cc1 -fsyntax-only -ast-dump -x c++ -std=c++11 %s | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP void bar(int); // CHECK-C: FunctionDecl{{.*}}code_align 'void ()' >From 6c44cc15df0b98967b6a76c73a16a77539c47ccc Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Wed, 1 Nov 2023 20:41:41 -0700 Subject: [PATCH 03/11] Fix clang format errors --- clang/lib/Sema/SemaStmtAttr.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index c34fc4de5b0c670..8a75b3021223083 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -333,11 +333,9 @@ CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, int align_value = ArgVal.getSExtValue(); if (align_value < CodeAlignAttr::getMinValue() || - align_value > CodeAlignAttr::getMaxValue() || - !ArgVal.isPowerOf2()) { - Diag(CI.getLoc(), diag:: err_attribute_power_of_two_in_range) - << CI << CodeAlignAttr::getMinValue() - << CodeAlignAttr::getMaxValue(); + align_value > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { + Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range) + << CI << CodeAlignAttr::getMinValue() << CodeAlignAttr::getMaxValue(); return nullptr; } } @@ -362,8 +360,8 @@ CheckForDuplicateLoopAttribute(Sema &S, if (A) { // Cannot specify same type of attribute twice. S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << A; - } - A = I; + } + A = I; } } } >From f35c4be758851246b8d11fe7cf64d760e6531a11 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Thu, 2 Nov 2023 06:14:58 -0700 Subject: [PATCH 04/11] Fix Lit test failure --- clang/test/Sema/code_align_ast.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/Sema/code_align_ast.c b/clang/test/Sema/code_align_ast.c index 962cfa09c539216..2cfbf11f1fd0eab 100644 --- a/clang/test/Sema/code_align_ast.c +++ b/clang/test/Sema/code_align_ast.c @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -ast-dump -verify -x c %s | FileCheck -check-prefix=CHECK-C %s // RUN: %clang_cc1 -fsyntax-only -ast-dump -x c++ -std=c++11 %s | FileCheck %s --check-prefixes CHECK-C,CHECK-CPP +// expected-no-diagnostics + void bar(int); // CHECK-C: FunctionDecl{{.*}}code_align 'void ()' void code_align() { >From 4c40ce27e81ae40f05aeabb513881032c04feb92 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 09:30:22 -0800 Subject: [PATCH 05/11] Address review comments --- clang/docs/ReleaseNotes.rst | 17 +++++++ .../clang/Basic/DiagnosticSemaKinds.td | 3 +- clang/lib/Sema/SemaStmtAttr.cpp | 28 ++++++---- clang/test/Sema/code_align.c | 51 ++++++++----------- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bc28bb567f6932a..37e985cb13d5072 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -288,6 +288,23 @@ Attribute Changes in Clang When viewing ``S::FruitKind`` in a debugger, it will behave as if the member was declared as type ``E`` rather than ``unsigned``. +- Clang now supports ``[[clang::code_align(N)]]`` as an attribute which can be + applied to a loop and specifies the byte alignment for a loop. This attribute + accepts a positive integer constant initialization expression indicating the + number of bytes for the minimum alignment boundary. Its value must be a power + of 2, between 1 and 4096(inclusive). + + .. code-block:: c++ + + void Array(int *array, size_t n) { + [[clang::code_align(64)]] for (int i = 0; i < n; ++i) array[i] = 0; + } + + template<int A> + void func() { + [[clang::code_align(A)]] for(;;) { } + } + Improvements to Clang's diagnostics ----------------------------------- - Clang constexpr evaluator now prints template arguments when displaying diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5d9aaba57131445..8dab0bb996d0e9d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10029,7 +10029,8 @@ def warn_missing_case_for_condition : def err_loop_attr_duplication : Error< "duplicate loop attribute %0">; def err_attribute_power_of_two_in_range : Error< - "%0 attribute must be a constant power of two between %1 and %2 inclusive">; + "%0 attribute requires an integer argument which is a constant power of two " + "between %1 and %2 inclusive - got %3">; def warn_def_missing_case : Warning<"%plural{" "1:enumeration value %1 not explicitly handled in switch|" diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 8a75b3021223083..a75b1d0b085bb34 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -331,15 +331,23 @@ CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, return nullptr; E = Res.get(); - int align_value = ArgVal.getSExtValue(); - if (align_value < CodeAlignAttr::getMinValue() || - align_value > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { + // This attribute requires a strictly positive value. + if (ArgVal <= 0) { + Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) + << CI << /*positive*/ 0; + return nullptr; + } + + // This attribute requires an integer argument which is a constant power of + // two between 1 and 4096 inclusive. + int AlignValue = ArgVal.getSExtValue(); + if (AlignValue > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range) - << CI << CodeAlignAttr::getMinValue() << CodeAlignAttr::getMaxValue(); + << CI << CodeAlignAttr::getMinValue() << CodeAlignAttr::getMaxValue() + << AlignValue; return nullptr; } } - return new (Context) CodeAlignAttr(Context, CI, E); } @@ -350,16 +358,16 @@ static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { } // Emit duplicate error for [[clang::code_align()]] attribute. -template <typename LoopAttrT> static void -CheckForDuplicateLoopAttribute(Sema &S, - const SmallVectorImpl<const Attr *> &Attrs) { +CheckForDuplicateCodeAlignAttribute(Sema &S, + const SmallVectorImpl<const Attr *> &Attrs) { const Attr *A = nullptr; for (const auto *I : Attrs) { - if (isa<LoopAttrT>(I)) { + if (isa<CodeAlignAttr>(I)) { if (A) { // Cannot specify same type of attribute twice. S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << A; + S.Diag(A->getLocation(),diag::note_previous_attribute); } A = I; } @@ -587,5 +595,5 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs, } CheckForIncompatibleAttributes(*this, OutAttrs); - CheckForDuplicateLoopAttribute<CodeAlignAttr>(*this, OutAttrs); + CheckForDuplicateCodeAlignAttribute(*this, OutAttrs); } diff --git a/clang/test/Sema/code_align.c b/clang/test/Sema/code_align.c index f4f977dbf65767d..715d2896969464b 100644 --- a/clang/test/Sema/code_align.c +++ b/clang/test/Sema/code_align.c @@ -21,24 +21,19 @@ void foo() { } void bar(int); -#if __cplusplus >= 201103L -// cpp-local-note@+2 {{declared here}} -#endif +// cpp-local-note@+1 {{declared here}} void foo1(int A) { - // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} [[clang::code_align(0)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1{{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} [[clang::code_align(-4)]] for(int I=0; I<128; ++I) { bar(I); } -#if __cplusplus >= 201103L - // cpp-local-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'double'}} -#else - // c-local-error@+2 {{integer constant expression must have integer type, not 'double'}} -#endif + // cpp-local-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'double'}} + // c-local-error@+1 {{integer constant expression must have integer type, not 'double'}} [[clang::code_align(64.0)]] for(int I=0; I<128; ++I) { bar(I); } @@ -54,38 +49,30 @@ void foo1(int A) [[clang::code_align(32)]] for(int I=0; I<128; ++I) { bar(I); } -#if __cplusplus >= 201103L - // cpp-local-error@+4 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} -#else - // c-local-error@+2 {{integer constant expression must have integer type, not 'char[4]'}} -#endif + // cpp-local-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} + // c-local-error@+1 {{integer constant expression must have integer type, not 'char[4]'}} [[clang::code_align("abc")]] for(int I=0; I<128; ++I) { bar(I); } - [[clang::code_align(64)]] - // expected-error@+1 {{duplicate loop attribute 'code_align'}} - [[clang::code_align(64)]] + [[clang::code_align(64)]] // expected-note {{previous attribute is here}} + [[clang::code_align(64)]] // expected-error {{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive - got 7}} [[clang::code_align(7)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive - got 5000}} [[clang::code_align(5000)]] for(int I=0; I<128; ++I) { bar(I); } -#if __cplusplus >= 201103L - // cpp-local-error@+5 {{expression is not an integral constant expression}} - // cpp-local-note@+4 {{function parameter 'A' with unknown value cannot be used in a constant expression}} -#else - // c-local-error@+2 {{expression is not an integer constant expression}} -#endif + // cpp-local-error@+3 {{expression is not an integral constant expression}} + // cpp-local-note@+2 {{function parameter 'A' with unknown value cannot be used in a constant expression}} + // c-local-error@+1 {{expression is not an integer constant expression}} [[clang::code_align(A)]] for(int I=0; I<128; ++I) { bar(I); } } -#if __cplusplus >= 201103L void check_code_align_expression() { int a[10]; @@ -97,24 +84,26 @@ void check_code_align_expression() { for (int i = 0; i != 10; ++i) a[i] = 0; +#if __cplusplus >= 201103L // Test that checks expression is a constant expression. constexpr int bars = 0; [[clang::code_align(bars + 1)]] for (int i = 0; i != 10; ++i) a[i] = 0; +#endif } +#if __cplusplus >= 201103L template <int A, int B, int C, int D> void code_align_dependent() { [[clang::code_align(C)]] for(int I=0; I<128; ++I) { bar(I); } - [[clang::code_align(A)]] - // cpp-local-error@+1 {{duplicate loop attribute 'code_align'}} - [[clang::code_align(B)]] + [[clang::code_align(A)]] // expected-note {{previous attribute is here}} + [[clang::code_align(B)]] // cpp-local-error {{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+2{{'code_align' attribute must be a constant power of two between 1 and 4096 inclusive}} + // cpp-local-error@+2{{'code_align' attribute requires a positive integral compile time constant expression}} // cpp-local-note@#neg-instantiation {{in instantiation of function template specialization}} [[clang::code_align(D)]] for(int I=0; I<128; ++I) { bar(I); } >From 9144e440b3898a24bad042158312643a29266cb6 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 10:07:30 -0800 Subject: [PATCH 06/11] Fix clang format errors --- clang/lib/Sema/SemaStmtAttr.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index a75b1d0b085bb34..e3671cee99422b0 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -344,7 +344,7 @@ CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, if (AlignValue > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range) << CI << CodeAlignAttr::getMinValue() << CodeAlignAttr::getMaxValue() - << AlignValue; + << AlignValue; return nullptr; } } @@ -358,16 +358,15 @@ static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { } // Emit duplicate error for [[clang::code_align()]] attribute. -static void -CheckForDuplicateCodeAlignAttribute(Sema &S, - const SmallVectorImpl<const Attr *> &Attrs) { +static void CheckForDuplicateCodeAlignAttribute( + Sema &S, const SmallVectorImpl<const Attr *> &Attrs) { const Attr *A = nullptr; for (const auto *I : Attrs) { if (isa<CodeAlignAttr>(I)) { if (A) { // Cannot specify same type of attribute twice. S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << A; - S.Diag(A->getLocation(),diag::note_previous_attribute); + S.Diag(A->getLocation(), diag::note_previous_attribute); } A = I; } >From 22f66bd0199300a92ea2aefc66a2640e79b734a4 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 11:56:08 -0800 Subject: [PATCH 07/11] Address review comments --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/CodeGen/CGLoopInfo.cpp | 10 ++++------ clang/lib/Sema/SemaStmtAttr.cpp | 10 ++-------- clang/test/Sema/code_align.c | 10 +++++----- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8dab0bb996d0e9d..886458f5e946e6d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10030,7 +10030,7 @@ def err_loop_attr_duplication : Error< "duplicate loop attribute %0">; def err_attribute_power_of_two_in_range : Error< "%0 attribute requires an integer argument which is a constant power of two " - "between %1 and %2 inclusive - got %3">; + "between %1 and %2 inclusive; got %3">; def warn_def_missing_case : Warning<"%plural{" "1:enumeration value %1 not explicitly handled in switch|" diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index a951198b925a513..0d4800b90a2f26c 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -800,12 +800,10 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, // Identify loop attribute 'code_align' from Attrs. // For attribute code_align: // n - 'llvm.loop.align i32 n' metadata will be emitted. - for (const auto *A : Attrs) { - if (const auto *CodeAlign = dyn_cast<CodeAlignAttr>(A)) { - const auto *CE = cast<ConstantExpr>(CodeAlign->getAlignment()); - llvm::APSInt ArgVal = CE->getResultAsAPSInt(); - setCodeAlign(ArgVal.getSExtValue()); - } + if (const auto *CodeAlign = getSpecificAttr<const CodeAlignAttr>(Attrs)) { + const auto *CE = cast<ConstantExpr>(CodeAlign->getAlignment()); + llvm::APSInt ArgVal = CE->getResultAsAPSInt(); + setCodeAlign(ArgVal.getSExtValue()); } setMustProgress(MustProgress); diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index e3671cee99422b0..96fa74427ee7852 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -331,17 +331,11 @@ CodeAlignAttr *Sema::BuildCodeAlignAttr(const AttributeCommonInfo &CI, return nullptr; E = Res.get(); - // This attribute requires a strictly positive value. - if (ArgVal <= 0) { - Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer) - << CI << /*positive*/ 0; - return nullptr; - } - // This attribute requires an integer argument which is a constant power of // two between 1 and 4096 inclusive. int AlignValue = ArgVal.getSExtValue(); - if (AlignValue > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { + if (AlignValue < CodeAlignAttr::getMinValue() || + AlignValue > CodeAlignAttr::getMaxValue() || !ArgVal.isPowerOf2()) { Diag(CI.getLoc(), diag::err_attribute_power_of_two_in_range) << CI << CodeAlignAttr::getMinValue() << CodeAlignAttr::getMaxValue() << AlignValue; diff --git a/clang/test/Sema/code_align.c b/clang/test/Sema/code_align.c index 715d2896969464b..51ecc070c672ed5 100644 --- a/clang/test/Sema/code_align.c +++ b/clang/test/Sema/code_align.c @@ -24,11 +24,11 @@ void bar(int); // cpp-local-note@+1 {{declared here}} void foo1(int A) { - // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 0}} [[clang::code_align(0)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires a positive integral compile time constant expression}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got -4}} [[clang::code_align(-4)]] for(int I=0; I<128; ++I) { bar(I); } @@ -58,11 +58,11 @@ void foo1(int A) [[clang::code_align(64)]] // expected-error {{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive - got 7}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 7}} [[clang::code_align(7)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive - got 5000}} + // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 5000}} [[clang::code_align(5000)]] for(int I=0; I<128; ++I) { bar(I); } @@ -103,7 +103,7 @@ void code_align_dependent() { [[clang::code_align(B)]] // cpp-local-error {{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+2{{'code_align' attribute requires a positive integral compile time constant expression}} + // cpp-local-error@+2{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got -10}} // cpp-local-note@#neg-instantiation {{in instantiation of function template specialization}} [[clang::code_align(D)]] for(int I=0; I<128; ++I) { bar(I); } >From 66f6269c4c00825e6f839fd9b6c1c204600e06b7 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 19:28:02 -0800 Subject: [PATCH 08/11] Fix lit test failure --- clang/test/Sema/code_align.c | 41 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/clang/test/Sema/code_align.c b/clang/test/Sema/code_align.c index 51ecc070c672ed5..ad8ec603a4d19e1 100644 --- a/clang/test/Sema/code_align.c +++ b/clang/test/Sema/code_align.c @@ -9,7 +9,7 @@ void foo() { for (i = 0; i < 10; ++i) { // this is OK a[i] = b[i] = 0; } - // expected-error@+1 {{'code_align' attribute only applies to 'for', 'while', and 'do' statements}} + // expected-error@+1{{'code_align' attribute only applies to 'for', 'while', and 'do' statements}} [[clang::code_align(4)]] i = 7; for (i = 0; i < 10; ++i) { @@ -21,27 +21,27 @@ void foo() { } void bar(int); -// cpp-local-note@+1 {{declared here}} +// cpp-local-note@+1{{declared here}} void foo1(int A) { - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 0}} + // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 0}} [[clang::code_align(0)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got -4}} + // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got -4}} [[clang::code_align(-4)]] for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'double'}} - // c-local-error@+1 {{integer constant expression must have integer type, not 'double'}} + // cpp-local-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'double'}} + // c-local-error@+1{{integer constant expression must have integer type, not 'double'}} [[clang::code_align(64.0)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute takes one argument}} + // expected-error@+1{{'code_align' attribute takes one argument}} [[clang::code_align()]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute takes one argument}} + // expected-error@+1{{'code_align' attribute takes one argument}} [[clang::code_align(4,8)]] for(int I=0; I<128; ++I) { bar(I); } @@ -49,26 +49,26 @@ void foo1(int A) [[clang::code_align(32)]] for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} - // c-local-error@+1 {{integer constant expression must have integer type, not 'char[4]'}} + // cpp-local-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} + // c-local-error@+1{{integer constant expression must have integer type, not 'char[4]'}} [[clang::code_align("abc")]] for(int I=0; I<128; ++I) { bar(I); } - [[clang::code_align(64)]] // expected-note {{previous attribute is here}} - [[clang::code_align(64)]] // expected-error {{duplicate loop attribute 'code_align'}} + [[clang::code_align(64)]] // expected-note{{previous attribute is here}} + [[clang::code_align(64)]] // expected-error{{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 7}} + // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 7}} [[clang::code_align(7)]] for(int I=0; I<128; ++I) { bar(I); } - // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 5000}} + // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got 5000}} [[clang::code_align(5000)]] for(int I=0; I<128; ++I) { bar(I); } - // cpp-local-error@+3 {{expression is not an integral constant expression}} - // cpp-local-note@+2 {{function parameter 'A' with unknown value cannot be used in a constant expression}} - // c-local-error@+1 {{expression is not an integer constant expression}} + // cpp-local-error@+3{{expression is not an integral constant expression}} + // cpp-local-note@+2{{function parameter 'A' with unknown value cannot be used in a constant expression}} + // c-local-error@+1{{expression is not an integer constant expression}} [[clang::code_align(A)]] for(int I=0; I<128; ++I) { bar(I); } } @@ -78,6 +78,7 @@ void check_code_align_expression() { // Test that checks expression is not a constant expression. int foo2; // cpp-local-note {{declared here}} + // c-local-error@+3{{expression is not an integer constant expression}} // cpp-local-error@+2{{expression is not an integral constant expression}} // cpp-local-note@+1{{read of non-const variable 'foo2' is not allowed in a constant expression}} [[clang::code_align(foo2 + 1)]] @@ -99,12 +100,12 @@ void code_align_dependent() { [[clang::code_align(C)]] for(int I=0; I<128; ++I) { bar(I); } - [[clang::code_align(A)]] // expected-note {{previous attribute is here}} - [[clang::code_align(B)]] // cpp-local-error {{duplicate loop attribute 'code_align'}} + [[clang::code_align(A)]] // expected-note{{previous attribute is here}} + [[clang::code_align(B)]] // cpp-local-error{{duplicate loop attribute 'code_align'}} for(int I=0; I<128; ++I) { bar(I); } // cpp-local-error@+2{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; got -10}} - // cpp-local-note@#neg-instantiation {{in instantiation of function template specialization}} + // cpp-local-note@#neg-instantiation{{in instantiation of function template specialization}} [[clang::code_align(D)]] for(int I=0; I<128; ++I) { bar(I); } } >From 3ac064bc26a516a81b2ff36ec0dc9c55350c3e3f Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 20:23:07 -0800 Subject: [PATCH 09/11] Fix DuplicateCodeAlignAttrs check --- clang/lib/Sema/SemaStmtAttr.cpp | 38 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 96fa74427ee7852..253b6378953b485 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -352,17 +352,33 @@ static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { } // Emit duplicate error for [[clang::code_align()]] attribute. -static void CheckForDuplicateCodeAlignAttribute( - Sema &S, const SmallVectorImpl<const Attr *> &Attrs) { - const Attr *A = nullptr; - for (const auto *I : Attrs) { - if (isa<CodeAlignAttr>(I)) { - if (A) { - // Cannot specify same type of attribute twice. - S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << A; - S.Diag(A->getLocation(), diag::note_previous_attribute); - } - A = I; +static void +CheckForDuplicateCodeAlignAttrs(Sema &S, + ArrayRef<const Attr *> Attrs) { + // Create a list of CodeAlign attributes only. + SmallVector<const CodeAlignAttr *, 8> OnlyCodeAlignAttrs; + llvm::transform( + Attrs, std::back_inserter(OnlyCodeAlignAttrs), [](const Attr *A) { + return dyn_cast_or_null<const CodeAlignAttr>(A); + }); + OnlyCodeAlignAttrs.erase( + std::remove(OnlyCodeAlignAttrs.begin(), OnlyCodeAlignAttrs.end(), + static_cast<CodeAlignAttr *>(nullptr)), + OnlyCodeAlignAttrs.end()); + if (OnlyCodeAlignAttrs.empty()) + return; + + for (const auto *I : OnlyCodeAlignAttrs) { + const auto *OtherAttrItr = + llvm::find_if(OnlyCodeAlignAttrs, [](const CodeAlignAttr *A) { + return isa<CodeAlignAttr>(A); + }); + + const CodeAlignAttr *OtherAttr = + OtherAttrItr == OnlyCodeAlignAttrs.end() ? nullptr : *OtherAttrItr; + if (OtherAttr != I) { + S.Diag(I->getLocation(), diag::err_loop_attr_duplication) << OtherAttr; + S.Diag(OtherAttr->getLocation(), diag::note_previous_attribute); } } } >From 172e2385edfb3f87b8c80c5d96a8fbb7c52e805d Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 20:42:01 -0800 Subject: [PATCH 10/11] Fix Clang format errors --- clang/lib/Sema/SemaStmtAttr.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 253b6378953b485..a3042a380913329 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -352,27 +352,26 @@ static Attr *handleCodeAlignAttr(Sema &S, Stmt *St, const ParsedAttr &A) { } // Emit duplicate error for [[clang::code_align()]] attribute. -static void -CheckForDuplicateCodeAlignAttrs(Sema &S, - ArrayRef<const Attr *> Attrs) { +static void CheckForDuplicateCodeAlignAttrs(Sema &S, + ArrayRef<const Attr *> Attrs) { // Create a list of CodeAlign attributes only. SmallVector<const CodeAlignAttr *, 8> OnlyCodeAlignAttrs; llvm::transform( - Attrs, std::back_inserter(OnlyCodeAlignAttrs), [](const Attr *A) { - return dyn_cast_or_null<const CodeAlignAttr>(A); - }); - OnlyCodeAlignAttrs.erase( - std::remove(OnlyCodeAlignAttrs.begin(), OnlyCodeAlignAttrs.end(), - static_cast<CodeAlignAttr *>(nullptr)), - OnlyCodeAlignAttrs.end()); + Attrs, std::back_inserter(OnlyCodeAlignAttrs), + [](const Attr *A) { return dyn_cast_or_null<const CodeAlignAttr>(A); }); + OnlyCodeAlignAttrs.erase(std::remove(OnlyCodeAlignAttrs.begin(), + OnlyCodeAlignAttrs.end(), + static_cast<CodeAlignAttr *>(nullptr)), + OnlyCodeAlignAttrs.end()); + if (OnlyCodeAlignAttrs.empty()) return; for (const auto *I : OnlyCodeAlignAttrs) { const auto *OtherAttrItr = - llvm::find_if(OnlyCodeAlignAttrs, [](const CodeAlignAttr *A) { - return isa<CodeAlignAttr>(A); - }); + llvm::find_if(OnlyCodeAlignAttrs, [](const CodeAlignAttr *A) { + return isa<CodeAlignAttr>(A); + }); const CodeAlignAttr *OtherAttr = OtherAttrItr == OnlyCodeAlignAttrs.end() ? nullptr : *OtherAttrItr; >From c8d5270bc4eca6a6b9c6beedbf00c92fa502f487 Mon Sep 17 00:00:00 2001 From: "Manna, Soumi" <soumi.ma...@intel.com> Date: Mon, 6 Nov 2023 20:52:56 -0800 Subject: [PATCH 11/11] Remove wrong function --- clang/lib/Sema/SemaStmtAttr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index a3042a380913329..81b25fd1bbe20d4 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -603,5 +603,5 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs, } CheckForIncompatibleAttributes(*this, OutAttrs); - CheckForDuplicateCodeAlignAttribute(*this, OutAttrs); + CheckForDuplicateCodeAlignAttrs(*this, OutAttrs); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits