[libunwind] [libunwind] Make sure `__STDC_FORMAT_MACROS` is defined to ensure `PRId64` is available (PR #117491)
MaskRay wrote: What old GCC versions need this? If it's just GCC 8, it's possible that we will drop GCC buildability soon. I think for runtime libraries we could pose a stricter requirement. https://github.com/llvm/llvm-project/pull/117491 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support symbolTags for document symbol (PR #113669)
chouzz wrote: @HighCommander4 Just try to avoid building clangd locally. https://github.com/llvm/llvm-project/pull/113669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix incorrect inferred lifetime_capture_by attr on STL (PR #118013)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/118013 >From feb9445efffa69c158407bda6f5981a033197567 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 28 Nov 2024 14:27:23 +0100 Subject: [PATCH 1/3] [clang] NFC, simplify the attr-lifetime-capture-by.test --- clang/test/AST/attr-lifetime-capture-by.cpp | 66 + 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/clang/test/AST/attr-lifetime-capture-by.cpp b/clang/test/AST/attr-lifetime-capture-by.cpp index c3afe267301ad7..3f22322719b6ab 100644 --- a/clang/test/AST/attr-lifetime-capture-by.cpp +++ b/clang/test/AST/attr-lifetime-capture-by.cpp @@ -37,67 +37,56 @@ struct vector { struct [[gsl::Pointer()]] View {}; std::vector views; // CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'View' -// CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (const View &)' -// CHECK: ParmVarDecl {{.*}} 'const View &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'const View &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} push_back 'void (View &&)' -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, View &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit template struct [[gsl::Pointer()]] ViewTemplate {}; std::vector> templated_views; -// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'ViewTemplate' -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation // CHECK: CXXMethodDecl {{.*}} push_back 'void (const ViewTemplate &)' -// CHECK: ParmVarDecl {{.*}} 'const ViewTemplate &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'const ViewTemplate &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (ViewTemplate &&)' -// CHECK: ParmVarDecl {{.*}} 'ViewTemplate &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, ViewTemplate &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}} 'ViewTemplate &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit std::vector pointers; // CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'int *' -// CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (int *const &)' -// CHECK: ParmVarDecl {{.*}} 'int *const &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'int *const &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} push_back 'void (int *&&)' -// CHECK: ParmVarDecl {{.*}} 'int *&&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int *&&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}}
[clang] [clang] Fix incorrect inferred lifetime_capture_by attr on STL (PR #118013)
@@ -37,67 +37,56 @@ struct vector { struct [[gsl::Pointer()]] View {}; std::vector views; // CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'View' -// CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (const View &)' -// CHECK: ParmVarDecl {{.*}} 'const View &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'const View &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} push_back 'void (View &&)' -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, View &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NOT: LifetimeCaptureByAttr {{.*}} Implicit hokein wrote: ah, right, this is even better. Done. https://github.com/llvm/llvm-project/pull/118013 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix incorrect inferred lifetime_capture_by attr on STL (PR #118013)
hokein wrote: > Can you also add a lit test for: > > ```c++ > std::vector getVector(); > std::set s; > s.insert(getVector().begin(), getVector().end()); // FIXME: taking iterator > of a temporary container without immediate dereference is almost always wrong. > ``` I think this is a different issue, I'd prefer not adding it to this test file. https://github.com/llvm/llvm-project/pull/118013 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Avoid creating LazyCompoundVal when possible (PR #116840)
steakhal wrote: I held this patch off because during testing I saw some interesting-looking (seemingly) FPs. I wanted to have a look, but I couldn't find disputable evidence for proving that they were FPs. I still believe that this patch is solid, and even if it exposes some FPs, those are more likely to be caused by some other bug. We may need to come back to this, or any other patch related to LCVs and copying structs prior the next release. Keep in mind this. https://github.com/llvm/llvm-project/pull/116840 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Avoid creating LazyCompoundVal when possible (PR #116840)
https://github.com/steakhal closed https://github.com/llvm/llvm-project/pull/116840 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 352f868 - [clang] Fix incorrect inferred lifetime_capture_by attr on STL (#118013)
Author: Haojian Wu Date: 2024-11-29T09:23:27+01:00 New Revision: 352f8688d0ca250c9e8774321f6c3bcd4298cc09 URL: https://github.com/llvm/llvm-project/commit/352f8688d0ca250c9e8774321f6c3bcd4298cc09 DIFF: https://github.com/llvm/llvm-project/commit/352f8688d0ca250c9e8774321f6c3bcd4298cc09.diff LOG: [clang] Fix incorrect inferred lifetime_capture_by attr on STL (#118013) We incorrectly annotate the iterator parameter for `insert` method (`void insert(const_iterator, const value_type& value)`), because iterator is also a gsl-pointer type. This patch fixes it. Added: Modified: clang/lib/Sema/SemaAttr.cpp clang/test/AST/attr-lifetime-capture-by.cpp Removed: diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index b0849c74e375ed..d3cf42251be2e7 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -287,7 +287,12 @@ void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) { if (PVD->hasAttr()) return; for (ParmVarDecl *PVD : MD->parameters()) { -if (sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { +// Methods in standard containers that capture values typically accept +// reference-type parameters, e.g., `void push_back(const T& value)`. +// We only apply the lifetime_capture_by attribute to parameters of +// pointer-like reference types (`const T&`, `T&&`). +if (PVD->getType()->isReferenceType() && +sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; PVD->addAttr( LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); diff --git a/clang/test/AST/attr-lifetime-capture-by.cpp b/clang/test/AST/attr-lifetime-capture-by.cpp index c3afe267301ad7..debad9b7204d72 100644 --- a/clang/test/AST/attr-lifetime-capture-by.cpp +++ b/clang/test/AST/attr-lifetime-capture-by.cpp @@ -37,67 +37,53 @@ struct vector { struct [[gsl::Pointer()]] View {}; std::vector views; // CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'View' -// CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (const View &)' -// CHECK: ParmVarDecl {{.*}} 'const View &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'const View &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} push_back 'void (View &&)' -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, View &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}} 'View &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit template struct [[gsl::Pointer()]] ViewTemplate {}; std::vector> templated_views; -// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation -// CHECK: TemplateArgument type 'ViewTemplate' -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation // CHECK: CXXMethodDecl {{.*}} push_back 'void (const ViewTemplate &)' -// CHECK: ParmVarDecl {{.*}} 'const ViewTemplate &' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'const ViewTemplate &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} push_back 'void (ViewTemplate &&)' -// CHECK: ParmVarDecl {{.*}} 'ViewTemplate &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, ViewTemplate &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK: ParmVarDecl {{.*}} 'ViewTemplate &&' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit -// CHECK-NOT: LifetimeCaptureByAttr +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NEXT:
[clang] [clang] Fix incorrect inferred lifetime_capture_by attr on STL (PR #118013)
https://github.com/hokein closed https://github.com/llvm/llvm-project/pull/118013 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format][CMake] Generate formatting options docs during build (PR #113739)
boomanaiden154 wrote: > I'd personally like a solution that doesn't remove the > ClangFormatStyleOptions.rst from the review Could we just test that the output looks as expected? I think it would be pretty easy to write a lit test that asserts all of the output is as expected. That would then show up in review. It would be a bit of a hack, but it would solve the original problem, making sure that the docs actually get updated with the script automatically, and that things show up in review. https://github.com/llvm/llvm-project/pull/113739 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenCL][AMDGPU] Allow a kernel to call another kernel (PR #115821)
@@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -emit-llvm -o - %s | FileCheck %s lalaniket8 wrote: The `update_cc_test_checks.py ` script iterates over clang AST generated by the provided runline. Since the stub variant are not present in the AST (emitted to IR), the script does not generate check lines to detect the stub variants, namely, `__clang_ocl_kern_imp_callee_kern` and `__clang_ocl_kern_imp_ext_callee_kern` https://github.com/llvm/llvm-project/pull/115821 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenCL][AMDGPU] Allow a kernel to call another kernel (PR #115821)
https://github.com/lalaniket8 edited https://github.com/llvm/llvm-project/pull/115821 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/vgvassilev approved this pull request. LGTM, with my suggestion. https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
@@ -69,27 +95,30 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::inconvertibleErrorCode()); } - OutputFile.close(); + ObjectFileOutput.close(); std::vector LinkerArgs = {"wasm-ld", "-shared", "--import-memory", - "--no-entry", - "--export-all", "--experimental-pic", "--stack-first", "--allow-undefined", - OutputFileName.c_str(), + ObjectFileName.c_str(), "-o", - OutputFileName.c_str()}; - int Result = - lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false); - if (!Result) + BinaryFileName.c_str()}; + + const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link}; + std::vector WasmDriverArgs; + WasmDriverArgs.push_back(WasmDriver); + lld::Result Result = + lld::lldMain(LinkerArgs, llvm::outs(), llvm::errs(), WasmDriverArgs); + + if (Result.retCode != 0) vgvassilev wrote: ```suggestion if (Result.retCode) ``` https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/vgvassilev milestoned https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/vgvassilev edited https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9b2ec87 - [analyzer] Avoid creating LazyCompoundVal when possible (#116840)
Author: Balazs Benics Date: 2024-11-29T09:19:33+01:00 New Revision: 9b2ec87f5bce57cc900cf52a99f805d999716053 URL: https://github.com/llvm/llvm-project/commit/9b2ec87f5bce57cc900cf52a99f805d999716053 DIFF: https://github.com/llvm/llvm-project/commit/9b2ec87f5bce57cc900cf52a99f805d999716053.diff LOG: [analyzer] Avoid creating LazyCompoundVal when possible (#116840) In #115916 I allowed copying empty structs. Later in #115917 I changed how objects are copied, and basically when we would want to copy a struct (an LCV) of a single symbol (likely coming from an opaque fncall or invalidation), just directly bind that symbol instead of creating an LCV referring to the symbol. This was an optimization to skip a layer of indirection. Now, it turns out I should have apply the same logic in #115916. I should not have just blindly created an LCV by calling `createLazyBinding()`, but rather check if I can apply the shortcut described in #115917 and only create the LCV if the shortcut doesn't apply. In this patch I check if there is a single default binding that the copy would refer to and if so, just return that symbol instead of creating an LCV. There shouldn't be any observable changes besides that we should have fewer LCVs. This change may surface bugs in checkers that were associating some metadata with entities in a wrong way. Notably, STLAlgorithmModeling and DebugIteratorModeling checkers would likely stop working after this change. I didn't investigate them deeply because they were broken even prior to this patch. Let me know if I should migrate these checkers to be just as bugged as they were prior to this patch - thus make the tests pass. Added: Modified: clang/lib/StaticAnalyzer/Core/RegionStore.cpp clang/test/Analysis/ctor-trivial-copy.cpp clang/test/Analysis/explain-svals.cpp clang/test/Analysis/iterator-modeling.cpp clang/test/Analysis/stl-algorithm-modeling-aggressive-std-find-modeling.cpp clang/test/Analysis/stl-algorithm-modeling.cpp clang/test/Analysis/template-param-objects.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 46e294a1741cfe..ad45ab5757a5ac 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -608,6 +608,8 @@ class RegionStoreManager : public StoreManager { return getBinding(getRegionBindings(S), L, T); } + std::optional getUniqueDefaultBinding(RegionBindingsConstRef B, + const TypedValueRegion *R) const; std::optional getUniqueDefaultBinding(nonloc::LazyCompoundVal LCV) const; @@ -2349,6 +2351,11 @@ SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, // behavior doesn't depend on the struct layout. // This way even an empty struct can carry taint, no matter if creduce drops // the last field member or not. + + // Try to avoid creating a LCV if it would anyways just refer to a single + // default binding. + if (std::optional Val = getUniqueDefaultBinding(B, R)) +return *Val; return createLazyBinding(B, R); } @@ -2609,14 +2616,12 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B, } std::optional -RegionStoreManager::getUniqueDefaultBinding(nonloc::LazyCompoundVal LCV) const { - const MemRegion *BaseR = LCV.getRegion(); - - // We only handle base regions. - if (BaseR != BaseR->getBaseRegion()) +RegionStoreManager::getUniqueDefaultBinding(RegionBindingsConstRef B, +const TypedValueRegion *R) const { + if (R != R->getBaseRegion()) return std::nullopt; - const auto *Cluster = getRegionBindings(LCV.getStore()).lookup(BaseR); + const auto *Cluster = B.lookup(R); if (!Cluster || !llvm::hasSingleElement(*Cluster)) return std::nullopt; @@ -2624,6 +2629,12 @@ RegionStoreManager::getUniqueDefaultBinding(nonloc::LazyCompoundVal LCV) const { return Key.isDirect() ? std::optional{} : Value; } +std::optional +RegionStoreManager::getUniqueDefaultBinding(nonloc::LazyCompoundVal LCV) const { + RegionBindingsConstRef B = getRegionBindings(LCV.getStore()); + return getUniqueDefaultBinding(B, LCV.getRegion()); +} + std::optional RegionStoreManager::tryBindSmallStruct( RegionBindingsConstRef B, const TypedValueRegion *R, const RecordDecl *RD, nonloc::LazyCompoundVal LCV) { diff --git a/clang/test/Analysis/ctor-trivial-copy.cpp b/clang/test/Analysis/ctor-trivial-copy.cpp index 41d0d97161bba1..45c8ca4c517762 100644 --- a/clang/test/Analysis/ctor-trivial-copy.cpp +++ b/clang/test/Analysis/ctor-trivial-copy.cpp @@ -3,8 +3,10 @@ void clang_analyzer_printState(); -template void clang_analyzer_dump_lref(T&); -template void clang_analyzer_dump_val(T); +template void clang_analyzer_dump_lref(T& param); +template void
[clang] [Clang][OpenCL][AMDGPU] Allow a kernel to call another kernel (PR #115821)
https://github.com/lalaniket8 updated https://github.com/llvm/llvm-project/pull/115821 >From 107f8dbc6b2fa157ce3936a086093882012b9d62 Mon Sep 17 00:00:00 2001 From: anikelal Date: Mon, 25 Nov 2024 14:18:36 +0530 Subject: [PATCH 1/2] [Clang][OpenCL][AMDGPU] Allow a kernel to call another kernel This feature is currently not supported in the compiler. To facilitate this we emit a stub version of each kernel function body with different name mangling scheme, and replaces the respective kernel call-sites appropriately. Fixes https://github.com/llvm/llvm-project/issues/60313 D120566 was an earlier attempt made to upstream a solution for this issue. --- clang/include/clang/AST/GlobalDecl.h | 37 + clang/lib/AST/Expr.cpp| 3 +- clang/lib/AST/ItaniumMangle.cpp | 15 ++ clang/lib/AST/Mangle.cpp | 2 +- clang/lib/AST/MicrosoftMangle.cpp | 6 +++ clang/lib/CodeGen/CGBlocks.cpp| 16 +++--- clang/lib/CodeGen/CGCall.cpp | 11 +++- clang/lib/CodeGen/CGExpr.cpp | 5 +- clang/lib/CodeGen/CGOpenCLRuntime.cpp | 11 +++- clang/lib/CodeGen/CGOpenCLRuntime.h | 4 +- clang/lib/CodeGen/CodeGenModule.cpp | 7 +++ .../test/CodeGenOpenCL/opencl-kernel-call.cl | 43 +++ clang/test/CodeGenOpenCL/reflect.cl | 2 +- clang/test/CodeGenOpenCL/spir-calling-conv.cl | 4 +- clang/test/CodeGenOpenCL/visibility.cl| 53 ++- 15 files changed, 178 insertions(+), 41 deletions(-) create mode 100644 clang/test/CodeGenOpenCL/opencl-kernel-call.cl diff --git a/clang/include/clang/AST/GlobalDecl.h b/clang/include/clang/AST/GlobalDecl.h index 386693cabb1fbb..8a9f4b4c60e5e5 100644 --- a/clang/include/clang/AST/GlobalDecl.h +++ b/clang/include/clang/AST/GlobalDecl.h @@ -71,6 +71,10 @@ class GlobalDecl { GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0) : MultiVersionIndex(MVIndex) { if (!D->hasAttr()) { + if (D->hasAttr()) { +Value.setPointerAndInt(D, unsigned(KernelReferenceKind::Kernel)); +return; + } Init(D); return; } @@ -78,7 +82,8 @@ class GlobalDecl { } GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind) : Value(D, unsigned(Kind)) { -assert(D->hasAttr() && "Decl is not a GPU kernel!"); +assert((D->hasAttr() && "Decl is not a GPU kernel!") || + (D->hasAttr() && "Decl is not a OpenCL kernel!")); } GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } @@ -130,13 +135,15 @@ class GlobalDecl { } KernelReferenceKind getKernelReferenceKind() const { -assert(((isa(getDecl()) && - cast(getDecl())->hasAttr()) || -(isa(getDecl()) && - cast(getDecl()) - ->getTemplatedDecl() - ->hasAttr())) && - "Decl is not a GPU kernel!"); +assertisa(getDecl()) && + cast(getDecl())->hasAttr()) || + (isa(getDecl()) && + cast(getDecl()) + ->getTemplatedDecl() + ->hasAttr())) && +"Decl is not a GPU kernel!") || + (isDeclOpenCLKernel() && "Decl is not a OpenCL kernel!")); + return static_cast(Value.getInt()); } @@ -196,13 +203,21 @@ class GlobalDecl { } GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) { -assert(isa(getDecl()) && - cast(getDecl())->hasAttr() && - "Decl is not a GPU kernel!"); +assert((isa(getDecl()) && +cast(getDecl())->hasAttr() && +"Decl is not a GPU kernel!") || + (isDeclOpenCLKernel() && "Decl is not a OpenCL kernel!")); GlobalDecl Result(*this); Result.Value.setInt(unsigned(Kind)); return Result; } + + bool isDeclOpenCLKernel() const { +auto FD = dyn_cast(getDecl()); +if (FD) + return FD->hasAttr(); +return FD; + } }; } // namespace clang diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index a4fb4d5a1f2ec4..ddd88ac6a21050 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -693,7 +693,8 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, GD = GlobalDecl(CD, Ctor_Base); else if (const CXXDestructorDecl *DD = dyn_cast(ND)) GD = GlobalDecl(DD, Dtor_Base); -else if (ND->hasAttr()) +else if (ND->hasAttr() || + ND->hasAttr()) GD = GlobalDecl(cast(ND)); else GD = GlobalDecl(ND); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 27a993a631dae9..7e46d6c520fb69 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -526,6 +526,7 @@ class CXXNameMangler { void mangleSourceName(const IdentifierInfo *II); void mangleRegCallName(const IdentifierInfo *II); void
[clang-tools-extra] [clangd] Support symbolTags for document symbol (PR #113669)
travkin79 wrote: Hi @chouzz, > @HighCommander4 Just try to avoid building clangd locally. I built your branch of llvm / clangd locally. I did the following on a linux machine * do a shallow clone `git clone -b support-symbolTags --depth 1 g...@github.com:chouzz/llvm-project.git` * prepare the build for Eclipse IDE and an install path `/usr/local/clangd-test/bin` (I did use this path to keep the original installed clangd version unchanged) `cmake -S llvm -B build -G "Eclipse CDT4 - Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_INSTALL_PREFIX=/usr/local/clangd-test -DCMAKE_BUILD_TYPE=Release` * build with `cmake --build build --target clangd` * optionally run the tests (I skipped that) `cmake --build build --target check-clangd` * optionally install `cmake --build build --target install` I must admit, it takes some time to clone and especially to build the project. https://github.com/llvm/llvm-project/pull/113669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Format bitfield width diagnostics with thousands-separators (PR #117763)
Timm =?utf-8?q?Bäder?= Message-ID: In-Reply-To: tbaederr wrote: Is the lifetime for the APSInt here OK? When I call `Diag()`, will the be diagnostic emitted immediately? Or does the APSInt need to life longer? https://github.com/llvm/llvm-project/pull/117763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenCL][AMDGPU] Allow a kernel to call another kernel (PR #115821)
@@ -196,13 +203,21 @@ class GlobalDecl { } GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) { -assert(isa(getDecl()) && - cast(getDecl())->hasAttr() && - "Decl is not a GPU kernel!"); +assert((isa(getDecl()) && +cast(getDecl())->hasAttr() && +"Decl is not a GPU kernel!") || + (isDeclOpenCLKernel() && "Decl is not a OpenCL kernel!")); GlobalDecl Result(*this); Result.Value.setInt(unsigned(Kind)); return Result; } + + bool isDeclOpenCLKernel() const { +auto FD = dyn_cast(getDecl()); +if (FD) + return FD->hasAttr(); +return FD; + } lalaniket8 wrote: Commited suggestion in 013801b1fc82ec6806b876d93da24d4f0f2ed098 > https://github.com/llvm/llvm-project/pull/115821 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (PR #116462)
steakhal wrote: I wanted to come back with another example: ```c++ int ternary_in_assume(int a, int b) { [[assume(a > 10 ? b == 4 : b == 10)]]; if (a > 20) return b + 100; // expecting 104 if (a > 10) return b + 200; // expecting 204 return b + 300; // expecting 310 } ``` Actually, neither gcc, clang, msvc, or icc optimizes the return paths to constants - even though I think they would be allowed to. https://compiler-explorer.com/z/1ajvcvG9h I'd need to think about of the implications for us though. I think it should be safe to eval these subexpressions and do state splits if and only if none of those expressions have sideeffects. In that case, they wouldn't be emitted into the CFG, so they shouldn't be a problem. https://github.com/llvm/llvm-project/pull/116462 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/117978 >From 987f77db9d45dee264c60f434652131438784f6f Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 28 Nov 2024 14:02:00 +0530 Subject: [PATCH 1/4] Fix generation of wasm binaries while running clang-repl in browser --- clang/lib/Interpreter/CMakeLists.txt | 2 + clang/lib/Interpreter/Interpreter.cpp | 1 + clang/lib/Interpreter/Wasm.cpp| 57 --- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index df7ea82e0dada5..bf70cdfbee01e1 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) set(WASM_SRC Wasm.cpp) set(WASM_LINK lldWasm) + set(COMMON_LINK lldCommon) endif() add_clang_library(clangInterpreter @@ -47,6 +48,7 @@ add_clang_library(clangInterpreter clangSema clangSerialization ${WASM_LINK} + ${COMMON_LINK} ) if ((MINGW OR CYGWIN) AND BUILD_SHARED_LIBS) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5dc67f6375098f..887b494ff98f19 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -201,6 +201,7 @@ IncrementalCompilerBuilder::CreateCpp() { Argv.push_back("-target"); Argv.push_back("wasm32-unknown-emscripten"); Argv.push_back("-shared"); + Argv.push_back("-fvisibility=default"); #endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index 79efbaa03982d0..0fd6ad509c2938 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -23,6 +23,31 @@ #include namespace lld { +enum Flavor { + Invalid, + Gnu, // -flavor gnu + MinGW, // -flavor gnu MinGW + WinLink, // -flavor link + Darwin, // -flavor darwin + Wasm,// -flavor wasm +}; + +using Driver = bool (*)(llvm::ArrayRef, llvm::raw_ostream &, +llvm::raw_ostream &, bool, bool); + +struct DriverDef { + Flavor f; + Driver d; +}; + +struct Result { +int retCode; +bool canRunAgain; +}; + +Result lldMain(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, +llvm::raw_ostream &stderrOS, llvm::ArrayRef drivers); + namespace wasm { bool link(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); @@ -51,45 +76,47 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::TargetMachine *TargetMachine = Target->createTargetMachine( PTU.TheModule->getTargetTriple(), "", "", TO, llvm::Reloc::Model::PIC_); PTU.TheModule->setDataLayout(TargetMachine->createDataLayout()); - std::string OutputFileName = PTU.TheModule->getName().str() + ".wasm"; + std::string ObjectFileName = PTU.TheModule->getName().str() + ".o"; // For the wasm object + std::string BinaryFileName = PTU.TheModule->getName().str() + ".wasm"; // For the wasm binary std::error_code Error; - llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error); + llvm::raw_fd_ostream ObjectFileOutput(llvm::StringRef(ObjectFileName), Error); llvm::legacy::PassManager PM; - if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr, + if (TargetMachine->addPassesToEmitFile(PM, ObjectFileOutput, nullptr, llvm::CodeGenFileType::ObjectFile)) { return llvm::make_error( "Wasm backend cannot produce object.", llvm::inconvertibleErrorCode()); } if (!PM.run(*PTU.TheModule)) { - return llvm::make_error("Failed to emit Wasm object.", llvm::inconvertibleErrorCode()); } - OutputFile.close(); + ObjectFileOutput.close(); std::vector LinkerArgs = {"wasm-ld", "-shared", "--import-memory", - "--no-entry", - "--export-all", "--experimental-pic", "--stack-first", "--allow-undefined", - OutputFileName.c_str(), + ObjectFileName.c_str(), "-o", - OutputFileName.c_str()}; - int Result = - lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false); - if (!Result) + BinaryFileName.c_str()}; + + const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link}; + std::vector WasmDriverArg
[clang] [Driver][OpenMP] Fix OpenMP target-toolchain-option parser (PR #115375)
jle-quel wrote: Ping @alexey-bataev @MaskRay https://github.com/llvm/llvm-project/pull/115375 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support symbolTags for document symbol (PR #113669)
chouzz wrote: @travkin79 OK. If you already build it locally, that's fine. I will try to fix the test. https://github.com/llvm/llvm-project/pull/113669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/117978 >From 987f77db9d45dee264c60f434652131438784f6f Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 28 Nov 2024 14:02:00 +0530 Subject: [PATCH 1/4] Fix generation of wasm binaries while running clang-repl in browser --- clang/lib/Interpreter/CMakeLists.txt | 2 + clang/lib/Interpreter/Interpreter.cpp | 1 + clang/lib/Interpreter/Wasm.cpp| 57 --- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index df7ea82e0dada5..bf70cdfbee01e1 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) set(WASM_SRC Wasm.cpp) set(WASM_LINK lldWasm) + set(COMMON_LINK lldCommon) endif() add_clang_library(clangInterpreter @@ -47,6 +48,7 @@ add_clang_library(clangInterpreter clangSema clangSerialization ${WASM_LINK} + ${COMMON_LINK} ) if ((MINGW OR CYGWIN) AND BUILD_SHARED_LIBS) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5dc67f6375098f..887b494ff98f19 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -201,6 +201,7 @@ IncrementalCompilerBuilder::CreateCpp() { Argv.push_back("-target"); Argv.push_back("wasm32-unknown-emscripten"); Argv.push_back("-shared"); + Argv.push_back("-fvisibility=default"); #endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index 79efbaa03982d0..0fd6ad509c2938 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -23,6 +23,31 @@ #include namespace lld { +enum Flavor { + Invalid, + Gnu, // -flavor gnu + MinGW, // -flavor gnu MinGW + WinLink, // -flavor link + Darwin, // -flavor darwin + Wasm,// -flavor wasm +}; + +using Driver = bool (*)(llvm::ArrayRef, llvm::raw_ostream &, +llvm::raw_ostream &, bool, bool); + +struct DriverDef { + Flavor f; + Driver d; +}; + +struct Result { +int retCode; +bool canRunAgain; +}; + +Result lldMain(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, +llvm::raw_ostream &stderrOS, llvm::ArrayRef drivers); + namespace wasm { bool link(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); @@ -51,45 +76,47 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::TargetMachine *TargetMachine = Target->createTargetMachine( PTU.TheModule->getTargetTriple(), "", "", TO, llvm::Reloc::Model::PIC_); PTU.TheModule->setDataLayout(TargetMachine->createDataLayout()); - std::string OutputFileName = PTU.TheModule->getName().str() + ".wasm"; + std::string ObjectFileName = PTU.TheModule->getName().str() + ".o"; // For the wasm object + std::string BinaryFileName = PTU.TheModule->getName().str() + ".wasm"; // For the wasm binary std::error_code Error; - llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error); + llvm::raw_fd_ostream ObjectFileOutput(llvm::StringRef(ObjectFileName), Error); llvm::legacy::PassManager PM; - if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr, + if (TargetMachine->addPassesToEmitFile(PM, ObjectFileOutput, nullptr, llvm::CodeGenFileType::ObjectFile)) { return llvm::make_error( "Wasm backend cannot produce object.", llvm::inconvertibleErrorCode()); } if (!PM.run(*PTU.TheModule)) { - return llvm::make_error("Failed to emit Wasm object.", llvm::inconvertibleErrorCode()); } - OutputFile.close(); + ObjectFileOutput.close(); std::vector LinkerArgs = {"wasm-ld", "-shared", "--import-memory", - "--no-entry", - "--export-all", "--experimental-pic", "--stack-first", "--allow-undefined", - OutputFileName.c_str(), + ObjectFileName.c_str(), "-o", - OutputFileName.c_str()}; - int Result = - lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false); - if (!Result) + BinaryFileName.c_str()}; + + const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link}; + std::vector WasmDriverArg
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
anutosh491 wrote: Hey @vgvassilev thanks for the reviews. Addressed them. Once merged, I shall do a cherry pick of the required commit ! https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Diagnose dangling references for parenthesized aggregate initialization. (PR #117690)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/117690 >From 63f9c7ecee11868d055ef7cd694cf6b06f738360 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 26 Nov 2024 10:31:12 +0100 Subject: [PATCH 1/2] [clang] Diagnose dangling references for parethesized aggregate initialization. --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/CheckExprLifetime.cpp | 15 + clang/test/AST/ByteCode/records.cpp | 6 +- ...xx20-warn-dangling-paren-list-agg-init.cpp | 59 +++ clang/test/SemaCXX/paren-list-agg-init.cpp| 4 ++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 2ecd19bdc39448..9ccdc099ad09ac 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -627,6 +627,8 @@ Improvements to Clang's diagnostics - Clang now supports using alias templates in deduction guides, aligning with the C++ standard, which treats alias templates as synonyms for their underlying types (#GH54909). +- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957). + Improvements to Clang's time-trace -- diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index de69d6537b5692..a56154296b4781 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -14,6 +14,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Sema.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" namespace clang::sema { namespace { @@ -204,6 +205,7 @@ struct IndirectLocalPathEntry { GslPointerInit, GslPointerAssignment, DefaultArg, +ParenAggInit, } Kind; Expr *E; union { @@ -985,6 +987,17 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (isa(Init) || isa(Init)) return visitFunctionCallArguments(Path, Init, Visit); + if (auto *CPE = dyn_cast(Init)) { +Path.push_back({IndirectLocalPathEntry::ParenAggInit, CPE}); +for (auto *I : CPE->getInitExprs()) { + if (I->isGLValue()) +visitLocalsRetainedByReferenceBinding(Path, I, RK_ReferenceBinding, + Visit); + else +visitLocalsRetainedByInitializer(Path, I, Visit, true); +} +Path.pop_back(); + } switch (Init->getStmtClass()) { case Stmt::UnaryOperatorClass: { auto *UO = cast(Init); @@ -1081,6 +1094,7 @@ static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, case IndirectLocalPathEntry::GslReferenceInit: case IndirectLocalPathEntry::GslPointerInit: case IndirectLocalPathEntry::GslPointerAssignment: +case IndirectLocalPathEntry::ParenAggInit: // These exist primarily to mark the path as not permitting or // supporting lifetime extension. break; @@ -1392,6 +1406,7 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, switch (Elem.Kind) { case IndirectLocalPathEntry::AddressOf: case IndirectLocalPathEntry::LValToRVal: + case IndirectLocalPathEntry::ParenAggInit: // These exist primarily to mark the path as not permitting or // supporting lifetime extension. break; diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index 2eeaafc04c516c..4601aface135ee 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -1015,11 +1015,13 @@ namespace ParenInit { }; /// Not constexpr! - O o1(0); + O o1(0); // both-warning {{temporary whose address is used as value of}} + // FIXME: the secondary warning message is bogus, would be nice to suppress it. constinit O o2(0); // both-error {{variable does not have a constant initializer}} \ // both-note {{required by 'constinit' specifier}} \ // both-note {{reference to temporary is not a constant expression}} \ - // both-note {{temporary created here}} + // both-note {{temporary created here}} \ + // both-warning {{temporary whose address is used as value}} /// Initializing an array. diff --git a/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp b/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp new file mode 100644 index 00..645a7caba714e2 --- /dev/null +++ b/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only + +namespace std { +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; + +templat
[clang] 26baa00 - [clang] Diagnose dangling references for parenthesized aggregate initialization. (#117690)
Author: Haojian Wu Date: 2024-11-29T10:15:19+01:00 New Revision: 26baa00908b2eb8b2925800af6bc64fbe53cac48 URL: https://github.com/llvm/llvm-project/commit/26baa00908b2eb8b2925800af6bc64fbe53cac48 DIFF: https://github.com/llvm/llvm-project/commit/26baa00908b2eb8b2925800af6bc64fbe53cac48.diff LOG: [clang] Diagnose dangling references for parenthesized aggregate initialization. (#117690) Unlike brace initialization, the parenthesized aggregate initialization in C++20 does not extend the lifetime of a temporary object bound to a reference in an aggreate. This can lead to dangling references: ``` struct A { const int& r; }; A a1(1); // well-formed, but results in a dangling reference. ``` With this patch, clang will diagnose this common dangling issues. Fixes #101957 Added: clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/CheckExprLifetime.cpp clang/test/AST/ByteCode/records.cpp clang/test/SemaCXX/paren-list-agg-init.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 102ffb56fec35f..9882a1c42d50c4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -627,6 +627,8 @@ Improvements to Clang's diagnostics - Clang now supports using alias templates in deduction guides, aligning with the C++ standard, which treats alias templates as synonyms for their underlying types (#GH54909). +- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957). + Improvements to Clang's time-trace -- diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index de69d6537b5692..15ceff873693a5 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -204,6 +204,7 @@ struct IndirectLocalPathEntry { GslPointerInit, GslPointerAssignment, DefaultArg, +ParenAggInit, } Kind; Expr *E; union { @@ -985,6 +986,17 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, if (isa(Init) || isa(Init)) return visitFunctionCallArguments(Path, Init, Visit); + if (auto *CPE = dyn_cast(Init)) { +RevertToOldSizeRAII RAII(Path); +Path.push_back({IndirectLocalPathEntry::ParenAggInit, CPE}); +for (auto *I : CPE->getInitExprs()) { + if (I->isGLValue()) +visitLocalsRetainedByReferenceBinding(Path, I, RK_ReferenceBinding, + Visit); + else +visitLocalsRetainedByInitializer(Path, I, Visit, true); +} + } switch (Init->getStmtClass()) { case Stmt::UnaryOperatorClass: { auto *UO = cast(Init); @@ -1081,6 +1093,7 @@ static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I, case IndirectLocalPathEntry::GslReferenceInit: case IndirectLocalPathEntry::GslPointerInit: case IndirectLocalPathEntry::GslPointerAssignment: +case IndirectLocalPathEntry::ParenAggInit: // These exist primarily to mark the path as not permitting or // supporting lifetime extension. break; @@ -1392,6 +1405,7 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, switch (Elem.Kind) { case IndirectLocalPathEntry::AddressOf: case IndirectLocalPathEntry::LValToRVal: + case IndirectLocalPathEntry::ParenAggInit: // These exist primarily to mark the path as not permitting or // supporting lifetime extension. break; diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index 2eeaafc04c516c..4601aface135ee 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -1015,11 +1015,13 @@ namespace ParenInit { }; /// Not constexpr! - O o1(0); + O o1(0); // both-warning {{temporary whose address is used as value of}} + // FIXME: the secondary warning message is bogus, would be nice to suppress it. constinit O o2(0); // both-error {{variable does not have a constant initializer}} \ // both-note {{required by 'constinit' specifier}} \ // both-note {{reference to temporary is not a constant expression}} \ - // both-note {{temporary created here}} + // both-note {{temporary created here}} \ + // both-warning {{temporary whose address is used as value}} /// Initializing an array. diff --git a/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp b/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp new file mode 100644 index 00..645a7caba714e2 --- /dev/null +++ b/clang/test/SemaCXX/cxx20-warn-dangling-paren-list-agg-init.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -verify -std=c++20 %s -fsynt
[clang] [clang] Diagnose dangling references for parenthesized aggregate initialization. (PR #117690)
https://github.com/hokein closed https://github.com/llvm/llvm-project/pull/117690 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [InstCombine] Fold `X Pred C2 ? X BOp C1 : C2 BOp C1` to `min/max(X, C2) BOp C1` (PR #116888)
@@ -1898,6 +1882,56 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI, return nullptr; } +/// Fold `X Pred C2 ? X BOp C1 : C2 BOp C1` to `min/max(X, C2) BOp C1`. +/// This allows for better canonicalization. +static Value *foldSelectWithConstOpToBinOp(ICmpInst *Cmp, Value *TrueVal, + Value *FalseVal, + IRBuilderBase &Builder) { + BinaryOperator *BOp; + Constant *C1, *C2, *C3; + Value *X; + ICmpInst::Predicate Predicate; + + if (!match(Cmp, m_ICmp(Predicate, m_Value(X), m_Constant(C1 +return nullptr; + + if (!ICmpInst::isRelational(Predicate)) +return nullptr; + + if (match(TrueVal, m_Constant())) { +std::swap(FalseVal, TrueVal); +Predicate = ICmpInst::getInversePredicate(Predicate); + } + + if (!match(TrueVal, m_BinOp(BOp)) || !match(FalseVal, m_Constant(C3))) +return nullptr; + + if (!match(BOp, m_OneUse(m_BinOp(m_Specific(X), m_Constant(C2) +return nullptr; + + Value *RHS; + SelectPatternFlavor SPF; + unsigned Opcode = BOp->getOpcode(); dtcxzyw wrote: Is it always profitable to perform this transform for div/rem? https://github.com/llvm/llvm-project/pull/116888 ___ 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 modernize-use-span-first-last check (PR #118074)
https://github.com/hjanuschka created https://github.com/llvm/llvm-project/pull/118074 Add new clang-tidy check that suggests using std::span's more expressive first() and last() member functions instead of equivalent subspan() calls. The check modernizes code by replacing: - subspan(0, n) -> first(n) - subspan(n) -> last(size() - n) These dedicated methods were added to the standard to provide clearer alternatives to common subspan operations. They improve readability by better expressing intent and are less error-prone by eliminating manual offset calculations. For example: ```cpp std::span s = ...; auto sub1 = s.subspan(0, n); // transforms to: auto sub1 = s.first(n); auto sub2 = s.subspan(n);// transforms to: auto sub2 = s.last(s.size() - n); auto sub3 = s.subspan(1, n); // not transformed, no direct equivalent ``` not sure if this is a readability or a modernize check ❓ >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/2] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + c
[clang-tools-extra] [clang-tidy] Add modernize-use-span-first-last check (PR #118074)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: Helmut Januschka (hjanuschka) Changes Add new clang-tidy check that suggests using std::span's more expressive first() and last() member functions instead of equivalent subspan() calls. The check modernizes code by replacing: - subspan(0, n) -> first(n) - subspan(n) -> last(size() - n) These dedicated methods were added to the standard to provide clearer alternatives to common subspan operations. They improve readability by better expressing intent and are less error-prone by eliminating manual offset calculations. For example: ```cpp std::spans = ...; auto sub1 = s.subspan(0, n); // transforms to: auto sub1 = s.first(n); auto sub2 = s.subspan(n);// transforms to: auto sub2 = s.last(s.size() - n); auto sub3 = s.subspan(1, n); // not transformed, no direct equivalent ``` not sure if this is a readability or a modernize check ❓ --- Full diff: https://github.com/llvm/llvm-project/pull/118074.diff 7 Files Affected: - (modified) clang-tools-extra/clang-tidy/modernize/CMakeLists.txt (+1) - (modified) clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp (+3) - (added) clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp (+98) - (added) clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h (+40) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4) - (added) clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst (+19) - (added) clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp (+50) ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..6cf01386b0c3fb --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,98 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = + hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration( + classTemplateSpecializationDecl(hasName("::std::span")); + + Finder->addMatcher(cxxMemberCallExpr(callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + c
[clang-tools-extra] [clang-tidy] Add modernize-use-span-first-last check (PR #118074)
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 056153f36eca184f81969f5cd5c8cd967c935f96 ec5a6b0ceb0fbbf03ea36a38fb627b25ab4e62de --extensions h,cpp -- clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 6fc5de5aad..d1778640bb 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -123,8 +123,8 @@ public: CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); - CheckFactories.registerCheck("modernize-use-span-first-last"); - +CheckFactories.registerCheck( +"modernize-use-span-first-last"); } }; `` https://github.com/llvm/llvm-project/pull/118074 ___ 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 modernize-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/3] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clang-tidy] Add modernize-use-span-first-last check (PR #118074)
carlosgalvezp wrote: ```cpp auto sub2 = s.subspan(n);// transforms to: auto sub2 = s.last(s.size() - n); ``` IMHO the transformed code is less readable. It would be more useful to do the opposite transformation, maybe that's what you intended? ```cpp auto sub2 = s.subspan(s.size() - n);// transforms to: auto sub2 = s.last(n); ``` https://github.com/llvm/llvm-project/pull/118074 ___ 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 modernize-use-span-first-last check (PR #118074)
@@ -0,0 +1,40 @@ +//===--- UseSpanFirstLastCheck.h - clang-tidy---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// Converts std::span::subspan() calls to the more modern first()/last() +/// methods where applicable. +/// +/// For example: +/// \code +/// std::span s = ...; +/// auto sub = s.subspan(0, n);// -> auto sub = s.first(n); +/// auto sub2 = s.subspan(n); // -> auto sub2 = s.last(s.size() - n); +/// \endcode +class UseSpanFirstLastCheck : public ClangTidyCheck { +public: + UseSpanFirstLastCheck(StringRef Name, ClangTidyContext *Context) carlosgalvezp wrote: Limit this check to C++20 https://github.com/llvm/llvm-project/pull/118074 ___ 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 modernize-use-span-first-last check (PR #118074)
carlosgalvezp wrote: > not sure if this is a readability or a modernize check `readability`. `modernize` is for using new features from newer standards. https://github.com/llvm/llvm-project/pull/118074 ___ 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 modernize-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/4] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clang-tidy] Add modernize-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/6] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang] [llvm] Support for dispatch construct (Sema & Codegen) support. (PR #117904)
https://github.com/SunilKuravinakop updated https://github.com/llvm/llvm-project/pull/117904 >From f466152e17c8057b98fbc88ebf413de82ca3ecb7 Mon Sep 17 00:00:00 2001 From: Sunil Kuravinakop Date: Fri, 20 Sep 2024 01:41:29 -0500 Subject: [PATCH] Support for dispatch construct (Sema & Codegen) support. Support for clauses depend, novariants & nocontext. --- .../clang/Basic/DiagnosticSemaKinds.td| 3 + clang/include/clang/Basic/OpenMPKinds.h | 6 + clang/include/clang/Sema/SemaOpenMP.h | 7 + clang/lib/Basic/OpenMPKinds.cpp | 5 + clang/lib/CodeGen/CGStmt.cpp | 2 +- clang/lib/CodeGen/CGStmtOpenMP.cpp| 4 + clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Sema/SemaOpenMP.cpp | 294 +- clang/test/OpenMP/dispatch_codegen.cpp| 359 ++ clang/test/OpenMP/dispatch_unsupported.c | 7 - .../include/llvm/Frontend/OpenMP/OMPContext.h | 6 + 11 files changed, 683 insertions(+), 11 deletions(-) create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8495884dcd058f..81b876f9fd85c5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error< "'%0' clause requires 'dispatch' context selector">; def err_omp_append_args_with_varargs : Error< "'append_args' is not allowed with varargs functions">; +def warn_omp_dispatch_clause_novariants_nocontext : Warning< + "only 'novariants' clause is supported when 'novariants' & 'nocontext' clauses occur on the same dispatch construct">, + InGroup; def err_openmp_vla_in_task_untied : Error< "variable length arrays are not supported in OpenMP tasking regions with 'untied' clause">; def warn_omp_unterminated_declare_target : Warning< diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 900ad6ca6d66f6..7579fab43dbb19 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind); /// parallel', otherwise - false. bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind); +/// Checks if the specified directive is a dispatch-kind directive. +/// \param DKind Specified directive. +/// \return true - the directive is a dispatch-like directive like 'omp +/// dispatch', otherwise - false. +bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind); + /// Checks if the specified directive is a target code offload directive. /// \param DKind Specified directive. /// \return true - the directive is a target code offload directive like diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 3d1cc4fab1c10f..80cee9e7583051 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase { : OMPDeclareVariantScopes.back().TI; } + StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind, +const DeclarationNameInfo &DirName, +OpenMPDirectiveKind CancelRegion, +ArrayRef Clauses, +Stmt *AStmt, SourceLocation StartLoc, +SourceLocation EndLoc); + /// The current `omp begin/end declare variant` scopes. SmallVector OMPDeclareVariantScopes; diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 62a13f01481b28..44ee63df46adb5 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel); } +bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_dispatch || + llvm::is_contained(getLeafConstructs(DKind), OMPD_target); +} + bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_target || llvm::is_contained(getLeafConstructs(DKind), OMPD_target); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 698baf853507f4..f3eedb79844378 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { EmitOMPInteropDirective(cast(*S)); break; case Stmt::OMPDispatchDirectiveClass: -CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); +Emit
[clang-tools-extra] [clang-tidy] Add modernize-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/7] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clang-tidy] Add readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka edited https://github.com/llvm/llvm-project/pull/118074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Support for dispatch construct (Sema & Codegen) support. (PR #117904)
@@ -5965,6 +5967,244 @@ static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema &SemaRef) { return Checker.teamsLoopCanBeParallelFor(); } +static Expr *getInitialExprFromCapturedExpr(Expr *Cond) { + + Expr *SubExpr = Cond->IgnoreParenImpCasts(); + + if (auto *DeclRef = dyn_cast(SubExpr)) { +if (auto *CapturedExprDecl = +dyn_cast(DeclRef->getDecl())) { + + // Retrieve the initial expression from the captured expression + return CapturedExprDecl->getInit(); +} + } + return nullptr; +} + +static Expr *copy_removePseudoObjectExpr(const ASTContext &Context, Expr *E, + SemaOpenMP *SemaPtr, bool NoContext) { + + BinaryOperator *BinaryCopyOpr = NULL; + bool BinaryOp = false; + if (E->getStmtClass() == Stmt::BinaryOperatorClass) { +BinaryOp = true; +BinaryOperator *E_BinOpr = static_cast(E); +BinaryCopyOpr = BinaryOperator::Create( +Context, E_BinOpr->getLHS(), E_BinOpr->getRHS(), E_BinOpr->getOpcode(), +E_BinOpr->getType(), E_BinOpr->getValueKind(), +E_BinOpr->getObjectKind(), E_BinOpr->getOperatorLoc(), +FPOptionsOverride()); +E = BinaryCopyOpr->getRHS(); + } + + // Change PseudoObjectExpr to a direct call + if (PseudoObjectExpr *PO = dyn_cast(E)) +E = *((PO->semantics_begin()) - 1); SunilKuravinakop wrote: I have added comments at the beginning of the function CloneAssociatedStmt(). I think this answers your question. Please let me know if I have to add comments to this statement in particular. https://github.com/llvm/llvm-project/pull/117904 ___ 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 readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 1/8] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clangd] Support symbolTags for document symbol (PR #113669)
travkin79 wrote: Hi @chouzz, I started testing your version of clangd that I built locally. It seems that clangd does not return any symbol tags. I'm checking if I missed something in LSP4J, LSP4E or somewhere else. I guess there is something missing when handling the json response and creating Java objects using JSONRPC, but I don't know yet. At the moment, what I get for your [example](https://github.com/clangd/clangd/issues/2123#issuecomment-2441427739) is the following response (`tags` field is always null): ```json [Either [ left = null right = DocumentSymbol [ name = "g_var" kind = Variable range = Range [ start = Position [ line = 0 character = 0 ] end = Position [ line = 0 character = 19 ] ] selectionRange = Range [ start = Position [ line = 0 character = 10 ] end = Position [ line = 0 character = 15 ] ] detail = "const int" tags = null deprecated = null children = null ] ], Either [ left = null right = DocumentSymbol [ name = "P" kind = Class range = Range [ start = Position [ line = 1 character = 0 ] end = Position [ line = 8 character = 1 ] ] selectionRange = Range [ start = Position [ line = 1 character = 6 ] end = Position [ line = 1 character = 7 ] ] detail = "class" tags = null deprecated = null children = ArrayList ( DocumentSymbol [ name = "pub" kind = Method range = Range [ start = Position [ line = 3 character = 4 ] end = Position [ line = 3 character = 14 ] ] selectionRange = Range [ start = Position [ line = 3 character = 9 ] end = Position [ line = 3 character = 12 ] ] detail = "void ()" tags = null deprecated = null children = null ], DocumentSymbol [ name = "pri" kind = Method range = Range [ start = Position [ line = 5 character = 4 ] end = Position [ line = 5 character = 14 ] ] selectionRange = Range [ start = Position [ line = 5 character = 9 ] end = Position [ line = 5 character = 12 ] ] detail = "void ()" tags = null deprecated = null children = null ], DocumentSymbol [ name = "pro" kind = Method range = Range [ start = Position [ line = 7 character = 4 ] end = Position [ line = 7 character = 14 ] ] selectionRange = Range [ start = Position [ line = 7 character = 9 ] end = Position [ line = 7 character = 12 ] ] detail = "void ()" tags = null deprecated = null children = null ] ) ] ]] ``` https://github.com/llvm/llvm-project/pull/113669 ___ 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 readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka edited https://github.com/llvm/llvm-project/pull/118074 ___ 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 readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 01/10] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang] [FixIt] Improve Source Ranges and Fix-It Hints for Unused Lambda Captures #106445 (PR #117953)
https://github.com/charan-003 updated https://github.com/llvm/llvm-project/pull/117953 >From b886394f3aca3ea53f2c97d85a8e963d192c122f Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:43:38 -0700 Subject: [PATCH 1/7] Update SemaLambda.cpp This patch refines how Clang handles source ranges for unused lambda captures. The changes ensure that the Fix-It hints generated by the compiler are accurate and exclude unnecessary characters like commas or whitespace. Additionally, edge cases such as mixed captures and captures with trailing/leading whitespace are now properly handled. --- clang/lib/Sema/SemaLambda.cpp | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a67c0b2b367d1a..e7417d1a884dcd 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,8 +1164,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) -LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; - continue; + { + SourceRange TrimmedRange = Lexer::makeFileCharRange( + C->ExplicitRange, SM, LangOpts); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; + } } assert(C->Id && "missing identifier for capture"); @@ -1329,7 +1332,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); } if (!LSI->Captures.empty()) - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; + { +SourceRange TrimmedRange = Lexer::makeFileCharRange( +C->ExplicitRange, SM, LangOpts); +LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; +} } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From ccb39521d4e246bb2b1fd2c9f3727d2332b9a6df Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:48:37 -0700 Subject: [PATCH 2/7] Update fixit-unused-lambda-capture.cpp This patch extends the existing test coverage in fixit-unused-lambda-capture.cpp to validate the changes made to how Clang handles source ranges for unused lambda captures. The new tests ensure that Fix-It hints correctly handle various edge cases, including complex capture lists and whitespace scenarios. --- .../FixIt/fixit-unused-lambda-capture.cpp | 32 +++ 1 file changed, 32 insertions(+) diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp index ce0c78d677099a..ae43d4ebbdf821 100644 --- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp +++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp @@ -66,6 +66,38 @@ void test() { // CHECK: [z = (n = i)] {}; [j,z = (n = i)] {}; // CHECK: [z = (n = i)] {}; + + // New Edge Cases + + // Test 1: Leading and trailing whitespace + [i,j] { return i; }; + // CHECK: [i] { return i; }; + [i ,j] { return j; }; + // CHECK: [j] { return j; }; + [i , j , k] { return j + k; }; + // CHECK: [j,k] { return j + k; }; + + // Test 2: Single unused capture + [i] {}; + // CHECK: [] {}; + [&i] {}; + // CHECK: [] {}; + + // Test 3: Multiple commas + [i,,j] { return j; }; + // CHECK: [j] { return j; }; + [,i,j,,k] { return k; }; + // CHECK: [k] { return k; }; + + // Test 4: Mixed captures + [=, &i, j] { return i; }; + // CHECK: [&i] { return i; }; + [&, i] {}; + // CHECK: [&] {}; + + // Test 5: Capture with comments + [/*capture*/ i, j] { return j; }; + // CHECK: [/*capture*/ j] { return j; }; } class ThisTest { >From 6b5fff5d2f10e422f94939213d2302a87501a867 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:52:22 -0700 Subject: [PATCH 3/7] Update SemaLambda.cpp added #include "clang/Lex/Lexer.h" --- clang/lib/Sema/SemaLambda.cpp | 5 + 1 file changed, 5 insertions(+) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e7417d1a884dcd..82a0f926d6af75 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "clang/Lex/Lexer.h" #include using namespace clang; using namespace sema; @@ -1165,6 +1166,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) { + SourceManager &SourceMgr = Context.getSourceManager(); + cons
[clang] a174aa1 - [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (#117978)
Author: Anutosh Bhat Date: 2024-11-29T12:01:02+02:00 New Revision: a174aa1e416c4e27945f5a8c646b119126dc8441 URL: https://github.com/llvm/llvm-project/commit/a174aa1e416c4e27945f5a8c646b119126dc8441 DIFF: https://github.com/llvm/llvm-project/commit/a174aa1e416c4e27945f5a8c646b119126dc8441.diff LOG: [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (#117978) Co-authored-by: Vassil Vassilev Added: Modified: clang/lib/Interpreter/CMakeLists.txt clang/lib/Interpreter/Interpreter.cpp clang/lib/Interpreter/Wasm.cpp Removed: diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index df7ea82e0dada5..bf70cdfbee01e1 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) set(WASM_SRC Wasm.cpp) set(WASM_LINK lldWasm) + set(COMMON_LINK lldCommon) endif() add_clang_library(clangInterpreter @@ -47,6 +48,7 @@ add_clang_library(clangInterpreter clangSema clangSerialization ${WASM_LINK} + ${COMMON_LINK} ) if ((MINGW OR CYGWIN) AND BUILD_SHARED_LIBS) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5dc67f6375098f..887b494ff98f19 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -201,6 +201,7 @@ IncrementalCompilerBuilder::CreateCpp() { Argv.push_back("-target"); Argv.push_back("wasm32-unknown-emscripten"); Argv.push_back("-shared"); + Argv.push_back("-fvisibility=default"); #endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index 79efbaa03982d0..aa10b160ccf847 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -23,6 +23,31 @@ #include namespace lld { +enum Flavor { + Invalid, + Gnu, // -flavor gnu + MinGW, // -flavor gnu MinGW + WinLink, // -flavor link + Darwin, // -flavor darwin + Wasm,// -flavor wasm +}; + +using Driver = bool (*)(llvm::ArrayRef, llvm::raw_ostream &, +llvm::raw_ostream &, bool, bool); + +struct DriverDef { + Flavor f; + Driver d; +}; + +struct Result { + int retCode; + bool canRunAgain; +}; + +Result lldMain(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, + llvm::raw_ostream &stderrOS, llvm::ArrayRef drivers); + namespace wasm { bool link(llvm::ArrayRef args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); @@ -51,13 +76,14 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::TargetMachine *TargetMachine = Target->createTargetMachine( PTU.TheModule->getTargetTriple(), "", "", TO, llvm::Reloc::Model::PIC_); PTU.TheModule->setDataLayout(TargetMachine->createDataLayout()); - std::string OutputFileName = PTU.TheModule->getName().str() + ".wasm"; + std::string ObjectFileName = PTU.TheModule->getName().str() + ".o"; + std::string BinaryFileName = PTU.TheModule->getName().str() + ".wasm"; std::error_code Error; - llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error); + llvm::raw_fd_ostream ObjectFileOutput(llvm::StringRef(ObjectFileName), Error); llvm::legacy::PassManager PM; - if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr, + if (TargetMachine->addPassesToEmitFile(PM, ObjectFileOutput, nullptr, llvm::CodeGenFileType::ObjectFile)) { return llvm::make_error( "Wasm backend cannot produce object.", llvm::inconvertibleErrorCode()); @@ -69,27 +95,30 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::inconvertibleErrorCode()); } - OutputFile.close(); + ObjectFileOutput.close(); std::vector LinkerArgs = {"wasm-ld", "-shared", "--import-memory", - "--no-entry", - "--export-all", "--experimental-pic", "--stack-first", "--allow-undefined", - OutputFileName.c_str(), + ObjectFileName.c_str(), "-o", - OutputFileName.c_str()}; - int Result = - lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false); - if (!Result) + BinaryFileName.c_str()}; + + const lld::Dr
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
https://github.com/vgvassilev closed https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [FixIt] Improve Source Ranges and Fix-It Hints for Unused Lambda Captures #106445 (PR #117953)
https://github.com/charan-003 updated https://github.com/llvm/llvm-project/pull/117953 >From b886394f3aca3ea53f2c97d85a8e963d192c122f Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:43:38 -0700 Subject: [PATCH 1/8] Update SemaLambda.cpp This patch refines how Clang handles source ranges for unused lambda captures. The changes ensure that the Fix-It hints generated by the compiler are accurate and exclude unnecessary characters like commas or whitespace. Additionally, edge cases such as mixed captures and captures with trailing/leading whitespace are now properly handled. --- clang/lib/Sema/SemaLambda.cpp | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a67c0b2b367d1a..e7417d1a884dcd 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,8 +1164,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) -LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; - continue; + { + SourceRange TrimmedRange = Lexer::makeFileCharRange( + C->ExplicitRange, SM, LangOpts); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; + } } assert(C->Id && "missing identifier for capture"); @@ -1329,7 +1332,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); } if (!LSI->Captures.empty()) - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; + { +SourceRange TrimmedRange = Lexer::makeFileCharRange( +C->ExplicitRange, SM, LangOpts); +LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; +} } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From ccb39521d4e246bb2b1fd2c9f3727d2332b9a6df Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:48:37 -0700 Subject: [PATCH 2/8] Update fixit-unused-lambda-capture.cpp This patch extends the existing test coverage in fixit-unused-lambda-capture.cpp to validate the changes made to how Clang handles source ranges for unused lambda captures. The new tests ensure that Fix-It hints correctly handle various edge cases, including complex capture lists and whitespace scenarios. --- .../FixIt/fixit-unused-lambda-capture.cpp | 32 +++ 1 file changed, 32 insertions(+) diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp index ce0c78d677099a..ae43d4ebbdf821 100644 --- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp +++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp @@ -66,6 +66,38 @@ void test() { // CHECK: [z = (n = i)] {}; [j,z = (n = i)] {}; // CHECK: [z = (n = i)] {}; + + // New Edge Cases + + // Test 1: Leading and trailing whitespace + [i,j] { return i; }; + // CHECK: [i] { return i; }; + [i ,j] { return j; }; + // CHECK: [j] { return j; }; + [i , j , k] { return j + k; }; + // CHECK: [j,k] { return j + k; }; + + // Test 2: Single unused capture + [i] {}; + // CHECK: [] {}; + [&i] {}; + // CHECK: [] {}; + + // Test 3: Multiple commas + [i,,j] { return j; }; + // CHECK: [j] { return j; }; + [,i,j,,k] { return k; }; + // CHECK: [k] { return k; }; + + // Test 4: Mixed captures + [=, &i, j] { return i; }; + // CHECK: [&i] { return i; }; + [&, i] {}; + // CHECK: [&] {}; + + // Test 5: Capture with comments + [/*capture*/ i, j] { return j; }; + // CHECK: [/*capture*/ j] { return j; }; } class ThisTest { >From 6b5fff5d2f10e422f94939213d2302a87501a867 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:52:22 -0700 Subject: [PATCH 3/8] Update SemaLambda.cpp added #include "clang/Lex/Lexer.h" --- clang/lib/Sema/SemaLambda.cpp | 5 + 1 file changed, 5 insertions(+) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e7417d1a884dcd..82a0f926d6af75 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "clang/Lex/Lexer.h" #include using namespace clang; using namespace sema; @@ -1165,6 +1166,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) { + SourceManager &SourceMgr = Context.getSourceManager(); + cons
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
anutosh491 wrote: /cherry-pick a174aa1e416c4e27945f5a8c646b119126dc8441 https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (PR #118076)
https://github.com/svs-quic created https://github.com/llvm/llvm-project/pull/118076 This extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. >From 42c15c348dd0cfec249058e5222475bc3620aaef Mon Sep 17 00:00:00 2001 From: Sudharsan Veeravalli Date: Fri, 29 Nov 2024 14:25:31 +0530 Subject: [PATCH] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension This extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. --- .../Driver/print-supported-extensions-riscv.c | 1 + llvm/docs/ReleaseNotes.md | 2 + .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 3 + .../RISCV/Disassembler/RISCVDisassembler.cpp | 2 + .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 + llvm/lib/Target/RISCV/RISCVFeatures.td| 8 + llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 36 llvm/lib/TargetParser/RISCVISAInfo.cpp| 3 +- llvm/test/CodeGen/RISCV/attributes.ll | 2 + llvm/test/MC/RISCV/xqcia-invalid.s| 201 ++ llvm/test/MC/RISCV/xqcia-valid.s | 55 + .../TargetParser/RISCVISAInfoTest.cpp | 6 + 12 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/RISCV/xqcia-invalid.s create mode 100644 llvm/test/MC/RISCV/xqcia-valid.s diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 70b7a96daf1daf..9df903115b57c1 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -188,6 +188,7 @@ // CHECK-NEXT: smctr1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) +// CHECK-NEXT: xqcia0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6d50839d68953e..dc3f3aeb735f87 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -215,6 +215,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) + extension. Changes to the WebAssembly Backend -- diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b843bb5ae43100..7c91dc07bbd3e5 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isUImm6() const { return IsUImm<6>(); } bool isUImm7() const { return IsUImm<7>(); } bool isUImm8() const { return IsUImm<8>(); } + bool isUImm11() const { return IsUImm<11>(); } bool isUImm16() const { return IsUImm<16>(); } bool isUImm20() const { return IsUImm<20>(); } bool isUImm32() const { return IsUImm<32>(); } @@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, "immediate must be a multiple of 16 bytes and non-zero in the range"); + case Match_InvalidUImm11: +return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1); case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 95658f24f79e1c..4d563046923a58 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC CSR custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32, "Qualcomm uC Scaled Load Store custom opcode table"); + TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32, +"Qualcomm uC Arithmetic custom opcode table"); TRY_TO_DECODE(
[clang] [llvm] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (PR #118076)
llvmbot wrote: @llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-clang Author: Sudharsan Veeravalli (svs-quic) Changes This extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. --- Full diff: https://github.com/llvm/llvm-project/pull/118076.diff 12 Files Affected: - (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) - (modified) llvm/docs/ReleaseNotes.md (+2) - (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+3) - (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2) - (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) - (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+36) - (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+2-1) - (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) - (added) llvm/test/MC/RISCV/xqcia-invalid.s (+201) - (added) llvm/test/MC/RISCV/xqcia-valid.s (+55) - (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+6) ``diff diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 70b7a96daf1daf..9df903115b57c1 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -188,6 +188,7 @@ // CHECK-NEXT: smctr1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) +// CHECK-NEXT: xqcia0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6d50839d68953e..dc3f3aeb735f87 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -215,6 +215,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) + extension. Changes to the WebAssembly Backend -- diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b843bb5ae43100..7c91dc07bbd3e5 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isUImm6() const { return IsUImm<6>(); } bool isUImm7() const { return IsUImm<7>(); } bool isUImm8() const { return IsUImm<8>(); } + bool isUImm11() const { return IsUImm<11>(); } bool isUImm16() const { return IsUImm<16>(); } bool isUImm20() const { return IsUImm<20>(); } bool isUImm32() const { return IsUImm<32>(); } @@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, "immediate must be a multiple of 16 bytes and non-zero in the range"); + case Match_InvalidUImm11: +return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1); case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 95658f24f79e1c..4d563046923a58 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC CSR custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32, "Qualcomm uC Scaled Load Store custom opcode table"); + TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32, +"Qualcomm uC Arithmetic custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index ca2f868cd4e764..9e36d62352ae51 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -312,6 +31
[clang] [llvm] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (PR #118076)
llvmbot wrote: @llvm/pr-subscribers-clang-driver Author: Sudharsan Veeravalli (svs-quic) Changes This extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. --- Full diff: https://github.com/llvm/llvm-project/pull/118076.diff 12 Files Affected: - (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) - (modified) llvm/docs/ReleaseNotes.md (+2) - (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+3) - (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2) - (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) - (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+36) - (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+2-1) - (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) - (added) llvm/test/MC/RISCV/xqcia-invalid.s (+201) - (added) llvm/test/MC/RISCV/xqcia-valid.s (+55) - (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+6) ``diff diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 70b7a96daf1daf..9df903115b57c1 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -188,6 +188,7 @@ // CHECK-NEXT: smctr1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) +// CHECK-NEXT: xqcia0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6d50839d68953e..dc3f3aeb735f87 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -215,6 +215,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) + extension. Changes to the WebAssembly Backend -- diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b843bb5ae43100..7c91dc07bbd3e5 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isUImm6() const { return IsUImm<6>(); } bool isUImm7() const { return IsUImm<7>(); } bool isUImm8() const { return IsUImm<8>(); } + bool isUImm11() const { return IsUImm<11>(); } bool isUImm16() const { return IsUImm<16>(); } bool isUImm20() const { return IsUImm<20>(); } bool isUImm32() const { return IsUImm<32>(); } @@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, "immediate must be a multiple of 16 bytes and non-zero in the range"); + case Match_InvalidUImm11: +return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1); case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 95658f24f79e1c..4d563046923a58 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC CSR custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32, "Qualcomm uC Scaled Load Store custom opcode table"); + TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32, +"Qualcomm uC Arithmetic custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index ca2f868cd4e764..9e36d62352ae51 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -312,6 +312,7 @@ enum OperandType : uns
[clang] [llvm] [RISCV] Add Qualcomm uC Xqcia (Arithmetic) extension (PR #118076)
llvmbot wrote: @llvm/pr-subscribers-mc Author: Sudharsan Veeravalli (svs-quic) Changes This extension adds 11 instructions that perform integer arithmetic. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. --- Full diff: https://github.com/llvm/llvm-project/pull/118076.diff 12 Files Affected: - (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) - (modified) llvm/docs/ReleaseNotes.md (+2) - (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+3) - (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2) - (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) - (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) - (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+36) - (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+2-1) - (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) - (added) llvm/test/MC/RISCV/xqcia-invalid.s (+201) - (added) llvm/test/MC/RISCV/xqcia-valid.s (+55) - (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+6) ``diff diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 70b7a96daf1daf..9df903115b57c1 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -188,6 +188,7 @@ // CHECK-NEXT: smctr1.0 'Smctr' (Control Transfer Records Machine Level) // CHECK-NEXT: ssctr1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) +// CHECK-NEXT: xqcia0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6d50839d68953e..dc3f3aeb735f87 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -215,6 +215,8 @@ Changes to the RISC-V Backend extension. * Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store) extension. +* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic) + extension. Changes to the WebAssembly Backend -- diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b843bb5ae43100..7c91dc07bbd3e5 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand { bool isUImm6() const { return IsUImm<6>(); } bool isUImm7() const { return IsUImm<7>(); } bool isUImm8() const { return IsUImm<8>(); } + bool isUImm11() const { return IsUImm<11>(); } bool isUImm16() const { return IsUImm<16>(); } bool isUImm20() const { return IsUImm<20>(); } bool isUImm32() const { return IsUImm<32>(); } @@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, "immediate must be a multiple of 16 bytes and non-zero in the range"); + case Match_InvalidUImm11: +return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1); case Match_InvalidSImm12: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 95658f24f79e1c..4d563046923a58 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, "Qualcomm uC CSR custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32, "Qualcomm uC Scaled Load Store custom opcode table"); + TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32, +"Qualcomm uC Arithmetic custom opcode table"); TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); return MCDisassembler::Fail; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index ca2f868cd4e764..9e36d62352ae51 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -312,6 +312,7 @@ enum OperandType : unsigned {
[clang] [clang] Infer lifetime_capture_by for map's subscript operator. (PR #118078)
https://github.com/hokein created https://github.com/llvm/llvm-project/pull/118078 None >From 18d56e847901653de9f84e256f30ec0e16ebca96 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 29 Nov 2024 11:07:56 +0100 Subject: [PATCH] [clang] Infer lifetime_capture_by for map's subscript operator. --- clang/lib/Sema/SemaAttr.cpp | 59 + clang/test/AST/attr-lifetime-capture-by.cpp | 16 ++ 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index d3cf42251be2e7..3279f4109a9c02 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -270,34 +270,49 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) { } void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) { - if (!FD) + auto *MD = dyn_cast_if_present(FD); + if (!MD || !MD->getParent()->isInStdNamespace()) return; - auto *MD = dyn_cast(FD); - if (!MD || !MD->getIdentifier() || !MD->getParent()->isInStdNamespace()) + auto Annotate = [this](const FunctionDecl *MD) { +// Do not infer if any parameter is explicitly annotated. +for (ParmVarDecl *PVD : MD->parameters()) + if (PVD->hasAttr()) +return; +for (ParmVarDecl *PVD : MD->parameters()) { + // Methods in standard containers that capture values typically accept + // reference-type parameters, e.g., `void push_back(const T& value)`. + // We only apply the lifetime_capture_by attribute to parameters of + // pointer-like reference types (`const T&`, `T&&`). + if (PVD->getType()->isReferenceType() && + sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { +int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; +PVD->addAttr( +LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); + } +} + }; + + if (!MD->getIdentifier()) { +static const llvm::StringSet<> MapLikeContainer{ +"map", +"multimap", +"unordered_map", +"unordered_multimap", +}; +// Infer for the map's operator []: +//std::map m; +//m[ReturnString(..)] = ...; // !dangling references in m. +if (MD->getOverloadedOperator() != OO_Subscript || +!MapLikeContainer.contains(MD->getParent()->getName())) + return; +Annotate(MD); return; - // FIXME: Infer for operator[] for map-like containers. For example: - //std::map m; - //m[ReturnString(..)] = ...; + } static const llvm::StringSet<> CapturingMethods{"insert", "push", "push_front", "push_back"}; if (!CapturingMethods.contains(MD->getName())) return; - // Do not infer if any parameter is explicitly annotated. - for (ParmVarDecl *PVD : MD->parameters()) -if (PVD->hasAttr()) - return; - for (ParmVarDecl *PVD : MD->parameters()) { -// Methods in standard containers that capture values typically accept -// reference-type parameters, e.g., `void push_back(const T& value)`. -// We only apply the lifetime_capture_by attribute to parameters of -// pointer-like reference types (`const T&`, `T&&`). -if (PVD->getType()->isReferenceType() && -sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { - int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; - PVD->addAttr( - LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); -} - } + Annotate(MD); } void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) { diff --git a/clang/test/AST/attr-lifetime-capture-by.cpp b/clang/test/AST/attr-lifetime-capture-by.cpp index debad9b7204d72..71b348dac764bc 100644 --- a/clang/test/AST/attr-lifetime-capture-by.cpp +++ b/clang/test/AST/attr-lifetime-capture-by.cpp @@ -30,6 +30,12 @@ struct vector { void insert(iterator, T&&); }; + +template +struct map { + Value& operator[](Key&& p); + Value& operator[](const Key& p); +}; } // namespace std // CHECK-NOT: LifetimeCaptureByAttr @@ -99,3 +105,13 @@ std::vector ints; // CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' // CHECK-NEXT: ParmVarDecl {{.*}} 'int &&' // CHECK-NOT: LifetimeCaptureByAttr + +std::map map; +// CHECK: ClassTemplateSpecializationDecl {{.*}} struct map definition implicit_instantiation + +// CHECK: CXXMethodDecl {{.*}} operator[] 'int &(View &&)' implicit_instantiation +// CHECK-NEXT: ParmVarDecl {{.*}} p 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK: CXXMethodDecl {{.*}} operator[] 'int &(const View &)' implicit_instantiation +// CHECK-NEXT: ParmVarDecl {{.*}} p 'const View &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Infer lifetime_capture_by for map's subscript operator. (PR #118078)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Haojian Wu (hokein) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/118078.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaAttr.cpp (+37-22) - (modified) clang/test/AST/attr-lifetime-capture-by.cpp (+16) ``diff diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index d3cf42251be2e7..3279f4109a9c02 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -270,34 +270,49 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) { } void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) { - if (!FD) + auto *MD = dyn_cast_if_present(FD); + if (!MD || !MD->getParent()->isInStdNamespace()) return; - auto *MD = dyn_cast(FD); - if (!MD || !MD->getIdentifier() || !MD->getParent()->isInStdNamespace()) + auto Annotate = [this](const FunctionDecl *MD) { +// Do not infer if any parameter is explicitly annotated. +for (ParmVarDecl *PVD : MD->parameters()) + if (PVD->hasAttr()) +return; +for (ParmVarDecl *PVD : MD->parameters()) { + // Methods in standard containers that capture values typically accept + // reference-type parameters, e.g., `void push_back(const T& value)`. + // We only apply the lifetime_capture_by attribute to parameters of + // pointer-like reference types (`const T&`, `T&&`). + if (PVD->getType()->isReferenceType() && + sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { +int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; +PVD->addAttr( +LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); + } +} + }; + + if (!MD->getIdentifier()) { +static const llvm::StringSet<> MapLikeContainer{ +"map", +"multimap", +"unordered_map", +"unordered_multimap", +}; +// Infer for the map's operator []: +//std::map m; +//m[ReturnString(..)] = ...; // !dangling references in m. +if (MD->getOverloadedOperator() != OO_Subscript || +!MapLikeContainer.contains(MD->getParent()->getName())) + return; +Annotate(MD); return; - // FIXME: Infer for operator[] for map-like containers. For example: - //std::map m; - //m[ReturnString(..)] = ...; + } static const llvm::StringSet<> CapturingMethods{"insert", "push", "push_front", "push_back"}; if (!CapturingMethods.contains(MD->getName())) return; - // Do not infer if any parameter is explicitly annotated. - for (ParmVarDecl *PVD : MD->parameters()) -if (PVD->hasAttr()) - return; - for (ParmVarDecl *PVD : MD->parameters()) { -// Methods in standard containers that capture values typically accept -// reference-type parameters, e.g., `void push_back(const T& value)`. -// We only apply the lifetime_capture_by attribute to parameters of -// pointer-like reference types (`const T&`, `T&&`). -if (PVD->getType()->isReferenceType() && -sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { - int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; - PVD->addAttr( - LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); -} - } + Annotate(MD); } void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) { diff --git a/clang/test/AST/attr-lifetime-capture-by.cpp b/clang/test/AST/attr-lifetime-capture-by.cpp index debad9b7204d72..71b348dac764bc 100644 --- a/clang/test/AST/attr-lifetime-capture-by.cpp +++ b/clang/test/AST/attr-lifetime-capture-by.cpp @@ -30,6 +30,12 @@ struct vector { void insert(iterator, T&&); }; + +template +struct map { + Value& operator[](Key&& p); + Value& operator[](const Key& p); +}; } // namespace std // CHECK-NOT: LifetimeCaptureByAttr @@ -99,3 +105,13 @@ std::vector ints; // CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' // CHECK-NEXT: ParmVarDecl {{.*}} 'int &&' // CHECK-NOT: LifetimeCaptureByAttr + +std::map map; +// CHECK: ClassTemplateSpecializationDecl {{.*}} struct map definition implicit_instantiation + +// CHECK: CXXMethodDecl {{.*}} operator[] 'int &(View &&)' implicit_instantiation +// CHECK-NEXT: ParmVarDecl {{.*}} p 'View &&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK: CXXMethodDecl {{.*}} operator[] 'int &(const View &)' implicit_instantiation +// CHECK-NEXT: ParmVarDecl {{.*}} p 'const View &' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit `` https://github.com/llvm/llvm-project/pull/118078 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] [libunwind][Haiku] Improve support (PR #115462)
https://github.com/korli updated https://github.com/llvm/llvm-project/pull/115462 From c88a3b1f8c8db4b222c0fdc306088a00bee54938 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Thu, 7 Jul 2022 22:19:34 +0700 Subject: [PATCH 1/2] [libunwind][Haiku] Improve support * Signal frame unwinding on x86_64 from X512 * Header search for commpage_defs.h on non-standard paths --- libunwind/src/CMakeLists.txt | 16 libunwind/src/UnwindCursor.hpp | 72 -- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt index 2e18b109656331..e7ea57734cca97 100644 --- a/libunwind/src/CMakeLists.txt +++ b/libunwind/src/CMakeLists.txt @@ -113,6 +113,22 @@ if (HAIKU) add_compile_flags("-D_DEFAULT_SOURCE") add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") + + find_path(LIBUNWIND_HAIKU_PRIVATE_HEADERS +"commpage_defs.h" +PATHS ${CMAKE_SYSTEM_INCLUDE_PATH} +PATH_SUFFIXES "/private/system" +NO_DEFAULT_PATH +REQUIRED) + + include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}") + if (LIBUNWIND_TARGET_TRIPLE) +if (${LIBUNWIND_TARGET_TRIPLE} MATCHES "^x86_64") + include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/x86_64") +endif() + else() +include_directories(SYSTEM "${LIBUNWIND_HAIKU_PRIVATE_HEADERS}/arch/${CMAKE_SYSTEM_PROCESSOR}") + endif() endif () string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index 32e6fb43d988ff..371f8dd647758f 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -1010,6 +1010,9 @@ class UnwindCursor : public AbstractUnwindCursor{ template int stepThroughSigReturn(Registers &) { return UNW_STEP_END; } +#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) + bool setInfoForSigReturn(); + int stepThroughSigReturn(); #endif #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) @@ -1313,7 +1316,8 @@ class UnwindCursor : public AbstractUnwindCursor{ unw_proc_info_t _info; bool _unwindInfoMissing; bool _isSignalFrame; -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ +(defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)) bool _isSigReturn = false; #endif }; @@ -2549,7 +2553,8 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, template void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ +(defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)) _isSigReturn = false; #endif @@ -2673,7 +2678,8 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { } #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ +(defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)) if (setInfoForSigReturn()) return; #endif @@ -2749,6 +2755,63 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { _isSignalFrame = true; return UNW_STEP_SUCCESS; } +#elif defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64) + +#include +#include + +extern "C" { +extern void *__gCommPageAddress; +} + +template +bool UnwindCursor::setInfoForSigReturn() { +#if defined(_LIBUNWIND_TARGET_X86_64) + addr_t signal_handler = + (((addr_t *)__gCommPageAddress)[COMMPAGE_ENTRY_X86_SIGNAL_HANDLER] + + (addr_t)__gCommPageAddress); + addr_t signal_handler_ret = signal_handler + 45; +#endif + pint_t pc = static_cast(this->getReg(UNW_REG_IP)); + if (pc == signal_handler_ret) { +_info = {}; +_info.start_ip = signal_handler; +_info.end_ip = signal_handler_ret; +_isSigReturn = true; +return true; + } + return false; +} + +template +int UnwindCursor::stepThroughSigReturn() { + _isSignalFrame = true; + pint_t sp = _registers.getSP(); +#if defined(_LIBUNWIND_TARGET_X86_64) + vregs *regs = (vregs *)(sp + 0x70); + + _registers.setRegister(UNW_REG_IP, regs->rip); + _registers.setRegister(UNW_REG_SP, regs->rsp); + _registers.setRegister(UNW_X86_64_RAX, regs->rax); + _registers.setRegister(UNW_X86_64_RDX, regs->rdx); + _registers.setRegister(UNW_X86_64_RCX, regs->rcx); + _registers.setRegister(UNW_X86_64_RBX, regs->rbx); + _registers.setRegister(UNW_X86_64_RSI, regs->rsi); + _registers.setRegister(UNW_X86_64_RDI, regs->rdi); + _registers.setRegister(UNW_X86_64_RBP, regs->rbp); + _registers.setRegister(UNW_X86_64_R8, regs->r8); + _registers.setRegister(UNW_X86_64_R9, regs->r9); + _registers.set
[libunwind] [libunwind][Haiku] Improve support (PR #115462)
@@ -2917,7 +2980,8 @@ template int UnwindCursor::step(bool stage2) { // Use unwinding info to modify register set as if function returned. int result; -#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) || \ +(defined(_LIBUNWIND_TARGET_HAIKU) && defined(_LIBUNWIND_TARGET_X86_64)) korli wrote: Right, removed the unneeded checks. https://github.com/llvm/llvm-project/pull/115462 ___ 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 readability-use-span-first-last check (PR #118074)
hjanuschka wrote: @carlosgalvezp thanks for the feedback. I've removed the transformation: ```c++ auto sub2 = s.subspan(n);// transforms to: auto sub2 = s.last(s.size() - n); ``` While I agree that the transformed expression is more complex (due to size() - x), I initially included it for two reasons: Consistency: Using `first()/last()` everywhere possible makes the codebase more uniform The method name `last()` better expresses the intent than `subspan()`, even if the calculation is more verbose Let me know if you think we should revisit this decision. https://github.com/llvm/llvm-project/pull/118074 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix generation of wasm binaries while running clang-repl in browser (PR #117978)
llvmbot wrote: /pull-request llvm/llvm-project#118077 https://github.com/llvm/llvm-project/pull/117978 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [FixIt] Improve Source Ranges and Fix-It Hints for Unused Lambda Captures #106445 (PR #117953)
https://github.com/charan-003 updated https://github.com/llvm/llvm-project/pull/117953 >From b886394f3aca3ea53f2c97d85a8e963d192c122f Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:43:38 -0700 Subject: [PATCH 1/9] Update SemaLambda.cpp This patch refines how Clang handles source ranges for unused lambda captures. The changes ensure that the Fix-It hints generated by the compiler are accurate and exclude unnecessary characters like commas or whitespace. Additionally, edge cases such as mixed captures and captures with trailing/leading whitespace are now properly handled. --- clang/lib/Sema/SemaLambda.cpp | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a67c0b2b367d1a..e7417d1a884dcd 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,8 +1164,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) -LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; - continue; + { + SourceRange TrimmedRange = Lexer::makeFileCharRange( + C->ExplicitRange, SM, LangOpts); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; + } } assert(C->Id && "missing identifier for capture"); @@ -1329,7 +1332,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); } if (!LSI->Captures.empty()) - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; + { +SourceRange TrimmedRange = Lexer::makeFileCharRange( +C->ExplicitRange, SM, LangOpts); +LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; +} } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From ccb39521d4e246bb2b1fd2c9f3727d2332b9a6df Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:48:37 -0700 Subject: [PATCH 2/9] Update fixit-unused-lambda-capture.cpp This patch extends the existing test coverage in fixit-unused-lambda-capture.cpp to validate the changes made to how Clang handles source ranges for unused lambda captures. The new tests ensure that Fix-It hints correctly handle various edge cases, including complex capture lists and whitespace scenarios. --- .../FixIt/fixit-unused-lambda-capture.cpp | 32 +++ 1 file changed, 32 insertions(+) diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp index ce0c78d677099a..ae43d4ebbdf821 100644 --- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp +++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp @@ -66,6 +66,38 @@ void test() { // CHECK: [z = (n = i)] {}; [j,z = (n = i)] {}; // CHECK: [z = (n = i)] {}; + + // New Edge Cases + + // Test 1: Leading and trailing whitespace + [i,j] { return i; }; + // CHECK: [i] { return i; }; + [i ,j] { return j; }; + // CHECK: [j] { return j; }; + [i , j , k] { return j + k; }; + // CHECK: [j,k] { return j + k; }; + + // Test 2: Single unused capture + [i] {}; + // CHECK: [] {}; + [&i] {}; + // CHECK: [] {}; + + // Test 3: Multiple commas + [i,,j] { return j; }; + // CHECK: [j] { return j; }; + [,i,j,,k] { return k; }; + // CHECK: [k] { return k; }; + + // Test 4: Mixed captures + [=, &i, j] { return i; }; + // CHECK: [&i] { return i; }; + [&, i] {}; + // CHECK: [&] {}; + + // Test 5: Capture with comments + [/*capture*/ i, j] { return j; }; + // CHECK: [/*capture*/ j] { return j; }; } class ThisTest { >From 6b5fff5d2f10e422f94939213d2302a87501a867 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:52:22 -0700 Subject: [PATCH 3/9] Update SemaLambda.cpp added #include "clang/Lex/Lexer.h" --- clang/lib/Sema/SemaLambda.cpp | 5 + 1 file changed, 5 insertions(+) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e7417d1a884dcd..82a0f926d6af75 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "clang/Lex/Lexer.h" #include using namespace clang; using namespace sema; @@ -1165,6 +1166,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) { + SourceManager &SourceMgr = Context.getSourceManager(); + cons
[clang-tools-extra] [clang-tidy] Add readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 01/11] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clang-tidy] Add readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 01/12] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang-tools-extra] [clang-tidy] Add readability-use-span-first-last check (PR #118074)
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/118074 >From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Fri, 29 Nov 2024 10:17:49 +0100 Subject: [PATCH 01/13] [clang-tidy] Add modernize-use-span-first-last check Add new check that modernizes std::span::subspan() calls to use the more expressive first() and last() member functions where applicable. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseSpanFirstLastCheck.cpp | 97 +++ .../modernize/UseSpanFirstLastCheck.h | 40 clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checks/modernize/use-span-first-last.rst | 19 .../modernize-subspan-conversion.cpp | 50 ++ 7 files changed, 214 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..47dd12a2640b6c 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseTransparentFunctorsCheck.cpp UseUncaughtExceptionsCheck.cpp UseUsingCheck.cpp + UseSpanFirstLastCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..6fc5de5aad20b7 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -42,6 +42,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseSpanFirstLastCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-uncaught-exceptions"); CheckFactories.registerCheck("modernize-use-using"); + CheckFactories.registerCheck("modernize-use-span-first-last"); + } }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp new file mode 100644 index 00..f57571f2aa7c86 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp @@ -0,0 +1,97 @@ +//===--- UseSpanFirstLastCheck.cpp - clang-tidy-*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseSpanFirstLastCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) { + // Match span::subspan calls + const auto HasSpanType = hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName("::std::span")); + + Finder->addMatcher( + cxxMemberCallExpr( + callee(memberExpr(hasDeclaration( + cxxMethodDecl(hasName("subspan"), + on(expr(HasSpanType))) + .bind("subspan"), + this); +} + +void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Call = Result.Nodes.getNodeAs("subspan"); + if (!Call) +return; + + handleSubspanCall(Result, Call); +} + +void UseSpanFirstLastCheck::handleSubspanCall( +const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) { + // Get arguments + unsigned NumArgs = Call->getNumArgs(); + if (NumArgs == 0 || NumArgs > 2) +return; + + const Expr *Offset = Call->getArg(0); + const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr; + auto &Context = *Result.Context; + bool IsZeroOffset = false; + + // Check if offset is zero through any implicit casts + const Expr* OffsetE = Offset->IgnoreImpCasts(); + if (const auto *IL = dyn_cast(OffsetE)) { +IsZeroOffset = IL->getValue() == 0; + } + + // Build replacement text + std::string Replacement; + if (IsZeroOffset && Count) { +
[clang] [clang][ARM] disable frame pointers by default for bare metal ARM targets (PR #117140)
https://github.com/stuij updated https://github.com/llvm/llvm-project/pull/117140 >From 4a85a0cd98bf328f31465d47c56640abdf7ec08c Mon Sep 17 00:00:00 2001 From: Ties Stuij Date: Fri, 15 Nov 2024 13:19:08 + Subject: [PATCH 1/6] [clang][ARM] disable frame pointers by default for bare metal ARM targets because: - This brings Clang in line with GCC for which this is the default for ARM - It frees up a register, so performance increase, especially on Thumb/6-M - It will also decrease code size --- clang/lib/Driver/ToolChains/BareMetal.cpp | 8 +- clang/lib/Driver/ToolChains/BareMetal.h| 2 ++ clang/lib/Driver/ToolChains/CommonArgs.cpp | 5 clang/test/Driver/frame-pointer-elim.c | 29 ++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index f9a73f60973e4c..13b510e7e70994 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -128,8 +128,11 @@ BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, } } +namespace clang { +namespace driver { +namespace toolchains { /// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ? -static bool isARMBareMetal(const llvm::Triple &Triple) { +bool isARMBareMetal(const llvm::Triple &Triple) { if (Triple.getArch() != llvm::Triple::arm && Triple.getArch() != llvm::Triple::thumb && Triple.getArch() != llvm::Triple::armeb && @@ -148,6 +151,9 @@ static bool isARMBareMetal(const llvm::Triple &Triple) { return true; } +} // namespace clang +} // namespace driver +} // namespace clang /// Is the triple {aarch64.aarch64_be}-none-elf? static bool isAArch64BareMetal(const llvm::Triple &Triple) { diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h index b385c8cf76aab0..ae09bcedd78a28 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -19,6 +19,8 @@ namespace driver { namespace toolchains { +bool isARMBareMetal(const llvm::Triple &Triple); + class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain { public: BareMetal(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 8d977149e62485..8d54d0a8649cc9 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -19,6 +19,7 @@ #include "Arch/SystemZ.h" #include "Arch/VE.h" #include "Arch/X86.h" +#include "BareMetal.h" #include "HIPAMD.h" #include "Hexagon.h" #include "MSP430.h" @@ -151,6 +152,10 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, } } + if (toolchains::isARMBareMetal(Triple)) { +return false; + } + return true; } diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c index cdedcc7ae4c89f..667c47b34bc703 100644 --- a/clang/test/Driver/frame-pointer-elim.c +++ b/clang/test/Driver/frame-pointer-elim.c @@ -162,5 +162,34 @@ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s + +// On ARM backend bare metal targets, frame pointer is omitted +// RUN: %clang -### --target=arm-arm-none-eabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s + +// AArch64 bare metal targets behave like hosted targets +// RUN: %clang -### --target=aarch64-none-elf -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KE
[clang] [clang][ARM] disable frame pointers by default for bare metal ARM targets (PR #117140)
@@ -151,6 +152,9 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, } } + if (toolchains::isARMBareMetal(Triple)) stuij wrote: done! https://github.com/llvm/llvm-project/pull/117140 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Support for dispatch construct (Sema & Codegen) support. (PR #117904)
https://github.com/SunilKuravinakop updated https://github.com/llvm/llvm-project/pull/117904 >From f4f557026880eb9dcb2c0ba01143cca2addf412f Mon Sep 17 00:00:00 2001 From: Sunil Kuravinakop Date: Fri, 20 Sep 2024 01:41:29 -0500 Subject: [PATCH] Support for dispatch construct (Sema & Codegen) support. Support for clauses depend, novariants & nocontext. --- .../clang/Basic/DiagnosticSemaKinds.td| 3 + clang/include/clang/Basic/OpenMPKinds.h | 6 + clang/include/clang/Sema/SemaOpenMP.h | 7 + clang/lib/Basic/OpenMPKinds.cpp | 5 + clang/lib/CodeGen/CGStmt.cpp | 2 +- clang/lib/CodeGen/CGStmtOpenMP.cpp| 4 + clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Sema/SemaOpenMP.cpp | 301 ++- clang/test/OpenMP/dispatch_codegen.cpp| 359 ++ clang/test/OpenMP/dispatch_unsupported.c | 7 - .../include/llvm/Frontend/OpenMP/OMPContext.h | 6 + 11 files changed, 687 insertions(+), 14 deletions(-) create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8495884dcd058f..81b876f9fd85c5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error< "'%0' clause requires 'dispatch' context selector">; def err_omp_append_args_with_varargs : Error< "'append_args' is not allowed with varargs functions">; +def warn_omp_dispatch_clause_novariants_nocontext : Warning< + "only 'novariants' clause is supported when 'novariants' & 'nocontext' clauses occur on the same dispatch construct">, + InGroup; def err_openmp_vla_in_task_untied : Error< "variable length arrays are not supported in OpenMP tasking regions with 'untied' clause">; def warn_omp_unterminated_declare_target : Warning< diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 900ad6ca6d66f6..7579fab43dbb19 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind); /// parallel', otherwise - false. bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind); +/// Checks if the specified directive is a dispatch-kind directive. +/// \param DKind Specified directive. +/// \return true - the directive is a dispatch-like directive like 'omp +/// dispatch', otherwise - false. +bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind); + /// Checks if the specified directive is a target code offload directive. /// \param DKind Specified directive. /// \return true - the directive is a target code offload directive like diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 3d1cc4fab1c10f..80cee9e7583051 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase { : OMPDeclareVariantScopes.back().TI; } + StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind, +const DeclarationNameInfo &DirName, +OpenMPDirectiveKind CancelRegion, +ArrayRef Clauses, +Stmt *AStmt, SourceLocation StartLoc, +SourceLocation EndLoc); + /// The current `omp begin/end declare variant` scopes. SmallVector OMPDeclareVariantScopes; diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 62a13f01481b28..44ee63df46adb5 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel); } +bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_dispatch || + llvm::is_contained(getLeafConstructs(DKind), OMPD_target); +} + bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_target || llvm::is_contained(getLeafConstructs(DKind), OMPD_target); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 698baf853507f4..f3eedb79844378 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { EmitOMPInteropDirective(cast(*S)); break; case Stmt::OMPDispatchDirectiveClass: -CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); +Emi
[clang] [clang] Fix a crash issue that caused by handling of fields with initializers in nested anonymous unions (PR #113049)
yronglin wrote: friendly ping~ https://github.com/llvm/llvm-project/pull/113049 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Support for dispatch construct (Sema & Codegen) support. (PR #117904)
https://github.com/SunilKuravinakop updated https://github.com/llvm/llvm-project/pull/117904 >From 1703aa62cfe35538aedbacb28e907535e838248c Mon Sep 17 00:00:00 2001 From: Sunil Kuravinakop Date: Fri, 20 Sep 2024 01:41:29 -0500 Subject: [PATCH] Support for dispatch construct (Sema & Codegen) support. Support for clauses depend, novariants & nocontext. --- .../clang/Basic/DiagnosticSemaKinds.td| 3 + clang/include/clang/Basic/OpenMPKinds.h | 6 + clang/include/clang/Sema/SemaOpenMP.h | 7 + clang/lib/Basic/OpenMPKinds.cpp | 5 + clang/lib/CodeGen/CGStmt.cpp | 2 +- clang/lib/CodeGen/CGStmtOpenMP.cpp| 4 + clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Sema/SemaOpenMP.cpp | 301 ++- clang/test/OpenMP/dispatch_codegen.cpp| 359 ++ clang/test/OpenMP/dispatch_unsupported.c | 7 - .../include/llvm/Frontend/OpenMP/OMPContext.h | 6 + 11 files changed, 687 insertions(+), 14 deletions(-) create mode 100644 clang/test/OpenMP/dispatch_codegen.cpp delete mode 100644 clang/test/OpenMP/dispatch_unsupported.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8495884dcd058f..81b876f9fd85c5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11774,6 +11774,9 @@ def err_omp_clause_requires_dispatch_construct : Error< "'%0' clause requires 'dispatch' context selector">; def err_omp_append_args_with_varargs : Error< "'append_args' is not allowed with varargs functions">; +def warn_omp_dispatch_clause_novariants_nocontext : Warning< + "only 'novariants' clause is supported when 'novariants' & 'nocontext' clauses occur on the same dispatch construct">, + InGroup; def err_openmp_vla_in_task_untied : Error< "variable length arrays are not supported in OpenMP tasking regions with 'untied' clause">; def warn_omp_unterminated_declare_target : Warning< diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 900ad6ca6d66f6..7579fab43dbb19 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -269,6 +269,12 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind); /// parallel', otherwise - false. bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind); +/// Checks if the specified directive is a dispatch-kind directive. +/// \param DKind Specified directive. +/// \return true - the directive is a dispatch-like directive like 'omp +/// dispatch', otherwise - false. +bool isOpenMPDispatchDirective(OpenMPDirectiveKind DKind); + /// Checks if the specified directive is a target code offload directive. /// \param DKind Specified directive. /// \return true - the directive is a target code offload directive like diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 3d1cc4fab1c10f..80cee9e7583051 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1462,6 +1462,13 @@ class SemaOpenMP : public SemaBase { : OMPDeclareVariantScopes.back().TI; } + StmtResult transformDispatchDirective(OpenMPDirectiveKind Kind, +const DeclarationNameInfo &DirName, +OpenMPDirectiveKind CancelRegion, +ArrayRef Clauses, +Stmt *AStmt, SourceLocation StartLoc, +SourceLocation EndLoc); + /// The current `omp begin/end declare variant` scopes. SmallVector OMPDeclareVariantScopes; diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 62a13f01481b28..44ee63df46adb5 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -621,6 +621,11 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel); } +bool clang::isOpenMPDispatchDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_dispatch || + llvm::is_contained(getLeafConstructs(DKind), OMPD_target); +} + bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_target || llvm::is_contained(getLeafConstructs(DKind), OMPD_target); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 698baf853507f4..f3eedb79844378 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -417,7 +417,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { EmitOMPInteropDirective(cast(*S)); break; case Stmt::OMPDispatchDirectiveClass: -CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); +Emi
[clang] [Clang][AArch64]Refactor typespec handling in SveEmitter.cpp (PR #117717)
@@ -50,20 +50,30 @@ using TypeSpec = std::string; namespace { class SVEType { - bool Float, Signed, Immediate, Void, Constant, Pointer, BFloat, MFloat; - bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp, - Svcount; + + enum TypeKind { +Void, +Float, +SInt, +UInt, +BFloat16, +MFloat8, +Svcount, +PrefetchOp, +PredicatePattern, +Predicate + }; + TypeKind Kind; + bool Immediate, Constant, Pointer, DefaultType, IsScalable; unsigned Bitwidth, ElementBitwidth, NumVectors; public: SVEType() : SVEType("", 'v') {} SVEType(StringRef TS, char CharMod, unsigned NumVectors = 1) - : Float(false), Signed(true), Immediate(false), Void(false), -Constant(false), Pointer(false), BFloat(false), MFloat(false), -DefaultType(false), IsScalable(true), Predicate(false), -PredicatePattern(false), PrefetchOp(false), Svcount(false), -Bitwidth(128), ElementBitwidth(~0U), NumVectors(NumVectors) { + : Kind(SInt), Immediate(false), Constant(false), Pointer(false), SpencerAbson wrote: I think this is a good idea, though it's a little tricky becuase the typespecs `'c'`, `'s'` ,`'i'` and`'l'` are often seen following a typespec modifier in arm_sve.td to change the element size (e.g, for predicates/SVCounts as you described before), and as typespecs in their own right (referring to the signed integer of their size, which is where the `Kind(SInt)` default comes from). One way to go about this is to make `'c'`, `'s'` ,`'i'` and`'l'` default to `SInt` if there is currently no type set, and leave the type unmodified if otherwise. Any thoughts? https://github.com/llvm/llvm-project/pull/117717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Infer lifetime_capture_by for map's subscript operator. (PR #118078)
https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/118078 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Infer lifetime_capture_by for map's subscript operator. (PR #118078)
https://github.com/usx95 approved this pull request. Thanks. LGTM. https://github.com/llvm/llvm-project/pull/118078 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Infer lifetime_capture_by for map's subscript operator. (PR #118078)
@@ -270,34 +270,49 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) { } void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) { - if (!FD) + auto *MD = dyn_cast_if_present(FD); + if (!MD || !MD->getParent()->isInStdNamespace()) return; - auto *MD = dyn_cast(FD); - if (!MD || !MD->getIdentifier() || !MD->getParent()->isInStdNamespace()) + auto Annotate = [this](const FunctionDecl *MD) { +// Do not infer if any parameter is explicitly annotated. +for (ParmVarDecl *PVD : MD->parameters()) + if (PVD->hasAttr()) +return; +for (ParmVarDecl *PVD : MD->parameters()) { + // Methods in standard containers that capture values typically accept + // reference-type parameters, e.g., `void push_back(const T& value)`. + // We only apply the lifetime_capture_by attribute to parameters of + // pointer-like reference types (`const T&`, `T&&`). + if (PVD->getType()->isReferenceType() && + sema::isPointerLikeType(PVD->getType().getNonReferenceType())) { +int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; +PVD->addAttr( +LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); + } +} + }; + + if (!MD->getIdentifier()) { +static const llvm::StringSet<> MapLikeContainer{ +"map", +"multimap", +"unordered_map", +"unordered_multimap", +}; +// Infer for the map's operator []: +//std::map m; +//m[ReturnString(..)] = ...; // !dangling references in m. +if (MD->getOverloadedOperator() != OO_Subscript || +!MapLikeContainer.contains(MD->getParent()->getName())) + return; usx95 wrote: nit: early returns complicates this. Maybe simplify like: ```cpp if (MD->getOverloadedOperator() == OO_Subscript && MapLikeContainer.contains(MD->getParent()->getName())) Annotate(MD); return; ``` https://github.com/llvm/llvm-project/pull/118078 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Format bitfield width diagnostics with thousands-separators (PR #117763)
Timm =?utf-8?q?Bäder?= Message-ID: In-Reply-To: Sirraide wrote: > Is the lifetime for the APSInt here OK? When I call `Diag()`, will the be > diagnostic emitted immediately? Or does the APSInt need to life longer? Iirc that cause problems if e.g. `PDiag` is used since the diagnostic is stored and emitted later. https://github.com/llvm/llvm-project/pull/117763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[clang] Fix name lookup for dependent bases" (PR #118003)
vbe-sc wrote: @cor3ntin, FYI: we reverted the patch you merged before. This is the second attempt https://github.com/llvm/llvm-project/pull/118003 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Modernize, improve and promote chroot checker (PR #117791)
vabridgers wrote: Thanks @steakhal ! https://github.com/llvm/llvm-project/pull/117791 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64]Refactor typespec handling in SveEmitter.cpp (PR #117717)
https://github.com/SpencerAbson edited https://github.com/llvm/llvm-project/pull/117717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64]Refactor typespec handling in SveEmitter.cpp (PR #117717)
https://github.com/SpencerAbson edited https://github.com/llvm/llvm-project/pull/117717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64]Refactor typespec handling in SveEmitter.cpp (PR #117717)
https://github.com/SpencerAbson edited https://github.com/llvm/llvm-project/pull/117717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
https://github.com/hokein created https://github.com/llvm/llvm-project/pull/118088 A specialization declaration can have an attribute even if the primary template does not, particularly when the specialization is instantiated from an annotated using-alias declaration. Fix #118064 >From b165ad7accfc746210c5ca894b488553124253ed Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 29 Nov 2024 13:35:56 +0100 Subject: [PATCH] [clang] Fix a regression. --- clang/lib/Sema/CheckExprLifetime.cpp | 18 +-- .../Sema/warn-lifetime-analysis-nocfg.cpp | 23 +++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 15ceff873693a5..86a5fa662aed0e 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -258,9 +258,23 @@ template static bool isRecordWithAttr(QualType Type) { auto *RD = Type->getAsCXXRecordDecl(); if (!RD) return false; + // Generally, if a primary template class declaration is annotated with an + // attribute, all its specializations generated from template instantiations + // should inherit the attribute. + // + // However, since lifetime analysis occurs during parsing, we may encounter + // cases where a full definition of the specialization is not required. In + // such cases, the specialization declaration remains incomplete and lacks the + // attribute. Therefore, we fall back to checking the primary template class. + // + // Note: it is possible for a specialization declaration to have an attribute + // even if the primary template does not. + bool Result = RD->hasAttr(); + if (auto *CTSD = dyn_cast(RD)) -RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); - return RD->hasAttr(); +Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); + + return Result; } bool isPointerLikeType(QualType QT) { diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index c18ecd86ad06f0..fc876926ba2e63 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -670,3 +670,26 @@ void test13() { } } // namespace GH100526 + +namespace std { +template +class __set_iterator {}; + +template +struct BB { + typedef __set_iterator iterator; +}; + +template +class set { +public: + typedef typename BB::iterator iterator; + iterator begin() const; +}; +} // namespace std +namespace GH118064{ + +void test() { + auto y = std::set{}.begin(); // expected-warning {{object backing the pointer}} +} +} // namespace GH118064 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Haojian Wu (hokein) Changes A specialization declaration can have an attribute even if the primary template does not, particularly when the specialization is instantiated from an annotated using-alias declaration. Fix #118064 --- Full diff: https://github.com/llvm/llvm-project/pull/118088.diff 2 Files Affected: - (modified) clang/lib/Sema/CheckExprLifetime.cpp (+16-2) - (modified) clang/test/Sema/warn-lifetime-analysis-nocfg.cpp (+23) ``diff diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 15ceff873693a5..86a5fa662aed0e 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -258,9 +258,23 @@ template static bool isRecordWithAttr(QualType Type) { auto *RD = Type->getAsCXXRecordDecl(); if (!RD) return false; + // Generally, if a primary template class declaration is annotated with an + // attribute, all its specializations generated from template instantiations + // should inherit the attribute. + // + // However, since lifetime analysis occurs during parsing, we may encounter + // cases where a full definition of the specialization is not required. In + // such cases, the specialization declaration remains incomplete and lacks the + // attribute. Therefore, we fall back to checking the primary template class. + // + // Note: it is possible for a specialization declaration to have an attribute + // even if the primary template does not. + bool Result = RD->hasAttr(); + if (auto *CTSD = dyn_cast(RD)) -RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); - return RD->hasAttr(); +Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); + + return Result; } bool isPointerLikeType(QualType QT) { diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index c18ecd86ad06f0..fc876926ba2e63 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -670,3 +670,26 @@ void test13() { } } // namespace GH100526 + +namespace std { +template +class __set_iterator {}; + +template +struct BB { + typedef __set_iterator iterator; +}; + +template +class set { +public: + typedef typename BB::iterator iterator; + iterator begin() const; +}; +} // namespace std +namespace GH118064{ + +void test() { + auto y = std::set{}.begin(); // expected-warning {{object backing the pointer}} +} +} // namespace GH118064 `` https://github.com/llvm/llvm-project/pull/118088 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] NFC, simplify the attr-lifetime-capture-by.test (PR #118001)
https://github.com/hokein closed https://github.com/llvm/llvm-project/pull/118001 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] NFC, simplify the attr-lifetime-capture-by.test (PR #118001)
hokein wrote: committed as part of https://github.com/llvm/llvm-project/commit/352f8688d0ca250c9e8774321f6c3bcd4298cc09. https://github.com/llvm/llvm-project/pull/118001 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
https://github.com/usx95 approved this pull request. Thanks for quickly addressing this! https://github.com/llvm/llvm-project/pull/118088 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/118088 >From b165ad7accfc746210c5ca894b488553124253ed Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 29 Nov 2024 13:35:56 +0100 Subject: [PATCH 1/2] [clang] Fix a regression. --- clang/lib/Sema/CheckExprLifetime.cpp | 18 +-- .../Sema/warn-lifetime-analysis-nocfg.cpp | 23 +++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 15ceff873693a5..86a5fa662aed0e 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -258,9 +258,23 @@ template static bool isRecordWithAttr(QualType Type) { auto *RD = Type->getAsCXXRecordDecl(); if (!RD) return false; + // Generally, if a primary template class declaration is annotated with an + // attribute, all its specializations generated from template instantiations + // should inherit the attribute. + // + // However, since lifetime analysis occurs during parsing, we may encounter + // cases where a full definition of the specialization is not required. In + // such cases, the specialization declaration remains incomplete and lacks the + // attribute. Therefore, we fall back to checking the primary template class. + // + // Note: it is possible for a specialization declaration to have an attribute + // even if the primary template does not. + bool Result = RD->hasAttr(); + if (auto *CTSD = dyn_cast(RD)) -RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); - return RD->hasAttr(); +Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); + + return Result; } bool isPointerLikeType(QualType QT) { diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index c18ecd86ad06f0..fc876926ba2e63 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -670,3 +670,26 @@ void test13() { } } // namespace GH100526 + +namespace std { +template +class __set_iterator {}; + +template +struct BB { + typedef __set_iterator iterator; +}; + +template +class set { +public: + typedef typename BB::iterator iterator; + iterator begin() const; +}; +} // namespace std +namespace GH118064{ + +void test() { + auto y = std::set{}.begin(); // expected-warning {{object backing the pointer}} +} +} // namespace GH118064 >From 11300e4a5a7632233bfd6c33ffaea4bd969b50c0 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 29 Nov 2024 13:54:03 +0100 Subject: [PATCH 2/2] Add a missing comment. --- clang/lib/Sema/CheckExprLifetime.cpp | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 86a5fa662aed0e..868081292bc32c 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -269,10 +269,14 @@ template static bool isRecordWithAttr(QualType Type) { // // Note: it is possible for a specialization declaration to have an attribute // even if the primary template does not. + // + // FIXME: What if the primary template and explicit specialization + // declarations have conflicting attributes? We should consider diagnosing + // this scenario. bool Result = RD->hasAttr(); if (auto *CTSD = dyn_cast(RD)) -Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); +Result |= CTSD->getSpecializedTemplate()->getTemplatedDecl()->hasAttr(); return Result; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
hokein wrote: @usx95 Looks like I uploaded an incomplete version, please take another look. https://github.com/llvm/llvm-project/pull/118088 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
@@ -258,9 +258,27 @@ template static bool isRecordWithAttr(QualType Type) { auto *RD = Type->getAsCXXRecordDecl(); if (!RD) return false; + // Generally, if a primary template class declaration is annotated with an + // attribute, all its specializations generated from template instantiations + // should inherit the attribute. + // + // However, since lifetime analysis occurs during parsing, we may encounter + // cases where a full definition of the specialization is not required. In + // such cases, the specialization declaration remains incomplete and lacks the + // attribute. Therefore, we fall back to checking the primary template class. + // + // Note: it is possible for a specialization declaration to have an attribute + // even if the primary template does not. + // + // FIXME: What if the primary template and explicit specialization + // declarations have conflicting attributes? We should consider diagnosing + // this scenario. usx95 wrote: I think this looks fine for now. Merging seems to be right thing for now. Although merging Owner and Pointer seems problematic though which we should diagnose. Let's revisit if there is a need. https://github.com/llvm/llvm-project/pull/118088 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix -Wdangling false negative regressions caused by 117315 (PR #118088)
https://github.com/usx95 approved this pull request. https://github.com/llvm/llvm-project/pull/118088 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Driver][OpenMP] Fix OpenMP target-toolchain-option parser (PR #115375)
https://github.com/alexey-bataev approved this pull request. https://github.com/llvm/llvm-project/pull/115375 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Change placeholder from `undef` to `poison` (PR #117064)
pedroclobo wrote: Ping https://github.com/llvm/llvm-project/pull/117064 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) (PR #118096)
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/118096 Like in the test case: ```c++ struct String { String(const String &) {} }; struct MatchComponent { unsigned numbers[2]; String prerelease; MatchComponent(MatchComponent const &) = default; }; MatchComponent get(); void consume(MatchComponent const &); MatchComponent parseMatchComponent() { MatchComponent component = get(); component.numbers[0] = 10; component.numbers[1] = 20; return component; // We should have no stack addr escape warning here. } void top() { consume(parseMatchComponent()); } ``` When calling `consume(parseMatchComponent())` the `parseMatchComponent()` would return a copy of a temporary of `component`. That copy would invoke the `MatchComponent::MatchComponent(const MatchComponent &)` ctor. That ctor would have a (reference typed) ParamVarRegion, holding the location (lvalue) of the object we are about to copy (&component). So far so good, but just before evaluating the binding operation for initializing the `numbers` field of the temporary, we evaluate the ArrayInitLoopExpr representing the by-value elementwise copy of the array `component.numbers`. This is represented by a LazyCompoundVal, because we (usually) don't just copy large arrays and bind many individual direct bindings. Rather, we take a snapshot by using a LCV. However, notice that the LCV representing this copy would look like this: lazyCompoundVal{ParamVarRegion{"reference param of cctor"}.numbers} Notice that it refers to the numbers field of a reference. It would be much better to desugar the reference to the actual object, thus it should be: `lazyCompoundVal{component.numbers}` Actually, when binding the result of the ArrayInitLoopExpr to the `temp_object.numbers` in the compiler-generated member initializer of the cctor, we should have two individual direct bindings because this is a "small array": ``` binding &Element{temp_object.numbers, 0} <- loadFrom(&Element{component.numbers, 0}) binding &Element{temp_object.numbers, 1} <- loadFrom(&Element{component.numbers, 1}) ``` Where `loadFrom(...)` would be: ``` loadFrom(&Element{component.numbers, 0}): 10 U32b loadFrom(&Element{component.numbers, 1}): 20 U32b ``` So the store should look like this, after PostInitializer of `temp_object.numbers`: ``` temp_object at offset 0: 10 U32b temp_object at offset 32: 20 U32b ``` The lesson is that it's okay to have TypedValueRegions of references as long as we don't form subregions of those. If we ever want to refer to a subregion of a "reference" we actually meant to "desugar" the reference and slice a subregion of the pointee of the reference instead. Once this canonicalization is in place, we can also drop the special handling of references in `ProcessInitializer`, because now reference TypedValueRegions are eagerly desugared into their referee region when forming a subregion of it. There should be no practical differences, but there are of course bugs that this patch may surface. >From 079fd758f8533cb66b026ba780d06d8a34f15b72 Mon Sep 17 00:00:00 2001 From: Balazs Benics Date: Fri, 29 Nov 2024 13:57:49 +0100 Subject: [PATCH] [analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) Like in the test case: ```c++ struct String { String(const String &) {} }; struct MatchComponent { unsigned numbers[2]; String prerelease; MatchComponent(MatchComponent const &) = default; }; MatchComponent get(); void consume(MatchComponent const &); MatchComponent parseMatchComponent() { MatchComponent component = get(); component.numbers[0] = 10; component.numbers[1] = 20; return component; // We should have no stack addr escape warning here. } void top() { consume(parseMatchComponent()); } ``` When calling `consume(parseMatchComponent())` the `parseMatchComponent()` would return a copy of a temporary of `component`. That copy would invoke the `MatchComponent::MatchComponent(const MatchComponent &)` ctor. That ctor would have a (reference typed) ParamVarRegion, holding the location (lvalue) of the object we are about to copy (&component). So far so good, but just before evaluating the binding operation for initializing the `numbers` field of the temporary, we evaluate the ArrayInitLoopExpr representing the by-value elementwise copy of the array `component.numbers`. This is represented by a LazyCompoundVal, because we (usually) don't just copy large arrays and bind many individual direct bindings. Rather, we take a snapshot by using a LCV. However, notice that the LCV representing this copy would look like this: lazyCompoundVal{ParamVarRegion{"reference param of cctor"}.numbers} Notice that it refers to the numbers field of a reference. It would be much better to desugar the reference to the actual object, thus it should be: `lazyCompoundVal{component.numbers}` Actually, when binding the result of the ArrayInitLoopExpr to the `temp_object.numbers`
[clang] [analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) (PR #118096)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: Balazs Benics (steakhal) Changes Like in the test case: ```c++ struct String { String(const String &) {} }; struct MatchComponent { unsigned numbers[2]; String prerelease; MatchComponent(MatchComponent const &) = default; }; MatchComponent get(); void consume(MatchComponent const &); MatchComponent parseMatchComponent() { MatchComponent component = get(); component.numbers[0] = 10; component.numbers[1] = 20; return component; // We should have no stack addr escape warning here. } void top() { consume(parseMatchComponent()); } ``` When calling `consume(parseMatchComponent())` the `parseMatchComponent()` would return a copy of a temporary of `component`. That copy would invoke the `MatchComponent::MatchComponent(const MatchComponent &)` ctor. That ctor would have a (reference typed) ParamVarRegion, holding the location (lvalue) of the object we are about to copy (&component). So far so good, but just before evaluating the binding operation for initializing the `numbers` field of the temporary, we evaluate the ArrayInitLoopExpr representing the by-value elementwise copy of the array `component.numbers`. This is represented by a LazyCompoundVal, because we (usually) don't just copy large arrays and bind many individual direct bindings. Rather, we take a snapshot by using a LCV. However, notice that the LCV representing this copy would look like this: lazyCompoundVal{ParamVarRegion{"reference param of cctor"}.numbers} Notice that it refers to the numbers field of a reference. It would be much better to desugar the reference to the actual object, thus it should be: `lazyCompoundVal{component.numbers}` Actually, when binding the result of the ArrayInitLoopExpr to the `temp_object.numbers` in the compiler-generated member initializer of the cctor, we should have two individual direct bindings because this is a "small array": ``` binding &Element{temp_object.numbers, 0} <- loadFrom(&Element{component.numbers, 0}) binding &Element{temp_object.numbers, 1} <- loadFrom(&Element{component.numbers, 1}) ``` Where `loadFrom(...)` would be: ``` loadFrom(&Element{component.numbers, 0}): 10 U32b loadFrom(&Element{component.numbers, 1}): 20 U32b ``` So the store should look like this, after PostInitializer of `temp_object.numbers`: ``` temp_object at offset 0: 10 U32b temp_object at offset 32: 20 U32b ``` The lesson is that it's okay to have TypedValueRegions of references as long as we don't form subregions of those. If we ever want to refer to a subregion of a "reference" we actually meant to "desugar" the reference and slice a subregion of the pointee of the reference instead. Once this canonicalization is in place, we can also drop the special handling of references in `ProcessInitializer`, because now reference TypedValueRegions are eagerly desugared into their referee region when forming a subregion of it. There should be no practical differences, but there are of course bugs that this patch may surface. --- Full diff: https://github.com/llvm/llvm-project/pull/118096.diff 5 Files Affected: - (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (+1) - (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1-9) - (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+8) - (modified) clang/lib/StaticAnalyzer/Core/ProgramState.cpp (+12) - (modified) clang/test/Analysis/initializer.cpp (+26) ``diff diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index eef7a54f03bf11..29f534eba2a265 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -487,6 +487,7 @@ class ProgramState : public llvm::FoldingSetNode { friend void ProgramStateRetain(const ProgramState *state); friend void ProgramStateRelease(const ProgramState *state); + SVal desugarReference(SVal Val) const; SVal wrapSymbolicRegion(SVal Base) const; }; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 22eab9f66418d4..648c7daf823ed3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1206,15 +1206,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer CFGInit, while ((ASE = dyn_cast(Init))) Init = ASE->getBase()->IgnoreImplicit(); -SVal LValue = State->getSVal(Init, stackFrame); -if (!Field->getType()->isReferenceType()) { - if (std::optional LValueLoc = LValue.getAs()) { -InitVal = State->getSVal(*LValueLoc); - } else if (auto CV = LValue.getAs()) { -// Initializer list for an array. -InitVal = *CV; - } -} +InitVal =
[clang] fix(clang/**.py): fix invalid escape sequences (PR #94029)
https://github.com/e-kwsm updated https://github.com/llvm/llvm-project/pull/94029 >From 93cb19e83e2b547f0a047a7f93ade40ffc4391c0 Mon Sep 17 00:00:00 2001 From: Eisuke Kawashima Date: Sat, 11 May 2024 02:39:21 +0900 Subject: [PATCH] fix(clang/**.py): fix invalid escape sequences --- clang/docs/tools/dump_ast_matchers.py | 10 +- clang/test/Analysis/check-analyzer-fixit.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/docs/tools/dump_ast_matchers.py b/clang/docs/tools/dump_ast_matchers.py index 705ff0d4d40985..d47111819a1e2d 100755 --- a/clang/docs/tools/dump_ast_matchers.py +++ b/clang/docs/tools/dump_ast_matchers.py @@ -86,11 +86,11 @@ def extract_result_types(comment): parsed. """ result_types = [] -m = re.search(r"Usable as: Any Matcher[\s\n]*$", comment, re.S) +m = re.search("Usable as: Any Matcher[\\s\n]*$", comment, re.S) if m: return ["*"] while True: -m = re.match(r"^(.*)Matcher<([^>]+)>\s*,?[\s\n]*$", comment, re.S) +m = re.match("^(.*)Matcher<([^>]+)>\\s*,?[\\s\n]*$", comment, re.S) if not m: if re.search(r"Usable as:\s*$", comment): return result_types @@ -101,9 +101,9 @@ def extract_result_types(comment): def strip_doxygen(comment): -"""Returns the given comment without \-escaped words.""" +r"""Returns the given comment without \-escaped words.""" # If there is only a doxygen keyword in the line, delete the whole line. -comment = re.sub(r"^\\[^\s]+\n", r"", comment, flags=re.M) +comment = re.sub("^[^\\s]+\n", r"", comment, flags=re.M) # If there is a doxygen \see command, change the \see prefix into "See also:". # FIXME: it would be better to turn this into a link to the target instead. @@ -236,7 +236,7 @@ def act_on_decl(declaration, comment, allowed_types): # Parse the various matcher definition macros. m = re.match( -""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER(?:_DECL)?\( +r""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER(?:_DECL)?\( \s*([^\s,]+\s*), \s*(?:[^\s,]+\s*), \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\) diff --git a/clang/test/Analysis/check-analyzer-fixit.py b/clang/test/Analysis/check-analyzer-fixit.py index b616255de89b0c..43968f4b1b6e8d 100644 --- a/clang/test/Analysis/check-analyzer-fixit.py +++ b/clang/test/Analysis/check-analyzer-fixit.py @@ -55,7 +55,7 @@ def run_test_once(args, extra_args): # themselves. We need to keep the comments to preserve line numbers while # avoiding empty lines which could potentially trigger formatting-related # checks. -cleaned_test = re.sub("// *CHECK-[A-Z0-9\-]*:[^\r\n]*", "//", input_text) +cleaned_test = re.sub("// *CHECK-[A-Z0-9\\-]*:[^\r\n]*", "//", input_text) write_file(temp_file_name, cleaned_test) original_file_name = temp_file_name + ".orig" ___ 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 positive in bugprone-return-const-ref-from-parameter (PR #117734)
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/117734 >From 528bc58e7abf3eed25ca4921d968e61b52571596 Mon Sep 17 00:00:00 2001 From: Qizhi Hu <836744...@qq.com> Date: Wed, 27 Nov 2024 00:57:00 +0800 Subject: [PATCH] [clang-tidy] fix false positive in bugprone-return-const-ref-from-parameter --- .../bugprone/ReturnConstRefFromParameterCheck.cpp | 6 -- clang-tools-extra/docs/ReleaseNotes.rst | 3 ++- .../bugprone/return-const-ref-from-parameter.cpp | 11 +++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp index 7cc4fe519d3a64..7da27c0474d519 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp @@ -21,11 +21,13 @@ void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) { to(parmVarDecl(hasType(hasCanonicalType( qualType(lValueReferenceType(pointee( qualType(isConstQualified() - .bind("type" + .bind("type"))), + hasDeclContext(functionDecl().bind("owner"))) .bind("param"))) .bind("dref")); const auto Func = - functionDecl(hasReturnTypeLoc(loc( + functionDecl(equalsBoundNode("owner"), + hasReturnTypeLoc(loc( qualType(hasCanonicalType(equalsBoundNode("type")) .bind("func"); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index f8507156aa4198..2f2189d6850e2b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -179,7 +179,8 @@ Changes in existing checks - Improved :doc:`bugprone-return-const-ref-from-parameter ` check to diagnose potential dangling references when returning a ``const &`` parameter - by using the conditional operator ``cond ? var1 : var2``. + by using the conditional operator ``cond ? var1 : var2`` and no longer giving + false positives for functions which contain lambda. - Improved :doc:`bugprone-sizeof-expression ` check to find suspicious diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp index d83d997a455d50..49aeb50155b157 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp @@ -76,6 +76,9 @@ struct C { // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: returning a constant reference parameter }; +const auto Lf1 = [](const T& t) -> const T& { return t; }; +// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter + } // namespace invalid namespace false_negative_because_dependent_and_not_instantiated { @@ -151,6 +154,14 @@ void instantiate(const int ¶m, const float ¶mf, int &mut_param, float &m itf6(mut_paramf); } +template +void f(const T& t) { +const auto get = [&t] -> const T& { return t; }; +return T{}; +} + +const auto Lf1 = [](T& t) -> const T& { return t; }; + } // namespace valid namespace overload { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add source range to 'use of undeclared identifier' diagnostics (PR #117671)
Timm =?utf-8?q?Bäder?= Message-ID: In-Reply-To: https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/117671 >From 1d77f36a1f7fa974d50ff7a5a98b93bbb01ba26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 26 Nov 2024 08:44:57 +0100 Subject: [PATCH 1/2] [clang] Add source range to 'use of undeclared identifier' diagnostics --- clang/lib/Sema/SemaExpr.cpp | 45 - 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6c7472ce92703b..d0d6d981827270 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2351,20 +2351,22 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, } } -static void emitEmptyLookupTypoDiagnostic( -const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS, -DeclarationName Typo, SourceLocation TypoLoc, ArrayRef Args, -unsigned DiagnosticID, unsigned DiagnosticSuggestID) { +static void emitEmptyLookupTypoDiagnostic(const TypoCorrection &TC, + Sema &SemaRef, const CXXScopeSpec &SS, + DeclarationName Typo, + SourceRange TypoRange, + unsigned DiagnosticID, + unsigned DiagnosticSuggestID) { DeclContext *Ctx = SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false); if (!TC) { // Emit a special diagnostic for failed member lookups. // FIXME: computing the declaration context might fail here (?) if (Ctx) - SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx - << SS.getRange(); + SemaRef.Diag(TypoRange.getBegin(), diag::err_no_member) + << Typo << Ctx << TypoRange; else - SemaRef.Diag(TypoLoc, DiagnosticID) << Typo; + SemaRef.Diag(TypoRange.getBegin(), DiagnosticID) << Typo << TypoRange; return; } @@ -2375,12 +2377,13 @@ static void emitEmptyLookupTypoDiagnostic( ? diag::note_implicit_param_decl : diag::note_previous_decl; if (!Ctx) -SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo, - SemaRef.PDiag(NoteID)); +SemaRef.diagnoseTypo( +TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo << TypoRange, +SemaRef.PDiag(NoteID)); else -SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) - << Typo << Ctx << DroppedSpecifier - << SS.getRange(), +SemaRef.diagnoseTypo(TC, + SemaRef.PDiag(diag::err_no_member_suggest) + << Typo << Ctx << DroppedSpecifier << TypoRange, SemaRef.PDiag(NoteID)); } @@ -2449,6 +2452,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, ArrayRef Args, DeclContext *LookupCtx, TypoExpr **Out) { DeclarationName Name = R.getLookupName(); + SourceRange NameRange = R.getLookupNameInfo().getSourceRange(); unsigned diagnostic = diag::err_undeclared_var_use; unsigned diagnostic_suggest = diag::err_undeclared_var_use_suggest; @@ -2506,13 +2510,12 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // We didn't find anything, so try to correct for a typo. TypoCorrection Corrected; if (S && Out) { -SourceLocation TypoLoc = R.getNameLoc(); assert(!ExplicitTemplateArgs && "Diagnosing an empty lookup with explicit template args!"); *Out = CorrectTypoDelayed( R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC, [=](const TypoCorrection &TC) { - emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args, + emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, NameRange, diagnostic, diagnostic_suggest); }, nullptr, CTK_ErrorRecovery, LookupCtx); @@ -2591,12 +2594,13 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, ? diag::note_implicit_param_decl : diag::note_previous_decl; if (SS.isEmpty()) -diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name, +diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name << NameRange, PDiag(NoteID), AcceptableWithRecovery); else -diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) - << DroppedSpecifier << SS.getRange(), +diagnoseTypo(Corrected, + PDiag(diag::err_no_member_suggest) +
[clang-tools-extra] [clang-tidy] fix false positive in bugprone-return-const-ref-from-parameter (PR #117734)
@@ -179,7 +179,8 @@ Changes in existing checks - Improved :doc:`bugprone-return-const-ref-from-parameter ` check to diagnose potential dangling references when returning a ``const &`` parameter - by using the conditional operator ``cond ? var1 : var2``. + by using the conditional operator ``cond ? var1 : var2`` and no longer giving jcsxky wrote: The function in this [issue](https://github.com/llvm/llvm-project/issues/115743) contains lambda and thus gives a false positive(because it should not report diagnose since the return statement is not belongs to current function). I have modified the release note and make it easier to be understood. https://github.com/llvm/llvm-project/pull/117734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Include SME attributes in the name mangling of function types (PR #114209)
https://github.com/kmclaughlin-arm updated https://github.com/llvm/llvm-project/pull/114209 >From c62f48766cf24636045286449e98705a6a5bd76c Mon Sep 17 00:00:00 2001 From: Kerry McLaughlin Date: Tue, 15 Oct 2024 15:22:56 + Subject: [PATCH 1/5] [Clang][AArch64] Include SME attributes in the name mangling of function types. Similar to arm_sve_vector_bits, the mangling of function types is implemented as a pseudo template if there are any SME attributes present, i.e. __SME_ATTRS For example, the following function: void f(svint8_t (*fn)() __arm_streaming) { fn(); } is mangled as: fP9__SME_ATTRSIFu10__SVInt8_tELj1ELj0ELj0EE See https://github.com/ARM-software/abi-aa/pull/290 --- clang/lib/AST/ItaniumMangle.cpp | 41 .../CodeGenCXX/aarch64-mangle-sme-atts.cpp| 65 +++ 2 files changed, 106 insertions(+) create mode 100644 clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 27a993a631dae9c..e3e94193d9cce10 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -574,6 +574,7 @@ class CXXNameMangler { static StringRef getCallingConvQualifierName(CallingConv CC); void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info); void mangleExtFunctionInfo(const FunctionType *T); + void mangleSMEAttrs(unsigned SMEAttrs); void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType, const FunctionDecl *FD = nullptr); void mangleNeonVectorType(const VectorType *T); @@ -3532,6 +3533,39 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) { // FIXME: noreturn } +bool hasSharedState(unsigned SMEAttrs) { + switch (SMEAttrs) { + case FunctionType::ARM_In: + case FunctionType::ARM_Out: + case FunctionType::ARM_InOut: + case FunctionType::ARM_Preserves: +return true; + default: +return false; + } +} + +void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) { + if (!SMEAttrs) +return; + + // Streaming Mode + if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask) +Out << "Lj1E"; + else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask) +Out << "Lj2E"; + else +Out << "Lj0E"; + + // ZA & ZT0 State + Out << (hasSharedState(FunctionType::getArmZAState(SMEAttrs)) ? "Lj1E" +: "Lj0E"); + Out << (hasSharedState(FunctionType::getArmZT0State(SMEAttrs)) ? "Lj1E" + : "Lj0E"); + + return; +} + void CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) { // Vendor-specific qualifiers are emitted in reverse alphabetical order. @@ -3569,6 +3603,11 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) { // ::= [] F [Y] // [] E void CXXNameMangler::mangleType(const FunctionProtoType *T) { + unsigned SMEAttrs = T->getAArch64SMEAttributes(); + + if (SMEAttrs) +Out << "11__SME_ATTRSI"; + mangleExtFunctionInfo(T); // Mangle CV-qualifiers, if present. These are 'this' qualifiers, @@ -3602,6 +3641,8 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) { // Mangle the ref-qualifier, if present. mangleRefQualifier(T->getRefQualifier()); + mangleSMEAttrs(SMEAttrs); + Out << 'E'; } diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp new file mode 100644 index 000..16d4111cdfaaa16 --- /dev/null +++ b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -target-feature +sme2 %s -emit-llvm -o - | FileCheck %s + +typedef __attribute__((neon_vector_type(2))) int int32x2_t; + +// +// Streaming-Mode Attributes +// + +// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFvvLj1ELj0ELj0EE( +void fn_streaming(void (*foo)() __arm_streaming) { foo(); } + +// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFivLj2ELj0ELj0EE( +void fn_streaming(int (*foo)() __arm_streaming_compatible) { foo(); } + +// +// ZA Attributes +// + +// CHECK: define dso_local void @_Z15fn_za_preservedP11__SME_ATTRSIF11__Int32x2_tvLj0ELj1ELj0EE( +__arm_new("za") void fn_za_preserved(int32x2_t (*foo)() __arm_preserves("za")) { foo(); } + +// CHECK: define dso_local void @_Z8fn_za_inP11__SME_ATTRSIFvu13__SVFloat64_tLj0ELj1ELj0EES_( +__arm_new("za") void fn_za_in(void (*foo)(__SVFloat64_t) __arm_in("za"), __SVFloat64_t x) { foo(x); } + +// CHECK: define dso_local noundef i32 @_Z9fn_za_outP11__SME_ATTRSIFivLj0ELj1ELj0EE( +__arm_new("za") int fn_za_out(int (*foo)() __arm_out("za")) { return foo(); } + +// CHECK: define dso_local void @_Z11fn_za_inoutP11__SME_ATTRSIFvvLj0ELj1ELj0EE( +__arm_new("za") void fn_za_inout(void (*