[clang] 6d1d937 - [clang][AIX] Strip unknown environment component for per target runtime directory (#140850)
Author: Jake Egan Date: 2025-05-24T03:05:27-04:00 New Revision: 6d1d9374bd83f83f7d631ea599e4e75f7e9163ea URL: https://github.com/llvm/llvm-project/commit/6d1d9374bd83f83f7d631ea599e4e75f7e9163ea DIFF: https://github.com/llvm/llvm-project/commit/6d1d9374bd83f83f7d631ea599e4e75f7e9163ea.diff LOG: [clang][AIX] Strip unknown environment component for per target runtime directory (#140850) Previously, when the triple is `powerpc-ibm-aix-unknown`, the driver fails to find subdirectory `lib/powerpc-ibm-aix`. This ensures the correct runtime path is found if the triple has the -unknown environment component attached. Added: Modified: clang/lib/Driver/ToolChain.cpp clang/test/Driver/aix-print-runtime-dir.c Removed: diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 4dab08cb6fd88..ce302b308fd19 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -933,6 +933,15 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const { if (auto Path = getPathForTriple(T)) return *Path; + if (T.isOSAIX() && T.getEnvironment() == Triple::UnknownEnvironment) { +// Strip unknown environment from the triple. +const llvm::Triple AIXTriple( +llvm::Triple(T.getArchName(), T.getVendorName(), + llvm::Triple::getOSTypeName(T.getOS(; +if (auto Path = getPathForTriple(AIXTriple)) + return *Path; + } + if (T.isOSzOS() && (!T.getOSVersion().empty() || !T.getEnvironmentVersion().empty())) { // Build the triple without version information diff --git a/clang/test/Driver/aix-print-runtime-dir.c b/clang/test/Driver/aix-print-runtime-dir.c index ffa4d15c21208..ef133728d731f 100644 --- a/clang/test/Driver/aix-print-runtime-dir.c +++ b/clang/test/Driver/aix-print-runtime-dir.c @@ -16,6 +16,16 @@ // RUN:-resource-dir=%S/Inputs/resource_dir_with_per_target_subdir\ // RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR64-PER-TARGET %s +// RUN: %clang -print-runtime-dir --target=powerpc-ibm-aix-unknown \ +// RUN:-resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR32-UNKNOWN-ENV %s + +// RUN: %clang -print-runtime-dir --target=powerpc64-ibm-aix-unknown \ +// RUN:-resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: | FileCheck --check-prefix=PRINT-RUNTIME-DIR64-UNKNOWN-ENV %s + // PRINT-RUNTIME-DIR: lib{{/|\\}}aix{{$}} // PRINT-RUNTIME-DIR32-PER-TARGET: lib{{/|\\}}powerpc-ibm-aix{{$}} // PRINT-RUNTIME-DIR64-PER-TARGET: lib{{/|\\}}powerpc64-ibm-aix{{$}} +// PRINT-RUNTIME-DIR32-UNKNOWN-ENV: lib{{/|\\}}powerpc-ibm-aix +// PRINT-RUNTIME-DIR64-UNKNOWN-ENV: lib{{/|\\}}powerpc64-ibm-aix ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AIX] Strip unknown environment component for per target runtime directory (PR #140850)
https://github.com/jakeegan closed https://github.com/llvm/llvm-project/pull/140850 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Explain why a type trait evaluated to false. (PR #141238)
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/141238 >From 19ed57f333a63665f7bc6808d353fe1fa7eea78a Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Wed, 21 May 2025 23:10:36 +0200 Subject: [PATCH 1/2] [Clang] Explain why a type trait evaluated to false. `static_assert(std::is_xx_v);` is a common pattern to check that a type meets a requirement. This patch produces diagnostics notes when such assertion fails. The first type trait for which we provide detailed explanation is std::is_trivially_relocatable. We employ the same mechanisn when a type trait appears an an unsatisfied atomic constraint. I plan to also support `std::is_trivially_replaceable` in a follow up PR, and hopefully, over time we can support more type traits. --- .../clang/Basic/DiagnosticSemaKinds.td| 23 +++ clang/include/clang/Sema/Sema.h | 5 + clang/lib/Sema/SemaConcept.cpp| 1 + clang/lib/Sema/SemaDeclCXX.cpp| 2 + clang/lib/Sema/SemaTypeTraits.cpp | 187 ++ .../type-traits-unsatisfied-diags-std.cpp | 101 ++ .../SemaCXX/type-traits-unsatisfied-diags.cpp | 146 ++ .../test/SemaObjCXX/objc-weak-type-traits.mm | 7 +- 8 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp create mode 100644 clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2835e3a9d9960..f2fcfe5d351f4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1762,6 +1762,29 @@ def err_user_defined_msg_constexpr : Error< "%sub{subst_user_defined_msg}0 must be produced by a " "constant expression">; +// Type traits explanations +def note_unsatisfied_trait : Note<"%0 is not %enum_select{" + "%TriviallyRelocatable{trivially relocatable}" + "}1">; + +def note_unsatisfied_trait_reason +: Note<"because it " + "%enum_select{" + "%Ref{is a reference type}|" + "%HasArcLifetime{has an ARC lifetime qualifier}|" + "%VLA{is a variably-modified type}|" + "%VBase{has a virtual base %1}|" + "%NRBase{has a non-trivially-relocatable base %1}|" + "%NRField{has a non-trivially-relocatable member %1 of type %2}|" + "%DeletedDtr{has a %select{deleted|user-provided}1 destructor}|" + "%UserProvidedCtr{has a user provided %select{copy|move}1 " + "constructor}|" + "%UserProvidedAssign{has a user provided %select{copy|move}1 " + "assignment operator}|" + "%UnionWithUserDeclaredSMF{is a union with a user-declared " + "%sub{select_special_member_kind}1}" + "}0">; + def warn_consteval_if_always_true : Warning< "consteval if is always true in an %select{unevaluated|immediate}0 context">, InGroup>; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1091a7f504b57..bbc5c181c6a10 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5910,6 +5910,11 @@ class Sema final : public SemaBase { /// with expression \E void DiagnoseStaticAssertDetails(const Expr *E); + /// If E represents a built-in type trait, or a known standard type trait, + /// try to print more information about why the type type-trait failed. + /// This assumes we already evaluated the expression to a false boolean value. + void DiagnoseTypeTraitDetails(const Expr *E); + /// Handle a friend type declaration. This works in tandem with /// ActOnTag. /// diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 7da8e696c90bd..c6a54dc141ded 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1320,6 +1320,7 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, S.Diag(SubstExpr->getSourceRange().getBegin(), diag::note_atomic_constraint_evaluated_to_false) << (int)First << SubstExpr; + S.DiagnoseTypeTraitDetails(SubstExpr); } template diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index ead53a995dff1..770ac9839eb98 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17694,6 +17694,8 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E) { << DiagSide[0].ValueString << Op->getOpcodeStr() << DiagSide[1].ValueString << Op->getSourceRange(); } + } else { +DiagnoseTypeTraitDetails(E); } } diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index bac71c07d9907..ca521dc79172f 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1917,3 +1917,190 @@ ExprResult
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/139859 >From 214aa7fa765c82121cbf3e8f6cf41a0ed2e06376 Mon Sep 17 00:00:00 2001 From: Rajveer Date: Wed, 14 May 2025 13:44:31 +0530 Subject: [PATCH] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks Resolves #138939 When enabling `--fno-exceptions` flag, discarded statements containing `try/catch/throw` in an independent context can be avoided from being rejected. --- clang/include/clang/Sema/Sema.h | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 2 +- clang/lib/Sema/SemaStmt.cpp | 8 +++- clang/lib/Sema/TreeTransform.h | 4 clang/test/SemaCXX/no-exceptions.cpp | 25 - 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6ea7ee281e14d..ebb40498e11aa 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11154,6 +11154,8 @@ class Sema final : public SemaBase { StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef Handlers); + void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry); + StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b2a982e953012..ca578b247a56b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -856,7 +856,7 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; +DiagnoseExceptionUse(OpLoc, /* IsTry */ false); } // In OpenMP target regions, we replace 'throw' with a trap on GPU targets. diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e8c1f8490342a..c97a1f8d53ba0 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4307,7 +4307,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(TryLoc, diag::err_exceptions_disabled) << "try"; +DiagnoseExceptionUse(TryLoc, /* IsTry */ true); } // In OpenMP target regions, we assume that catch is never reached on GPU @@ -4410,6 +4410,12 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, Handlers); } +void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) { + if (!CurContext->isDependentContext()) { +targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw"); + } +} + StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler) { assert(TryBlock && Handler); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 335e21d927b76..f8f2927d58bd6 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9162,6 +9162,8 @@ StmtResult TreeTransform::TransformCXXTryStmt(CXXTryStmt *S) { Handlers.push_back(Handler.getAs()); } + getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry */ true); + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && !HandlerChanged) return S; @@ -14384,6 +14386,8 @@ TreeTransform::TransformCXXThrowExpr(CXXThrowExpr *E) { if (SubExpr.isInvalid()) return ExprError(); + getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry */ false); + if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) return E; diff --git a/clang/test/SemaCXX/no-exceptions.cpp b/clang/test/SemaCXX/no-exceptions.cpp index 097123d3fe523..e8ac8a657ab84 100644 --- a/clang/test/SemaCXX/no-exceptions.cpp +++ b/clang/test/SemaCXX/no-exceptions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s // Various tests for -fno-exceptions @@ -30,5 +30,28 @@ void g() { } catch (...) { } } +} + +namespace test2 { +template void foo(auto &&Fnc) { + if constexpr (enable) +try { + Fnc(); +} catch (...) { +} + else +Fnc(); +} + +void bar1() { + foo([] {}); +} +template void foo() { + try { // expected-error {{cannot use 'try' with exceptions disabled}} + } catch (...) { + } + throw 1; // expected-error {{cannot use 'throw' with exceptions disabled}} +} +void bar2(
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
Rajveer100 wrote: I have made the changes, let me know if this is fair enough. https://github.com/llvm/llvm-project/pull/139859 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0804ca8 - [Clang] Explain why a type trait evaluated to false. (#141238)
Author: cor3ntin Date: 2025-05-24T10:36:18+02:00 New Revision: 0804ca88abbfc5951be1e3f2ccb4fe7d46c3a410 URL: https://github.com/llvm/llvm-project/commit/0804ca88abbfc5951be1e3f2ccb4fe7d46c3a410 DIFF: https://github.com/llvm/llvm-project/commit/0804ca88abbfc5951be1e3f2ccb4fe7d46c3a410.diff LOG: [Clang] Explain why a type trait evaluated to false. (#141238) `static_assert(std::is_xx_v);` is a common pattern to check that a type meets a requirement. This patch produces diagnostics notes when such assertion fails. The first type trait for which we provide detailed explanation is std::is_trivially_relocatable. We employ the same mechanisn when a type trait appears an an unsatisfied atomic constraint. I plan to also support `std::is_trivially_replaceable` in a follow up PR, and hopefully, over time we can support more type traits. Added: clang/test/SemaCXX/type-traits-unsatisfied-diags-std.cpp clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTypeTraits.cpp clang/test/SemaObjCXX/objc-weak-type-traits.mm Removed: diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2835e3a9d9960..f2fcfe5d351f4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1762,6 +1762,29 @@ def err_user_defined_msg_constexpr : Error< "%sub{subst_user_defined_msg}0 must be produced by a " "constant expression">; +// Type traits explanations +def note_unsatisfied_trait : Note<"%0 is not %enum_select{" + "%TriviallyRelocatable{trivially relocatable}" + "}1">; + +def note_unsatisfied_trait_reason +: Note<"because it " + "%enum_select{" + "%Ref{is a reference type}|" + "%HasArcLifetime{has an ARC lifetime qualifier}|" + "%VLA{is a variably-modified type}|" + "%VBase{has a virtual base %1}|" + "%NRBase{has a non-trivially-relocatable base %1}|" + "%NRField{has a non-trivially-relocatable member %1 of type %2}|" + "%DeletedDtr{has a %select{deleted|user-provided}1 destructor}|" + "%UserProvidedCtr{has a user provided %select{copy|move}1 " + "constructor}|" + "%UserProvidedAssign{has a user provided %select{copy|move}1 " + "assignment operator}|" + "%UnionWithUserDeclaredSMF{is a union with a user-declared " + "%sub{select_special_member_kind}1}" + "}0">; + def warn_consteval_if_always_true : Warning< "consteval if is always true in an %select{unevaluated|immediate}0 context">, InGroup>; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 1091a7f504b57..bbc5c181c6a10 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5910,6 +5910,11 @@ class Sema final : public SemaBase { /// with expression \E void DiagnoseStaticAssertDetails(const Expr *E); + /// If E represents a built-in type trait, or a known standard type trait, + /// try to print more information about why the type type-trait failed. + /// This assumes we already evaluated the expression to a false boolean value. + void DiagnoseTypeTraitDetails(const Expr *E); + /// Handle a friend type declaration. This works in tandem with /// ActOnTag. /// diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 7da8e696c90bd..c6a54dc141ded 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1320,6 +1320,7 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, S.Diag(SubstExpr->getSourceRange().getBegin(), diag::note_atomic_constraint_evaluated_to_false) << (int)First << SubstExpr; + S.DiagnoseTypeTraitDetails(SubstExpr); } template diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index ead53a995dff1..770ac9839eb98 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17694,6 +17694,8 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E) { << DiagSide[0].ValueString << Op->getOpcodeStr() << DiagSide[1].ValueString << Op->getSourceRange(); } + } else { +DiagnoseTypeTraitDetails(E); } } diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index bac71c07d9907..71d1d44e93a84 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1917,3 +1917,188 @@ ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, return new (Context) ExpressionTraitExpr(KW
[clang] [Clang] Explain why a type trait evaluated to false. (PR #141238)
https://github.com/cor3ntin closed https://github.com/llvm/llvm-project/pull/141238 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [Clang] Preserve CXXParenListInitExpr in TreeTransform. (PR #138518)
alexfh wrote: Reduced test case: ``` template void invoke(_Fn __f) { __f(); } struct Duration { int lo_; int rep_hi_; int rep_lo_; }; Duration Seconds(int); struct Time { friend bool operator<(Time, Time); Duration rep_; }; Time operator+(Time, Duration); Time Now(); struct Node { long val; Node *n; }; struct IntrusiveMPSCQueue { void Push(Node *); int notifier_; }; int *L; template struct C {}; struct CoreImpl { template CoreImpl(C) { (void)invoke(Q(L)); } }; struct AnyInvocable : CoreImpl { template AnyInvocable(F f) : CoreImpl(C()) {} }; void S(AnyInvocable); template void BatchPull() { IntrusiveMPSCQueue q; S([&] { Time stop = Now() + Seconds(3); long i; for (long j; j; ++j) q.Push(new Node(++i)); while (Now() < stop); q.Push(new Node(0)); }); } void TestBody() { (void)BatchPull; } ``` ``` $ diff -u10 <(./clang-good -fnew-alignment=8 -fsanitize=alignment,null -O0 -std=c++20 test.cc -emit-llvm -S -o -) <(./clang-bad -fnew-alignment=8 -fsanitize=alignment,null -O0 -std=c++20 test.cc -emit-llvm -S -o -) --- /dev/fd/63 2025-05-24 07:54:29.833789023 + +++ /dev/fd/62 2025-05-24 07:54:29.833789023 + @@ -275,21 +275,21 @@ %91 = icmp eq i64 %90, 0, !nosanitize !4 %92 = and i1 %88, %91, !nosanitize !4 br i1 %92, label %94, label %93, !prof !5, !nosanitize !4 93: ; preds = %86 call void @__ubsan_handle_type_mismatch_v1(ptr @13, i64 %89) #6, !nosanitize !4 br label %94, !nosanitize !4 94: ; preds = %93, %86 %95 = getelementptr inbounds nuw %struct.Node, ptr %87, i32 0, i32 0 - store i64 0, ptr %95, align 8 + store i32 0, ptr %95, align 8 %96 = getelementptr inbounds nuw %struct.Node, ptr %87, i32 0, i32 1 store ptr null, ptr %96, align 8 call void @_ZN18IntrusiveMPSCQueue4PushEP4Node(ptr noundef nonnull align 4 dereferenceable(4) %81, ptr noundef %87) ret void } declare dso_local { i64, i32 } @_Zpl4Time8Duration(i64, i32, i64, i32) #2 declare dso_local { i64, i32 } @_Z3Nowv() #2 ``` https://github.com/llvm/llvm-project/pull/138518 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Driver][X86] Add -m[no-]apxf to m_x86_Features_Group (PR #140874)
https://github.com/fzou1 edited https://github.com/llvm/llvm-project/pull/140874 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AIX] Strip unknown environment component for per target runtime directory (PR #140850)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `amdgpu-offload-rhel-9-cmake-build-only` running on `rocm-docker-rhel-9` while building `clang` at step 2 "update-annotated-scripts". Full details are available at: https://lab.llvm.org/buildbot/#/builders/205/builds/10303 Here is the relevant piece of the build log for the reference ``` Step 2 (update-annotated-scripts) failure: update (failure) git version 2.43.5 fatal: unable to access 'https://github.com/llvm/llvm-zorg.git/': The requested URL returned error: 403 fatal: unable to access 'https://github.com/llvm/llvm-zorg.git/': The requested URL returned error: 403 ``` https://github.com/llvm/llvm-project/pull/140850 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] Include [[clang::require_explicit_initialization]] warnings in system headers (PR #141133)
cor3ntin wrote: Let me chat with @AaronBallman and @erichkeane on Monday with this. This feels like a very narrow fix for a widespread issue. - Presumably, we don't want to warn if library implementers (mis)use std::construct_at internally - There are _tons_ of other warnings that are silenced. So I think that either - We need a better heuristics to hide warnings than "comes from a system header" - We should add the ShowInSystemHeader flags to a lot of warnings, not just this one. https://github.com/llvm/llvm-project/pull/141133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] suggest headers on undeclared errors (PR #140247)
cor3ntin wrote: @jongmyeong-choi did you see that discussion here? https://github.com/llvm/llvm-project/issues/139855 There might be useful ideas https://github.com/llvm/llvm-project/pull/140247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang-tools-extra] [clang-tidy] Fix false positive for cppcoreguidelines-pro-bounds-pointer-arithmetic (PR #127394)
https://github.com/flovent updated https://github.com/llvm/llvm-project/pull/127394 >From 0e8cde49f93a4e0c81d9cdfdd78c52f077455ce1 Mon Sep 17 00:00:00 2001 From: flovent Date: Sun, 16 Feb 2025 21:07:55 +0800 Subject: [PATCH 1/4] [clang-tidy] Fix false positive for cppcoreguidelines-pro-bounds-pointer-arithmetic --- .../ProBoundsPointerArithmeticCheck.cpp | 3 ++- clang-tools-extra/docs/ReleaseNotes.rst | 4 ...-bounds-pointer-arithmetic-issue126424.cpp | 19 +++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp index a1494a095f5b6..0d68790349fb5 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp @@ -42,7 +42,8 @@ void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) { arraySubscriptExpr( hasBase(ignoringImpCasts( anyOf(AllPointerTypes, -hasType(decayedType(hasDecayedType(pointerType( +hasType(decayedType(hasDecayedType(pointerType())), + hasIndex(hasType(isInteger( .bind("expr"), this); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 8032f0d23f494..fa644277b5afa 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -234,6 +234,10 @@ Changes in existing checks tolerating fix-it breaking compilation when functions is used as pointers to avoid matching usage of functions within the current compilation unit. +- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic + ` check by + fix false positives related to operator overloading and templates. + Removed checks ^^ diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp new file mode 100644 index 0..b6b7a9664f38d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp @@ -0,0 +1,19 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t + +namespace std { +template +class pair {}; + +template +class map { + public: + using value_type = pair; + value_type& operator[](const Key& key); + value_type& operator[](Key&& key); + }; +} + +template +int f(std::map& map, R* r) { + return map[r]; // OK +} \ No newline at end of file >From 0db35e9cf8973c4d1249209055f53814bc010b50 Mon Sep 17 00:00:00 2001 From: flovent Date: Sun, 16 Feb 2025 21:18:45 +0800 Subject: [PATCH 2/4] add missing new line for testcase --- .../pro-bounds-pointer-arithmetic-issue126424.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp index b6b7a9664f38d..a76798423ee17 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-issue126424.cpp @@ -16,4 +16,4 @@ class map { template int f(std::map& map, R* r) { return map[r]; // OK -} \ No newline at end of file +} >From 8284ecf985e8c8f685887f7bb4646b281e5562a6 Mon Sep 17 00:00:00 2001 From: flovent Date: Mon, 17 Feb 2025 20:11:06 +0800 Subject: [PATCH 3/4] keep alpha order for release note --- clang-tools-extra/docs/ReleaseNotes.rst | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fa644277b5afa..4d7def9b1db16 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -176,6 +176,10 @@ Changes in existing checks ` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. +- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic + ` check by + fix false positives related to operator overloading and templates. + - Improved :doc:`misc-const-correctness ` check by adding the option `AllowedTypes`, that excludes specified types from const-correctness @@ -234,10 +238,6 @@ Changes in existing checks tolerating fix-it breaking compilation when functions is used as pointers to avoid match
[clang-tools-extra] [clang-tidy] Disable bugprone-multi-level-pointer-conversion in C code (PR #141209)
PiotrZSL wrote: Ok, but that is for "some projects". If you search internet you may find examples when people omit those casts and were people add those casts. For example: https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm And with multi level pointer conversion it's easy to make mistake later. This is why I don't like disabling permanently check for C, as for some projects it could be hiding potential issues. But adding option "EnableInC" and even set it to "false" by default would be fine, as it would still allow projects that want such conversions be explicit to enable it. https://github.com/llvm/llvm-project/pull/141209 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Disable bugprone-multi-level-pointer-conversion in C code (PR #141209)
https://github.com/PiotrZSL approved this pull request. I'm accepting change and leaving final decision to you. I can always change this later in internal fork or add option later. https://github.com/llvm/llvm-project/pull/141209 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][bytecode] Check lifetime of all ptr bases in placement-new (PR #141272)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `sanitizer-x86_64-linux-android` running on `sanitizer-buildbot-android` while building `clang` at step 2 "annotate". Full details are available at: https://lab.llvm.org/buildbot/#/builders/186/builds/9314 Here is the relevant piece of the build log for the reference ``` Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure) ... [ OK ] AddressSanitizer.AtoiAndFriendsOOBTest (2249 ms) [ RUN ] AddressSanitizer.HasFeatureAddressSanitizerTest [ OK ] AddressSanitizer.HasFeatureAddressSanitizerTest (0 ms) [ RUN ] AddressSanitizer.CallocReturnsZeroMem [ OK ] AddressSanitizer.CallocReturnsZeroMem (8 ms) [ DISABLED ] AddressSanitizer.DISABLED_TSDTest [ RUN ] AddressSanitizer.IgnoreTest [ OK ] AddressSanitizer.IgnoreTest (0 ms) [ RUN ] AddressSanitizer.SignalTest [ OK ] AddressSanitizer.SignalTest (205 ms) [ RUN ] AddressSanitizer.ReallocTest [ OK ] AddressSanitizer.ReallocTest (28 ms) [ RUN ] AddressSanitizer.WrongFreeTest [ OK ] AddressSanitizer.WrongFreeTest (107 ms) [ RUN ] AddressSanitizer.LongJmpTest [ OK ] AddressSanitizer.LongJmpTest (0 ms) [ RUN ] AddressSanitizer.ThreadStackReuseTest [ OK ] AddressSanitizer.ThreadStackReuseTest (9 ms) [ DISABLED ] AddressSanitizer.DISABLED_MemIntrinsicUnalignedAccessTest [ DISABLED ] AddressSanitizer.DISABLED_LargeFunctionSymbolizeTest [ DISABLED ] AddressSanitizer.DISABLED_MallocFreeUnwindAndSymbolizeTest [ RUN ] AddressSanitizer.UseThenFreeThenUseTest [ OK ] AddressSanitizer.UseThenFreeThenUseTest (126 ms) [ RUN ] AddressSanitizer.FileNameInGlobalReportTest [ OK ] AddressSanitizer.FileNameInGlobalReportTest (132 ms) [ DISABLED ] AddressSanitizer.DISABLED_StressStackReuseAndExceptionsTest [ RUN ] AddressSanitizer.MlockTest [ OK ] AddressSanitizer.MlockTest (0 ms) [ DISABLED ] AddressSanitizer.DISABLED_DemoThreadedTest [ DISABLED ] AddressSanitizer.DISABLED_DemoStackTest [ DISABLED ] AddressSanitizer.DISABLED_DemoThreadStackTest [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowIn [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowLeft [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowRight [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFHigh [ DISABLED ] AddressSanitizer.DISABLED_DemoOOM [ DISABLED ] AddressSanitizer.DISABLED_DemoDoubleFreeTest [ DISABLED ] AddressSanitizer.DISABLED_DemoNullDerefTest [ DISABLED ] AddressSanitizer.DISABLED_DemoFunctionStaticTest [ DISABLED ] AddressSanitizer.DISABLED_DemoTooMuchMemoryTest [ RUN ] AddressSanitizer.LongDoubleNegativeTest [ OK ] AddressSanitizer.LongDoubleNegativeTest (0 ms) [--] 19 tests from AddressSanitizer (27781 ms total) [--] Global test environment tear-down [==] 22 tests from 2 test suites ran. (27785 ms total) [ PASSED ] 22 tests. YOU HAVE 1 DISABLED TEST Step 34 (run instrumented asan tests [aarch64/bluejay-userdebug/TQ3A.230805.001]) failure: run instrumented asan tests [aarch64/bluejay-userdebug/TQ3A.230805.001] (failure) ... [ RUN ] AddressSanitizer.HasFeatureAddressSanitizerTest [ OK ] AddressSanitizer.HasFeatureAddressSanitizerTest (0 ms) [ RUN ] AddressSanitizer.CallocReturnsZeroMem [ OK ] AddressSanitizer.CallocReturnsZeroMem (8 ms) [ DISABLED ] AddressSanitizer.DISABLED_TSDTest [ RUN ] AddressSanitizer.IgnoreTest [ OK ] AddressSanitizer.IgnoreTest (0 ms) [ RUN ] AddressSanitizer.SignalTest [ OK ] AddressSanitizer.SignalTest (205 ms) [ RUN ] AddressSanitizer.ReallocTest [ OK ] AddressSanitizer.ReallocTest (28 ms) [ RUN ] AddressSanitizer.WrongFreeTest [ OK ] AddressSanitizer.WrongFreeTest (107 ms) [ RUN ] AddressSanitizer.LongJmpTest [ OK ] AddressSanitizer.LongJmpTest (0 ms) [ RUN ] AddressSanitizer.ThreadStackReuseTest [ OK ] AddressSanitizer.ThreadStackReuseTest (9 ms) [ DISABLED ] AddressSanitizer.DISABLED_MemIntrinsicUnalignedAccessTest [ DISABLED ] AddressSanitizer.DISABLED_LargeFunctionSymbolizeTest [ DISABLED ] AddressSanitizer.DISABLED_MallocFreeUnwindAndSymbolizeTest [ RUN ] AddressSanitizer.UseThenFreeThenUseTest [ OK ] AddressSanitizer.UseThenFreeThenUseTest (126 ms) [ RUN ] AddressSanitizer.FileNameInGlobalReportTest [ OK ] AddressSanitizer.FileNameInGlobalReportTest (132 ms) [ DISABLED ] AddressSanitizer.DISABLED_StressStackReuseAndExceptionsTest [ RUN ] AddressSanitizer.MlockTest [ OK ] AddressSanitizer.MlockTest (0 ms) [ DISABLED ] AddressSanitizer.DISABLED_DemoThreadedTest [ DISABLED ] AddressSanitizer.DISABLED_DemoStackTest [ DISABLED ] AddressSanitizer.DISABLED_DemoThreadStackTest [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowIn [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowLeft [ DISABLED ] AddressSanitizer.DISABLED_DemoUAFLowRight [ DISABLED ] Addr
[clang] [ASTMatchers][NFC] fix typos in AST-matchers docs. (PR #141307)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/141307 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3f3b19d - [clang][NFC] Clean up SemaChecking.cpp (#141041)
Author: Timm Baeder Date: 2025-05-24T16:17:37+02:00 New Revision: 3f3b19d2b788e976281be1d8441d167540d1e197 URL: https://github.com/llvm/llvm-project/commit/3f3b19d2b788e976281be1d8441d167540d1e197 DIFF: https://github.com/llvm/llvm-project/commit/3f3b19d2b788e976281be1d8441d167540d1e197.diff LOG: [clang][NFC] Clean up SemaChecking.cpp (#141041) Make pointer parameters const, remove some unused parameters, fix coding style, etc. Added: Modified: clang/include/clang/Sema/Sema.h clang/include/clang/Sema/SemaObjC.h clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaObjC.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index bbc5c181c6a10..6680a459a77fd 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2604,8 +2604,8 @@ class Sema final : public SemaBase { /// Check for comparisons of floating-point values using == and !=. Issue a /// warning if the comparison is not likely to do what the programmer /// intended. - void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, -BinaryOperatorKind Opcode); + void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, +const Expr *RHS, BinaryOperatorKind Opcode); /// Register a magic integral constant to be used as a type tag. void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, @@ -3013,7 +3013,8 @@ class Sema final : public SemaBase { // Warn on anti-patterns as the 'size' argument to strncat. // The correct size argument should look like following: // strncat(dst, src, sizeof(dst) - strlen(dest) - 1); - void CheckStrncatArguments(const CallExpr *Call, IdentifierInfo *FnName); + void CheckStrncatArguments(const CallExpr *Call, + const IdentifierInfo *FnName); /// Alerts the user that they are attempting to free a non-malloc'd object. void CheckFreeArguments(const CallExpr *E); diff --git a/clang/include/clang/Sema/SemaObjC.h b/clang/include/clang/Sema/SemaObjC.h index 4cda41a82b61f..b629c6d291402 100644 --- a/clang/include/clang/Sema/SemaObjC.h +++ b/clang/include/clang/Sema/SemaObjC.h @@ -170,7 +170,7 @@ class SemaObjC : public SemaBase { bool isSignedCharBool(QualType Ty); void adornBoolConversionDiagWithTernaryFixit( - Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder); + const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder); /// Check an Objective-C dictionary literal being converted to the given /// target type. diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0b2a74e272339..930e9083365a1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -9358,10 +9358,10 @@ void Sema::CheckMaxUnsignedZero(const CallExpr *Call, /// /// This is to catch typos like `if (memcmp(&a, &b, sizeof(a) > 0))`. static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, - IdentifierInfo *FnName, + const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc) { - const BinaryOperator *Size = dyn_cast(E); + const auto *Size = dyn_cast(E); if (!Size) return false; @@ -9955,7 +9955,7 @@ static const Expr *getStrlenExprArg(const Expr *E) { } void Sema::CheckStrncatArguments(const CallExpr *CE, - IdentifierInfo *FnName) { + const IdentifierInfo *FnName) { // Don't crash if the user has the wrong number of arguments. if (CE->getNumArgs() < 3) return; @@ -10050,7 +10050,7 @@ void CheckFreeArgumentsAddressof(Sema &S, const std::string &CalleeName, const UnaryOperator *UnaryExpr) { if (const auto *Lvalue = dyn_cast(UnaryExpr->getSubExpr())) { const Decl *D = Lvalue->getDecl(); -if (auto *DD = dyn_cast(D)) { +if (const auto *DD = dyn_cast(D)) { if (!DD->getType()->isReferenceType()) return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D); } @@ -10190,15 +10190,15 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, PPC().CheckPPCMMAType(RetValExp->getType(), ReturnLoc); } -void Sema::CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, -BinaryOperatorKind Opcode) { +void Sema::CheckFloatComparison(SourceLocation Loc, const Expr *LHS, +const Expr *RHS, BinaryOperatorKind Opcode) { if (!BinaryOperator::isEqualityOp(Opcode)) return; // Match and capture subexpressions such as "(float) X == 0.1". - FloatingLiteral *FPLiteral; - CastExpr *FPCast; - auto getCastAnd
[clang] [clang][NFC] Clean up SemaChecking.cpp (PR #141041)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/141041 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add check for assignment or comparision operators' operand in `readability-math-missing-parentheses` (PR #141345)
@@ -176,6 +176,11 @@ Changes in existing checks ` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. +- Improved :doc:`readability-math-missing-parentheses EugeneZelenko wrote: Please keep alphabetical order (by check name) in this list. https://github.com/llvm/llvm-project/pull/141345 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST][NFC] fix spelling typos in clang AST files (PR #141346)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Baranov Victor (vbvictor) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141346.diff 7 Files Affected: - (modified) clang/include/clang/AST/ASTContext.h (+5-5) - (modified) clang/include/clang/AST/ASTImporterLookupTable.h (+1-1) - (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1) - (modified) clang/lib/AST/ASTContext.cpp (+2-2) - (modified) clang/lib/AST/ASTImporter.cpp (+2-2) - (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+1-1) - (modified) clang/lib/Serialization/ASTReader.cpp (+1-1) ``diff diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1fdc488a76507..fc2f0cbce88ac 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -582,7 +582,7 @@ class ASTContext : public RefCountedBase { llvm::DenseMap InstantiatedFromUsingEnumDecl; - /// Simlarly maps instantiated UsingShadowDecls to their origin. + /// Similarly maps instantiated UsingShadowDecls to their origin. llvm::DenseMap InstantiatedFromUsingShadowDecl; @@ -790,7 +790,7 @@ class ASTContext : public RefCountedBase { } return new (*this) DeclListNode(ND); } - /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList + /// Deallocates a \c DeclListNode by returning it to the \c ListNodeFreeList /// pool. void DeallocateDeclListNode(DeclListNode *N) { N->Rest = ListNodeFreeList; @@ -1123,7 +1123,7 @@ class ASTContext : public RefCountedBase { /// Clean up the merged definition list. Call this if you might have /// added duplicates into the list. - void deduplicateMergedDefinitonsFor(NamedDecl *ND); + void deduplicateMergedDefinitionsFor(NamedDecl *ND); /// Get the additional modules in which the definition \p Def has /// been merged. @@ -2565,7 +2565,7 @@ class ASTContext : public RefCountedBase { /// Return the ABI-specified natural alignment of a (complete) type \p T, /// before alignment adjustments, in bits. /// - /// This alignment is curently used only by ARM and AArch64 when passing + /// This alignment is currently used only by ARM and AArch64 when passing /// arguments of a composite type. unsigned getTypeUnadjustedAlign(QualType T) const { return getTypeUnadjustedAlign(T.getTypePtr()); @@ -2638,7 +2638,7 @@ class ASTContext : public RefCountedBase { /// considered specifically for the query. CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; - /// Return the minimum alignement as specified by the target. If \p VD is + /// Return the minimum alignment as specified by the target. If \p VD is /// non-null it may be used to identify external or weak variables. unsigned getMinGlobalAlignOfVar(uint64_t Size, const VarDecl *VD) const; diff --git a/clang/include/clang/AST/ASTImporterLookupTable.h b/clang/include/clang/AST/ASTImporterLookupTable.h index 2dbc44c5dcd44..54b8c417b9927 100644 --- a/clang/include/clang/AST/ASTImporterLookupTable.h +++ b/clang/include/clang/AST/ASTImporterLookupTable.h @@ -34,7 +34,7 @@ class DeclContext; // Example 2: // // The fwd decl to Foo is not found in the lookupPtr of the DC of the // // translation unit decl. -// // Here we could find the node by doing a traverse throught the list of +// // Here we could find the node by doing a traverse through the list of // // the Decls in the DC, but that would not scale. // struct A { struct Foo *p; }; // This is a severe problem because the importer decides if it has to create a diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 5ab438715ecf7..586ad3be62a7e 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -1,4 +1,4 @@ -//==--- AbstractBasiceReader.h - Abstract basic value deserialization -===// +//==--- AbstractBasicReader.h - Abstract basic value deserialization -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b5417fcf20ddd..b56a64e07f110 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1085,7 +1085,7 @@ void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, MergedDefModules[cast(ND->getCanonicalDecl())].push_back(M); } -void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) { +void ASTContext::deduplicateMergedDefinitionsFor(NamedDecl *ND) { auto It = MergedDefModules.find(cast(ND->getCanonicalDecl())); if (It == MergedDefModules.end()) return; @@ -1803,7 +1803,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { Align = Target->getCharWidth(); } -// Ensure mimin
[clang-tools-extra] Follow style configuration in clangd when inserting missing includes (PR #140594)
@@ -297,7 +301,8 @@ TEST(IncludeCleaner, GenerateMissingHeaderDiags) { Findings.UnusedIncludes.clear(); std::vector Diags = issueIncludeCleanerDiagnostics( AST, TU.Code, Findings, MockFS(), - {[](llvm::StringRef Header) { return Header.ends_with("buzz.h"); }}); + {[](llvm::StringRef Header) { return Header.ends_with("buzz.h"); }}, Harald-R wrote: Done: https://github.com/llvm/llvm-project/pull/140594/commits/da30c7d30208dfc8e6507f7263995d55fd18e306 https://github.com/llvm/llvm-project/pull/140594 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ASTMatchers][NFC] fix typos in AST-matchers docs. (PR #141307)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/141307 >From 4ee68d62a21f75110b9406c86c9c059b1c2a840d Mon Sep 17 00:00:00 2001 From: Baranov Victor Date: Sat, 24 May 2025 03:17:57 +0300 Subject: [PATCH 1/2] [ASTMatchers][NFC] fix typos in AST-matchers docs. --- clang/include/clang/ASTMatchers/ASTMatchers.h | 20 +-- .../clang/ASTMatchers/ASTMatchersInternal.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index e6b684b24b080..e4d605d165324 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -612,7 +612,7 @@ extern const internal::VariadicDynCastAllOfMatcher templateTemplateParmDecl; -/// Matches public C++ declarations and C++ base specifers that specify public +/// Matches public C++ declarations and C++ base specifiers that specify public /// inheritance. /// /// Examples: @@ -635,7 +635,7 @@ AST_POLYMORPHIC_MATCHER(isPublic, return getAccessSpecifier(Node) == AS_public; } -/// Matches protected C++ declarations and C++ base specifers that specify +/// Matches protected C++ declarations and C++ base specifiers that specify /// protected inheritance. /// /// Examples: @@ -657,8 +657,8 @@ AST_POLYMORPHIC_MATCHER(isProtected, return getAccessSpecifier(Node) == AS_protected; } -/// Matches private C++ declarations and C++ base specifers that specify private -/// inheritance. +/// Matches private C++ declarations and C++ base specifiers that specify +/// private inheritance. /// /// Examples: /// \code @@ -1212,7 +1212,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType, /// Matches a TemplateArgument of integral type with a given value. /// /// Note that 'Value' is a string as the template argument's value is -/// an arbitrary precision integer. 'Value' must be euqal to the canonical +/// an arbitrary precision integer. 'Value' must be equal to the canonical /// representation of that integral value in base 10. /// /// Given @@ -5689,7 +5689,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, // FIXME: Figure out whether it makes sense to allow this // on any other node types. // For *Loc it probably does not make sense, as those seem - // unique. For NestedNameSepcifier it might make sense, as + // unique. For NestedNameSpecifier it might make sense, as // those also have pointer identity, but I'm not sure whether // they're ever reused. internal::NotEqualsBoundNodePredicate Predicate; @@ -6322,7 +6322,7 @@ AST_MATCHER_P(CXXMethodDecl, forEachOverridden, return Matched; } -/// Matches declarations of virtual methods and C++ base specifers that specify +/// Matches declarations of virtual methods and C++ base specifiers that specify /// virtual inheritance. /// /// Example: @@ -7710,7 +7710,7 @@ extern const AstTypeMatcher injectedClassNameType; /// \endcode extern const AstTypeMatcher decayedType; -/// Matches the decayed type, whoes decayed type matches \c InnerMatcher +/// Matches the decayed type, whose decayed type matches \c InnerMatcher AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher, InnerType) { return InnerType.matches(Node.getDecayedType(), Finder, Builder); @@ -7750,7 +7750,7 @@ extern const AstTypeMatcher /// } /// \endcode /// -/// \c cxxRcordDecl(hasDeclContext(namedDecl(hasName("M" matches the +/// \c cxxRecordDecl(hasDeclContext(namedDecl(hasName("M" matches the /// declaration of \c class \c D. AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher, InnerMatcher) { const DeclContext *DC = Node.getDeclContext(); @@ -8464,7 +8464,7 @@ AST_MATCHER_P(Stmt, forCallable, internal::Matcher, InnerMatcher) { /// \endcode /// /// Example matches f() because it has external formal linkage despite being -/// unique to the translation unit as though it has internal likage +/// unique to the translation unit as though it has internal linkage /// (matcher = functionDecl(hasExternalFormalLinkage())) /// /// \code diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 4a27a5d099e60..667a044abcef1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1034,7 +1034,7 @@ class HasDeclarationMatcher : public MatcherInterface { // A SubstTemplateTypeParmType exists solely to mark a type substitution // on the instantiated template. As users usually want to match the // template parameter on the uninitialized template, we can always desugar -// one level without loss of expressivness. +// one level without loss of expressiveness. // For example, given: // template struct X { T t; } class A {}; X a; // The following matcher will match, which otherwise would not: >Fr
[clang] [clang][AST][NFC] fix spelling typos in clang AST files (PR #141346)
https://github.com/vbvictor created https://github.com/llvm/llvm-project/pull/141346 None >From d10598db7d58f0c06673c81b675924bb497792be Mon Sep 17 00:00:00 2001 From: Baranov Victor Date: Sat, 24 May 2025 17:12:21 +0300 Subject: [PATCH] [clang][AST][NFC] fix spelling typos in clang AST files --- clang/include/clang/AST/ASTContext.h | 10 +- clang/include/clang/AST/ASTImporterLookupTable.h | 2 +- clang/include/clang/AST/AbstractBasicReader.h| 2 +- clang/lib/AST/ASTContext.cpp | 4 ++-- clang/lib/AST/ASTImporter.cpp| 4 ++-- clang/lib/AST/ASTStructuralEquivalence.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp| 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1fdc488a76507..fc2f0cbce88ac 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -582,7 +582,7 @@ class ASTContext : public RefCountedBase { llvm::DenseMap InstantiatedFromUsingEnumDecl; - /// Simlarly maps instantiated UsingShadowDecls to their origin. + /// Similarly maps instantiated UsingShadowDecls to their origin. llvm::DenseMap InstantiatedFromUsingShadowDecl; @@ -790,7 +790,7 @@ class ASTContext : public RefCountedBase { } return new (*this) DeclListNode(ND); } - /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList + /// Deallocates a \c DeclListNode by returning it to the \c ListNodeFreeList /// pool. void DeallocateDeclListNode(DeclListNode *N) { N->Rest = ListNodeFreeList; @@ -1123,7 +1123,7 @@ class ASTContext : public RefCountedBase { /// Clean up the merged definition list. Call this if you might have /// added duplicates into the list. - void deduplicateMergedDefinitonsFor(NamedDecl *ND); + void deduplicateMergedDefinitionsFor(NamedDecl *ND); /// Get the additional modules in which the definition \p Def has /// been merged. @@ -2565,7 +2565,7 @@ class ASTContext : public RefCountedBase { /// Return the ABI-specified natural alignment of a (complete) type \p T, /// before alignment adjustments, in bits. /// - /// This alignment is curently used only by ARM and AArch64 when passing + /// This alignment is currently used only by ARM and AArch64 when passing /// arguments of a composite type. unsigned getTypeUnadjustedAlign(QualType T) const { return getTypeUnadjustedAlign(T.getTypePtr()); @@ -2638,7 +2638,7 @@ class ASTContext : public RefCountedBase { /// considered specifically for the query. CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; - /// Return the minimum alignement as specified by the target. If \p VD is + /// Return the minimum alignment as specified by the target. If \p VD is /// non-null it may be used to identify external or weak variables. unsigned getMinGlobalAlignOfVar(uint64_t Size, const VarDecl *VD) const; diff --git a/clang/include/clang/AST/ASTImporterLookupTable.h b/clang/include/clang/AST/ASTImporterLookupTable.h index 2dbc44c5dcd44..54b8c417b9927 100644 --- a/clang/include/clang/AST/ASTImporterLookupTable.h +++ b/clang/include/clang/AST/ASTImporterLookupTable.h @@ -34,7 +34,7 @@ class DeclContext; // Example 2: // // The fwd decl to Foo is not found in the lookupPtr of the DC of the // // translation unit decl. -// // Here we could find the node by doing a traverse throught the list of +// // Here we could find the node by doing a traverse through the list of // // the Decls in the DC, but that would not scale. // struct A { struct Foo *p; }; // This is a severe problem because the importer decides if it has to create a diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 5ab438715ecf7..586ad3be62a7e 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -1,4 +1,4 @@ -//==--- AbstractBasiceReader.h - Abstract basic value deserialization -===// +//==--- AbstractBasicReader.h - Abstract basic value deserialization -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b5417fcf20ddd..b56a64e07f110 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1085,7 +1085,7 @@ void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, MergedDefModules[cast(ND->getCanonicalDecl())].push_back(M); } -void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) { +void ASTContext::deduplicateMergedDefinitionsFor(NamedDecl *ND) { auto It = MergedDefModules.find(cast(ND->getCanonicalDecl())); if (It == MergedDefModules.end()) return; @@ -1803,7 +1803,7 @@
[clang] [clang][AST][NFC] fix spelling typos in clang AST files (PR #141346)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Baranov Victor (vbvictor) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141346.diff 7 Files Affected: - (modified) clang/include/clang/AST/ASTContext.h (+5-5) - (modified) clang/include/clang/AST/ASTImporterLookupTable.h (+1-1) - (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-1) - (modified) clang/lib/AST/ASTContext.cpp (+2-2) - (modified) clang/lib/AST/ASTImporter.cpp (+2-2) - (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+1-1) - (modified) clang/lib/Serialization/ASTReader.cpp (+1-1) ``diff diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1fdc488a76507..fc2f0cbce88ac 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -582,7 +582,7 @@ class ASTContext : public RefCountedBase { llvm::DenseMap InstantiatedFromUsingEnumDecl; - /// Simlarly maps instantiated UsingShadowDecls to their origin. + /// Similarly maps instantiated UsingShadowDecls to their origin. llvm::DenseMap InstantiatedFromUsingShadowDecl; @@ -790,7 +790,7 @@ class ASTContext : public RefCountedBase { } return new (*this) DeclListNode(ND); } - /// Deallcates a \c DeclListNode by returning it to the \c ListNodeFreeList + /// Deallocates a \c DeclListNode by returning it to the \c ListNodeFreeList /// pool. void DeallocateDeclListNode(DeclListNode *N) { N->Rest = ListNodeFreeList; @@ -1123,7 +1123,7 @@ class ASTContext : public RefCountedBase { /// Clean up the merged definition list. Call this if you might have /// added duplicates into the list. - void deduplicateMergedDefinitonsFor(NamedDecl *ND); + void deduplicateMergedDefinitionsFor(NamedDecl *ND); /// Get the additional modules in which the definition \p Def has /// been merged. @@ -2565,7 +2565,7 @@ class ASTContext : public RefCountedBase { /// Return the ABI-specified natural alignment of a (complete) type \p T, /// before alignment adjustments, in bits. /// - /// This alignment is curently used only by ARM and AArch64 when passing + /// This alignment is currently used only by ARM and AArch64 when passing /// arguments of a composite type. unsigned getTypeUnadjustedAlign(QualType T) const { return getTypeUnadjustedAlign(T.getTypePtr()); @@ -2638,7 +2638,7 @@ class ASTContext : public RefCountedBase { /// considered specifically for the query. CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; - /// Return the minimum alignement as specified by the target. If \p VD is + /// Return the minimum alignment as specified by the target. If \p VD is /// non-null it may be used to identify external or weak variables. unsigned getMinGlobalAlignOfVar(uint64_t Size, const VarDecl *VD) const; diff --git a/clang/include/clang/AST/ASTImporterLookupTable.h b/clang/include/clang/AST/ASTImporterLookupTable.h index 2dbc44c5dcd44..54b8c417b9927 100644 --- a/clang/include/clang/AST/ASTImporterLookupTable.h +++ b/clang/include/clang/AST/ASTImporterLookupTable.h @@ -34,7 +34,7 @@ class DeclContext; // Example 2: // // The fwd decl to Foo is not found in the lookupPtr of the DC of the // // translation unit decl. -// // Here we could find the node by doing a traverse throught the list of +// // Here we could find the node by doing a traverse through the list of // // the Decls in the DC, but that would not scale. // struct A { struct Foo *p; }; // This is a severe problem because the importer decides if it has to create a diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 5ab438715ecf7..586ad3be62a7e 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -1,4 +1,4 @@ -//==--- AbstractBasiceReader.h - Abstract basic value deserialization -===// +//==--- AbstractBasicReader.h - Abstract basic value deserialization -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b5417fcf20ddd..b56a64e07f110 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1085,7 +1085,7 @@ void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, MergedDefModules[cast(ND->getCanonicalDecl())].push_back(M); } -void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) { +void ASTContext::deduplicateMergedDefinitionsFor(NamedDecl *ND) { auto It = MergedDefModules.find(cast(ND->getCanonicalDecl())); if (It == MergedDefModules.end()) return; @@ -1803,7 +1803,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { Align = Target->getCharWidth(); } -// Ensure miminum align
[clang] [clang] Use llvm::partition_point (NFC) (PR #141351)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/141351 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Remove an unused local variable (NFC) (PR #141358)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/141358 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3ac2b5c - [Serialization] Remove an unused local variable (NFC) (#141358)
Author: Kazu Hirata Date: 2025-05-24T09:37:46-07:00 New Revision: 3ac2b5c55bdf3dcecf5dca731f5cdd6996c3b63d URL: https://github.com/llvm/llvm-project/commit/3ac2b5c55bdf3dcecf5dca731f5cdd6996c3b63d DIFF: https://github.com/llvm/llvm-project/commit/3ac2b5c55bdf3dcecf5dca731f5cdd6996c3b63d.diff LOG: [Serialization] Remove an unused local variable (NFC) (#141358) Note that getTimestampFilename just constructs a file name, so it's mostly a "pure" function except possible heap allocation. Added: Modified: clang/lib/Serialization/ModuleCache.cpp Removed: diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp index 4ae49c4ec9a05..f42bdc16d815d 100644 --- a/clang/lib/Serialization/ModuleCache.cpp +++ b/clang/lib/Serialization/ModuleCache.cpp @@ -34,8 +34,6 @@ class CrossProcessModuleCache : public ModuleCache { } std::time_t getModuleTimestamp(StringRef ModuleFilename) override { -std::string TimestampFilename = -serialization::ModuleFile::getTimestampFilename(ModuleFilename); llvm::sys::fs::file_status Status; if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{}) return 0; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
https://github.com/chomosuke updated https://github.com/llvm/llvm-project/pull/118568 >From b43a2602025bdacea06ced5171904fb5d765de9f Mon Sep 17 00:00:00 2001 From: chomosuke Date: Tue, 3 Dec 2024 07:10:33 + Subject: [PATCH 1/5] fixed removeFunctionArgs don't remove comma --- .../clang-tidy/utils/UseRangesCheck.cpp | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index aba4d17ccd035..88cba70b931d5 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include +#include #include #include @@ -173,21 +174,21 @@ static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, for (unsigned Index : Sorted) { const Expr *Arg = Call.getArg(Index); if (Commas[Index]) { - if (Index >= Commas.size()) { -Diag << FixItHint::CreateRemoval(Arg->getSourceRange()); - } else { + if (Index + 1 < Call.getNumArgs()) { // Remove the next comma Commas[Index + 1] = true; +const Expr *NextArg = Call.getArg(Index + 1); Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( -{Arg->getBeginLoc(), - Lexer::getLocForEndOfToken( - Arg->getEndLoc(), 0, Ctx.getSourceManager(), Ctx.getLangOpts()) - .getLocWithOffset(1)})); +{Arg->getBeginLoc(), NextArg->getBeginLoc().getLocWithOffset(-1)})); + } else { +Diag << FixItHint::CreateRemoval(Arg->getSourceRange()); } } else { - Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( - Arg->getBeginLoc().getLocWithOffset(-1), Arg->getEndLoc())); + // At this point we know Index > 0 because `Commas[0] = true` earlier Commas[Index] = true; + const Expr *PrevArg = Call.getArg(Index - 1); + Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( + PrevArg->getEndLoc().getLocWithOffset(1), Arg->getEndLoc())); } } } >From 644c8491e0fba203e89595827781d0c2c0609081 Mon Sep 17 00:00:00 2001 From: chomosuke Date: Mon, 23 Dec 2024 05:17:08 +1100 Subject: [PATCH 2/5] find , and remove only , --- .../clang-tidy/utils/UseRangesCheck.cpp | 49 +++ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index 88cba70b931d5..8b8e44a9898fd 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -28,7 +28,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include -#include #include #include @@ -165,6 +164,33 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) { static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, ArrayRef Indexes, const ASTContext &Ctx) { + auto GetCommaLoc = + [&](SourceLocation BeginLoc, + SourceLocation EndLoc) -> std::optional { +auto Invalid = false; +auto SourceText = Lexer::getSourceText( +CharSourceRange::getCharRange({BeginLoc, EndLoc}), +Ctx.getSourceManager(), Ctx.getLangOpts(), &Invalid); +assert(!Invalid); + +size_t I = 0; +while (I < SourceText.size() && SourceText[I] != ',') { + I++; +} + +if (I < SourceText.size()) { + // also remove space after , + size_t J = I + 1; + while (J < SourceText.size() && SourceText[J] == ' ') { +J++; + } + + return std::make_optional(CharSourceRange::getCharRange( + {BeginLoc.getLocWithOffset(I), BeginLoc.getLocWithOffset(J)})); +} +return std::nullopt; + }; + llvm::SmallVector Sorted(Indexes); llvm::sort(Sorted); // Keep track of commas removed @@ -176,20 +202,25 @@ static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, if (Commas[Index]) { if (Index + 1 < Call.getNumArgs()) { // Remove the next comma -Commas[Index + 1] = true; const Expr *NextArg = Call.getArg(Index + 1); -Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( -{Arg->getBeginLoc(), NextArg->getBeginLoc().getLocWithOffset(-1)})); - } else { -Diag << FixItHint::CreateRemoval(Arg->getSourceRange()); +auto CommaLoc = GetCommaLoc(Arg->getEndLoc().getLocWithOffset(1), +NextArg->getBeginLoc()); +if (CommaLoc) { + Commas[Index + 1] = true; + Diag << FixItHint::CreateRemoval(*CommaLoc); +} } } else { // At this point we know Index > 0 because `
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
chomosuke wrote: Ping https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added check 'bugprone-function-visibility-change' (PR #140086)
=?utf-8?q?Balázs_Kéri?= , =?utf-8?q?Balázs_Kéri?= Message-ID: In-Reply-To: https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/140086 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fb14c83 - [StaticAnalyzer] Use llvm::is_contained (NFC) (#141371)
Author: Kazu Hirata Date: 2025-05-24T14:46:01-07:00 New Revision: fb14c8338a4187f87b525a58bd653c85b9b123fd URL: https://github.com/llvm/llvm-project/commit/fb14c8338a4187f87b525a58bd653c85b9b123fd DIFF: https://github.com/llvm/llvm-project/commit/fb14c8338a4187f87b525a58bd653c85b9b123fd.diff LOG: [StaticAnalyzer] Use llvm::is_contained (NFC) (#141371) Added: Modified: clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 77258958ae027..c9f5dc99aaf6b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -962,10 +962,8 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx, // `AllocFirstBinding` to be one of them. In situations like this, // it would still be the easiest case to explain to our users. if (!AllVarBindings.empty() && - llvm::count_if(AllVarBindings, - [this](const std::pair Binding) { - return Binding.first == AllocFirstBinding; - }) == 0) { + !llvm::is_contained(llvm::make_first_range(AllVarBindings), + AllocFirstBinding)) { // Let's pick one of them at random (if there is something to pick from). AllocBindingToReport = AllVarBindings[0].first; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Correct FixIt ranges for unused capture warnings (PR #141148)
@@ -84,6 +84,21 @@ SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) { return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts); } +SourceRange Sema::getRangeForNextToken(SourceLocation Loc, + bool IncludeComments) { + if (!Loc.isValid()) +return SourceRange(); + std::optional NextToken = + Lexer::findNextToken(Loc, SourceMgr, LangOpts, IncludeComments); + if (!NextToken) +return SourceRange(); + SourceLocation TokenStart = NextToken->getLocation(); + SourceLocation TokenEnd = NextToken->getLastLoc(); + if (!TokenStart.isValid() || !TokenEnd.isValid()) +return SourceRange(); ojhunt wrote: Yup! But that kind of results in this no longer being just a wrapper so I'm not sure if that's "good" - I might make it a flag? https://github.com/llvm/llvm-project/pull/141148 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Correct FixIt ranges for unused capture warnings (PR #141148)
@@ -2164,15 +2164,29 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, bool IsLast = (I + 1) == LSI->NumExplicitCaptures; SourceRange FixItRange; if (CaptureRange.isValid()) { +auto GetTrailingEndLocation = [&](SourceLocation StartPoint) { + SourceRange NextToken = + getRangeForNextToken(StartPoint, /*IncludeComments=*/true); + if (!NextToken.isValid()) +return SourceLocation(); + // Return the last location preceding the next token + return NextToken.getBegin().getLocWithOffset(-1); +}; if (!CurHasPreviousCapture && !IsLast) { // If there are no captures preceding this capture, remove the - // following comma. - FixItRange = SourceRange(CaptureRange.getBegin(), - getLocForEndOfToken(CaptureRange.getEnd())); + // trailing comma and anything up to the next token + SourceRange CommaRange = + getRangeForNextToken(CaptureRange.getEnd()); + SourceLocation FixItEnd = + GetTrailingEndLocation(CommaRange.getBegin()); + FixItRange = SourceRange(CaptureRange.getBegin(), FixItEnd); } else { - // Otherwise, remove the comma since the last used capture. - FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc), - CaptureRange.getEnd()); + // Otherwise, remove the comma since the last used capture, and + // anything up to the next token + SourceLocation FixItStart = getLocForEndOfToken(PrevCaptureLoc); + SourceLocation FixItEnd = + GetTrailingEndLocation(CaptureRange.getEnd()); ojhunt wrote: no, we care about compile times and having an entire additional will make compilation slower. :D :D (yes, I'll make it a function) https://github.com/llvm/llvm-project/pull/141148 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Correct FixIt ranges for unused capture warnings (PR #141148)
@@ -84,6 +84,21 @@ SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) { return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts); } +SourceRange Sema::getRangeForNextToken(SourceLocation Loc, + bool IncludeComments) { + if (!Loc.isValid()) +return SourceRange(); + std::optional NextToken = + Lexer::findNextToken(Loc, SourceMgr, LangOpts, IncludeComments); ojhunt wrote: I'm using this one function for two purposes: * Finding the (presumed) comma and stepping over it * Finding the start of the next token It seemed like a reasonable approach, and given we're producing a fixit diagnostic I don't think the perf matters. Basically what I'm trying to do is say given an unused capture: ```cpp auto foo = [a, unused, b] ... // just a pile of white space for illustrative purposes auto bar = [a, unused, /* ... */ b] ... auto wibble = [a, /* ... */ unused, b] ... auto thingy = [a, unused /* ... */, b] ... ``` produce fixits that result in ```cpp auto foo = [a, b] ... // just a pile of white space for illustrative purposes auto bar = [a, /* ... */ b] ... auto wibble = [a, b] ... auto thingy = [a, b] ... ``` and for that what we want to do is find the end of the comma, and the start of the next token, simply using the "findNextToken" to just get those tokens seems reasonable. Of course as we discussed in discord, that function doesn't handle macros, and handling this correctly for macros would imply the Sema "wrapper" excludes macro wrappers (so would not just be a wrapper) or every user has to check for macros. https://github.com/llvm/llvm-project/pull/141148 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle Java text blocks (PR #141334)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/141334 >From 470eca4b4d963bf5c1ba87fb2f22620eb717c848 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Fri, 23 May 2025 23:21:12 -0700 Subject: [PATCH 1/2] [clang-format] Handle Java text blocks Fix #61954 --- clang/lib/Format/FormatTokenLexer.cpp | 45 clang/lib/Format/FormatTokenLexer.h | 2 + clang/unittests/Format/FormatTestJava.cpp | 52 +++ 3 files changed, 99 insertions(+) diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index 864486a9b878d..31c3613c8b083 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -694,6 +694,49 @@ bool FormatTokenLexer::canPrecedeRegexLiteral(FormatToken *Prev) { return true; } +void FormatTokenLexer::tryParseJavaTextBlock() { + if (FormatTok->TokenText != "\"\"") +return; + + const auto *Str = Lex->getBufferLocation(); + const auto *End = Lex->getBuffer().end(); + + if (Str == End || *Str != '\"') +return; + + // Skip the `"""` that begins a text block. + const auto *S = Str + 1; + + // From docs.oracle.com/en/java/javase/15/text-blocks/#text-block-syntax: + // A text block begins with three double-quote characters followed by a line + // terminator. + while (S < End && *S != '\n') { +if (!isblank(*S)) + return; +++S; + } + + // Find the `"""` that ends the text block. + for (int Count = 0; Count < 3; ++S) { +if (S == End) + return; + +switch (*S) { +case '\\': + Count = -1; + break; +case '\"': + ++Count; + break; +default: + Count = 0; +} + } + + // Skip the text block. + resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(S))); +} + // Tries to parse a JavaScript Regex literal starting at the current token, // if that begins with a slash and is in a location where JavaScript allows // regex literals. Changes the current token to a regex literal and updates @@ -1374,6 +1417,8 @@ FormatToken *FormatTokenLexer::getNextToken() { FormatTok->TokenText = FormatTok->TokenText.substr(0, 1); ++Column; StateStack.push(LexerState::TOKEN_STASHED); + } else if (Style.isJava() && FormatTok->is(tok::string_literal)) { +tryParseJavaTextBlock(); } if (Style.isVerilog() && Tokens.size() > 0 && diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 105847b126e20..026383db1fe6c 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -72,6 +72,8 @@ class FormatTokenLexer { bool canPrecedeRegexLiteral(FormatToken *Prev); + void tryParseJavaTextBlock(); + // Tries to parse a JavaScript Regex literal starting at the current token, // if that begins with a slash and is in a location where JavaScript allows // regex literals. Changes the current token to a regex literal and updates diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp index e01c1d6d7e684..35ee257d015d3 100644 --- a/clang/unittests/Format/FormatTestJava.cpp +++ b/clang/unittests/Format/FormatTestJava.cpp @@ -791,6 +791,58 @@ TEST_F(FormatTestJava, AlignCaseArrows) { Style); } +TEST_F(FormatTestJava, TextBlock) { + verifyNoChange("String myStr = \"\"\"\n" + "hello\n" + "there\n" + "\"\"\";"); + + verifyNoChange("String tb = \"\"\"\n" + "the new\"\"\";"); + + verifyNoChange("System.out.println(\"\"\"\n" + "This is the first line\n" + "This is the second line\n" + "\"\"\");"); + + verifyNoChange("void writeHTML() {\n" + " String html = \"\"\" \n" + "\n" + "Hello World.\n" + "\n" + "\"\"\";\n" + " writeOutput(html);\n" + "}"); + + verifyNoChange("String colors = \"\"\"\t\n" + "red\n" + "green\n" + "blue\"\"\".indent(4);"); + + verifyNoChange("String code = \"\"\"\n" + "String source = \\\"\"\"\n" + "String message = \"Hello, World!\";\n" + "System.out.println(message);\n" + "\\\"\"\";\n" + "\"\"\";"); + + verifyNoChange( + "class Outer {\n" + " void printPoetry() {\n" + "String lilacs = \"\"\"\n" + "Passing the apple-tree blows of white and pink in the orchards\n" + "\"\"\";\n" + "System.out.println(lilacs);\n" + " }\n" + "}"); + + verifyNoChange("String name = \"\"\"\n" + "red\n" + "green\n" + "blue\\\n" + "\"\"\";"
[clang] [clang-format] Handle Java text blocks (PR #141334)
https://github.com/HazardyKnusperkeks approved this pull request. https://github.com/llvm/llvm-project/pull/141334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Clean up the fix for deferred access checking (PR #141340)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) Changes https://github.com/llvm/llvm-project/commit/200f3bd39562f4d605f13567398025d30fa27d61 introduced a parsing scope to avoid deferring access checking for friend declarations. That turned out to be insufficient because it only sets up the scope until we see the friend keyword, which can be bypassed if the declaration occurs before the keyword. That said, based on the discussion in https://github.com/llvm/llvm-project/issues/12361, we still want to preserve the fix since a friend function declaration doesn't grant the access to other redeclarations. This patch implemented it by not considering the friend declaration functions as effective contexts. So we don't end up checking the canonical function declaration when we're supposed to check only non-function friend declarations. --- Full diff: https://github.com/llvm/llvm-project/pull/141340.diff 6 Files Affected: - (modified) clang/include/clang/Sema/Scope.h (-6) - (modified) clang/lib/Parse/ParseDecl.cpp (+2-5) - (modified) clang/lib/Sema/Scope.cpp (-1) - (modified) clang/lib/Sema/SemaAccess.cpp (+34-26) - (removed) clang/test/SemaCXX/PR12361.cpp (-30) - (modified) clang/test/SemaCXX/access-control-check.cpp (+39-1) ``diff diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index ad12a3d73413b..77497918f54eb 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -160,9 +160,6 @@ class Scope { /// This is a scope of type alias declaration. TypeAliasScope = 0x2000, - -/// This is a scope of friend declaration. -FriendScope = 0x4000, }; private: @@ -590,9 +587,6 @@ class Scope { /// Determine whether this scope is a type alias scope. bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; } - /// Determine whether this scope is a friend scope. - bool isFriendScope() const { return getFlags() & Scope::FriendScope; } - /// Returns if rhs has a higher scope depth than this. /// /// The caller is responsible for calling this only if one of the two scopes diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 7a87cd2e340cc..bcebf14aa4fdc 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4219,12 +4219,9 @@ void Parser::ParseDeclarationSpecifiers( // friend case tok::kw_friend: - if (DSContext == DeclSpecContext::DSC_class) { + if (DSContext == DeclSpecContext::DSC_class) isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); -Scope *CurS = getCurScope(); -if (!isInvalid && CurS) - CurS->setFlags(CurS->getFlags() | Scope::FriendScope); - } else { + else { PrevSpec = ""; // not actually used by the diagnostic DiagID = diag::err_friend_invalid_in_context; isInvalid = true; diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index 5bc7e79a68186..ec7fd92f53e6e 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -233,7 +233,6 @@ void Scope::dumpImpl(raw_ostream &OS) const { {LambdaScope, "LambdaScope"}, {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"}, {TypeAliasScope, "TypeAliasScope"}, - {FriendScope, "FriendScope"}, }; for (auto Info : FlagInfo) { diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 890df09157aa0..40ee20419c2a5 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1469,32 +1469,12 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, // specifier, like this: // A::private_type A::foo() { ... } // - // friend declaration should not be delayed because it may lead to incorrect - // redeclaration chain, such as: - // class D { - //class E{ - // class F{}; - // friend void foo(D::E::F& q); - //}; - //friend void foo(D::E::F& q); - // }; + // Or we might be parsing something that will turn out to be a friend: + // void foo(A::private_type); + // void B::foo(A::private_type); if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { -// [class.friend]p9: -// A member nominated by a friend declaration shall be accessible in the -// class containing the friend declaration. The meaning of the friend -// declaration is the same whether the friend declaration appears in the -// private, protected, or public ([class.mem]) portion of the class -// member-specification. -Scope *TS = S.getCurScope(); -bool IsFriendDeclaration = false; -while (TS && !IsFriendDeclaration) { - IsFriendDeclaration = TS->isFriendScope(); - TS = TS->getParent(); -} -if (!IsFriendDeclaration) { - S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity)); - return Sema::AR_delayed; -} +S.DelayedDiagnostics.add(DelayedDiagn
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [clang][bytecode] Check lifetime of all ptr bases in placement-new (PR #141272)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/141272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add fix-it hints for unknown attributes (PR #141305)
a-tarasyuk wrote: @zwuis Thanks for the feedback. I've added additional tests to cover this case https://github.com/llvm/llvm-project/pull/141305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
https://github.com/mcinally created https://github.com/llvm/llvm-project/pull/141380 This patch adds support for the -mprefer-vector-width= command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. >From 05221439896aabdcadf79d15ae6875dc34f10edd Mon Sep 17 00:00:00 2001 From: Cameron McInally Date: Sat, 24 May 2025 13:35:13 -0700 Subject: [PATCH] [flang] Add support for -mprefer-vector-width= This patch adds support for the -mprefer-vector-width= command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- clang/include/clang/Driver/Options.td| 2 +- flang/include/flang/Frontend/CodeGenOptions.h| 3 +++ .../include/flang/Optimizer/Transforms/Passes.td | 4 flang/include/flang/Tools/CrossToolHelpers.h | 3 +++ flang/lib/Frontend/CompilerInvocation.cpp| 14 ++ flang/lib/Frontend/FrontendActions.cpp | 2 ++ flang/lib/Optimizer/Passes/Pipelines.cpp | 2 +- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 5 + flang/test/Driver/prefer-vector-width.f90| 16 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 + mlir/lib/Target/LLVMIR/ModuleImport.cpp | 4 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 +++ 12 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 flang/test/Driver/prefer-vector-width.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set u
[clang-tools-extra] [clang] Default-construct values with DenseMap::try_emplace (NFC) (PR #141373)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: Kazu Hirata (kazutakahirata) Changes try_emplace can default-construct values, so we do not need to do so on our own. --- Full diff: https://github.com/llvm/llvm-project/pull/141373.diff 1 Files Affected: - (modified) clang-tools-extra/clangd/index/SymbolCollector.cpp (+2-2) ``diff diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index 3f5633357073d..6bdb1080fb294 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -1201,7 +1201,7 @@ void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) { } SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { - auto It = DeclToIDCache.try_emplace(D, SymbolID{}); + auto It = DeclToIDCache.try_emplace(D); if (It.second) It.first->second = getSymbolID(D); return It.first->second; @@ -1210,7 +1210,7 @@ SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { SymbolID SymbolCollector::getSymbolIDCached(const llvm::StringRef MacroName, const MacroInfo *MI, const SourceManager &SM) { - auto It = MacroToIDCache.try_emplace(MI, SymbolID{}); + auto It = MacroToIDCache.try_emplace(MI); if (It.second) It.first->second = getSymbolID(MacroName, MI, SM); return It.first->second; `` https://github.com/llvm/llvm-project/pull/141373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::count (NFC) (PR #141370)
https://github.com/tgymnich approved this pull request. https://github.com/llvm/llvm-project/pull/141370 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::is_contained (NFC) (PR #141371)
https://github.com/tgymnich approved this pull request. https://github.com/llvm/llvm-project/pull/141371 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- flang/include/flang/Frontend/CodeGenOptions.h flang/include/flang/Tools/CrossToolHelpers.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/Optimizer/Passes/Pipelines.cpp flang/lib/Optimizer/Transforms/FunctionAttr.cpp mlir/lib/Target/LLVMIR/ModuleImport.cpp mlir/lib/Target/LLVMIR/ModuleTranslation.cpp `` View the diff from clang-format here. ``diff diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 122eb56fa..918323d66 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -310,8 +310,8 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.LLVMPassPlugins.push_back(a->getValue()); // -mprefer_vector_width option - if (const llvm::opt::Arg *a = - args.getLastArg(clang::driver::options::OPT_mprefer_vector_width_EQ)) { + if (const llvm::opt::Arg *a = args.getLastArg( + clang::driver::options::OPT_mprefer_vector_width_EQ)) { llvm::StringRef s = a->getValue(); unsigned Width; if (s == "none") `` https://github.com/llvm/llvm-project/pull/141380 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
llvmbot wrote: @llvm/pr-subscribers-mlir-llvm Author: Cameron McInally (mcinally) Changes This patch adds support for the -mprefer-vector-width=command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- Full diff: https://github.com/llvm/llvm-project/pull/141380.diff 12 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+1-1) - (modified) flang/include/flang/Frontend/CodeGenOptions.h (+3) - (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+4) - (modified) flang/include/flang/Tools/CrossToolHelpers.h (+3) - (modified) flang/lib/Frontend/CompilerInvocation.cpp (+14) - (modified) flang/lib/Frontend/FrontendActions.cpp (+2) - (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+1-1) - (modified) flang/lib/Optimizer/Transforms/FunctionAttr.cpp (+5) - (added) flang/test/Driver/prefer-vector-width.f90 (+16) - (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+1) - (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+4) - (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+3) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. std::string InstrumentFunctionEntry = diff --git a/flang/lib/
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
llvmbot wrote: @llvm/pr-subscribers-flang-fir-hlfir Author: Cameron McInally (mcinally) Changes This patch adds support for the -mprefer-vector-width=command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- Full diff: https://github.com/llvm/llvm-project/pull/141380.diff 12 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+1-1) - (modified) flang/include/flang/Frontend/CodeGenOptions.h (+3) - (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+4) - (modified) flang/include/flang/Tools/CrossToolHelpers.h (+3) - (modified) flang/lib/Frontend/CompilerInvocation.cpp (+14) - (modified) flang/lib/Frontend/FrontendActions.cpp (+2) - (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+1-1) - (modified) flang/lib/Optimizer/Transforms/FunctionAttr.cpp (+5) - (added) flang/test/Driver/prefer-vector-width.f90 (+16) - (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+1) - (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+4) - (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+3) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. std::string InstrumentFunctionEntry = diff --git a/flan
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
llvmbot wrote: @llvm/pr-subscribers-flang-driver Author: Cameron McInally (mcinally) Changes This patch adds support for the -mprefer-vector-width=command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- Full diff: https://github.com/llvm/llvm-project/pull/141380.diff 12 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+1-1) - (modified) flang/include/flang/Frontend/CodeGenOptions.h (+3) - (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+4) - (modified) flang/include/flang/Tools/CrossToolHelpers.h (+3) - (modified) flang/lib/Frontend/CompilerInvocation.cpp (+14) - (modified) flang/lib/Frontend/FrontendActions.cpp (+2) - (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+1-1) - (modified) flang/lib/Optimizer/Transforms/FunctionAttr.cpp (+5) - (added) flang/test/Driver/prefer-vector-width.f90 (+16) - (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+1) - (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+4) - (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+3) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. std::string InstrumentFunctionEntry = diff --git a/flang/l
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
llvmbot wrote: @llvm/pr-subscribers-mlir @llvm/pr-subscribers-clang Author: Cameron McInally (mcinally) Changes This patch adds support for the -mprefer-vector-width=command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- Full diff: https://github.com/llvm/llvm-project/pull/141380.diff 12 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+1-1) - (modified) flang/include/flang/Frontend/CodeGenOptions.h (+3) - (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+4) - (modified) flang/include/flang/Tools/CrossToolHelpers.h (+3) - (modified) flang/lib/Frontend/CompilerInvocation.cpp (+14) - (modified) flang/lib/Frontend/FrontendActions.cpp (+2) - (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+1-1) - (modified) flang/lib/Optimizer/Transforms/FunctionAttr.cpp (+5) - (added) flang/test/Driver/prefer-vector-width.f90 (+16) - (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+1) - (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+4) - (modified) mlir/lib/Target/LLVMIR/ModuleTranslation.cpp (+3) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. std::string InstrumentFunctionEntry = d
[clang-tools-extra] [clang] Default-construct values with DenseMap::try_emplace (NFC) (PR #141373)
https://github.com/tgymnich approved this pull request. https://github.com/llvm/llvm-project/pull/141373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
mcinally wrote: This is my first patch to Flang, so please be suspicious and gentle. In particular, I am not sure if `FlangOption, FC1Option` were the correct phases to pass this option to or not. https://github.com/llvm/llvm-project/pull/141380 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::count (NFC) (PR #141370)
https://github.com/tgymnich approved this pull request. https://github.com/llvm/llvm-project/pull/141370 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream global initialization for ComplexType (PR #141369)
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/141369 This change adds support for zero and global init for ComplexType #141365 >From 3a8bcd052d25d138b3a9a53bbcc69d48500b4b41 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 24 May 2025 14:18:06 +0200 Subject: [PATCH] [CIR] Upstream global initialization for ComplexType --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 2 + .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 34 ++ .../include/clang/CIR/Dialect/IR/CIRTypes.td | 43 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 27 ++-- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 7 ++ clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 20 ++ clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 6 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 26 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 65 +++ clang/test/CIR/CodeGen/complex.cpp| 29 + clang/test/CIR/IR/complex.cir | 16 + 11 files changed, 257 insertions(+), 18 deletions(-) create mode 100644 clang/test/CIR/CodeGen/complex.cpp create mode 100644 clang/test/CIR/IR/complex.cir diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 9de3a66755778..878aba69c0e24 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -89,6 +89,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return cir::IntAttr::get(ty, 0); if (cir::isAnyFloatingPointType(ty)) return cir::FPAttr::getZero(ty); +if (auto complexType = mlir::dyn_cast(ty)) + return cir::ZeroAttr::get(complexType); if (auto arrTy = mlir::dyn_cast(ty)) return cir::ZeroAttr::get(arrTy); if (auto vecTy = mlir::dyn_cast(ty)) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 8152535930095..4effae1cf2e29 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -276,4 +276,38 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { }]; } +//===--===// +// ConstComplexAttr +//===--===// + +def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", [TypedAttrInterface]> { + let summary = "An attribute that contains a constant complex value"; + let description = [{ +The `#cir.const_complex` attribute contains a constant value of complex number +type. The `real` parameter gives the real part of the complex number and the +`imag` parameter gives the imaginary part of the complex number. + +The `real` and `imag` parameter must be either an IntAttr or an FPAttr that +contains values of the same CIR type. + }]; + + let parameters = (ins +AttributeSelfTypeParameter<"", "cir::ComplexType">:$type, +"mlir::TypedAttr":$real, "mlir::TypedAttr":$imag); + + let builders = [ +AttrBuilderWithInferredContext<(ins "cir::ComplexType":$type, +"mlir::TypedAttr":$real, +"mlir::TypedAttr":$imag), [{ + return $_get(type.getContext(), type, real, imag); +}]>, + ]; + + let genVerifyDecl = 1; + + let assemblyFormat = [{ +`<` qualified($real) `,` qualified($imag) `>` + }]; +} + #endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 26f1122a4b261..ec994620893fe 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -161,6 +161,49 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { }]; } +//===--===// +// ComplexType +//===--===// + +def CIR_ComplexType : CIR_Type<"Complex", "complex", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR complex type"; + let description = [{ +CIR type that represents a C complex number. `cir.complex` models the C type +`T _Complex`. + +The type models complex values, per C99 6.2.5p11. It supports the C99 +complex float types as well as the GCC integer complex extensions. + +The parameter `elementType` gives the type of the real and imaginary part of +the complex number. `elementType` must be either a CIR integer type or a CIR +floating-point type. + }]; + + let parameters = (ins CIR_AnyIntOrFloatType:$elementType); + + let builders = [ +TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ + return $_get(elementType.getContext(), elementType); +}
[clang] [CIR] Upstream global initialization for ComplexType (PR #141369)
llvmbot wrote: @llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) Changes This change adds support for zero and global init for ComplexType #141365 --- Full diff: https://github.com/llvm/llvm-project/pull/141369.diff 11 Files Affected: - (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+2) - (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+34) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.td (+43) - (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+23-4) - (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+7) - (modified) clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (+20) - (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+4-2) - (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (+26) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+53-12) - (added) clang/test/CIR/CodeGen/complex.cpp (+29) - (added) clang/test/CIR/IR/complex.cir (+16) ``diff diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 9de3a66755778..878aba69c0e24 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -89,6 +89,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return cir::IntAttr::get(ty, 0); if (cir::isAnyFloatingPointType(ty)) return cir::FPAttr::getZero(ty); +if (auto complexType = mlir::dyn_cast(ty)) + return cir::ZeroAttr::get(complexType); if (auto arrTy = mlir::dyn_cast(ty)) return cir::ZeroAttr::get(arrTy); if (auto vecTy = mlir::dyn_cast(ty)) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 8152535930095..4effae1cf2e29 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -276,4 +276,38 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { }]; } +//===--===// +// ConstComplexAttr +//===--===// + +def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex", [TypedAttrInterface]> { + let summary = "An attribute that contains a constant complex value"; + let description = [{ +The `#cir.const_complex` attribute contains a constant value of complex number +type. The `real` parameter gives the real part of the complex number and the +`imag` parameter gives the imaginary part of the complex number. + +The `real` and `imag` parameter must be either an IntAttr or an FPAttr that +contains values of the same CIR type. + }]; + + let parameters = (ins +AttributeSelfTypeParameter<"", "cir::ComplexType">:$type, +"mlir::TypedAttr":$real, "mlir::TypedAttr":$imag); + + let builders = [ +AttrBuilderWithInferredContext<(ins "cir::ComplexType":$type, +"mlir::TypedAttr":$real, +"mlir::TypedAttr":$imag), [{ + return $_get(type.getContext(), type, real, imag); +}]>, + ]; + + let genVerifyDecl = 1; + + let assemblyFormat = [{ +`<` qualified($real) `,` qualified($imag) `>` + }]; +} + #endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 26f1122a4b261..ec994620893fe 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -161,6 +161,49 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { }]; } +//===--===// +// ComplexType +//===--===// + +def CIR_ComplexType : CIR_Type<"Complex", "complex", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR complex type"; + let description = [{ +CIR type that represents a C complex number. `cir.complex` models the C type +`T _Complex`. + +The type models complex values, per C99 6.2.5p11. It supports the C99 +complex float types as well as the GCC integer complex extensions. + +The parameter `elementType` gives the type of the real and imaginary part of +the complex number. `elementType` must be either a CIR integer type or a CIR +floating-point type. + }]; + + let parameters = (ins CIR_AnyIntOrFloatType:$elementType); + + let builders = [ +TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{ + return $_get(elementType.getContext(), elementType); +}]>, + ]; + + let assemblyFormat = [{ +`<` $elementType `>` + }]; + + let extraClassDeclaration = [{ +bool isFloatingPointComplex() const { + return isAnyFloatingPointType(getElementType()); +} + +bool isIntege
[clang] [StaticAnalyzer] Use llvm::is_contained (NFC) (PR #141371)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141371.diff 1 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp (+2-4) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 77258958ae027..c9f5dc99aaf6b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -962,10 +962,8 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx, // `AllocFirstBinding` to be one of them. In situations like this, // it would still be the easiest case to explain to our users. if (!AllVarBindings.empty() && - llvm::count_if(AllVarBindings, - [this](const std::pair Binding) { - return Binding.first == AllocFirstBinding; - }) == 0) { + !llvm::is_contained(llvm::make_first_range(AllVarBindings), + AllocFirstBinding)) { // Let's pick one of them at random (if there is something to pick from). AllocBindingToReport = AllVarBindings[0].first; `` https://github.com/llvm/llvm-project/pull/141371 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::is_contained (NFC) (PR #141371)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141371.diff 1 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp (+2-4) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 77258958ae027..c9f5dc99aaf6b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -962,10 +962,8 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx, // `AllocFirstBinding` to be one of them. In situations like this, // it would still be the easiest case to explain to our users. if (!AllVarBindings.empty() && - llvm::count_if(AllVarBindings, - [this](const std::pair Binding) { - return Binding.first == AllocFirstBinding; - }) == 0) { + !llvm::is_contained(llvm::make_first_range(AllVarBindings), + AllocFirstBinding)) { // Let's pick one of them at random (if there is something to pick from). AllocBindingToReport = AllVarBindings[0].first; `` https://github.com/llvm/llvm-project/pull/141371 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
https://github.com/klausler commented: I'm not really qualified to review driver patches, but it looks okay as far as I can tell. https://github.com/llvm/llvm-project/pull/141380 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] Default-construct values with DenseMap::try_emplace (NFC) (PR #141373)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/141373 try_emplace can default-construct values, so we do not need to do so on our own. >From c4590156c4dab5a70edca1056bc533a073f615e3 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 24 May 2025 11:24:36 -0700 Subject: [PATCH] [clang] Default-construct values with DenseMap::try_emplace (NFC) try_emplace can default-construct values, so we do not need to do so on our own. --- clang-tools-extra/clangd/index/SymbolCollector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index 3f5633357073d..6bdb1080fb294 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -1201,7 +1201,7 @@ void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) { } SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { - auto It = DeclToIDCache.try_emplace(D, SymbolID{}); + auto It = DeclToIDCache.try_emplace(D); if (It.second) It.first->second = getSymbolID(D); return It.first->second; @@ -1210,7 +1210,7 @@ SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { SymbolID SymbolCollector::getSymbolIDCached(const llvm::StringRef MacroName, const MacroInfo *MI, const SourceManager &SM) { - auto It = MacroToIDCache.try_emplace(MI, SymbolID{}); + auto It = MacroToIDCache.try_emplace(MI); if (It.second) It.first->second = getSymbolID(MacroName, MI, SM); return It.first->second; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::is_contained (NFC) (PR #141371)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/141371 None >From 4b31c73fb378e6f3d3ea8b272574397c1ac8418e Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 24 May 2025 11:48:54 -0700 Subject: [PATCH] [StaticAnalyzer] Use llvm::is_contained (NFC) --- .../Checkers/RetainCountChecker/RetainCountDiagnostics.cpp | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index 77258958ae027..c9f5dc99aaf6b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -962,10 +962,8 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx, // `AllocFirstBinding` to be one of them. In situations like this, // it would still be the easiest case to explain to our users. if (!AllVarBindings.empty() && - llvm::count_if(AllVarBindings, - [this](const std::pair Binding) { - return Binding.first == AllocFirstBinding; - }) == 0) { + !llvm::is_contained(llvm::make_first_range(AllVarBindings), + AllocFirstBinding)) { // Let's pick one of them at random (if there is something to pick from). AllocBindingToReport = AllVarBindings[0].first; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [mlir] [flang] Add support for -mprefer-vector-width= (PR #141380)
https://github.com/mcinally updated https://github.com/llvm/llvm-project/pull/141380 >From 9f8619cb54a3a11e4c90af7f5156141ddc59e4d4 Mon Sep 17 00:00:00 2001 From: Cameron McInally Date: Sat, 24 May 2025 13:35:13 -0700 Subject: [PATCH] [flang] Add support for -mprefer-vector-width= This patch adds support for the -mprefer-vector-width= command line option. The parsing of this options is equivalent to Clang's and it is implemented by setting the "prefer-vector-width" function attribute. --- clang/include/clang/Driver/Options.td| 2 +- flang/include/flang/Frontend/CodeGenOptions.h| 3 +++ .../include/flang/Optimizer/Transforms/Passes.td | 4 flang/include/flang/Tools/CrossToolHelpers.h | 3 +++ flang/lib/Frontend/CompilerInvocation.cpp| 14 ++ flang/lib/Frontend/FrontendActions.cpp | 2 ++ flang/lib/Optimizer/Passes/Pipelines.cpp | 2 +- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 5 + flang/test/Driver/prefer-vector-width.f90| 16 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 + mlir/lib/Target/LLVMIR/ModuleImport.cpp | 4 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 +++ 12 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 flang/test/Driver/prefer-vector-width.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..b0b642796010b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5480,7 +5480,7 @@ def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group, " = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'] ) | 'all' | 'default' | 'none'">, MarshallingInfoStringVector>; def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">, MarshallingInfoString>; def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 2b4e823b3fef4..61e56e51c4bbb 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -53,6 +53,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The paths to the pass plugins that were registered using -fpass-plugin. std::vector LLVMPassPlugins; + // The prefered vector width, if requested by -mprefer-vector-width. + std::string PreferVectorWidth; + /// List of filenames passed in using the -fembed-offload-object option. These /// are offloading binaries containing device images and metadata. std::vector OffloadObjects; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index b251534e1a8f6..2e932d9ad4a26 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -418,6 +418,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { "module.">, Option<"unsafeFPMath", "unsafe-fp-math", "bool", /*default=*/"false", "Set the unsafe-fp-math attribute on functions in the module.">, + Option<"preferVectorWidth", "prefer-vector-width", "std::string", + /*default=*/"", + "Set the prefer-vector-width attribute on functions in the " + "module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, ]; diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 118695bbe2626..058024a4a04c5 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -102,6 +102,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { UnsafeFPMath = mathOpts.getAssociativeMath() && mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); +PreferVectorWidth = opts.PreferVectorWidth; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; @@ -126,6 +127,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. + std::string PreferVectorWidth = ""; ///< Set prefer-vector-width attribute for + ///< functions. bool NSWOnLoopVarInc = true; //
[clang] [StaticAnalyzer] Use llvm::count (NFC) (PR #141370)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/141370 None >From 0d1f3e67da90cd8aaf153736d30db05bea224b0c Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sat, 24 May 2025 08:54:32 -0700 Subject: [PATCH] [StaticAnalyzer] Use llvm::count (NFC) --- clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp index 434c1d1526a22..4cb6bd34fa36d 100644 --- a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp +++ b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp @@ -35,11 +35,7 @@ class ResultMap { public: ResultMap(std::initializer_list> Data) - : Found(0), -Total(std::count_if(Data.begin(), Data.end(), -[](const std::pair &Pair) { - return Pair.second == true; -})), + : Found(0), Total(llvm::count(llvm::make_second_range(Data), true)), Impl(std::move(Data)) {} const bool *lookup(const CallEvent &Call) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/139859 >From 136f1c030db440054a2052a69c5c4dd27f50823e Mon Sep 17 00:00:00 2001 From: Rajveer Date: Wed, 14 May 2025 13:44:31 +0530 Subject: [PATCH] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks Resolves #138939 When enabling `--fno-exceptions` flag, discarded statements containing `try/catch/throw` in an independent context can be avoided from being rejected. --- clang/include/clang/Sema/Sema.h | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 5 ++--- clang/lib/Sema/SemaStmt.cpp | 20 +--- clang/lib/Sema/TreeTransform.h | 4 clang/test/SemaCXX/no-exceptions.cpp | 25 - 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6ea7ee281e14d..ebb40498e11aa 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11154,6 +11154,8 @@ class Sema final : public SemaBase { StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef Handlers); + void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry); + StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b2a982e953012..5383153728468 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -853,10 +853,9 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); // Don't report an error if 'throw' is used in system headers or in an OpenMP // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { + if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; +DiagnoseExceptionUse(OpLoc, /* IsTry */ false); } // In OpenMP target regions, we replace 'throw' with a trap on GPU targets. diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e8c1f8490342a..b3731d58a250f 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4304,10 +4304,9 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); // Don't report an error if 'try' is used in system headers or in an OpenMP // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) { + if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(TryLoc, diag::err_exceptions_disabled) << "try"; +DiagnoseExceptionUse(TryLoc, /* IsTry */ true); } // In OpenMP target regions, we assume that catch is never reached on GPU @@ -4410,6 +4409,21 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, Handlers); } +void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) { + const llvm::Triple &T = Context.getTargetInfo().getTriple(); + const bool IsOpenMPGPUTarget = + getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); + + if (IsOpenMPGPUTarget || getLangOpts().CUDA) +return; + + if (!getLangOpts().CXXExceptions && + !getSourceManager().isInSystemHeader(Loc) && + !CurContext->isDependentContext()) { +targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw"); + } +} + StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler) { assert(TryBlock && Handler); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 335e21d927b76..f8f2927d58bd6 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9162,6 +9162,8 @@ StmtResult TreeTransform::TransformCXXTryStmt(CXXTryStmt *S) { Handlers.push_back(Handler.getAs()); } + getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry */ true); + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && !HandlerChanged) return S; @@ -14384,6 +14386,8 @@ TreeTransform::TransformCXXThrowExpr(CXXThrowExpr *E) { if (SubExpr.isInvalid()) return ExprError(); + getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry */ false); + if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->get
[clang-tools-extra] [clang-tidy] Add check for assignment or comparision operators' operand in `readability-math-missing-parentheses` (PR #141345)
https://github.com/flovent updated https://github.com/llvm/llvm-project/pull/141345 >From 5842c573aa94063ea842230f19d5807a77b130e6 Mon Sep 17 00:00:00 2001 From: fubowen Date: Sat, 24 May 2025 21:29:53 +0800 Subject: [PATCH 1/2] [clang-tidy] Add check for assignment or comparision operators' operand in `readability-math-missing-parentheses` --- .../readability/MathMissingParenthesesCheck.cpp | 16 +--- clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../readability/math-missing-parentheses.cpp | 14 ++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp index 64ce94e3fc1db..d867c94242f9b 100644 --- a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -16,13 +16,15 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), -unless(isAssignmentOperator()), -unless(isComparisonOperator()), -unless(hasAnyOperatorName("&&", "||")), -hasDescendant(binaryOperator())) - .bind("binOp"), - this); + Finder->addMatcher( + binaryOperator( + unless(hasParent(binaryOperator(unless(isAssignmentOperator()), + unless(isComparisonOperator(), + unless(isAssignmentOperator()), unless(isComparisonOperator()), + unless(hasAnyOperatorName("&&", "||")), + hasDescendant(binaryOperator())) + .bind("binOp"), + this); } static int getPrecedence(const BinaryOperator *BinOp) { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 8032f0d23f494..a7530a236e9ec 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -176,6 +176,11 @@ Changes in existing checks ` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. +- Improved :doc:`readability-math-missing-parentheses + ` check by fixing + false negatives where math expressions are the operand of assignment operators + or comparison operators. + - Improved :doc:`misc-const-correctness ` check by adding the option `AllowedTypes`, that excludes specified types from const-correctness diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp index 80d2bc304bb5b..5c10ed59178d8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp @@ -157,3 +157,17 @@ namespace PR92516 { for (j = i + 1, 2; j < 1; ++j) {} } } + +namespace PR141249 { + void AssignAsParentBinOp(int* netChange, int* nums, int k, int i) { +//CHECK-MESSAGES: :[[@LINE+1]]:30: warning: '-' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] +netChange[i] = nums[i] ^ k - nums[i]; + } +} + +void CompareAsParentBinOp(int b) { + //CHECK-MESSAGES: :[[@LINE+1]]:12: warning: '*' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + if (b == 1 * 2 - 3) { + + } +} >From 855cef0a05d69a4b68f9a132918ece47c47517f6 Mon Sep 17 00:00:00 2001 From: fubowen Date: Sat, 24 May 2025 22:41:31 +0800 Subject: [PATCH 2/2] keep alpha order of note --- clang-tools-extra/docs/ReleaseNotes.rst | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a7530a236e9ec..2f859e47d0b70 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -176,11 +176,6 @@ Changes in existing checks ` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. -- Improved :doc:`readability-math-missing-parentheses - ` check by fixing - false negatives where math expressions are the operand of assignment operators - or comparison operators. - - Improved :doc:`misc-const-correctness ` check by adding the option `AllowedTypes`, that excludes specified types from const-correctness @@ -239,6 +234,11 @@ Changes in existing checks tolerating fix-it breaking compilation when functions is used as pointers to avoid matching usage of functions within the c
[clang] [ASTMatchers][NFC] fix typos in AST-matchers docs. (PR #141307)
vbvictor wrote: P.S. Found these typos using [CSpell](https://cspell.org/) utility. https://github.com/llvm/llvm-project/pull/141307 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST][NFC] fix spelling typos in clang AST files (PR #141346)
https://github.com/cor3ntin approved this pull request. https://github.com/llvm/llvm-project/pull/141346 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle Java text blocks (PR #141334)
https://github.com/mydeveloperday approved this pull request. https://github.com/llvm/llvm-project/pull/141334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ASTMatchers][NFC] fix typos in AST-matchers docs. (PR #141307)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/141307 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::count (NFC) (PR #141370)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141370.diff 1 Files Affected: - (modified) clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp (+1-5) ``diff diff --git a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp index 434c1d1526a22..4cb6bd34fa36d 100644 --- a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp +++ b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp @@ -35,11 +35,7 @@ class ResultMap { public: ResultMap(std::initializer_list> Data) - : Found(0), -Total(std::count_if(Data.begin(), Data.end(), -[](const std::pair &Pair) { - return Pair.second == true; -})), + : Found(0), Total(llvm::count(llvm::make_second_range(Data), true)), Impl(std::move(Data)) {} const bool *lookup(const CallEvent &Call) { `` https://github.com/llvm/llvm-project/pull/141370 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 1cc9e6e - [StaticAnalyzer] Use llvm::count (NFC) (#141370)
Author: Kazu Hirata Date: 2025-05-24T14:45:46-07:00 New Revision: 1cc9e6e5aa1f8a0e065f567a63516254afba6d81 URL: https://github.com/llvm/llvm-project/commit/1cc9e6e5aa1f8a0e065f567a63516254afba6d81 DIFF: https://github.com/llvm/llvm-project/commit/1cc9e6e5aa1f8a0e065f567a63516254afba6d81.diff LOG: [StaticAnalyzer] Use llvm::count (NFC) (#141370) Added: Modified: clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp Removed: diff --git a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp index 434c1d1526a22..4cb6bd34fa36d 100644 --- a/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp +++ b/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp @@ -35,11 +35,7 @@ class ResultMap { public: ResultMap(std::initializer_list> Data) - : Found(0), -Total(std::count_if(Data.begin(), Data.end(), -[](const std::pair &Pair) { - return Pair.second == true; -})), + : Found(0), Total(llvm::count(llvm::make_second_range(Data), true)), Impl(std::move(Data)) {} const bool *lookup(const CallEvent &Call) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::count (NFC) (PR #141370)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/141370 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [StaticAnalyzer] Use llvm::is_contained (NFC) (PR #141371)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/141371 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 4eb91b9 - [clang] Default-construct values with DenseMap::try_emplace (NFC) (#141373)
Author: Kazu Hirata Date: 2025-05-24T14:47:18-07:00 New Revision: 4eb91b9a6a31554ac6cb9bf211527bbcbb71ccb6 URL: https://github.com/llvm/llvm-project/commit/4eb91b9a6a31554ac6cb9bf211527bbcbb71ccb6 DIFF: https://github.com/llvm/llvm-project/commit/4eb91b9a6a31554ac6cb9bf211527bbcbb71ccb6.diff LOG: [clang] Default-construct values with DenseMap::try_emplace (NFC) (#141373) try_emplace can default-construct values, so we do not need to do so on our own. Added: Modified: clang-tools-extra/clangd/index/SymbolCollector.cpp Removed: diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index 3f5633357073d..6bdb1080fb294 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -1201,7 +1201,7 @@ void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) { } SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { - auto It = DeclToIDCache.try_emplace(D, SymbolID{}); + auto It = DeclToIDCache.try_emplace(D); if (It.second) It.first->second = getSymbolID(D); return It.first->second; @@ -1210,7 +1210,7 @@ SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) { SymbolID SymbolCollector::getSymbolIDCached(const llvm::StringRef MacroName, const MacroInfo *MI, const SourceManager &SM) { - auto It = MacroToIDCache.try_emplace(MI, SymbolID{}); + auto It = MacroToIDCache.try_emplace(MI); if (It.second) It.first->second = getSymbolID(MacroName, MI, SM); return It.first->second; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] Default-construct values with DenseMap::try_emplace (NFC) (PR #141373)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/141373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use llvm::partition_point (NFC) (PR #141351)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/141351 None >From 1d24b61eff5dc9fb25a4769166374657041808a5 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Fri, 23 May 2025 22:53:30 -0700 Subject: [PATCH] [clang] Use llvm::partition_point (NFC) --- clang/lib/Sema/SemaType.cpp| 4 ++-- clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 874e41ac0b90c..49d10f5502084 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -324,8 +324,8 @@ namespace { // FIXME: This is quadratic if we have lots of reuses of the same // attributed type. - for (auto It = std::partition_point( - AttrsForTypes.begin(), AttrsForTypes.end(), + for (auto It = llvm::partition_point( + AttrsForTypes, [=](const TypeAttrPair &A) { return A.first < AT; }); It != AttrsForTypes.end() && It->first == AT; ++It) { if (It->second) { diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 2ab248f9aa6d9..6715ab2f30b3a 100644 --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -574,8 +574,8 @@ void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM, }) && "PathDiagnostic is not partitioned so that notes precede the rest"); - PathPieces::const_iterator FirstNonNote = std::partition_point( - Path.begin(), Path.end(), [](const PathDiagnosticPieceRef &E) { + PathPieces::const_iterator FirstNonNote = + llvm::partition_point(Path, [](const PathDiagnosticPieceRef &E) { return E->getKind() == PathDiagnosticPiece::Note; }); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use llvm::partition_point (NFC) (PR #141351)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/141351.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaType.cpp (+2-2) - (modified) clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (+2-2) ``diff diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 874e41ac0b90c..49d10f5502084 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -324,8 +324,8 @@ namespace { // FIXME: This is quadratic if we have lots of reuses of the same // attributed type. - for (auto It = std::partition_point( - AttrsForTypes.begin(), AttrsForTypes.end(), + for (auto It = llvm::partition_point( + AttrsForTypes, [=](const TypeAttrPair &A) { return A.first < AT; }); It != AttrsForTypes.end() && It->first == AT; ++It) { if (It->second) { diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 2ab248f9aa6d9..6715ab2f30b3a 100644 --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -574,8 +574,8 @@ void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM, }) && "PathDiagnostic is not partitioned so that notes precede the rest"); - PathPieces::const_iterator FirstNonNote = std::partition_point( - Path.begin(), Path.end(), [](const PathDiagnosticPieceRef &E) { + PathPieces::const_iterator FirstNonNote = + llvm::partition_point(Path, [](const PathDiagnosticPieceRef &E) { return E->getKind() == PathDiagnosticPiece::Note; }); `` https://github.com/llvm/llvm-project/pull/141351 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Remove an unused local variable (NFC) (PR #141358)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/141358 Note that getTimestampFilename just constructs a file name, so it's mostly a "pure" function except possible heap allocation. >From c30f6c7c2ebe80ad84f36fd9e4172f5323779a97 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Fri, 23 May 2025 22:43:54 -0700 Subject: [PATCH] [Serialization] Remove an unused local variable (NFC) Note that getTimestampFilename just constructs a file name, so it's mostly a "pure" function except possible heap allocation. --- clang/lib/Serialization/ModuleCache.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp index 4ae49c4ec9a05..f42bdc16d815d 100644 --- a/clang/lib/Serialization/ModuleCache.cpp +++ b/clang/lib/Serialization/ModuleCache.cpp @@ -34,8 +34,6 @@ class CrossProcessModuleCache : public ModuleCache { } std::time_t getModuleTimestamp(StringRef ModuleFilename) override { -std::string TimestampFilename = -serialization::ModuleFile::getTimestampFilename(ModuleFilename); llvm::sys::fs::file_status Status; if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{}) return 0; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Remove an unused local variable (NFC) (PR #141358)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Kazu Hirata (kazutakahirata) Changes Note that getTimestampFilename just constructs a file name, so it's mostly a "pure" function except possible heap allocation. --- Full diff: https://github.com/llvm/llvm-project/pull/141358.diff 1 Files Affected: - (modified) clang/lib/Serialization/ModuleCache.cpp (-2) ``diff diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp index 4ae49c4ec9a05..f42bdc16d815d 100644 --- a/clang/lib/Serialization/ModuleCache.cpp +++ b/clang/lib/Serialization/ModuleCache.cpp @@ -34,8 +34,6 @@ class CrossProcessModuleCache : public ModuleCache { } std::time_t getModuleTimestamp(StringRef ModuleFilename) override { -std::string TimestampFilename = -serialization::ModuleFile::getTimestampFilename(ModuleFilename); llvm::sys::fs::file_status Status; if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{}) return 0; `` https://github.com/llvm/llvm-project/pull/141358 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Remove an unused local variable (NFC) (PR #141358)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Kazu Hirata (kazutakahirata) Changes Note that getTimestampFilename just constructs a file name, so it's mostly a "pure" function except possible heap allocation. --- Full diff: https://github.com/llvm/llvm-project/pull/141358.diff 1 Files Affected: - (modified) clang/lib/Serialization/ModuleCache.cpp (-2) ``diff diff --git a/clang/lib/Serialization/ModuleCache.cpp b/clang/lib/Serialization/ModuleCache.cpp index 4ae49c4ec9a05..f42bdc16d815d 100644 --- a/clang/lib/Serialization/ModuleCache.cpp +++ b/clang/lib/Serialization/ModuleCache.cpp @@ -34,8 +34,6 @@ class CrossProcessModuleCache : public ModuleCache { } std::time_t getModuleTimestamp(StringRef ModuleFilename) override { -std::string TimestampFilename = -serialization::ModuleFile::getTimestampFilename(ModuleFilename); llvm::sys::fs::file_status Status; if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{}) return 0; `` https://github.com/llvm/llvm-project/pull/141358 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [CIR] Allow use different Int types together in Vec Shift Op (PR #141111)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/14 >From 05ef5317602f61debe9a4d853e61a7e508a5a00d Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Thu, 22 May 2025 19:38:08 +0200 Subject: [PATCH 1/5] [CIR] Allow use different Int types together in Vec Shift Op --- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 +- clang/test/CIR/CodeGen/vector.cpp | 69 - 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 36dcbc6a4be4a..a49a6c4b42de0 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1427,12 +1427,12 @@ OpFoldResult cir::SelectOp::fold(FoldAdaptor adaptor) { //===--===// LogicalResult cir::ShiftOp::verify() { mlir::Operation *op = getOperation(); - mlir::Type resType = getResult().getType(); const bool isOp0Vec = mlir::isa(op->getOperand(0).getType()); const bool isOp1Vec = mlir::isa(op->getOperand(1).getType()); if (isOp0Vec != isOp1Vec) return emitOpError() << "input types cannot be one vector and one scalar"; - if (isOp1Vec && op->getOperand(1).getType() != resType) { + + if (isOp1Vec && !mlir::isa(getResult().getType())) { return emitOpError() << "shift amount must have the type of the result " << "if it is vector shift"; } diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index cdfd0b05deddb..16fd137348a95 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -396,19 +396,9 @@ void foo9() { // CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr>, ["b", init] // CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr>, ["shl", init] // CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr>, ["shr", init] -// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i -// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i -// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i -// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i -// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] : -// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr> -// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i -// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i -// CIR: %[[CONST_7:.*]] = cir.const #cir.int<7> : !s32i -// CIR: %[[CONST_8:.*]] = cir.const #cir.int<8> : !s32i -// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_6]], %[[CONST_7]], %[[CONST_8]] : -// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> // CIR: cir.store{{.*}} %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !s32i>, !cir.ptr> // CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr>, !cir.vector<4 x !s32i> // CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr>, !cir.vector<4 x !s32i> @@ -449,6 +439,61 @@ void foo9() { // OGCG: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]] // OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16 +void foo10() { + vi4 a = {1, 2, 3, 4}; + uvi4 b = {5u, 6u, 7u, 8u}; + + vi4 shl = a << b; + uvi4 shr = b >> a; +} + +// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr>, ["a", init] +// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr>, ["b", init] +// CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr>, ["shl", init] +// CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr>, ["shr", init] +// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: cir.store %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr> +// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : !u32i, !u32i, !u32i, !u32i) : !cir.vector<4 x !u32i> +// CIR: cir.store %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !u32i>, !cir.ptr> +// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr>, !cir.vector<4 x !s32i> +// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr>, !cir.vector<4 x !u32i> +// CIR: %[[SHL:.*]] = cir.shift(left, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[TMP_B]] : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !s32i> +// CIR: cir.store %[[SHL]], %[[SHL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr> +// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr>, !cir.vector<4 x !u32i> +// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.p
[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/139859 >From f3201c1089203963f8cb73c58ea498a84848dd88 Mon Sep 17 00:00:00 2001 From: Rajveer Date: Wed, 14 May 2025 13:44:31 +0530 Subject: [PATCH] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks Resolves #138939 When enabling `--fno-exceptions` flag, discarded statements containing `try/catch/throw` in an independent context can be avoided from being rejected. --- clang/include/clang/Sema/Sema.h | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 5 ++--- clang/lib/Sema/SemaStmt.cpp | 13 ++--- clang/lib/Sema/TreeTransform.h | 14 ++ clang/test/SemaCXX/no-exceptions.cpp | 25 - 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6ea7ee281e14d..ebb40498e11aa 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11154,6 +11154,8 @@ class Sema final : public SemaBase { StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef Handlers); + void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry); + StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b2a982e953012..5383153728468 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -853,10 +853,9 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); // Don't report an error if 'throw' is used in system headers or in an OpenMP // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { + if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; +DiagnoseExceptionUse(OpLoc, /* IsTry */ false); } // In OpenMP target regions, we replace 'throw' with a trap on GPU targets. diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e8c1f8490342a..eea50e66484da 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4304,10 +4304,9 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); // Don't report an error if 'try' is used in system headers or in an OpenMP // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) { + if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) { // Delay error emission for the OpenMP device code. -targetDiag(TryLoc, diag::err_exceptions_disabled) << "try"; +DiagnoseExceptionUse(TryLoc, /* IsTry */ true); } // In OpenMP target regions, we assume that catch is never reached on GPU @@ -4410,6 +4409,14 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, Handlers); } +void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) { + if (!getLangOpts().CXXExceptions && + !getSourceManager().isInSystemHeader(Loc) && + !CurContext->isDependentContext()) { +targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw"); + } +} + StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler) { assert(TryBlock && Handler); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 335e21d927b76..8b663b2c6240b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9162,6 +9162,13 @@ StmtResult TreeTransform::TransformCXXTryStmt(CXXTryStmt *S) { Handlers.push_back(Handler.getAs()); } + const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple(); + const bool IsOpenMPGPUTarget = getSema().getLangOpts().OpenMPIsTargetDevice && + (T.isNVPTX() || T.isAMDGCN()); + + if (!IsOpenMPGPUTarget && !getSema().getLangOpts().CUDA) +getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry */ true); + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && !HandlerChanged) return S; @@ -14384,6 +14391,13 @@ TreeTransform::TransformCXXThrowExpr(CXXThrowExpr *E) { if (SubExpr.isInvalid()) return ExprError(); + const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple(); + const bool IsOp
[clang] [llvm] Add macro to suppress -Wunnecessary-virtual-specifier (PR #139614)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `clang-with-lto-ubuntu` running on `as-worker-91` while building `clang,llvm` at step 6 "build-stage1-compiler". Full details are available at: https://lab.llvm.org/buildbot/#/builders/49/builds/1544 Here is the relevant piece of the build log for the reference ``` Step 6 (build-stage1-compiler) failure: build (failure) 0.019 [6494/72/1] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/AutoConvert.cpp.o 0.021 [6493/72/2] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o FAILED: lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/build/stage1/lib/Support -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/build/stage1/include -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17 -fno-exceptions -funwind-tables -fno-rtti -MD -MT lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o -MF lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o.d -o lib/Support/CMakeFiles/LLVMSupport.dir/COM.cpp.o -c /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support/COM.cpp In file included from /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include/llvm/Support/COM.h:17, from /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support/COM.cpp:13: /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include/llvm/Support/Compiler.h:719:40: error: missing binary operator before token "(" 719 | #if defined(__clang__) && __has_warning("-Wunnecessary-virtual-specifier") |^ 0.022 [6493/71/3] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/ABIBreak.cpp.o 0.031 [6493/70/4] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/ExtensibleRTTI.cpp.o FAILED: lib/Support/CMakeFiles/LLVMSupport.dir/ExtensibleRTTI.cpp.o /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/build/stage1/lib/Support -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/build/stage1/include -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17 -fno-exceptions -funwind-tables -fno-rtti -MD -MT lib/Support/CMakeFiles/LLVMSupport.dir/ExtensibleRTTI.cpp.o -MF lib/Support/CMakeFiles/LLVMSupport.dir/ExtensibleRTTI.cpp.o.d -o lib/Support/CMakeFiles/LLVMSupport.dir/ExtensibleRTTI.cpp.o -c /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support/ExtensibleRTTI.cpp In file included from /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include/llvm/Support/ExtensibleRTTI.h:63, from /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/lib/Support/ExtensibleRTTI.cpp:9: /home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-project/llvm/include/llvm/Support/Compiler.h:719:40: error: missing binary operator before token "(" 719 | #if defined(__clang__) && __has_warning("-Wunnecessary-virtual-specifier") |^ 0.240 [6493/69/5] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/DivisionByConstantInfo.cpp.o FAILED: lib/Support/CMakeFiles/LLVMSupport.dir/DivisionByConstantInfo.cpp.o /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/build/stage1/lib/Support -I/home/buildbot/as-worker-91/clang-with-lto-ubuntu/llvm-pr
[clang] [libcxx] [Clang] Add __builtin_common_reference (PR #121199)
@@ -3231,6 +3241,230 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate, } } +static QualType CopyCV(QualType From, QualType To) { + if (From.isConstQualified()) +To.addConst(); + if (From.isVolatileQualified()) +To.addVolatile(); + return To; +} + +// COND-RES(X, Y) be decltype(false ? declval()() : declval()()) +static QualType CondRes(Sema &S, QualType X, QualType Y, SourceLocation Loc) { + EnterExpressionEvaluationContext UnevaluatedContext( + S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); + Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); + + // false + OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy, VK_PRValue); + ExprResult Cond = &CondExpr; + + // declval()() + OpaqueValueExpr LHSExpr(Loc, X.getNonLValueExprType(S.Context), + Expr::getValueKindForType(X)); + ExprResult LHS = &LHSExpr; + + // declval()() + OpaqueValueExpr RHSExpr(Loc, Y.getNonLValueExprType(S.Context), + Expr::getValueKindForType(Y)); + ExprResult RHS = &RHSExpr; + + ExprValueKind VK = VK_PRValue; + ExprObjectKind OK = OK_Ordinary; + + // decltype(false ? declval()() : declval()()) + QualType Result = S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, Loc); + + if (SFINAE.hasErrorOccurred()) +return QualType(); + if (VK == VK_LValue) +return S.BuiltinAddLValueReference(Result, Loc); + if (VK == VK_XValue) +return S.BuiltinAddRValueReference(Result, Loc); + return Result; +} + +static QualType CommonRef(Sema &S, QualType A, QualType B, SourceLocation Loc) { + // Given types A and B, let X be remove_reference_t, let Y be + // remove_reference_t, and let COMMON-REF(A, B) be: + assert(A->isReferenceType() && B->isReferenceType() && + "A and B have to be ref qualified for a COMMON-REF"); + auto X = A.getNonReferenceType(); + auto Y = B.getNonReferenceType(); + + // If A and B are both lvalue reference types, COMMON-REF(A, B) is + // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) if that type exists and is a + // reference type. + if (A->isLValueReferenceType() && B->isLValueReferenceType()) { +auto CR = CondRes(S, S.BuiltinAddLValueReference(CopyCV(X, Y), Loc), + S.BuiltinAddLValueReference(CopyCV(Y, X), Loc), Loc); +if (CR.isNull() || !CR->isReferenceType()) + return QualType(); +return CR; + } + + // Otherwise, let C be remove_reference_t&&. If A and B + // are both rvalue reference types, C is well-formed, and + // is_convertible_v && is_convertible_v is true, then + // COMMON-REF(A, B) is C. + if (A->isRValueReferenceType() && B->isRValueReferenceType()) { +auto C = CommonRef(S, S.BuiltinAddLValueReference(X, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (C.isNull()) + return QualType(); + +C = C.getNonReferenceType(); + +if (S.BuiltinIsConvertible(A, C, Loc) && S.BuiltinIsConvertible(B, C, Loc)) + return S.BuiltinAddRValueReference(C, Loc); +return QualType(); + } + + // Otherwise, if A is an lvalue reference and B is an rvalue reference, then + // COMMON-REF(A, B) is COMMON-REF(B, A). + if (A->isLValueReferenceType() && B->isRValueReferenceType()) +std::swap(A, B); + + // Otherwise, let D be COMMON-REF(const X&, Y&). If A is an rvalue reference + // and B is an lvalue reference and D is well-formed and + // is_convertible_v is true, then COMMON-REF(A, B) is D. + if (A->isRValueReferenceType() && B->isLValueReferenceType()) { +auto X2 = X; +X2.addConst(); +auto D = CommonRef(S, S.BuiltinAddLValueReference(X2, Loc), + S.BuiltinAddLValueReference(Y, Loc), Loc); +if (!D.isNull() && S.BuiltinIsConvertible(A, D, Loc)) + return D; +return QualType(); + } + + // Otherwise, COMMON-REF(A, B) is ill-formed. + // This is implemented by returning from the individual branches above. + + llvm_unreachable("The above cases should be exhaustive"); +} + +static QualType builtinCommonReferenceImpl(Sema &S, + TemplateName CommonReference, + TemplateName CommonType, + SourceLocation TemplateLoc, + ArrayRef Ts) { + switch (Ts.size()) { + // If sizeof...(T) is zero, there shall be no member type. + case 0: +return QualType(); + + // Otherwise, if sizeof...(T) is one, let T0 denote the sole type in the + // pack T. The member typedef type shall denote the same type as T0. + case 1: +return Ts[0].getAsType(); + + // Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in + // the pack T. Then + case 2: { +auto T1 = Ts[0].getAsType(); +auto T2 = Ts[1].getAsType(); + +// Let R be COMMON-REF(T1, T2). If T1 and T2 are reference ty
[clang] [CMake][Release] Build with -ffat-lto-objects (PR #140381)
https://github.com/nikic commented: This is an improvement, but should we also strip the bitcode? Otherwise people will still get errors if they try to use the archives if their host clang version is older. https://github.com/llvm/llvm-project/pull/140381 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
https://github.com/vbvictor requested changes to this pull request. https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
@@ -164,6 +165,24 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) { static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, ArrayRef Indexes, const ASTContext &Ctx) { + const auto GetCommaLoc = [&](SourceLocation BeginLoc, vbvictor wrote: Nit suggestion: as far as I can see, we only need `Ctx` here, so no point in capturing all variables. ```suggestion const auto GetCommaLoc = [&Ctx](SourceLocation BeginLoc, ``` https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix false positives with deducing this in `readability-convert-member-functions-to-static` check (PR #141391)
@@ -0,0 +1,14 @@ +// RUN: %check_clang_tidy -std=c++23 %s readability-convert-member-functions-to-static %t + +namespace std{ + class string {}; + void println(const char *format, const std::string &str) {} +} + +namespace PR141381 { +struct Hello { + std::string str_; + + void hello(this Hello &self) { std::println("Hello, {0}!", self.str_); } vbvictor wrote: Please add tests: - with some are other parameters. - unnamed object parameter (see p.5 of https://en.cppreference.com/w/cpp/language/function#Parameter_list) - with `this Hello self`, `this Hello&& self`, `template void hello(this Self&& self);` https://github.com/llvm/llvm-project/pull/141391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix false positives with deducing this in `readability-convert-member-functions-to-static` check (PR #141391)
https://github.com/vbvictor requested changes to this pull request. https://github.com/llvm/llvm-project/pull/141391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
@@ -148,6 +148,9 @@ New check aliases Changes in existing checks ^^ +- Improved :doc:`boost-use-ranges + ` check to more precisely remove comma. vbvictor wrote: In discussion, I saw that we don't need release notes for this change. However, if there is a note, then it should also state that this change only affects `clangd`. ```suggestion ` check to more precisely remove comma when creating fix-its with :program:`clangd` code action. ``` Note that lines should be no more than 80 characters long. https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][clangd] Fixed removeFunctionArgs don't remove comma for use-ranges check (PR #118568)
@@ -164,6 +165,24 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) { static void removeFunctionArgs(DiagnosticBuilder &Diag, const CallExpr &Call, ArrayRef Indexes, const ASTContext &Ctx) { + const auto GetCommaLoc = [&](SourceLocation BeginLoc, + SourceLocation EndLoc) -> CharSourceRange { +const SourceLocation CommaLoc = +lexer::findNextAnyTokenKind(BeginLoc, Ctx.getSourceManager(), +Ctx.getLangOpts(), tok::comma, tok::comma); + +const std::optional NextTok = lexer::findNextTokenIncludingComments( +CommaLoc, Ctx.getSourceManager(), Ctx.getLangOpts()); + +if (!NextTok) { + return {}; +} vbvictor wrote: ```suggestion if (!NextTok) return {}; ``` Don't use braces around single-statement if's as (LLVM coding guide) https://github.com/llvm/llvm-project/pull/118568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix false positives with deducing this in `readability-convert-member-functions-to-static` check (PR #141391)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/141391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Clean up the fix for deferred access checking (PR #141340)
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/141340 https://github.com/llvm/llvm-project/commit/200f3bd39562f4d605f13567398025d30fa27d61 introduced a parsing scope to avoid deferring access checking for friend declarations. That turned out to be insufficient because it only sets up the scope until we see the friend keyword, which can be bypassed if the declaration occurs before the keyword. That said, based on the discussion in https://github.com/llvm/llvm-project/issues/12361, we still want to preserve the fix since a friend function declaration doesn't grant the access to other redeclarations. This patch implemented it by not considering the friend declaration functions as effective contexts. So we don't end up checking the canonical function declaration when we're supposed to check only non-function friend declarations. >From 57fd785b2dde19e287c2478644312bc112db3045 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Sat, 24 May 2025 16:02:15 +0800 Subject: [PATCH 1/2] Revert "[Clang][Sema] access checking of friend declaration should not be delayed (#91430)" This reverts commit 200f3bd39562f4d605f13567398025d30fa27d61. --- clang/include/clang/Sema/Scope.h | 6 -- clang/lib/Parse/ParseDecl.cpp| 7 ++- clang/lib/Sema/Scope.cpp | 1 - clang/lib/Sema/SemaAccess.cpp| 30 +- clang/test/SemaCXX/PR12361.cpp | 30 -- 5 files changed, 7 insertions(+), 67 deletions(-) delete mode 100644 clang/test/SemaCXX/PR12361.cpp diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index ad12a3d73413b..77497918f54eb 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -160,9 +160,6 @@ class Scope { /// This is a scope of type alias declaration. TypeAliasScope = 0x2000, - -/// This is a scope of friend declaration. -FriendScope = 0x4000, }; private: @@ -590,9 +587,6 @@ class Scope { /// Determine whether this scope is a type alias scope. bool isTypeAliasScope() const { return getFlags() & Scope::TypeAliasScope; } - /// Determine whether this scope is a friend scope. - bool isFriendScope() const { return getFlags() & Scope::FriendScope; } - /// Returns if rhs has a higher scope depth than this. /// /// The caller is responsible for calling this only if one of the two scopes diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 7a87cd2e340cc..bcebf14aa4fdc 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4219,12 +4219,9 @@ void Parser::ParseDeclarationSpecifiers( // friend case tok::kw_friend: - if (DSContext == DeclSpecContext::DSC_class) { + if (DSContext == DeclSpecContext::DSC_class) isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID); -Scope *CurS = getCurScope(); -if (!isInvalid && CurS) - CurS->setFlags(CurS->getFlags() | Scope::FriendScope); - } else { + else { PrevSpec = ""; // not actually used by the diagnostic DiagID = diag::err_friend_invalid_in_context; isInvalid = true; diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index 5bc7e79a68186..ec7fd92f53e6e 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -233,7 +233,6 @@ void Scope::dumpImpl(raw_ostream &OS) const { {LambdaScope, "LambdaScope"}, {OpenACCComputeConstructScope, "OpenACCComputeConstructScope"}, {TypeAliasScope, "TypeAliasScope"}, - {FriendScope, "FriendScope"}, }; for (auto Info : FlagInfo) { diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 890df09157aa0..92da29b47dbf7 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -1469,32 +1469,12 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, // specifier, like this: // A::private_type A::foo() { ... } // - // friend declaration should not be delayed because it may lead to incorrect - // redeclaration chain, such as: - // class D { - //class E{ - // class F{}; - // friend void foo(D::E::F& q); - //}; - //friend void foo(D::E::F& q); - // }; + // Or we might be parsing something that will turn out to be a friend: + // void foo(A::private_type); + // void B::foo(A::private_type); if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { -// [class.friend]p9: -// A member nominated by a friend declaration shall be accessible in the -// class containing the friend declaration. The meaning of the friend -// declaration is the same whether the friend declaration appears in the -// private, protected, or public ([class.mem]) portion of the class -// member-specification. -Scope *TS = S.getCurScope(); -bool IsFriendDeclaration = false; -while (TS && !IsFriendDeclaration) { - IsFriend