[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/130990 >From 48f8e2591c317f90eff6f1d0a4ecdf27e19a1b01 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Thu, 13 Mar 2025 00:39:09 +0800 Subject: [PATCH 1/4] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC. --- clang/test/CodeGen/ubsan-attr.cpp | 84 +++ 1 file changed, 84 insertions(+) create mode 100644 clang/test/CodeGen/ubsan-attr.cpp diff --git a/clang/test/CodeGen/ubsan-attr.cpp b/clang/test/CodeGen/ubsan-attr.cpp new file mode 100644 index 0..e0a8570154939 --- /dev/null +++ b/clang/test/CodeGen/ubsan-attr.cpp @@ -0,0 +1,84 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5 +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 %s -o - -fsanitize-recover=signed-integer-overflow | FileCheck %s --check-prefixes=RECOVER +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s --check-prefixes=ABORT + +// RECOVER: Function Attrs: mustprogress nounwind +// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32 @_Z4testRiRs( +// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], ptr noundef nonnull readonly align 2 captures(none) dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// RECOVER-NEXT: [[ENTRY:.*]]: +// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa [[TBAA2:![0-9]+]] +// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32 +// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[TBAA6:![0-9]+]] +// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize [[META8:![0-9]+]] +// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META8]] +// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]] +// RECOVER: [[HANDLER_ADD_OVERFLOW]]: +// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META8]] +// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize [[META8]] +// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]] +// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa [[TBAA2]] +// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32 +// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]] +// RECOVER: [[CONT]]: +// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]], %[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ] +// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META8]] +// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]] +// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]] +// +// ABORT: Function Attrs: mustprogress nounwind +// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32 @_Z4testRiRs( +// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]], ptr noundef nonnull readonly align 2 captures(none) dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// ABORT-NEXT: [[ENTRY:.*:]] +// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa [[TBAA2:![0-9]+]] +// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32 +// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[TBAA6:![0-9]+]] +// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize [[META8:![0-9]+]] +// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META8]] +// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]] +// ABORT: [[HANDLER_ADD_OVERFLOW]]: +// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META8]] +// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize [[META8]] +// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]] +// ABORT-NEXT:unreachable, !nosanitize [[META8]] +// ABORT: [[CONT]]: +// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META8]] +// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]] +// ABORT-NEXT:ret i32 [[CONV]] +// +int test(int &a, short &c) { + a += c; + return c; +} +//. +// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "tar
[libclc] [libclc] link_bc target should depends on target builtins.link.clc-arch_suffix (PR #132338)
https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/132338 >From 6ce54aa767f8cdff2f938cdce8656e495a1346f0 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Thu, 20 Mar 2025 22:01:55 -0700 Subject: [PATCH 1/2] [libclc] link_bc target should depends on target builtins.link.clc-arch_suffix Currently link_bc command depends on the bitcode file that is associated with custom target builtins.link.clc-arch_suffix. On windows we randomly see following error: ` Generating builtins.link.clc-${ARCH}--.bc Generating builtins.link.libspirv-${ARCH}.bc error : The requested operation cannot be performed on a file with a user-mapped section open. ` I suspect that builtins.link.clc-${ARCH}--.bc file is being generated while it is being used in link_bc. This PR adds target-level dependency to ensure builtins.link.clc-${ARCH}--.bc is generated first. --- libclc/CMakeLists.txt| 2 +- libclc/cmake/modules/AddLibclc.cmake | 9 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 426f210a73fcc..3de7ee9b707a8 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -413,7 +413,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) GEN_FILES ${opencl_gen_files} ALIASES ${${d}_aliases} # Link in the CLC builtins and internalize their symbols - INTERNAL_LINK_DEPENDENCIES $ + INTERNAL_LINK_DEPENDENCIES builtins.link.clc-${arch_suffix} ) endforeach( d ) endforeach( t ) diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake index 911559ff4bfa9..0808b39e06555 100644 --- a/libclc/cmake/modules/AddLibclc.cmake +++ b/libclc/cmake/modules/AddLibclc.cmake @@ -211,8 +211,9 @@ endfunction() # * ALIASES ... # List of aliases # * INTERNAL_LINK_DEPENDENCIES ... -# A list of extra bytecode files to link into the builtin library. Symbols -# from these link dependencies will be internalized during linking. +# A list of extra bytecode file's targets. The bitcode files will be linked +# into the builtin library. Symbols from these link dependencies will be +# internalized during linking. function(add_libclc_builtin_set) cmake_parse_arguments(ARG "CLC_INTERNAL" @@ -313,8 +314,8 @@ function(add_libclc_builtin_set) INTERNALIZE TARGET ${builtins_link_lib_tgt} INPUTS $ -${ARG_INTERNAL_LINK_DEPENDENCIES} - DEPENDENCIES ${builtins_link_lib_tmp_tgt} +$ + DEPENDENCIES ${builtins_link_lib_tmp_tgt} ${ARG_INTERNAL_LINK_DEPENDENCIES} ) endif() >From 7b9a65f8dac3ab5e13fcabade3e9ed4d384c5b92 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Fri, 21 Mar 2025 01:29:51 -0700 Subject: [PATCH 2/2] update comment, fix files to link --- libclc/cmake/modules/AddLibclc.cmake | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake index 0808b39e06555..29d728494cd3e 100644 --- a/libclc/cmake/modules/AddLibclc.cmake +++ b/libclc/cmake/modules/AddLibclc.cmake @@ -210,7 +210,7 @@ endfunction() # Optimization options (for opt) # * ALIASES ... # List of aliases -# * INTERNAL_LINK_DEPENDENCIES ... +# * INTERNAL_LINK_DEPENDENCIES ... # A list of extra bytecode file's targets. The bitcode files will be linked # into the builtin library. Symbols from these link dependencies will be # internalized during linking. @@ -310,11 +310,15 @@ function(add_libclc_builtin_set) INPUTS ${bytecode_files} DEPENDENCIES ${builtins_comp_lib_tgt} ) +set( internal_link_depend_files ) +foreach( tgt ${ARG_INTERNAL_LINK_DEPENDENCIES} ) + list( APPEND internal_link_depend_files $ ) +endforeach() link_bc( INTERNALIZE TARGET ${builtins_link_lib_tgt} INPUTS $ -$ +${internal_link_depend_files} DEPENDENCIES ${builtins_link_lib_tmp_tgt} ${ARG_INTERNAL_LINK_DEPENDENCIES} ) endif() ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Ignore unnamed bitfields in UninitializedObjectChecker (PR #132427)
YLChenZ wrote: @steakhal Okay, glad to do it. But I don't know specifically about the workflow of review. Could you give me some guidance? https://github.com/llvm/llvm-project/pull/132427 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Docs] Document freestanding requirements (PR #132232)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) Changes This adds some initial documentation about freestanding requirements for Clang. The most critical part of the documentation is spelling out that a conforming freestanding C Standard Library is required; Clang will not be providing the headers forin C23 which expose a number of symbols in freestanding mode. The docs also make it clear that in addition to a conforming freestanding C standard library, the library must provide some additional symbols which LLVM requires. These docs are not comprehensive, this is just getting the bare bones in place so that they can be expanded later. This also updates the C status page to make it clear that we don't have anything to do for WG14 N2524 which adds string interfaces to freestanding mode. --- Full diff: https://github.com/llvm/llvm-project/pull/132232.diff 3 Files Affected: - (modified) clang/docs/CommandGuide/clang.rst (+4-3) - (modified) clang/docs/UsersManual.rst (+24) - (modified) clang/www/c_status.html (-5) ``diff diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index f0d94a4e628b0..dfe28fc5d2bcb 100644 --- a/clang/docs/CommandGuide/clang.rst +++ b/clang/docs/CommandGuide/clang.rst @@ -262,9 +262,10 @@ Language Selection and Mode Options .. option:: -ffreestanding Indicate that the file should be compiled for a freestanding, not a hosted, - environment. Note that it is assumed that a freestanding environment will - additionally provide `memcpy`, `memmove`, `memset` and `memcmp` - implementations, as these are needed for efficient codegen for many programs. + environment. Note that a freestanding build still requires linking against a C + Standard Library which supports the freestanding interfaces for the specified + language mode and target environment. This includes functions like `memcpy`, + `memmove`, `memset` and `memcmp`. .. option:: -fno-builtin diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 2ea4b9d90ad34..d73e8eb78dbf6 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1073,6 +1073,30 @@ inputs. Here is some example of ``$``-prefixed options: Language and Target-Independent Features +Freestanding Builds +--- +Passing the ``-ffreestanding`` flag causes Clang to build for a freestanding +(rather than a hosted) environment. The ``__STDC_HOSTED__`` predefined macro +will expand to ``0`` in a freestanding environment. In such an environment, +execution of the program may happen without an operating system and so a +startup function (e.g., ``main``) may not be automatically called, though file +scope objects which need to run startup code (constructors in C++, +``__attribute__((constructor))``, etc) are executed via implementation-defined +means such as ``__cxx_global_var_init``. + +A freestanding environment is not one which has no C standard library support. +A conforming freestanding C standard library implementation is required. Clang +supplies some of the header files needed for a freestanding execution, such as +, , , etc. However, Clang still +requires the runtime freestanding library to provide the interfaces required by +Clause 4 (Conformance) of the C standard. Additionally, Clang requires the +following runtime interfaces to be provided: + + * `memcpy`, + * `memmove`, + * `memset`, and + * `memcmp`. + Controlling Errors and Warnings --- diff --git a/clang/www/c_status.html b/clang/www/c_status.html index c9e2eda4304f3..ee0cd057916ba 100644 --- a/clang/www/c_status.html +++ b/clang/www/c_status.html @@ -534,11 +534,6 @@ C23 implementation status Clang 16 - - String functions for freestanding implementations - https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2524.htm";>N2524 - No - Digit separators https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2626.pdf";>N2626 `` https://github.com/llvm/llvm-project/pull/132232 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Avoid processing declarations in system headers (PR #128150)
carlosgalvezp wrote: Hmm, it does not remove much - Baseline: `Suppressed 196093 warnings (196093 in non-user code)` - Trunk: `Suppressed 8050 warnings (8050 in non-user code).` - Apparently there's a bug in the `isSystemHeader` function, since some core compiler headers like `os_defines.h` are *not* classified as system, and `clang-tidy` still processes those). - Proposal: `Suppressed 141779 warnings (141779 in non-user code).` https://github.com/llvm/llvm-project/pull/128150 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/steakhal approved this pull request. Thabk you! https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3853116 - [SPARC][Driver] Set correct IAS mode defaults for Linux and Free/OpenBSD (#130108)
Author: Koakuma Date: 2025-03-23T20:56:40+07:00 New Revision: 385311625945e65990bd60bea76a045dcaf3f47b URL: https://github.com/llvm/llvm-project/commit/385311625945e65990bd60bea76a045dcaf3f47b DIFF: https://github.com/llvm/llvm-project/commit/385311625945e65990bd60bea76a045dcaf3f47b.diff LOG: [SPARC][Driver] Set correct IAS mode defaults for Linux and Free/OpenBSD (#130108) On those OSes, clang should set the assembler to enable VIS by default. This is already the case when clang calls an external assembler, so make sure clang+IAS use the same defaults. This should fix [issue #125124](https://github.com/llvm/llvm-project/issues/125124). Added: Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/sparc-ias-Wa.s Removed: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index fe917902a01cd..fb3ed2db0e3c0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2875,6 +2875,17 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back("-target-feature"); CmdArgs.push_back(MipsTargetFeature); } + + // Those OSes default to enabling VIS on 64-bit SPARC. + // See also the corresponding code for external assemblers in + // sparc::getSparcAsmModeForCPU(). + bool IsSparcV9ATarget = + (C.getDefaultToolChain().getArch() == llvm::Triple::sparcv9) && + (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD()); + if (IsSparcV9ATarget && SparcTargetFeatures.empty()) { +CmdArgs.push_back("-target-feature"); +CmdArgs.push_back("+vis"); + } for (const char *Feature : SparcTargetFeatures) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back(Feature); diff --git a/clang/test/Driver/sparc-ias-Wa.s b/clang/test/Driver/sparc-ias-Wa.s index 79456c02935be..c031f237297d3 100644 --- a/clang/test/Driver/sparc-ias-Wa.s +++ b/clang/test/Driver/sparc-ias-Wa.s @@ -58,3 +58,12 @@ // V9D: "-target-feature" "+vis" // V9D: "-target-feature" "+vis2" // V9D: "-target-feature" "+vis3" + +// RUN: %clang --target=sparc64-linux-gnu -### -fintegrated-as -c %s 2>&1 | \ +// RUN: FileCheck -check-prefix=VIS-DEFAULT %s +// RUN: %clang --target=sparc64-freebsd -### -fintegrated-as -c %s 2>&1 | \ +// RUN: FileCheck -check-prefix=VIS-DEFAULT %s +// RUN: %clang --target=sparc64-openbsd -### -fintegrated-as -c %s 2>&1 | \ +// RUN: FileCheck -check-prefix=VIS-DEFAULT %s +// VIS-DEFAULT: -cc1as +// VIS-DEFAULT: "-target-feature" "+vis" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang] improve class type sugar preservation in pointers to members (PR #130537)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-aarch64-ubuntu` running on `linaro-lldb-aarch64-ubuntu` while building `clang-tools-extra,clang` at step 4 "build". Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/14624 Here is the relevant piece of the build log for the reference ``` Step 4 (build) failure: build (failure) ... 1529.788 [913/10/5628] Building CXX object tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbSymUid.cpp.o 1529.793 [912/10/5629] Building CXX object tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbIndex.cpp.o 1529.796 [911/10/5630] Building CXX object tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbUtil.cpp.o 1529.834 [910/10/5631] Building CXX object tools/lldb/source/Plugins/SymbolFile/PDB/CMakeFiles/lldbPluginSymbolFilePDB.dir/PDBLocationToDWARFExpression.cpp.o 1529.897 [910/9/5632] Building CXX object tools/lldb/source/Plugins/SymbolFile/Symtab/CMakeFiles/lldbPluginSymbolFileSymtab.dir/SymbolFileSymtab.cpp.o 1531.901 [910/8/5633] Building CXX object tools/lldb/source/Plugins/SymbolFile/CTF/CMakeFiles/lldbPluginSymbolFileCTF.dir/SymbolFileCTF.cpp.o 1537.136 [909/8/5634] Building CXX object tools/lldb/source/Plugins/SymbolFile/DWARF/CMakeFiles/lldbPluginSymbolFileDWARF.dir/DWARFASTParserClang.cpp.o 1538.621 [909/7/5635] Building CXX object tools/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeFiles/lldbPluginSystemRuntimeMacOSX.dir/AppleGetItemInfoHandler.cpp.o 1539.276 [909/6/5636] Building CXX object tools/lldb/source/Plugins/SymbolFile/DWARF/CMakeFiles/lldbPluginSymbolFileDWARF.dir/SymbolFileDWARF.cpp.o 1539.510 [909/5/5637] Building CXX object tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbAstBuilder.cpp.o FAILED: tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbAstBuilder.cpp.o /usr/local/bin/c++ -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/source/Plugins/SymbolFile/NativePDB -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/include -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/include -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/llvm/include -I/usr/include/python3.10 -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/llvm/../clang/include -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/../clang/include -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/source -I/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/source -isystem /usr/include/libxml2 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-vla-extension -O3 -DNDEBUG -std=c++17 -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbAstBuilder.cpp.o -MF tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbAstBuilder.cpp.o.d -o tools/lldb/source/Plugins/SymbolFile/NativePDB/CMakeFiles/lldbPluginSymbolFileNativePDB.dir/PdbAstBuilder.cpp.o -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp ../llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp:565:46: error: too few arguments to function call, expected 3, have 2 564 | return m_clang.getASTContext().getMemberPointerType( | 565 | pointee_type, class_type.getTypePtr()); | ^ ../llvm-project/clang/include/clang/AST/ASTContext.h:1562:12: note: 'getMemberPointerType' declared here 1562 | QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier, |^ ~~~ 1563 | const CXXRecordDecl *Cls) const; |
[clang] [llvm] [OpenEmbedded] Fix include and lib paths for multilib targets (PR #121302)
mikecrowe wrote: I [tried asking](https://lists.openembedded.org/g/openembedded-core/topic/gcc_library_directory_and/111849200) about this on the OpenEmbedded mailing list. The response was that it has been this way for so long that it's going to be a major undertaking to change it even though they would quite like to do so. I had a go at using symlinks to work around the problem. Unfortunately because `ScanLibDirForGCCTriple` ends up using `../../..` to turn `/usr/lib/gcc/${TARGET_SYS}/${gccversion}` (where `${TARGET_SYS}` is the triple) back into just `/usr/lib` it's necessary to have real directories for each of those components and only have symlinks below that. In other words: ```sh mkdir -p $sysroot/usr/lib/gcc/arm-oemllib32-linux-gnueabi/9.5.0 cd $sysroot/usr/lib/gcc/arm-oemllib32-linux-gnueabi/9.5.0 ln -s ln -s ../../../arm-oemllib32-linux-gnueabi/9.5.0/* . ``` Presumably there's a reason that `../../..` (made up of the `ReversePath` in the `Suffixes` array and another `/../` when constructing `GCCParentLibPath`) is used rather than removing components from the path or just using the `--sysroot` path to find `/usr/lib`? https://github.com/llvm/llvm-project/pull/121302 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][analyzer] Multipart checker refactor 2: NullabilityChecker (PR #132250)
=?utf-8?q?Donát?= Nagy , =?utf-8?q?Donát?= Nagy , =?utf-8?q?Donát?= Nagy Message-ID: In-Reply-To: @@ -112,25 +112,30 @@ class NullabilityChecker void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override; - enum CheckKind { -CK_NullPassedToNonnull, -CK_NullReturnedFromNonnull, -CK_NullableDereferenced, -CK_NullablePassedToNonnull, -CK_NullableReturnedFromNonnull, -CK_NumCheckKinds + // FIXME: This enumeration of checker parts is extremely similar to the + // ErrorKind enum. It would be nice to unify them to simplify the code. + enum : CheckerPartIdx { +NullPassedToNonnullChecker, +NullReturnedFromNonnullChecker, +NullableDereferencedChecker, +NullablePassedToNonnullChecker, +NullableReturnedFromNonnullChecker, +NumCheckerParts }; - bool ChecksEnabled[CK_NumCheckKinds] = {false}; - CheckerNameRef CheckNames[CK_NumCheckKinds]; - mutable std::unique_ptr BTs[CK_NumCheckKinds]; - - const std::unique_ptr &getBugType(CheckKind Kind) const { -if (!BTs[Kind]) - BTs[Kind].reset(new BugType(CheckNames[Kind], "Nullability", - categories::MemoryError)); -return BTs[Kind]; - } + // FIXME: Currently the `Description` fields of these `BugType`s are all + // identical ("Nullability") -- they should be more descriptive than this. + BugType BugTypes[NumCheckerParts] = { + {this, NullPassedToNonnullChecker, "Nullability", + categories::MemoryError}, + {this, NullReturnedFromNonnullChecker, "Nullability", + categories::MemoryError}, + {this, NullableDereferencedChecker, "Nullability", + categories::MemoryError}, + {this, NullablePassedToNonnullChecker, "Nullability", + categories::MemoryError}, + {this, NullableReturnedFromNonnullChecker, "Nullability", + categories::MemoryError}}; steakhal wrote: I have something like this in mind: ```diff diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 3a635e0d0125..75c7786aea3e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -29,7 +29,7 @@ class BugType { private: struct CheckerPartRef { const CheckerBase *Checker; -CheckerPartIdx Idx; +const CheckerPart &Part; }; using CheckerNameInfo = std::variant; @@ -55,14 +55,14 @@ public: // pointer to the checker and later use that to query the name. BugType(const CheckerBase *Checker, StringRef Desc, StringRef Cat = categories::LogicError, bool SuppressOnSink = false) - : CheckerName(CheckerPartRef{Checker, DefaultPart}), Description(Desc), -Category(Cat), SuppressOnSink(SuppressOnSink) {} + : CheckerName(Checker->getName()), Description(Desc), Category(Cat), +SuppressOnSink(SuppressOnSink) {} // Constructor that can be called from the constructor of a checker object // when it has multiple parts with separate names. We save the name and the // part index to be able to query the name of that part later. - BugType(const CheckerBase *Checker, CheckerPartIdx Idx, StringRef Desc, + BugType(const CheckerBase *Checker, const CheckerPart &Part, StringRef Desc, StringRef Cat = categories::LogicError, bool SuppressOnSink = false) - : CheckerName(CheckerPartRef{Checker, Idx}), Description(Desc), + : CheckerName(CheckerPartRef{Checker, Part}), Description(Desc), Category(Cat), SuppressOnSink(SuppressOnSink) {} virtual ~BugType() = default; @@ -72,8 +72,8 @@ public: if (const auto *CNR = std::get_if(&CheckerName)) return *CNR; -auto [Checker, Idx] = std::get(CheckerName); -return Checker->getName(Idx); +auto [Checker, Part] = std::get(CheckerName); +return Checker->getName(Part); } /// isSuppressOnSink - Returns true if bug reports associated with this bug diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index a54c5bee612f..e63b3454b853 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -17,6 +17,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Casting.h" namespace clang { @@ -488,31 +489,30 @@ class CheckerBase : public ProgramPointTag { /// A single checker class (i.e. a subclass of `CheckerBase`) can implement /// multiple user-facing checkers that have separate names and can be enabled /// separately, but are backed by the same singleton checker object. - SmallVector, 1> RegisteredNames; + llvm::SmallDenseMap RegisteredNames; + Check
[clang-tools-extra] [clang-tidy] Improve `bugprone-capturing-this-in-member-variable` check: add support of `bind` functions. (PR #132635)
https://github.com/vbvictor created https://github.com/llvm/llvm-project/pull/132635 Improve `bugprone-capturing-this-in-member-variable` check: Added support of `bind`-like functions that capture and store `this` pointer in class member. Closes https://github.com/llvm/llvm-project/issues/131220. >From c91ad611e7a64b08a243a4a7f07a7f51e96b8ac0 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 23 Mar 2025 23:57:15 +0300 Subject: [PATCH] [clang-tidy] Add support of `bind` function calls that capture `this` --- .../CapturingThisInMemberVariableCheck.cpp| 56 +- .../CapturingThisInMemberVariableCheck.h | 1 + clang-tools-extra/docs/ReleaseNotes.rst | 5 +- .../capturing-this-in-member-variable.rst | 8 +++ .../capturing-this-in-member-variable.cpp | 58 ++- 5 files changed, 110 insertions(+), 18 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp index add0576a42c33..c0bcd7698a6ae 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp @@ -64,16 +64,21 @@ AST_MATCHER(CXXRecordDecl, correctHandleCaptureThisLambda) { constexpr const char *DefaultFunctionWrapperTypes = "::std::function;::std::move_only_function;::boost::function"; +constexpr const char *DefaultBindFunctions = "::std::bind;::boost::bind"; CapturingThisInMemberVariableCheck::CapturingThisInMemberVariableCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), FunctionWrapperTypes(utils::options::parseStringList( - Options.get("FunctionWrapperTypes", DefaultFunctionWrapperTypes))) {} + Options.get("FunctionWrapperTypes", DefaultFunctionWrapperTypes))), + BindFunctions(utils::options::parseStringList( + Options.get("BindFunctions", DefaultBindFunctions))) {} void CapturingThisInMemberVariableCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "FunctionWrapperTypes", utils::options::serializeStringList(FunctionWrapperTypes)); + Options.store(Opts, "BindFunctions", +utils::options::serializeStringList(BindFunctions)); } void CapturingThisInMemberVariableCheck::registerMatchers(MatchFinder *Finder) { @@ -87,33 +92,54 @@ void CapturingThisInMemberVariableCheck::registerMatchers(MatchFinder *Finder) { // [self = this] capturesVar(varDecl(hasInitializer(cxxThisExpr()); auto IsLambdaCapturingThis = - lambdaExpr(hasAnyCapture(CaptureThis.bind("capture"))).bind("lambda"); - auto IsInitWithLambda = - anyOf(IsLambdaCapturingThis, -cxxConstructExpr(hasArgument(0, IsLambdaCapturingThis))); + lambdaExpr(hasAnyCapture(CaptureThis)).bind("lambda"); + + auto IsBindCapturingThis = + callExpr( + callee(functionDecl(matchers::matchesAnyListedName(BindFunctions)) + .bind("callee")), + hasAnyArgument(cxxThisExpr())) + .bind("bind"); + + auto IsInitWithLambdaOrBind = + anyOf(IsLambdaCapturingThis, IsBindCapturingThis, +cxxConstructExpr(hasArgument( +0, anyOf(IsLambdaCapturingThis, IsBindCapturingThis; + Finder->addMatcher( cxxRecordDecl( anyOf(has(cxxConstructorDecl( unless(isCopyConstructor()), unless(isMoveConstructor()), hasAnyConstructorInitializer(cxxCtorInitializer( isMemberInitializer(), forField(IsStdFunctionField), -withInitializer(IsInitWithLambda), +withInitializer(IsInitWithLambdaOrBind), has(fieldDecl(IsStdFunctionField, - hasInClassInitializer(IsInitWithLambda, + hasInClassInitializer(IsInitWithLambdaOrBind, unless(correctHandleCaptureThisLambda())), this); } - void CapturingThisInMemberVariableCheck::check( const MatchFinder::MatchResult &Result) { - const auto *Capture = Result.Nodes.getNodeAs("capture"); - const auto *Lambda = Result.Nodes.getNodeAs("lambda"); + const auto EmitDiag = [this](const SourceLocation &Location, + const FunctionDecl *Bind) { +const std::string BindName = Bind ? Bind->getQualifiedNameAsString() : ""; +diag(Location, "'this' captured by a %select{lambda|'%1' call}0 and " + "stored in a class member variable; disable implicit class " + "copying/moving to prevent potential use-after-free") +<< (Bind ? 1 : 0) << BindName; + }; + + if (const auto *Lambda = Result.Nodes.getNodeAs("lambda")) { +EmitDiag(Lambda->getBeginLoc(), nullptr); + } else if (const auto *Bind = Result.Nodes.getNo
[clang-tools-extra] [clang-tidy] Improve `bugprone-capturing-this-in-member-variable` check: add support of `bind` functions. (PR #132635)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: Baranov Victor (vbvictor) Changes Improve `bugprone-capturing-this-in-member-variable` check: Added support of `bind`-like functions that capture and store `this` pointer in class member. Closes https://github.com/llvm/llvm-project/issues/131220. --- Full diff: https://github.com/llvm/llvm-project/pull/132635.diff 5 Files Affected: - (modified) clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp (+41-15) - (modified) clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.h (+1) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+3-2) - (modified) clang-tools-extra/docs/clang-tidy/checks/bugprone/capturing-this-in-member-variable.rst (+8) - (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/capturing-this-in-member-variable.cpp (+57-1) ``diff diff --git a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp index add0576a42c33..c0bcd7698a6ae 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp @@ -64,16 +64,21 @@ AST_MATCHER(CXXRecordDecl, correctHandleCaptureThisLambda) { constexpr const char *DefaultFunctionWrapperTypes = "::std::function;::std::move_only_function;::boost::function"; +constexpr const char *DefaultBindFunctions = "::std::bind;::boost::bind"; CapturingThisInMemberVariableCheck::CapturingThisInMemberVariableCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), FunctionWrapperTypes(utils::options::parseStringList( - Options.get("FunctionWrapperTypes", DefaultFunctionWrapperTypes))) {} + Options.get("FunctionWrapperTypes", DefaultFunctionWrapperTypes))), + BindFunctions(utils::options::parseStringList( + Options.get("BindFunctions", DefaultBindFunctions))) {} void CapturingThisInMemberVariableCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "FunctionWrapperTypes", utils::options::serializeStringList(FunctionWrapperTypes)); + Options.store(Opts, "BindFunctions", +utils::options::serializeStringList(BindFunctions)); } void CapturingThisInMemberVariableCheck::registerMatchers(MatchFinder *Finder) { @@ -87,33 +92,54 @@ void CapturingThisInMemberVariableCheck::registerMatchers(MatchFinder *Finder) { // [self = this] capturesVar(varDecl(hasInitializer(cxxThisExpr()); auto IsLambdaCapturingThis = - lambdaExpr(hasAnyCapture(CaptureThis.bind("capture"))).bind("lambda"); - auto IsInitWithLambda = - anyOf(IsLambdaCapturingThis, -cxxConstructExpr(hasArgument(0, IsLambdaCapturingThis))); + lambdaExpr(hasAnyCapture(CaptureThis)).bind("lambda"); + + auto IsBindCapturingThis = + callExpr( + callee(functionDecl(matchers::matchesAnyListedName(BindFunctions)) + .bind("callee")), + hasAnyArgument(cxxThisExpr())) + .bind("bind"); + + auto IsInitWithLambdaOrBind = + anyOf(IsLambdaCapturingThis, IsBindCapturingThis, +cxxConstructExpr(hasArgument( +0, anyOf(IsLambdaCapturingThis, IsBindCapturingThis; + Finder->addMatcher( cxxRecordDecl( anyOf(has(cxxConstructorDecl( unless(isCopyConstructor()), unless(isMoveConstructor()), hasAnyConstructorInitializer(cxxCtorInitializer( isMemberInitializer(), forField(IsStdFunctionField), -withInitializer(IsInitWithLambda), +withInitializer(IsInitWithLambdaOrBind), has(fieldDecl(IsStdFunctionField, - hasInClassInitializer(IsInitWithLambda, + hasInClassInitializer(IsInitWithLambdaOrBind, unless(correctHandleCaptureThisLambda())), this); } - void CapturingThisInMemberVariableCheck::check( const MatchFinder::MatchResult &Result) { - const auto *Capture = Result.Nodes.getNodeAs("capture"); - const auto *Lambda = Result.Nodes.getNodeAs("lambda"); + const auto EmitDiag = [this](const SourceLocation &Location, + const FunctionDecl *Bind) { +const std::string BindName = Bind ? Bind->getQualifiedNameAsString() : ""; +diag(Location, "'this' captured by a %select{lambda|'%1' call}0 and " + "stored in a class member variable; disable implicit class " + "copying/moving to prevent potential use-after-free") +<< (Bind ? 1 : 0) << BindName; + }; + + if (const auto *Lambda = Result.Nodes.getNodeAs("lambda")) { +EmitDiag(Lambda->getBeginLoc(), nullptr); + } else if (const auto *Bind = Result.
[clang] Retry for Unique Path Creation (PR #132640)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Ayush Pareek (ayushpareek2003) Changes At line 754, added a FOR loop for retrying until we get a unique path --- Full diff: https://github.com/llvm/llvm-project/pull/132640.diff 1 Files Affected: - (modified) clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp (+19-3) ``diff diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index ca15a088c308d..5527275575b26 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -750,9 +750,25 @@ bool DependencyScanningWorker::computeDependencies( auto InMemoryFS = llvm::makeIntrusiveRefCnt(); InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); SmallString<128> FakeInputPath; - // TODO: We should retry the creation if the path already exists. - llvm::sys::fs::createUniquePath(ModuleName + "-.input", FakeInputPath, - /*MakeAbsolute=*/false); + + unsigned RetryCount = 5; // retries to create + bool UniquePathCreated = false; + + for (unsigned i = 0; i < RetryCount; ++i) { +if (llvm::sys::fs::createUniquePath(ModuleName + "-.input", FakeInputPath, +/*MakeAbsolute=*/false)) { + if (!llvm::sys::fs::exists(FakeInputPath)) { +UniquePathCreated = true; +break; // Successfully created a unique path + } +} + } + if (!UniquePathCreated) { +llvm::errs() << "Error: Failed to create a unique input path after " + << RetryCount << " retries.\n"; +return false; // Handle failure appropriately + } + InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer("")); llvm::IntrusiveRefCntPtr InMemoryOverlay = InMemoryFS; `` https://github.com/llvm/llvm-project/pull/132640 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Retry for Unique Path Creation (PR #132640)
https://github.com/ayushpareek2003 created https://github.com/llvm/llvm-project/pull/132640 At line 754, added a FOR loop for retrying until we get a unique path >From 3927b90a26ea1bd04fe7e55a6d21e7d27ce68839 Mon Sep 17 00:00:00 2001 From: Ayush Pareek Date: Mon, 24 Mar 2025 03:45:31 +0530 Subject: [PATCH] Retry for Unique Path Creation At line 754, added a FOR loop for retrying until we get a unique path --- .../DependencyScanningWorker.cpp | 22 --- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index ca15a088c308d..5527275575b26 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -750,9 +750,25 @@ bool DependencyScanningWorker::computeDependencies( auto InMemoryFS = llvm::makeIntrusiveRefCnt(); InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); SmallString<128> FakeInputPath; - // TODO: We should retry the creation if the path already exists. - llvm::sys::fs::createUniquePath(ModuleName + "-.input", FakeInputPath, - /*MakeAbsolute=*/false); + + unsigned RetryCount = 5; // retries to create + bool UniquePathCreated = false; + + for (unsigned i = 0; i < RetryCount; ++i) { +if (llvm::sys::fs::createUniquePath(ModuleName + "-.input", FakeInputPath, +/*MakeAbsolute=*/false)) { + if (!llvm::sys::fs::exists(FakeInputPath)) { +UniquePathCreated = true; +break; // Successfully created a unique path + } +} + } + if (!UniquePathCreated) { +llvm::errs() << "Error: Failed to create a unique input path after " + << RetryCount << " retries.\n"; +return false; // Handle failure appropriately + } + InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer("")); llvm::IntrusiveRefCntPtr InMemoryOverlay = InMemoryFS; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (flovent) Changes This PR fixs #132010. Associative containers in STL has an unique `insert` overload member function comparing to un-associative containers(https://en.cppreference.com/w/cpp/container/unordered_set/insert): ``` template< class InputIt > void insert( InputIt first, InputIt last ); ``` Add support for this `insert` overload in `MismatchedIteratorChecker`, verify if `first` and `last` belongs to the same container in this case. --- Full diff: https://github.com/llvm/llvm-project/pull/132596.diff 4 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp (+12-6) - (modified) clang/test/Analysis/Inputs/system-header-simulator-cxx.h (+4) - (added) clang/test/Analysis/issue-132010.cpp (+12) - (modified) clang/test/Analysis/mismatched-iterator.cpp (+10) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..1c101b91f727f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -91,12 +91,18 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, InstCall->getCXXThisVal().getAsRegion()); } } else if (isInsertCall(Func)) { - verifyMatch(C, Call.getArgSVal(0), - InstCall->getCXXThisVal().getAsRegion()); - if (Call.getNumArgs() == 3 && - isIteratorType(Call.getArgExpr(1)->getType()) && - isIteratorType(Call.getArgExpr(2)->getType())) { -verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); + if (Call.getNumArgs() == 2 && + isIteratorType(Call.getArgExpr(0)->getType()) && + isIteratorType(Call.getArgExpr(1)->getType())) { +verifyMatch(C, Call.getArgSVal(0), Call.getArgSVal(1)); + } else { +verifyMatch(C, Call.getArgSVal(0), +InstCall->getCXXThisVal().getAsRegion()); +if (Call.getNumArgs() == 3 && +isIteratorType(Call.getArgExpr(1)->getType()) && +isIteratorType(Call.getArgExpr(2)->getType())) { + verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); +} } } else if (isEmplaceCall(Func)) { verifyMatch(C, Call.getArgSVal(0), diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index a379a47515668..c5aeb0af9d578 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1244,6 +1244,7 @@ template< class Alloc = std::allocator > class unordered_set { public: +unordered_set() {} unordered_set(initializer_list __list) {} class iterator { @@ -1260,6 +1261,9 @@ template< Key *val; iterator begin() const { return iterator(val); } iterator end() const { return iterator(val + 1); } + +template< class InputIt > +void insert( InputIt first, InputIt last ); }; template diff --git a/clang/test/Analysis/issue-132010.cpp b/clang/test/Analysis/issue-132010.cpp new file mode 100644 index 0..abdaed57f26b9 --- /dev/null +++ b/clang/test/Analysis/issue-132010.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning +} diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 570e742751ead..325e7764ad7fa 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -19,6 +19,11 @@ void good_insert4(std::vector &V, int len, int n) { V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning } +void good_insert5(std::vector &V, int len, int n) { + std::unordered_set us; + us.insert(V.cbegin(), V.cend()); // no-warning +} + void good_insert_find(std::vector &V, int n, int m) { auto i = std::find(V.cbegin(), V.cend(), n); V.insert(i, m); // no-warning @@ -70,6 +75,11 @@ void bad_insert4(std::vector &V1, std::vector &V2, int len, int n) { V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} } +void bad_insert5(std::vector &V1, std::vector &V2, int len, int n) { + std::unordered_set us; + us.insert(V1.cbegin(), V2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} +} + void bad_erase1(std::vector &V1, std::vector &V2) { V2.erase(V1.cbegin()); // expected-warning{{Container accessed using
[clang-tools-extra] [clang-tools-extra] Use *Set::insert_range (NFC) (PR #132589)
https://github.com/steakhal approved this pull request. https://github.com/llvm/llvm-project/pull/132589 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: None (flovent) Changes This PR fixs #132010. Associative containers in STL has an unique `insert` overload member function comparing to un-associative containers(https://en.cppreference.com/w/cpp/container/unordered_set/insert): ``` template< class InputIt > void insert( InputIt first, InputIt last ); ``` Add support for this `insert` overload in `MismatchedIteratorChecker`, verify if `first` and `last` belongs to the same container in this case. --- Full diff: https://github.com/llvm/llvm-project/pull/132596.diff 4 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp (+12-6) - (modified) clang/test/Analysis/Inputs/system-header-simulator-cxx.h (+4) - (added) clang/test/Analysis/issue-132010.cpp (+12) - (modified) clang/test/Analysis/mismatched-iterator.cpp (+10) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..1c101b91f727f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -91,12 +91,18 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, InstCall->getCXXThisVal().getAsRegion()); } } else if (isInsertCall(Func)) { - verifyMatch(C, Call.getArgSVal(0), - InstCall->getCXXThisVal().getAsRegion()); - if (Call.getNumArgs() == 3 && - isIteratorType(Call.getArgExpr(1)->getType()) && - isIteratorType(Call.getArgExpr(2)->getType())) { -verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); + if (Call.getNumArgs() == 2 && + isIteratorType(Call.getArgExpr(0)->getType()) && + isIteratorType(Call.getArgExpr(1)->getType())) { +verifyMatch(C, Call.getArgSVal(0), Call.getArgSVal(1)); + } else { +verifyMatch(C, Call.getArgSVal(0), +InstCall->getCXXThisVal().getAsRegion()); +if (Call.getNumArgs() == 3 && +isIteratorType(Call.getArgExpr(1)->getType()) && +isIteratorType(Call.getArgExpr(2)->getType())) { + verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); +} } } else if (isEmplaceCall(Func)) { verifyMatch(C, Call.getArgSVal(0), diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index a379a47515668..c5aeb0af9d578 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1244,6 +1244,7 @@ template< class Alloc = std::allocator > class unordered_set { public: +unordered_set() {} unordered_set(initializer_list __list) {} class iterator { @@ -1260,6 +1261,9 @@ template< Key *val; iterator begin() const { return iterator(val); } iterator end() const { return iterator(val + 1); } + +template< class InputIt > +void insert( InputIt first, InputIt last ); }; template diff --git a/clang/test/Analysis/issue-132010.cpp b/clang/test/Analysis/issue-132010.cpp new file mode 100644 index 0..abdaed57f26b9 --- /dev/null +++ b/clang/test/Analysis/issue-132010.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning +} diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 570e742751ead..325e7764ad7fa 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -19,6 +19,11 @@ void good_insert4(std::vector &V, int len, int n) { V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning } +void good_insert5(std::vector &V, int len, int n) { + std::unordered_set us; + us.insert(V.cbegin(), V.cend()); // no-warning +} + void good_insert_find(std::vector &V, int n, int m) { auto i = std::find(V.cbegin(), V.cend(), n); V.insert(i, m); // no-warning @@ -70,6 +75,11 @@ void bad_insert4(std::vector &V1, std::vector &V2, int len, int n) { V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} } +void bad_insert5(std::vector &V1, std::vector &V2, int len, int n) { + std::unordered_set us; + us.insert(V1.cbegin(), V2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} +} + void bad_erase1(std::vector &V1, std::vector &V2) { V2.erase(V1.cbegin()); // expected-warning{{Contain
[clang-tools-extra] 4a76434 - [clang-tools-extra] Use *Set::insert_range (NFC) (#132589)
Author: Kazu Hirata Date: 2025-03-23T00:23:19-07:00 New Revision: 4a7643400c44db434983c172d2329bf31679e8fa URL: https://github.com/llvm/llvm-project/commit/4a7643400c44db434983c172d2329bf31679e8fa DIFF: https://github.com/llvm/llvm-project/commit/4a7643400c44db434983c172d2329bf31679e8fa.diff LOG: [clang-tools-extra] Use *Set::insert_range (NFC) (#132589) DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently gained C++23-style insert_range. This patch replaces: Dest.insert(Src.begin(), Src.end()); with: Dest.insert_range(Src); Added: Modified: clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp clang-tools-extra/clangd/unittests/TestIndex.cpp Removed: diff --git a/clang-tools-extra/clang-move/Move.cpp b/clang-tools-extra/clang-move/Move.cpp index ac16803b46783..17f597170f9f6 100644 --- a/clang-tools-extra/clang-move/Move.cpp +++ b/clang-tools-extra/clang-move/Move.cpp @@ -464,7 +464,7 @@ getUsedDecls(const HelperDeclRefGraph *RG, for (const auto *D : Decls) { auto Result = RG->getReachableNodes( HelperDeclRGBuilder::getOutmostClassOrFunDecl(D)); -Nodes.insert(Result.begin(), Result.end()); +Nodes.insert_range(Result); } llvm::DenseSet Results; for (const auto *Node : Nodes) diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index 3d1f63fcf33a5..7e9551532b72f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -43,13 +43,11 @@ ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, IgnoredExceptionsVec; StringRef(RawFunctionsThatShouldNotThrow) .split(FunctionsThatShouldNotThrowVec, ",", -1, false); - FunctionsThatShouldNotThrow.insert(FunctionsThatShouldNotThrowVec.begin(), - FunctionsThatShouldNotThrowVec.end()); + FunctionsThatShouldNotThrow.insert_range(FunctionsThatShouldNotThrowVec); llvm::StringSet<> IgnoredExceptions; StringRef(RawIgnoredExceptions).split(IgnoredExceptionsVec, ",", -1, false); - IgnoredExceptions.insert(IgnoredExceptionsVec.begin(), - IgnoredExceptionsVec.end()); + IgnoredExceptions.insert_range(IgnoredExceptionsVec); Tracer.ignoreExceptions(std::move(IgnoredExceptions)); Tracer.ignoreBadAlloc(true); } diff --git a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp index 2250bba4db669..47f3f96ed803b 100644 --- a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp @@ -51,7 +51,7 @@ template class ImmutableSmallSet { // We've decided that it isn't performant to keep using vector. // Let's migrate the data into Set. Set.reserve(Storage.size()); -Set.insert(Storage.begin(), Storage.end()); +Set.insert_range(Storage); } /// count - Return 1 if the element is in the set, 0 otherwise. @@ -97,7 +97,7 @@ template class SmartSmallSetVector { const size_t NewMaxElts = 4 * Vector.size(); Vector.reserve(NewMaxElts); Set.reserve(NewMaxElts); -Set.insert(Vector.begin(), Vector.end()); +Set.insert_range(Vector); } /// count - Return 1 if the element is in the set, 0 otherwise. diff --git a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp index b414fd3b4d1a3..64ca212473e10 100644 --- a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp @@ -30,8 +30,7 @@ ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, StringRef(RawIgnoredExceptions).split(IgnoredExceptionsVec, ",", -1, false); llvm::transform(IgnoredExceptionsVec, IgnoredExceptionsVec.begin(), [](StringRef S) { return S.trim(); }); - IgnoredExceptions.insert(IgnoredExceptionsVec.begin(), - IgnoredExceptionsVec.end()); + IgnoredExceptions.insert_range(IgnoredExceptionsVec); Tracer.ignoreExceptions(std::move(IgnoredExceptions)); Tracer.ignoreBadAlloc(true); } diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index bc49fa856bafc..e28ee7d9c70f7 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -22,7 +22,7 @@ void ExceptionAnalyzer::ExceptionI
[clang-tools-extra] [clang-tools-extra] Use *Set::insert_range (NFC) (PR #132589)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/132589 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/flovent created https://github.com/llvm/llvm-project/pull/132596 This PR fixs #132010. Associative containers in STL has an unique `insert` overload member function comparing to un-associative containers(https://en.cppreference.com/w/cpp/container/unordered_set/insert): ``` template< class InputIt > void insert( InputIt first, InputIt last ); ``` Add support for this `insert` overload in `MismatchedIteratorChecker`, verify if `first` and `last` belongs to the same container in this case. >From 778f8c2dfa4d3c87e1b260fcff8b4f9f69d5aa50 Mon Sep 17 00:00:00 2001 From: flovent Date: Sun, 23 Mar 2025 14:54:28 +0800 Subject: [PATCH] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker --- .../Checkers/MismatchedIteratorChecker.cpp | 18 -- .../Inputs/system-header-simulator-cxx.h | 4 clang/test/Analysis/issue-132010.cpp | 12 clang/test/Analysis/mismatched-iterator.cpp| 10 ++ 4 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 clang/test/Analysis/issue-132010.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..1c101b91f727f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -91,12 +91,18 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, InstCall->getCXXThisVal().getAsRegion()); } } else if (isInsertCall(Func)) { - verifyMatch(C, Call.getArgSVal(0), - InstCall->getCXXThisVal().getAsRegion()); - if (Call.getNumArgs() == 3 && - isIteratorType(Call.getArgExpr(1)->getType()) && - isIteratorType(Call.getArgExpr(2)->getType())) { -verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); + if (Call.getNumArgs() == 2 && + isIteratorType(Call.getArgExpr(0)->getType()) && + isIteratorType(Call.getArgExpr(1)->getType())) { +verifyMatch(C, Call.getArgSVal(0), Call.getArgSVal(1)); + } else { +verifyMatch(C, Call.getArgSVal(0), +InstCall->getCXXThisVal().getAsRegion()); +if (Call.getNumArgs() == 3 && +isIteratorType(Call.getArgExpr(1)->getType()) && +isIteratorType(Call.getArgExpr(2)->getType())) { + verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); +} } } else if (isEmplaceCall(Func)) { verifyMatch(C, Call.getArgSVal(0), diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index a379a47515668..c5aeb0af9d578 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1244,6 +1244,7 @@ template< class Alloc = std::allocator > class unordered_set { public: +unordered_set() {} unordered_set(initializer_list __list) {} class iterator { @@ -1260,6 +1261,9 @@ template< Key *val; iterator begin() const { return iterator(val); } iterator end() const { return iterator(val + 1); } + +template< class InputIt > +void insert( InputIt first, InputIt last ); }; template diff --git a/clang/test/Analysis/issue-132010.cpp b/clang/test/Analysis/issue-132010.cpp new file mode 100644 index 0..abdaed57f26b9 --- /dev/null +++ b/clang/test/Analysis/issue-132010.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning +} diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 570e742751ead..325e7764ad7fa 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -19,6 +19,11 @@ void good_insert4(std::vector &V, int len, int n) { V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning } +void good_insert5(std::vector &V, int len, int n) { + std::unordered_set us; + us.insert(V.cbegin(), V.cend()); // no-warning +} + void good_insert_find(std::vector &V, int n, int m) { auto i = std::find(V.cbegin(), V.cend(), n); V.insert(i, m); // no-warning @@ -70,6 +75,11 @@ void bad_insert4(std::vector &V1, std::vector &V2, int len, int n) { V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} } +void bad_insert5(std::vector &V1, std::vector &V2, int len, int n) { + std::unordered_set us; + us.insert(V1.cbegin(), V2.cend()); // expected-warnin
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Ignore unnamed bitfields in UninitializedObjectChecker (PR #132427)
steakhal wrote: > @steakhal Okay, glad to do it. But I don't know specifically about the > workflow of review. Could you give me some guidance? How is this proposal different from yours? What do you think is objectively a better approach? Do the added tests cover the intended behavior? Would the test indeed fail without the fix, but pass with the fix? Which approach is more maintainable for the long run? Can we think of some other solutions that we haven't discussed yet? https://github.com/llvm/llvm-project/pull/132427 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang] Improve diagnostics for expansion length mismatch" (PR #121044)
zyn0217 wrote: @cor3ntin do you have any other concerns? thanks https://github.com/llvm/llvm-project/pull/121044 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 5fc891b - [clang][bytecode][NFC] Use getElemType() in __builtin_memchr as well (#132550)
Author: Timm Baeder Date: 2025-03-22T16:34:22+01:00 New Revision: 5fc891b965223d66b552397e49fb4b09d781d5da URL: https://github.com/llvm/llvm-project/commit/5fc891b965223d66b552397e49fb4b09d781d5da DIFF: https://github.com/llvm/llvm-project/commit/5fc891b965223d66b552397e49fb4b09d781d5da.diff LOG: [clang][bytecode][NFC] Use getElemType() in __builtin_memchr as well (#132550) For consistency. Added: Modified: clang/lib/AST/ByteCode/InterpBuiltin.cpp Removed: diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 2cbbfe5a9987f..4c359b100ab7e 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2053,9 +2053,7 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC, (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr); PrimType ElemT = - IsRawByte - ? PT_Sint8 - : *S.getContext().classify(Ptr.getFieldDesc()->getElemQualType()); + IsRawByte ? PT_Sint8 : *S.getContext().classify(getElemType(Ptr)); size_t Index = Ptr.getIndex(); size_t Step = 0; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/steakhal commented: Thanks. It looks good with nits. https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Placement new error when modifying consts (PR #132460)
mariusdr wrote: > The tests should go into a file not under `ByteCode/` since they aren't > specific to the bytecode interpreter. There should be existing placement new > tests in `SemaCXX/`. Thanks for the hint, moved them to clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp https://github.com/llvm/llvm-project/pull/132460 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
@@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning steakhal wrote: Isn't this test covered by the other test? Id say, let's drop this and keep the other. https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Placement new error when modifying consts (PR #132460)
https://github.com/mariusdr updated https://github.com/llvm/llvm-project/pull/132460 >From d4af25b14fb21f50c3771cce4595ca5c1bb920a7 Mon Sep 17 00:00:00 2001 From: marius doerner Date: Fri, 21 Mar 2025 20:19:57 +0100 Subject: [PATCH 1/2] [clang] Placement new error when modifying consts Raise an error when placement new is used to modify a const-qualified variable in a constexpr function. --- clang/lib/AST/ExprConstant.cpp| 9 ++ clang/test/AST/ByteCode/placement-new.cpp | 39 +++ 2 files changed, 48 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 92a28897cf3ee..b4fc3d4471064 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10415,7 +10415,16 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { typedef bool result_type; bool failed() { return false; } + bool checkConst(QualType QT) { +if (QT.isConstQualified()) { + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; + return false; +} +return true; + } bool found(APValue &Subobj, QualType SubobjType) { +if (!checkConst(SubobjType)) + return false; // FIXME: Reject the cases where [basic.life]p8 would not permit the // old name of the object to be used to name the new object. unsigned SubobjectSize = 1; diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index c353162a7aab0..9b12c9f2b1714 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -376,3 +376,42 @@ constexpr int N = [] // expected-error {{must be initialized by a constant expre return s.a[0]; }(); #endif + +constexpr int modify_const_variable() { + const int a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable()); // both-error {{not an integral constant expression}} \ +// both-note {{in call to}} + +typedef const int T0; +typedef T0 T1; +constexpr T1 modify_const_variable_td() { + T1 a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_td()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +template +constexpr T modify_const_variable_tmpl() { + T a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_tmpl()); // both-error {{not an integral constant expression}} \ +// both-note {{in call to}} + +namespace ModifyMutableMember { + struct S { +mutable int a {10}; + }; + constexpr int modify_mutable_member() { +const S s; +new ((int *)&s.a) int(12); +return s.a; + } + static_assert(modify_mutable_member() == 12); +} >From b596108cb5f66f81bdc1a0809f91cfa9b4dad0a6 Mon Sep 17 00:00:00 2001 From: marius doerner Date: Sun, 23 Mar 2025 09:21:34 +0100 Subject: [PATCH 2/2] Move tests from Ast/Bytecode to SemaCxx --- clang/test/AST/ByteCode/placement-new.cpp | 39 --- .../SemaCXX/cxx2c-constexpr-placement-new.cpp | 39 +++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index 9b12c9f2b1714..c353162a7aab0 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -376,42 +376,3 @@ constexpr int N = [] // expected-error {{must be initialized by a constant expre return s.a[0]; }(); #endif - -constexpr int modify_const_variable() { - const int a = 10; - new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} - return a; -} -static_assert(modify_const_variable()); // both-error {{not an integral constant expression}} \ -// both-note {{in call to}} - -typedef const int T0; -typedef T0 T1; -constexpr T1 modify_const_variable_td() { - T1 a = 10; - new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}} - return a; -} -static_assert(modify_const_variable_td()); // both-error {{not an integral constant expression}} \ - // both-note {{in call to}} - -template -constexpr T modify_const_variable_tmpl() { - T a = 10; - n
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
@@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning flovent wrote: This file is deleted in new commit https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/flovent updated https://github.com/llvm/llvm-project/pull/132596 >From 778f8c2dfa4d3c87e1b260fcff8b4f9f69d5aa50 Mon Sep 17 00:00:00 2001 From: flovent Date: Sun, 23 Mar 2025 14:54:28 +0800 Subject: [PATCH 1/2] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker --- .../Checkers/MismatchedIteratorChecker.cpp | 18 -- .../Inputs/system-header-simulator-cxx.h | 4 clang/test/Analysis/issue-132010.cpp | 12 clang/test/Analysis/mismatched-iterator.cpp| 10 ++ 4 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 clang/test/Analysis/issue-132010.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..1c101b91f727f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -91,12 +91,18 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, InstCall->getCXXThisVal().getAsRegion()); } } else if (isInsertCall(Func)) { - verifyMatch(C, Call.getArgSVal(0), - InstCall->getCXXThisVal().getAsRegion()); - if (Call.getNumArgs() == 3 && - isIteratorType(Call.getArgExpr(1)->getType()) && - isIteratorType(Call.getArgExpr(2)->getType())) { -verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); + if (Call.getNumArgs() == 2 && + isIteratorType(Call.getArgExpr(0)->getType()) && + isIteratorType(Call.getArgExpr(1)->getType())) { +verifyMatch(C, Call.getArgSVal(0), Call.getArgSVal(1)); + } else { +verifyMatch(C, Call.getArgSVal(0), +InstCall->getCXXThisVal().getAsRegion()); +if (Call.getNumArgs() == 3 && +isIteratorType(Call.getArgExpr(1)->getType()) && +isIteratorType(Call.getArgExpr(2)->getType())) { + verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); +} } } else if (isEmplaceCall(Func)) { verifyMatch(C, Call.getArgSVal(0), diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index a379a47515668..c5aeb0af9d578 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1244,6 +1244,7 @@ template< class Alloc = std::allocator > class unordered_set { public: +unordered_set() {} unordered_set(initializer_list __list) {} class iterator { @@ -1260,6 +1261,9 @@ template< Key *val; iterator begin() const { return iterator(val); } iterator end() const { return iterator(val + 1); } + +template< class InputIt > +void insert( InputIt first, InputIt last ); }; template diff --git a/clang/test/Analysis/issue-132010.cpp b/clang/test/Analysis/issue-132010.cpp new file mode 100644 index 0..abdaed57f26b9 --- /dev/null +++ b/clang/test/Analysis/issue-132010.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_analyze_cc1 -analyzer-config aggressive-binary-operation-simplification=true -analyzer-checker=alpha.cplusplus.MismatchedIterator -analyzer-output text -verify %s + +// expected-no-diagnostics + +#include "Inputs/system-header-simulator-cxx.h" + +void f() +{ +std::list l; +std::unordered_set us; +us.insert(l.cbegin(), l.cend()); // no warning +} diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 570e742751ead..325e7764ad7fa 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -19,6 +19,11 @@ void good_insert4(std::vector &V, int len, int n) { V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning } +void good_insert5(std::vector &V, int len, int n) { + std::unordered_set us; + us.insert(V.cbegin(), V.cend()); // no-warning +} + void good_insert_find(std::vector &V, int n, int m) { auto i = std::find(V.cbegin(), V.cend(), n); V.insert(i, m); // no-warning @@ -70,6 +75,11 @@ void bad_insert4(std::vector &V1, std::vector &V2, int len, int n) { V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} } +void bad_insert5(std::vector &V1, std::vector &V2, int len, int n) { + std::unordered_set us; + us.insert(V1.cbegin(), V2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} +} + void bad_erase1(std::vector &V1, std::vector &V2) { V2.erase(V1.cbegin()); // expected-warning{{Container accessed using foreign iterator argument}} } >From a8cde1217f73e48b78fd80b7d244fb2cc80a7149 Mon Sep 17 00:00:00 2001 From: flovent Date: Sun, 23 Mar 2025 16:29:26 +0800 Subject: [PATCH 2/2] delete redundant testcase file --- cl
[clang] [llvm] [BPF] Make -mcpu=v3 as the default (PR #107008)
yonghong-song wrote: @yuvald-sweet-security I did one example with your above example, ``` sudo ~/veristat /tmp/test-v1.o --filter=trace_ret_vfs_writev_tail sudo ~/veristat /tmp/test-v3.o --filter=trace_ret_vfs_writev_tail ``` I can reproduce the issue. The v3 failure reason is actually due to your have inline asm code which prevents compiler from doing a good job for v3. I did the following change to the source ``` diff --git a/pkg/ebpf/c/common/filesystem.h b/pkg/ebpf/c/common/filesystem.h index f1f042e35..27dffb431 100644 --- a/pkg/ebpf/c/common/filesystem.h +++ b/pkg/ebpf/c/common/filesystem.h @@ -487,6 +487,8 @@ statfunc void fill_vfs_file_bin_args(u32 type, statfunc void fill_file_header(u8 header[FILE_MAGIC_HDR_SIZE], io_data_t io_data) { u32 len = (u32) io_data.len; +// The following is needed only for -mcpu=v1. +asm volatile("" : "+r"(len)); if (io_data.is_buf) { // inline bounds check to force compiler to use the register of len asm volatile("if %[size] < %[max_size] goto +1;\n" @@ -499,10 +501,15 @@ statfunc void fill_file_header(u8 header[FILE_MAGIC_HDR_SIZE], io_data_t io_data __builtin_memset(&io_vec, 0, sizeof(io_vec)); bpf_probe_read(&io_vec, sizeof(struct iovec), io_data.ptr); // inline bounds check to force compiler to use the register of len +#if 0 asm volatile("if %[size] < %[max_size] goto +1;\n" "%[size] = %[max_size];\n" : : [size] "r"(len), [max_size] "i"(FILE_MAGIC_HDR_SIZE)); +#else +if (len >= FILE_MAGIC_HDR_SIZE) +len = FILE_MAGIC_HDR_SIZE; +#endif bpf_probe_read(header, len, io_vec.iov_base); } } ``` The barrier_var(len) (i.e., asm volatile("" : "+r"(len))) is only needed for cpu=v1 but also works for cpu=v3. The original asm code prevents a good compiler transformation at cpu=v3. I suggest you try to replace asm code with proper C code and if necessary barrier_var. That should resolve your issue in most cases and it is also portable between different cpu versions. https://github.com/llvm/llvm-project/pull/107008 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Placement new error when modifying consts (PR #132460)
https://github.com/mariusdr updated https://github.com/llvm/llvm-project/pull/132460 >From d4af25b14fb21f50c3771cce4595ca5c1bb920a7 Mon Sep 17 00:00:00 2001 From: marius doerner Date: Fri, 21 Mar 2025 20:19:57 +0100 Subject: [PATCH 1/2] [clang] Placement new error when modifying consts Raise an error when placement new is used to modify a const-qualified variable in a constexpr function. --- clang/lib/AST/ExprConstant.cpp| 9 ++ clang/test/AST/ByteCode/placement-new.cpp | 39 +++ 2 files changed, 48 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 92a28897cf3ee..b4fc3d4471064 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10415,7 +10415,16 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { typedef bool result_type; bool failed() { return false; } + bool checkConst(QualType QT) { +if (QT.isConstQualified()) { + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; + return false; +} +return true; + } bool found(APValue &Subobj, QualType SubobjType) { +if (!checkConst(SubobjType)) + return false; // FIXME: Reject the cases where [basic.life]p8 would not permit the // old name of the object to be used to name the new object. unsigned SubobjectSize = 1; diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index c353162a7aab0..9b12c9f2b1714 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -376,3 +376,42 @@ constexpr int N = [] // expected-error {{must be initialized by a constant expre return s.a[0]; }(); #endif + +constexpr int modify_const_variable() { + const int a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable()); // both-error {{not an integral constant expression}} \ +// both-note {{in call to}} + +typedef const int T0; +typedef T0 T1; +constexpr T1 modify_const_variable_td() { + T1 a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_td()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +template +constexpr T modify_const_variable_tmpl() { + T a = 10; + new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_tmpl()); // both-error {{not an integral constant expression}} \ +// both-note {{in call to}} + +namespace ModifyMutableMember { + struct S { +mutable int a {10}; + }; + constexpr int modify_mutable_member() { +const S s; +new ((int *)&s.a) int(12); +return s.a; + } + static_assert(modify_mutable_member() == 12); +} >From 197063860b652ba93ee3baab8b6213bb5dc809de Mon Sep 17 00:00:00 2001 From: marius doerner Date: Sun, 23 Mar 2025 09:21:34 +0100 Subject: [PATCH 2/2] Move tests from Ast/Bytecode to SemaCxx --- clang/test/AST/ByteCode/placement-new.cpp | 39 --- .../SemaCXX/cxx2c-constexpr-placement-new.cpp | 39 +++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp index 9b12c9f2b1714..c353162a7aab0 100644 --- a/clang/test/AST/ByteCode/placement-new.cpp +++ b/clang/test/AST/ByteCode/placement-new.cpp @@ -376,42 +376,3 @@ constexpr int N = [] // expected-error {{must be initialized by a constant expre return s.a[0]; }(); #endif - -constexpr int modify_const_variable() { - const int a = 10; - new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} - return a; -} -static_assert(modify_const_variable()); // both-error {{not an integral constant expression}} \ -// both-note {{in call to}} - -typedef const int T0; -typedef T0 T1; -constexpr T1 modify_const_variable_td() { - T1 a = 10; - new ((int *)&a) int(12); // both-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}} - return a; -} -static_assert(modify_const_variable_td()); // both-error {{not an integral constant expression}} \ - // both-note {{in call to}} - -template -constexpr T modify_const_variable_tmpl() { - T a = 10; - n
[clang] [llvm] [BPF] Make -mcpu=v3 as the default (PR #107008)
yuvald-sweet-security wrote: @yonghong-song thank you for taking the time to help with this issue and providing your suggestions, it’s greatly appreciated. I am also glad to hear that asm barriers are no longer necessary, as they caused quite some trouble for me in the past. However, I've encountered a few issues while attempting to apply this as a solution to the problem with moving to mpcu v3. * while you are correct in that removing the barriers fixes the verifier failure in `trace_ret_vfs_writev_tail`, the original issue I've pointed out - the increased size of kernel verifier states and instructions when using v3 - still remains: ``` $ sudo /root/veristat /tmp/test-v1.o --filter=trace_ret_vfs_writev_tail Processing 'test-v1.o'... File ProgramVerdict Duration (us) Insns States Program size Jited size - - --- - - -- -- test-v1.o trace_ret_vfs_writev_tail success 23158 252921874 7163 38486 - - --- - - -- -- Done. Processed 1 files, 0 programs. Skipped 1 files, 158 programs. $ sudo /root/veristat /tmp/test-v3-nobarrier.o --filter=trace_ret_vfs_writev_tail Processing 'test-v3-nobarrier.o'... File ProgramVerdict Duration (us) Insns States Program size Jited size --- - --- - -- -- -- test-v3-nobarrier.o trace_ret_vfs_writev_tail success 69161 104971 7618 6999 37490 --- - --- - -- -- -- Done. Processed 1 files, 0 programs. Skipped 1 files, 158 programs. ``` As you can see the v3 codegen causes the verifier to consume about 4 times the number of instructions when verifying it, and while it's not such a big issue for this particular function, it can be an issue for larger functions which are already close to the verifier's 1 million instructions limit as this can cause them to go over it. * Many verifier failures still remain after removing the barriers. e.g. the function `vfs_writev_magic_return` still fails even after I've removed all asm volatile/barrier vars (you can use [patch.txt](https://github.com/user-attachments/files/19407900/patch.txt) which removes all of them). Also, in some of the code that I have removing the barrier vars on v3 codegen actually introduces more verifier failures (compared to v3 with barrier vars), I'll see if I can make a minimal example of this. thank you again for your thoughtful advice and support https://github.com/llvm/llvm-project/pull/107008 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2fe7585 - [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (#132596)
Author: flovent Date: 2025-03-23T09:49:37+01:00 New Revision: 2fe75856865e20633da33f6b526e47367a035152 URL: https://github.com/llvm/llvm-project/commit/2fe75856865e20633da33f6b526e47367a035152 DIFF: https://github.com/llvm/llvm-project/commit/2fe75856865e20633da33f6b526e47367a035152.diff LOG: [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (#132596) Fixes #132010 Associative containers in STL has an unique `insert` overload member function comparing to un-associative containers(https://en.cppreference.com/w/cpp/container/unordered_set/insert): ``` template< class InputIt > void insert( InputIt first, InputIt last ); ``` Add support for this `insert` overload in `MismatchedIteratorChecker`, verify if `first` and `last` belongs to the same container in this case. Added: Modified: clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp clang/test/Analysis/Inputs/system-header-simulator-cxx.h clang/test/Analysis/mismatched-iterator.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..1c101b91f727f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -91,12 +91,18 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, InstCall->getCXXThisVal().getAsRegion()); } } else if (isInsertCall(Func)) { - verifyMatch(C, Call.getArgSVal(0), - InstCall->getCXXThisVal().getAsRegion()); - if (Call.getNumArgs() == 3 && - isIteratorType(Call.getArgExpr(1)->getType()) && - isIteratorType(Call.getArgExpr(2)->getType())) { -verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); + if (Call.getNumArgs() == 2 && + isIteratorType(Call.getArgExpr(0)->getType()) && + isIteratorType(Call.getArgExpr(1)->getType())) { +verifyMatch(C, Call.getArgSVal(0), Call.getArgSVal(1)); + } else { +verifyMatch(C, Call.getArgSVal(0), +InstCall->getCXXThisVal().getAsRegion()); +if (Call.getNumArgs() == 3 && +isIteratorType(Call.getArgExpr(1)->getType()) && +isIteratorType(Call.getArgExpr(2)->getType())) { + verifyMatch(C, Call.getArgSVal(1), Call.getArgSVal(2)); +} } } else if (isEmplaceCall(Func)) { verifyMatch(C, Call.getArgSVal(0), diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index a379a47515668..c5aeb0af9d578 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -1244,6 +1244,7 @@ template< class Alloc = std::allocator > class unordered_set { public: +unordered_set() {} unordered_set(initializer_list __list) {} class iterator { @@ -1260,6 +1261,9 @@ template< Key *val; iterator begin() const { return iterator(val); } iterator end() const { return iterator(val + 1); } + +template< class InputIt > +void insert( InputIt first, InputIt last ); }; template diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 570e742751ead..325e7764ad7fa 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -19,6 +19,11 @@ void good_insert4(std::vector &V, int len, int n) { V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning } +void good_insert5(std::vector &V, int len, int n) { + std::unordered_set us; + us.insert(V.cbegin(), V.cend()); // no-warning +} + void good_insert_find(std::vector &V, int n, int m) { auto i = std::find(V.cbegin(), V.cend(), n); V.insert(i, m); // no-warning @@ -70,6 +75,11 @@ void bad_insert4(std::vector &V1, std::vector &V2, int len, int n) { V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} } +void bad_insert5(std::vector &V1, std::vector &V2, int len, int n) { + std::unordered_set us; + us.insert(V1.cbegin(), V2.cend()); // expected-warning{{Iterators of diff erent containers used where the same container is expected}} +} + void bad_erase1(std::vector &V1, std::vector &V2) { V2.erase(V1.cbegin()); // expected-warning{{Container accessed using foreign iterator argument}} } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve the modeling of insert in MismatchedIteratorChecker (PR #132596)
https://github.com/steakhal closed https://github.com/llvm/llvm-project/pull/132596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
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 1019457891fda0b2f32f50ba99d6a261df12ec08 6545414a97b6458333f399c7252ae55c88a42d62 --extensions cpp -- clang/lib/Interpreter/Interpreter.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5f48117dbf..3fbfd3c746 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -155,17 +155,19 @@ static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { if (FrontendOpts.ShowVersion) { llvm::cl::PrintVersionMessage(); -return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); +return llvm::createStringError(llvm::errc::not_supported, + "Version displayed"); } if (!FrontendOpts.LLVMArgs.empty()) { unsigned NumArgs = FrontendOpts.LLVMArgs.size(); -auto Args = std::make_unique(NumArgs + 2); +auto Args = std::make_unique(NumArgs + 2); Args[0] = "clang-repl (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); Args[NumArgs + 1] = nullptr; -llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; +llvm::errs() +<< "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } `` https://github.com/llvm/llvm-project/pull/132670 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Avoid repeated map lookups (NFC) (PR #132656)
https://github.com/steakhal approved this pull request. https://github.com/llvm/llvm-project/pull/132656 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
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 5ac680c5bffdc216d131fd260d2b1c9435b15571 fa0f1079587e6e26279c293fe4467ff0388f6a43 --extensions cpp -- clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize/use-emplace.cpp `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 277994bbb6..ea449944bb 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -225,12 +225,11 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // allow for T{} to be replaced, even if no CTOR is declared auto HasConstructInitListExpr = has(initListExpr( - initCountLeq(1), - anyOf(allOf(has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0, -has(cxxBindTemporaryExpr(has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0))) - ); + initCountLeq(1), anyOf(allOf(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0, + has(cxxBindTemporaryExpr( + has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0; auto HasBracedInitListExpr = anyOf(has(cxxBindTemporaryExpr(HasConstructInitListExpr)), HasConstructInitListExpr); `` https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial for-loop support (PR #132266)
@@ -165,6 +165,25 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) { return LValue(); } +mlir::Value CIRGenFunction::evaluateExprAsBool(const Expr *e) { erichkeane wrote: This should only be necessary in C, right? Where 'bool' isn't available. SO how would this work? https://github.com/llvm/llvm-project/pull/132266 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Objects (PR #131969)
https://github.com/RiverDave edited https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/132669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave edited https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave updated https://github.com/llvm/llvm-project/pull/131969 >From c966cef850ed1350264110e622866dae66f99a07 Mon Sep 17 00:00:00 2001 From: David Rivera Date: Sun, 16 Mar 2025 16:20:16 -0400 Subject: [PATCH] [clang-tidy] Add support for Initialization Forwarding in Nested Objects within modernize-use-emplace --- .../clang-tidy/modernize/UseEmplaceCheck.cpp | 121 ++ clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checkers/modernize/use-emplace.cpp| 26 +++- 3 files changed, 126 insertions(+), 25 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 430455a38f395..4c601d2677257 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -98,8 +98,8 @@ auto hasWantedType(llvm::ArrayRef TypeNames) { // Matches member call expressions of the named method on the listed container // types. -auto cxxMemberCallExprOnContainer( -StringRef MethodName, llvm::ArrayRef ContainerNames) { +auto cxxMemberCallExprOnContainer(StringRef MethodName, + llvm::ArrayRef ContainerNames) { return cxxMemberCallExpr( hasDeclaration(functionDecl(hasName(MethodName))), on(hasTypeOrPointeeType(hasWantedType(ContainerNames; @@ -174,19 +174,19 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // passed pointer because smart pointer won't be constructed // (and destructed) as in push_back case. auto IsCtorOfSmartPtr = - hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(SmartPointers; + cxxConstructorDecl(ofClass(hasAnyName(SmartPointers))); // Bitfields binds only to consts and emplace_back take it by universal ref. - auto BitFieldAsArgument = hasAnyArgument( - ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField()); + auto BitFieldAsArgument = + ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField(); // Initializer list can't be passed to universal reference. - auto InitializerListAsArgument = hasAnyArgument( + auto InitializerListAsArgument = ignoringImplicit(allOf(cxxConstructExpr(isListInitialization()), - unless(cxxTemporaryObjectExpr(); + unless(cxxTemporaryObjectExpr(; // We could have leak of resource. - auto NewExprAsArgument = hasAnyArgument(ignoringImplicit(cxxNewExpr())); + auto NewExprAsArgument = ignoringImplicit(cxxNewExpr()); // We would call another constructor. auto ConstructingDerived = hasParent(implicitCastExpr(hasCastKind(CastKind::CK_DerivedToBase))); @@ -202,19 +202,36 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // overloaded functions and template names. auto SoughtConstructExpr = cxxConstructExpr( - unless(anyOf(IsCtorOfSmartPtr, HasInitList, BitFieldAsArgument, - InitializerListAsArgument, NewExprAsArgument, - ConstructingDerived, IsPrivateOrProtectedCtor))) + unless(anyOf(hasDeclaration(IsCtorOfSmartPtr), HasInitList, + hasAnyArgument(BitFieldAsArgument), + hasAnyArgument(InitializerListAsArgument), + hasAnyArgument(NewExprAsArgument), ConstructingDerived, + IsPrivateOrProtectedCtor))) .bind("ctor"); - auto HasConstructExpr = has(ignoringImplicit(SoughtConstructExpr)); + + auto IsPrimitiveType = hasType(builtinType()); + + auto AggregateInitExpr = + getLangOpts().CPlusPlus20 + ? initListExpr(unless(anyOf(HasInitList, has(IsCtorOfSmartPtr), + has(BitFieldAsArgument), + has(InitializerListAsArgument), + has(NewExprAsArgument), IsPrimitiveType))) +.bind("agg_init") + : unless(anything()); + + auto HasConstructExpr = + has(ignoringImplicit(anyOf(SoughtConstructExpr, AggregateInitExpr))); // allow for T{} to be replaced, even if no CTOR is declared auto HasConstructInitListExpr = has(initListExpr( - initCountLeq(1), anyOf(allOf(has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0, - has(cxxBindTemporaryExpr( - has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0; + initCountLeq(1), + anyOf(allOf(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0, +has(cxxBindTemporaryExpr(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0))) + + ); auto HasBracedIni
[clang-tools-extra] [clang-doc] [feat] add --repository-line-prefix argument (PR #131280)
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280 >From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 01/10] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 --- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector &References, return Out; } -static std::unique_ptr -writeFileDefinition(const Location &L, -std::optional RepositoryUrl = std::nullopt) { +static std::unique_ptr writeFileDefinition( +const Location &L, std::optional RepositoryUrl = std::nullopt, +std::optional RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); - // The links to a specific line in the source code use the github / - // googlesource notation so it won't work for all hosting pages. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) +LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique(" of file ")); + auto LocFileNode = std::make_unique( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique(")")); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-too
[clang] [llvm] Optimize Module Dependency Handling for Efficient Memory Usage (PR #132294)
https://github.com/ayushpareek2003 closed https://github.com/llvm/llvm-project/pull/132294 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
anutosh491 wrote: After handling these args we should see ``` (base) anutosh491@Anutoshs-MacBook-Air bin % ./clang-repl --Xcc -Xclang --Xcc -version LLVM (http://llvm.org/): LLVM version 21.0.0git Optimized build. clang-repl: Version displayed ``` rather than the abort. https://github.com/llvm/llvm-project/pull/132670 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) Changes Thanks to the example provided by @MagentaTreehouse, I realized the assertion I added didn't cover all valid cases like, when inheriting from a class template specialization, the source of a synthesized template parameter might be an implicit specialization, whose inner function template is thus living at depth 0, for which we don’t want it to overflow too. --- Full diff: https://github.com/llvm/llvm-project/pull/132669.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+7-5) - (modified) clang/test/SemaTemplate/deduction-guide.cpp (+26) ``diff diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 9cfdb7596b660..e20130a33f368 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -376,12 +376,14 @@ struct ConvertConstructorToDeductionGuideTransform { if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); auto [Depth, Index] = getDepthAndIndex(Param); -// Depth can still be 0 if FTD belongs to an explicit class template -// specialization with an empty template parameter list. In that case, -// we don't want the NewDepth to overflow, and it should remain 0. +// Depth can be 0 if FTD belongs to a class template specialization with +// an empty template parameter list (i.e. either an explicit full +// specialization or an implicit specialization) In that case, we don't +// want the NewDepth to overflow, and it should remain 0. assert(Depth || - cast(FTD->getDeclContext()) - ->isExplicitSpecialization()); + isa( + cast(FTD->getDeclContext()) + ->getSpecializedTemplateOrPartial())); NamedDecl *NewParam = transformTemplateParameter( SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth ? Depth - 1 : 0); diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index ecd152abebd74..95e740a026550 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -723,3 +723,29 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr // CHECK-NEXT: `-ParmVarDecl {{.+}} 'T' } // namespace GH128691 + +namespace GH132616_DeductionGuide { + +template struct A { + template + A(U); +}; + +template +struct B: A { + using A::A; +}; + +template +B(T) -> B; + +B b(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit 'auto (U) -> B' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +} // namespace GH132616_DeductionGuide `` https://github.com/llvm/llvm-project/pull/132669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
https://github.com/anutosh491 created https://github.com/llvm/llvm-project/pull/132670 1) How usual clang works It goes from Creating the Compiler Instance -> [Addressing these llvmargs](https://github.com/llvm/llvm-project/blob/4e4e4a190fb7c74453994935c843b09cc682f4bb/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp#L231-L239) -> calling [executeAction](https://github.com/llvm/llvm-project/blob/4e4e4a190fb7c74453994935c843b09cc682f4bb/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp#L280) 2) what clang-repl does is create the Compiler Instance -> calls executeAction (and doesn't handle some options in between) So ExecuteAction is framed like this ``` bool CompilerInstance::ExecuteAction(FrontendAction &Act) { assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); ``` And clang-repl would need to handle these before getting to executeAction. Otherwise 1) processing the -Xclang -version flag would give us the following (as shown while running clang-repl in the browser)  2) This would also help us process a try-catch block while running clang-repl in the browser which can't be done currently  >From 6545414a97b6458333f399c7252ae55c88a42d62 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 24 Mar 2025 10:09:59 +0530 Subject: [PATCH] Handle frontend options for clang-repl before calling executeAction --- clang/lib/Interpreter/Interpreter.cpp | 38 ++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index fa4c1439c9261..5f48117dbf3b8 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -141,6 +141,37 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { return std::move(Clang); } +static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { + const auto &FrontendOpts = CI.getFrontendOpts(); + + if (FrontendOpts.ShowHelp) { +driver::getDriverOptTable().printHelp( +llvm::outs(), "clang -cc1 [options] file...", +"LLVM 'Clang' Compiler: http://clang.llvm.org";, +/*ShowHidden=*/false, /*ShowAllAliases=*/false, +llvm::opt::Visibility(driver::options::CC1Option)); +return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); + } + + if (FrontendOpts.ShowVersion) { +llvm::cl::PrintVersionMessage(); +return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); + } + + if (!FrontendOpts.LLVMArgs.empty()) { +unsigned NumArgs = FrontendOpts.LLVMArgs.size(); +auto Args = std::make_unique(NumArgs + 2); +Args[0] = "clang-repl (LLVM option parsing)"; +for (unsigned i = 0; i != NumArgs; ++i) + Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); +Args[NumArgs + 1] = nullptr; +llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; +llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); + } + + return llvm::Error::success(); +} + } // anonymous namespace namespace clang { @@ -451,7 +482,12 @@ const char *const Runtimes = R"( llvm::Expected> Interpreter::create(std::unique_ptr CI) { - llvm::Error Err = llvm::Error::success(); + + llvm::Error Err = HandleFrontendOptions(*CI); + if (Err) { +return std::move(Err); + } + auto Interp = std::unique_ptr(new Interpreter(std::move(CI), Err)); if (Err) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Anutosh Bhat (anutosh491) Changes 1) How usual clang works It goes from Creating the Compiler Instance -> [Addressing these llvmargs](https://github.com/llvm/llvm-project/blob/4e4e4a190fb7c74453994935c843b09cc682f4bb/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp#L231-L239) -> calling [executeAction](https://github.com/llvm/llvm-project/blob/4e4e4a190fb7c74453994935c843b09cc682f4bb/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp#L280) 2) what clang-repl does is create the Compiler Instance -> calls executeAction (and doesn't handle some options in between) So ExecuteAction is framed like this ``` bool CompilerInstance::ExecuteAction(FrontendAction &Act) { assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); ``` And clang-repl would need to handle these before getting to executeAction. Otherwise 1) processing the -Xclang -version flag would give us the following (as shown while running clang-repl in the browser)  2) This would also help us process a try-catch block while running clang-repl in the browser which can't be done currently  --- Full diff: https://github.com/llvm/llvm-project/pull/132670.diff 1 Files Affected: - (modified) clang/lib/Interpreter/Interpreter.cpp (+37-1) ``diff diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index fa4c1439c9261..5f48117dbf3b8 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -141,6 +141,37 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { return std::move(Clang); } +static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { + const auto &FrontendOpts = CI.getFrontendOpts(); + + if (FrontendOpts.ShowHelp) { +driver::getDriverOptTable().printHelp( +llvm::outs(), "clang -cc1 [options] file...", +"LLVM 'Clang' Compiler: http://clang.llvm.org";, +/*ShowHidden=*/false, /*ShowAllAliases=*/false, +llvm::opt::Visibility(driver::options::CC1Option)); +return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); + } + + if (FrontendOpts.ShowVersion) { +llvm::cl::PrintVersionMessage(); +return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); + } + + if (!FrontendOpts.LLVMArgs.empty()) { +unsigned NumArgs = FrontendOpts.LLVMArgs.size(); +auto Args = std::make_unique(NumArgs + 2); +Args[0] = "clang-repl (LLVM option parsing)"; +for (unsigned i = 0; i != NumArgs; ++i) + Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); +Args[NumArgs + 1] = nullptr; +llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; +llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); + } + + return llvm::Error::success(); +} + } // anonymous namespace namespace clang { @@ -451,7 +482,12 @@ const char *const Runtimes = R"( llvm::Expected> Interpreter::create(std::unique_ptr CI) { - llvm::Error Err = llvm::Error::success(); + + llvm::Error Err = HandleFrontendOptions(*CI); + if (Err) { +return std::move(Err); + } + auto Interp = std::unique_ptr(new Interpreter(std::move(CI), Err)); if (Err) `` https://github.com/llvm/llvm-project/pull/132670 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Fix RUN line and rename test name for pr129995 (PR #132676)
https://github.com/4vtomat created https://github.com/llvm/llvm-project/pull/132676 ninja check-clang can not detect .cc suffix, so the typo is not detected. >From e7b0b4feae891046553a04ddbf17e550742db54c Mon Sep 17 00:00:00 2001 From: Brandon Wu Date: Sun, 23 Mar 2025 23:29:27 -0700 Subject: [PATCH] [clang][RISCV] Fix RUN line and rename test name for pr129995 ninja check-clang can not detect .cc suffix, so the typo is not detected. --- clang/test/CodeGen/RISCV/{pr129995.cc => issue-129995.cpp} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename clang/test/CodeGen/RISCV/{pr129995.cc => issue-129995.cpp} (77%) diff --git a/clang/test/CodeGen/RISCV/pr129995.cc b/clang/test/CodeGen/RISCV/issue-129995.cpp similarity index 77% rename from clang/test/CodeGen/RISCV/pr129995.cc rename to clang/test/CodeGen/RISCV/issue-129995.cpp index 590c6b9fbdf96..4cd60a854558e 100644 --- a/clang/test/CodeGen/RISCV/pr129995.cc +++ b/clang/test/CodeGen/RISCV/issue-129995.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 triple riscv64 -emit-llvm -target-feature +m -target-feature +v -target-abi lp64d -o /dev/null %s +// RUN: %clang_cc1 -triple riscv64 -emit-llvm -target-feature +m -target-feature +v -target-abi lp64d -o /dev/null %s struct a { using b = char __attribute__((vector_size(sizeof(char; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][TableGen] Support specifying address space in clang builtin prototypes (PR #108497)
vikramRH wrote: handled https://github.com/llvm/llvm-project/pull/122873 https://github.com/llvm/llvm-project/pull/108497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Fix RUN line and rename test name for pr129995 (PR #132676)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Brandon Wu (4vtomat) Changes ninja check-clang can not detect .cc suffix, so the typo is not detected. --- Full diff: https://github.com/llvm/llvm-project/pull/132676.diff 1 Files Affected: - (renamed) clang/test/CodeGen/RISCV/issue-129995.cpp (+1-1) ``diff diff --git a/clang/test/CodeGen/RISCV/pr129995.cc b/clang/test/CodeGen/RISCV/issue-129995.cpp similarity index 77% rename from clang/test/CodeGen/RISCV/pr129995.cc rename to clang/test/CodeGen/RISCV/issue-129995.cpp index 590c6b9fbdf96..4cd60a854558e 100644 --- a/clang/test/CodeGen/RISCV/pr129995.cc +++ b/clang/test/CodeGen/RISCV/issue-129995.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 triple riscv64 -emit-llvm -target-feature +m -target-feature +v -target-abi lp64d -o /dev/null %s +// RUN: %clang_cc1 -triple riscv64 -emit-llvm -target-feature +m -target-feature +v -target-abi lp64d -o /dev/null %s struct a { using b = char __attribute__((vector_size(sizeof(char; `` https://github.com/llvm/llvm-project/pull/132676 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Optimize Module Dependency Handling for Efficient Memory Usage (PR #132294)
https://github.com/ayushpareek2003 updated https://github.com/llvm/llvm-project/pull/132294 >From 53a31ec6ed3d9ace8e7d822c2b2de4f6f58ece8d Mon Sep 17 00:00:00 2001 From: Ayush Pareek Date: Fri, 21 Mar 2025 03:44:05 +0530 Subject: [PATCH 1/2] Optimize Module Dependency Handling for Efficient Memory Usage -Optimized addModuleFiles functions for both CompilerInvocation and CowCompilerInvocation to reduce redundant function calls and improve efficiency -Introduced memory preallocation using reserve() when eager load is enabled to reduce reallocation overhead -Used try_emplace() instead of insert() for PrebuiltModuleFiles to avoid unnecessary overwrites --- .../DependencyScanning/ModuleDepCollector.cpp | 61 --- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index d715ef874e002..e172285c4b32d 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -393,41 +393,58 @@ void ModuleDepCollector::addModuleMapFiles( CompilerInvocation &CI, ArrayRef ClangModuleDeps) const { if (Service.shouldEagerLoadModules()) return; // Only pcm is needed for eager load. - + + // Preallocate memory to avoid multiple allocations + CI.getFrontendOpts().ModuleMapFiles.reserve( + CI.getFrontendOpts().ModuleMapFiles.size() + ClangModuleDeps.size()); for (const ModuleID &MID : ClangModuleDeps) { -ModuleDeps *MD = ModuleDepsByID.lookup(MID); -assert(MD && "Inconsistent dependency info"); -CI.getFrontendOpts().ModuleMapFiles.push_back(MD->ClangModuleMapFile); +if (ModuleDeps *MD = ModuleDepsByID.lookup(MID)) { // Single lookup + assert(MD && "Inconsistent dependency info"); + CI.getFrontendOpts().ModuleMapFiles.emplace_back(MD->ClangModuleMapFile); +} } } void ModuleDepCollector::addModuleFiles( CompilerInvocation &CI, ArrayRef ClangModuleDeps) const { + +// Preallocate memory if eager load is enabled + if (Service.shouldEagerLoadModules()) { +CI.getFrontendOpts().ModuleFiles.reserve( +CI.getFrontendOpts().ModuleFiles.size() + ClangModuleDeps.size()); + } for (const ModuleID &MID : ClangModuleDeps) { -ModuleDeps *MD = ModuleDepsByID.lookup(MID); -std::string PCMPath = -Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); - -if (Service.shouldEagerLoadModules()) - CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath)); -else - CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert( - {MID.ModuleName, std::move(PCMPath)}); +if (ModuleDeps *MD = ModuleDepsByID.lookup(MID)) { + std::string PCMPath = + Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); + if (Service.shouldEagerLoadModules()) { +CI.getFrontendOpts().ModuleFiles.emplace_back(std::move(PCMPath)); + } else { +CI.getHeaderSearchOpts().PrebuiltModuleFiles.try_emplace( +MID.ModuleName, std::move(PCMPath)); + } +} } } void ModuleDepCollector::addModuleFiles( CowCompilerInvocation &CI, ArrayRef ClangModuleDeps) const { +// Preallocation + if (Service.shouldEagerLoadModules()) { +CI.getMutFrontendOpts().ModuleFiles.reserve( +CI.getMutFrontendOpts().ModuleFiles.size() + ClangModuleDeps.size()); + } for (const ModuleID &MID : ClangModuleDeps) { -ModuleDeps *MD = ModuleDepsByID.lookup(MID); -std::string PCMPath = -Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); - -if (Service.shouldEagerLoadModules()) - CI.getMutFrontendOpts().ModuleFiles.push_back(std::move(PCMPath)); -else - CI.getMutHeaderSearchOpts().PrebuiltModuleFiles.insert( - {MID.ModuleName, std::move(PCMPath)}); +if (ModuleDeps *MD = ModuleDepsByID.lookup(MID)) { + std::string PCMPath = + Controller.lookupModuleOutput(*MD, ModuleOutputKind::ModuleFile); + if (Service.shouldEagerLoadModules()) { +CI.getMutFrontendOpts().ModuleFiles.emplace_back(std::move(PCMPath)); + } else { +CI.getMutHeaderSearchOpts().PrebuiltModuleFiles.try_emplace( +MID.ModuleName, std::move(PCMPath)); + } +} } } >From 153cc53186c60454154e205e48249177b1695eff Mon Sep 17 00:00:00 2001 From: Ayush Pareek Date: Mon, 24 Mar 2025 03:02:03 +0530 Subject: [PATCH 2/2] Update README.md --- bolt/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/bolt/README.md b/bolt/README.md index fe54bd82a356a..44ef33bcebeb0 100644 --- a/bolt/README.md +++ b/bolt/README.md @@ -7,6 +7,7 @@ An overview of the ideas implemented in BOLT along with a discussion of its potential and current results is available in [CGO'19 paper](https://research.fb.com/publications/bolt-a-practical-binary-optimizer-for-data-centers-and-beyond/).
[clang-tools-extra] [clang-doc] [feat] add --repository-line-prefix argument (PR #131280)
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280 >From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 01/10] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 --- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector &References, return Out; } -static std::unique_ptr -writeFileDefinition(const Location &L, -std::optional RepositoryUrl = std::nullopt) { +static std::unique_ptr writeFileDefinition( +const Location &L, std::optional RepositoryUrl = std::nullopt, +std::optional RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); - // The links to a specific line in the source code use the github / - // googlesource notation so it won't work for all hosting pages. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) +LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique(" of file ")); + auto LocFileNode = std::make_unique( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique(")")); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-too
[clang] Retry for Unique Path Creation (PR #132640)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/132640 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Mips] Fix clang compile error when -march=p5600 with -mmsa (PR #132679)
https://github.com/yingopq created https://github.com/llvm/llvm-project/pull/132679 When -march=p5600 with -mmsa, the result of getISARev is 0, so report error. Append p5600 to cases mips32r5. >From 6f4c2dc2b9815172023ac8bf80347bd293f0647d Mon Sep 17 00:00:00 2001 From: Ying Huang Date: Sun, 23 Mar 2025 23:26:08 -0400 Subject: [PATCH] [Mips] Fix clang compile error when -march=p5600 with -mmsa When -march=p5600 with -mmsa, the result of getISARev is 0, so report error. Append p5600 to cases mips32r5. --- clang/lib/Basic/Targets/Mips.cpp | 2 +- clang/test/Driver/mips-abi.c | 14 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 08f9e3c29d1ed..193a2035873ae 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -72,7 +72,7 @@ unsigned MipsTargetInfo::getISARev() const { .Cases("mips32", "mips64", 1) .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2) .Cases("mips32r3", "mips64r3", 3) - .Cases("mips32r5", "mips64r5", 5) + .Cases("mips32r5", "mips64r5", "p5600", 5) .Cases("mips32r6", "mips64r6", 6) .Default(0); } diff --git a/clang/test/Driver/mips-abi.c b/clang/test/Driver/mips-abi.c index f131a07888dba..14eb890c74bc0 100644 --- a/clang/test/Driver/mips-abi.c +++ b/clang/test/Driver/mips-abi.c @@ -115,6 +115,20 @@ // MIPS-ARCH-P5600: "-target-cpu" "p5600" // MIPS-ARCH-P5600: "-target-abi" "o32" // +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-MSA %s +// MIPS-ARCH-P5600-MSA: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+msa" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+fp64" +// +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-NAN2008 %s +// MIPS-ARCH-P5600-NAN2008: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+nan2008" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+abs2008" +// // RUN: not %clang --target=mips-linux-gnu -c %s \ // RUN:-march=p5600 -mabi=64 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-N64 %s ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Mips] Fix clang compile error when -march=p5600 with -mmsa (PR #132679)
llvmbot wrote: @llvm/pr-subscribers-clang-driver Author: None (yingopq) Changes When -march=p5600 with -mmsa, the result of getISARev is 0, so report error. Append p5600 to cases mips32r5. --- Full diff: https://github.com/llvm/llvm-project/pull/132679.diff 2 Files Affected: - (modified) clang/lib/Basic/Targets/Mips.cpp (+1-1) - (modified) clang/test/Driver/mips-abi.c (+14) ``diff diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 08f9e3c29d1ed..193a2035873ae 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -72,7 +72,7 @@ unsigned MipsTargetInfo::getISARev() const { .Cases("mips32", "mips64", 1) .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2) .Cases("mips32r3", "mips64r3", 3) - .Cases("mips32r5", "mips64r5", 5) + .Cases("mips32r5", "mips64r5", "p5600", 5) .Cases("mips32r6", "mips64r6", 6) .Default(0); } diff --git a/clang/test/Driver/mips-abi.c b/clang/test/Driver/mips-abi.c index f131a07888dba..14eb890c74bc0 100644 --- a/clang/test/Driver/mips-abi.c +++ b/clang/test/Driver/mips-abi.c @@ -115,6 +115,20 @@ // MIPS-ARCH-P5600: "-target-cpu" "p5600" // MIPS-ARCH-P5600: "-target-abi" "o32" // +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-MSA %s +// MIPS-ARCH-P5600-MSA: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+msa" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+fp64" +// +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-NAN2008 %s +// MIPS-ARCH-P5600-NAN2008: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+nan2008" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+abs2008" +// // RUN: not %clang --target=mips-linux-gnu -c %s \ // RUN:-march=p5600 -mabi=64 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-N64 %s `` https://github.com/llvm/llvm-project/pull/132679 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Mips] Fix clang compile error when -march=p5600 with -mmsa (PR #132679)
https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/132679 >From 57facf0cf984b68d5c186aebe31a859827a2a3e3 Mon Sep 17 00:00:00 2001 From: Ying Huang Date: Sun, 23 Mar 2025 23:26:08 -0400 Subject: [PATCH] [Mips] Fix clang compile error when -march=p5600 with -mmsa When -march=p5600 with -mmsa, the result of getISARev is 0, so report error. Append p5600 to cases mips32r5. Fix #91948. --- clang/lib/Basic/Targets/Mips.cpp | 2 +- clang/test/Driver/mips-abi.c | 14 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 08f9e3c29d1ed..193a2035873ae 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -72,7 +72,7 @@ unsigned MipsTargetInfo::getISARev() const { .Cases("mips32", "mips64", 1) .Cases("mips32r2", "mips64r2", "octeon", "octeon+", 2) .Cases("mips32r3", "mips64r3", 3) - .Cases("mips32r5", "mips64r5", 5) + .Cases("mips32r5", "mips64r5", "p5600", 5) .Cases("mips32r6", "mips64r6", 6) .Default(0); } diff --git a/clang/test/Driver/mips-abi.c b/clang/test/Driver/mips-abi.c index f131a07888dba..14eb890c74bc0 100644 --- a/clang/test/Driver/mips-abi.c +++ b/clang/test/Driver/mips-abi.c @@ -115,6 +115,20 @@ // MIPS-ARCH-P5600: "-target-cpu" "p5600" // MIPS-ARCH-P5600: "-target-abi" "o32" // +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-MSA %s +// MIPS-ARCH-P5600-MSA: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+msa" +// MIPS-ARCH-P5600-MSA: "-target-feature" "+fp64" +// +// RUN: %clang --target=mips-linux-gnu -### -c %s \ +// RUN:-march=p5600 -mmsa -mnan=2008 2>&1 \ +// RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-NAN2008 %s +// MIPS-ARCH-P5600-NAN2008: "-target-cpu" "p5600" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+nan2008" +// MIPS-ARCH-P5600-NAN2008: "-target-feature" "+abs2008" +// // RUN: not %clang --target=mips-linux-gnu -c %s \ // RUN:-march=p5600 -mabi=64 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ARCH-P5600-N64 %s ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] [feat] add --repository-line-prefix argument (PR #131280)
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280 >From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 1/9] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 --- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector &References, return Out; } -static std::unique_ptr -writeFileDefinition(const Location &L, -std::optional RepositoryUrl = std::nullopt) { +static std::unique_ptr writeFileDefinition( +const Location &L, std::optional RepositoryUrl = std::nullopt, +std::optional RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); - // The links to a specific line in the source code use the github / - // googlesource notation so it won't work for all hosting pages. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) +LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique(" of file ")); + auto LocFileNode = std::make_unique( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique(")")); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools
[clang] [clang-tools-extra] [lldb] Reland: [clang] preserve class type sugar when taking pointer to member (PR #132401)
mstorsjo wrote: > Thanks, for the report, will be fixed by #132551 Thanks for the quick fix, I can confirm that Qt builds fine for me again! https://github.com/llvm/llvm-project/pull/132401 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 converted_to_draft https://github.com/llvm/llvm-project/pull/132669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave edited https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave edited https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [alpha.webkit.RetainPtrCtorAdoptChecker] Support adopt(cast(copy(~)) (PR #132316)
https://github.com/rniwa created https://github.com/llvm/llvm-project/pull/132316 This PR adds the support for recognizing calling adoptCF/adoptNS on the result of a cast operation on the return value of a function which creates NS or CF types. It also fixes a bug that we weren't reporting memory leaks when CF types are created without ever calling RetainPtr's constructor, adoptCF, or adoptNS. To do this, this PR adds a new mechanism to report a memory leak whenever create or copy CF functions are invoked unless this CallExpr has already been visited while validating a call to adoptCF. Also added an early exit when isOwned returns IsOwnedResult::Skip due to an unresolved template argument. >From 642057c409b1c3b98ee4ecb16e95b5fb5be47a01 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Thu, 20 Mar 2025 17:54:22 -0700 Subject: [PATCH] [alpha.webkit.RetainPtrCtorAdoptChecker] Support adopt(cast(copy(~)) This PR adds the support for recognizing calling adoptCF/adoptNS on the result of a cast operation on the return value of a function which creates NS or CF types. It also fixes a bug that we weren't reporting memory leaks when CF types are created without ever calling RetainPtr's constructor, adoptCF, or adoptNS. To do this, this PR adds a new mechanism to report a memory leak whenever create or copy CF functions are invoked unless this CallExpr has already been visited while validating a call to adoptCF. Also added an early exit when isOwned returns IsOwnedResult::Skip due to an unresolved template argument. --- .../WebKit/RetainPtrCtorAdoptChecker.cpp | 70 ++ .../Checkers/WebKit/objc-mock-types.h | 72 ++- .../WebKit/retain-ptr-ctor-adopt-use-arc.mm | 9 ++- .../WebKit/retain-ptr-ctor-adopt-use.mm | 9 ++- 4 files changed, 140 insertions(+), 20 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp index 4ce3262e90e13..2d9620cc8ee5e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RetainPtrCtorAdoptChecker.cpp @@ -34,6 +34,7 @@ class RetainPtrCtorAdoptChecker mutable BugReporter *BR; mutable std::unique_ptr Summaries; mutable llvm::DenseSet CreateOrCopyOutArguments; + mutable llvm::DenseSet CreateOrCopyFnCall; mutable RetainTypeChecker RTC; public: @@ -119,7 +120,7 @@ class RetainPtrCtorAdoptChecker return; if (!isAdoptFn(F) || !CE->getNumArgs()) { - rememberOutArguments(CE, F); + checkCreateOrCopyFunction(CE, F, DeclWithIssue); return; } @@ -128,24 +129,30 @@ class RetainPtrCtorAdoptChecker auto Name = safeGetName(F); if (Result == IsOwnedResult::Unknown) Result = IsOwnedResult::NotOwned; -if (Result == IsOwnedResult::NotOwned && !isAllocInit(Arg) && -!isCreateOrCopy(Arg)) { - if (auto *DRE = dyn_cast(Arg)) { -if (CreateOrCopyOutArguments.contains(DRE->getDecl())) - return; - } - if (RTC.isARCEnabled() && isAdoptNS(F)) -reportUseAfterFree(Name, CE, DeclWithIssue, "when ARC is disabled"); - else -reportUseAfterFree(Name, CE, DeclWithIssue); +if (isAllocInit(Arg) || isCreateOrCopy(Arg)) { + CreateOrCopyFnCall.insert(Arg); // Avoid double reporting. + return; +} +if (Result == IsOwnedResult::Owned || Result == IsOwnedResult::Skip) + return; + +if (auto *DRE = dyn_cast(Arg)) { + if (CreateOrCopyOutArguments.contains(DRE->getDecl())) +return; } +if (RTC.isARCEnabled() && isAdoptNS(F)) + reportUseAfterFree(Name, CE, DeclWithIssue, "when ARC is disabled"); +else + reportUseAfterFree(Name, CE, DeclWithIssue); } - void rememberOutArguments(const CallExpr *CE, -const FunctionDecl *Callee) const { + void checkCreateOrCopyFunction(const CallExpr *CE, + const FunctionDecl *Callee, + const Decl *DeclWithIssue) const { if (!isCreateOrCopyFunction(Callee)) return; +bool hasOutArgument = false; unsigned ArgCount = CE->getNumArgs(); for (unsigned ArgIndex = 0; ArgIndex < ArgCount; ++ArgIndex) { auto *Arg = CE->getArg(ArgIndex)->IgnoreParenCasts(); @@ -164,7 +171,10 @@ class RetainPtrCtorAdoptChecker if (!Decl) continue; CreateOrCopyOutArguments.insert(Decl); + hasOutArgument = true; } +if (!hasOutArgument && !CreateOrCopyFnCall.contains(CE)) + reportLeak(CE, DeclWithIssue); } void visitConstructExpr(const CXXConstructExpr *CE, @@ -190,6 +200,13 @@ class RetainPtrCtorAdoptChecker std::string Name = "RetainPtr constructor"; auto *Arg = CE->getArg(0)->IgnoreParenCasts(); auto Result = isOwned(Arg); + +if (isCreateOrCopy(Arg)) + CreateOrCopyFnCall.inser
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/132669 >From 27a42c2b5186b8bd5a71ca7e8bc574439d21e7fd Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 12:43:17 +0800 Subject: [PATCH 1/2] [Clang] Fix the assertion condition after b8d1f3d6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to the example provided by @MagentaTreehouse, I realized the assertion I added didn't cover all valid cases like, when inheriting from a class template specialization, the source of a synthesized template parameter might be an implicit specialization, whose inner function template is thus living at depth 0, for which we don’t want it to overflow too. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 12 + clang/test/SemaTemplate/deduction-guide.cpp | 26 +++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 9cfdb7596b660..e20130a33f368 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -376,12 +376,14 @@ struct ConvertConstructorToDeductionGuideTransform { if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); auto [Depth, Index] = getDepthAndIndex(Param); -// Depth can still be 0 if FTD belongs to an explicit class template -// specialization with an empty template parameter list. In that case, -// we don't want the NewDepth to overflow, and it should remain 0. +// Depth can be 0 if FTD belongs to a class template specialization with +// an empty template parameter list (i.e. either an explicit full +// specialization or an implicit specialization) In that case, we don't +// want the NewDepth to overflow, and it should remain 0. assert(Depth || - cast(FTD->getDeclContext()) - ->isExplicitSpecialization()); + isa( + cast(FTD->getDeclContext()) + ->getSpecializedTemplateOrPartial())); NamedDecl *NewParam = transformTemplateParameter( SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth ? Depth - 1 : 0); diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index ecd152abebd74..95e740a026550 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -723,3 +723,29 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr // CHECK-NEXT: `-ParmVarDecl {{.+}} 'T' } // namespace GH128691 + +namespace GH132616_DeductionGuide { + +template struct A { + template + A(U); +}; + +template +struct B: A { + using A::A; +}; + +template +B(T) -> B; + +B b(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit 'auto (U) -> B' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +} // namespace GH132616_DeductionGuide >From 49f2a7e56874a7d097e1236942089765e016f755 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 13:16:15 +0800 Subject: [PATCH 2/2] Drive-by fix for https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718 --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 27 +-- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index e20130a33f368..3d06663dc8054 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -972,6 +972,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } +bool IsNonDeducedArgument(const TemplateArgument &TA) { + // The following cases indicate the template argument is non-deducible: + // 1. The result is null. E.g. When it comes from a default template + // argument that doesn't appear in the alias declaration. + // 2. The template parameter is a pack and that cannot be deduced from + // the arguments within the alias declaration. + // Non-deducible template parameters will persist in the transformed + // deduction guide. + return TA.isNull() || + (TA.getKind() == TemplateArgument::Pack && + llvm::any_of(TA.pack_elements(), IsNonDeducedArgument)); +} + // Build deduction guides for a type alias template from the given underlying // deduction guide F. FunctionTemplateDecl * @@ -1035,20 +1048,6 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, Al
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/132669 >From 2894090c356438867c182fd76c9b89354c0bafee Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 12:43:17 +0800 Subject: [PATCH 1/2] [Clang] Fix the assertion condition after b8d1f3d6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to the example provided by @MagentaTreehouse, I realized the assertion I added didn't cover all valid cases like, when inheriting from a class template specialization, the source of a synthesized template parameter might be an implicit specialization, whose inner function template is thus living at depth 0, for which we don’t want it to overflow too. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 10 ++-- clang/test/SemaTemplate/deduction-guide.cpp | 48 +++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 9cfdb7596b660..6685fdd60dc09 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -376,12 +376,10 @@ struct ConvertConstructorToDeductionGuideTransform { if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); auto [Depth, Index] = getDepthAndIndex(Param); -// Depth can still be 0 if FTD belongs to an explicit class template -// specialization with an empty template parameter list. In that case, -// we don't want the NewDepth to overflow, and it should remain 0. -assert(Depth || - cast(FTD->getDeclContext()) - ->isExplicitSpecialization()); +// Depth can be 0 if FTD belongs to a non-template class/a class +// template specialization with an empty template parameter list. In +// that case, we don't want the NewDepth to overflow, and it should +// remain 0. NamedDecl *NewParam = transformTemplateParameter( SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth ? Depth - 1 : 0); diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index ecd152abebd74..6db132ca37c7e 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -723,3 +723,51 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr // CHECK-NEXT: `-ParmVarDecl {{.+}} 'T' } // namespace GH128691 + +namespace GH132616_DeductionGuide { + +template struct A { + template + A(U); +}; + +template +struct B : A { + using A::A; +}; + +template +B(T) -> B; + +B b(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit 'auto (U) -> B' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +struct C { + template + C(U); +}; + +template +struct D : C { + using C::C; +}; + +template +D(T) -> D; + +D d(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit 'auto (U) -> D' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +} // namespace GH132616_DeductionGuide >From b7bef605503bc566dd0624b338d7ce6bec856fd3 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 13:16:15 +0800 Subject: [PATCH 2/2] Drive-by fix for https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718 --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 27 +-- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 6685fdd60dc09..3b2129e0df815 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -968,6 +968,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } +bool IsNonDeducedArgument(const TemplateArgument &TA) { + // The following cases indicate the template argument is non-deducible: + // 1. The result is null. E.g. When it comes from a default template + // argument that doesn't appear in the alias declaration. + // 2. The template parameter is a pack and that cannot be deduced from + // the arguments within the alias declaration. + // Non-deducible template parameters will persist in the transformed + // deduction guide. + return TA.isNull() || + (TA.getKind() == Templ
[clang-tools-extra] [clang-tidy] Avoid repeated map lookups (NFC) (PR #132656)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/132656.diff 1 Files Affected: - (modified) clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp (+3-4) ``diff diff --git a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp index afe70dc8e6d5b..f574c94e6f144 100644 --- a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp +++ b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp @@ -88,11 +88,10 @@ class HeaderGuardPPCallbacks : public PPCallbacks { continue; // Look up Locations for this guard. - SourceLocation Ifndef = - Ifndefs[MacroEntry.first.getIdentifierInfo()].second; + const auto &Locs = Ifndefs[MacroEntry.first.getIdentifierInfo()]; + SourceLocation Ifndef = Locs.second; SourceLocation Define = MacroEntry.first.getLocation(); - SourceLocation EndIf = - EndIfs[Ifndefs[MacroEntry.first.getIdentifierInfo()].first]; + SourceLocation EndIf = EndIfs[Locs.first]; // If the macro Name is not equal to what we can compute, correct it in // the #ifndef and #define. `` https://github.com/llvm/llvm-project/pull/132656 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Avoid repeated map lookups (NFC) (PR #132656)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: Kazu Hirata (kazutakahirata) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/132656.diff 1 Files Affected: - (modified) clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp (+3-4) ``diff diff --git a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp index afe70dc8e6d5b..f574c94e6f144 100644 --- a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp +++ b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp @@ -88,11 +88,10 @@ class HeaderGuardPPCallbacks : public PPCallbacks { continue; // Look up Locations for this guard. - SourceLocation Ifndef = - Ifndefs[MacroEntry.first.getIdentifierInfo()].second; + const auto &Locs = Ifndefs[MacroEntry.first.getIdentifierInfo()]; + SourceLocation Ifndef = Locs.second; SourceLocation Define = MacroEntry.first.getLocation(); - SourceLocation EndIf = - EndIfs[Ifndefs[MacroEntry.first.getIdentifierInfo()].first]; + SourceLocation EndIf = EndIfs[Locs.first]; // If the macro Name is not equal to what we can compute, correct it in // the #ifndef and #define. `` https://github.com/llvm/llvm-project/pull/132656 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Avoid repeated map lookups (NFC) (PR #132656)
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/132656 None >From efa4f020eda6ff2f9da14f250be72fb6bc17b59c Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Sun, 23 Mar 2025 08:06:57 -0700 Subject: [PATCH] [clang-tidy] Avoid repeated map lookups (NFC) --- clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp index afe70dc8e6d5b..f574c94e6f144 100644 --- a/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp +++ b/clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp @@ -88,11 +88,10 @@ class HeaderGuardPPCallbacks : public PPCallbacks { continue; // Look up Locations for this guard. - SourceLocation Ifndef = - Ifndefs[MacroEntry.first.getIdentifierInfo()].second; + const auto &Locs = Ifndefs[MacroEntry.first.getIdentifierInfo()]; + SourceLocation Ifndef = Locs.second; SourceLocation Define = MacroEntry.first.getLocation(); - SourceLocation EndIf = - EndIfs[Ifndefs[MacroEntry.first.getIdentifierInfo()].first]; + SourceLocation EndIf = EndIfs[Locs.first]; // If the macro Name is not equal to what we can compute, correct it in // the #ifndef and #define. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave updated https://github.com/llvm/llvm-project/pull/131969 >From fa0f1079587e6e26279c293fe4467ff0388f6a43 Mon Sep 17 00:00:00 2001 From: David Rivera Date: Sun, 16 Mar 2025 16:20:16 -0400 Subject: [PATCH] [clang-tidy] Add support for Initialization Forwarding in Nested Objects within modernize-use-emplace --- .../clang-tidy/modernize/UseEmplaceCheck.cpp | 120 ++ clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checkers/modernize/use-emplace.cpp| 26 +++- 3 files changed, 125 insertions(+), 25 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 430455a38f395..277994bbb6082 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -98,8 +98,8 @@ auto hasWantedType(llvm::ArrayRef TypeNames) { // Matches member call expressions of the named method on the listed container // types. -auto cxxMemberCallExprOnContainer( -StringRef MethodName, llvm::ArrayRef ContainerNames) { +auto cxxMemberCallExprOnContainer(StringRef MethodName, + llvm::ArrayRef ContainerNames) { return cxxMemberCallExpr( hasDeclaration(functionDecl(hasName(MethodName))), on(hasTypeOrPointeeType(hasWantedType(ContainerNames; @@ -174,19 +174,19 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // passed pointer because smart pointer won't be constructed // (and destructed) as in push_back case. auto IsCtorOfSmartPtr = - hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(SmartPointers; + cxxConstructorDecl(ofClass(hasAnyName(SmartPointers))); // Bitfields binds only to consts and emplace_back take it by universal ref. - auto BitFieldAsArgument = hasAnyArgument( - ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField()); + auto BitFieldAsArgument = + ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField(); // Initializer list can't be passed to universal reference. - auto InitializerListAsArgument = hasAnyArgument( + auto InitializerListAsArgument = ignoringImplicit(allOf(cxxConstructExpr(isListInitialization()), - unless(cxxTemporaryObjectExpr(); + unless(cxxTemporaryObjectExpr(; // We could have leak of resource. - auto NewExprAsArgument = hasAnyArgument(ignoringImplicit(cxxNewExpr())); + auto NewExprAsArgument = ignoringImplicit(cxxNewExpr()); // We would call another constructor. auto ConstructingDerived = hasParent(implicitCastExpr(hasCastKind(CastKind::CK_DerivedToBase))); @@ -202,19 +202,35 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // overloaded functions and template names. auto SoughtConstructExpr = cxxConstructExpr( - unless(anyOf(IsCtorOfSmartPtr, HasInitList, BitFieldAsArgument, - InitializerListAsArgument, NewExprAsArgument, - ConstructingDerived, IsPrivateOrProtectedCtor))) + unless(anyOf(hasDeclaration(IsCtorOfSmartPtr), HasInitList, + hasAnyArgument(BitFieldAsArgument), + hasAnyArgument(InitializerListAsArgument), + hasAnyArgument(NewExprAsArgument), ConstructingDerived, + IsPrivateOrProtectedCtor))) .bind("ctor"); - auto HasConstructExpr = has(ignoringImplicit(SoughtConstructExpr)); + + auto IsPrimitiveType = hasType(builtinType()); + + auto AggregateInitExpr = + getLangOpts().CPlusPlus20 + ? initListExpr(unless(anyOf(HasInitList, has(IsCtorOfSmartPtr), + has(BitFieldAsArgument), + has(InitializerListAsArgument), + has(NewExprAsArgument), IsPrimitiveType))) +.bind("agg_init") + : unless(anything()); + + auto HasConstructExpr = + has(ignoringImplicit(anyOf(SoughtConstructExpr, AggregateInitExpr))); // allow for T{} to be replaced, even if no CTOR is declared auto HasConstructInitListExpr = has(initListExpr( - initCountLeq(1), anyOf(allOf(has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0, - has(cxxBindTemporaryExpr( - has(SoughtConstructExpr), - has(cxxConstructExpr(argumentCountIs(0; + initCountLeq(1), + anyOf(allOf(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0, +has(cxxBindTemporaryExpr(has(SoughtConstructExpr), + has(cxxConstructExpr(argumentCountIs(0))) + ); auto HasBracedInitL
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/132669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/132670 >From 6545414a97b6458333f399c7252ae55c88a42d62 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 24 Mar 2025 10:09:59 +0530 Subject: [PATCH 1/2] Handle frontend options for clang-repl before calling executeAction --- clang/lib/Interpreter/Interpreter.cpp | 38 ++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index fa4c1439c9261..5f48117dbf3b8 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -141,6 +141,37 @@ CreateCI(const llvm::opt::ArgStringList &Argv) { return std::move(Clang); } +static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { + const auto &FrontendOpts = CI.getFrontendOpts(); + + if (FrontendOpts.ShowHelp) { +driver::getDriverOptTable().printHelp( +llvm::outs(), "clang -cc1 [options] file...", +"LLVM 'Clang' Compiler: http://clang.llvm.org";, +/*ShowHidden=*/false, /*ShowAllAliases=*/false, +llvm::opt::Visibility(driver::options::CC1Option)); +return llvm::createStringError(llvm::errc::not_supported, "Help displayed"); + } + + if (FrontendOpts.ShowVersion) { +llvm::cl::PrintVersionMessage(); +return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); + } + + if (!FrontendOpts.LLVMArgs.empty()) { +unsigned NumArgs = FrontendOpts.LLVMArgs.size(); +auto Args = std::make_unique(NumArgs + 2); +Args[0] = "clang-repl (LLVM option parsing)"; +for (unsigned i = 0; i != NumArgs; ++i) + Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); +Args[NumArgs + 1] = nullptr; +llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; +llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); + } + + return llvm::Error::success(); +} + } // anonymous namespace namespace clang { @@ -451,7 +482,12 @@ const char *const Runtimes = R"( llvm::Expected> Interpreter::create(std::unique_ptr CI) { - llvm::Error Err = llvm::Error::success(); + + llvm::Error Err = HandleFrontendOptions(*CI); + if (Err) { +return std::move(Err); + } + auto Interp = std::unique_ptr(new Interpreter(std::move(CI), Err)); if (Err) >From fa4e295389e51da41b6b96baed099e739664b730 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Mon, 24 Mar 2025 10:29:03 +0530 Subject: [PATCH 2/2] apply code formatting changes --- clang/lib/Interpreter/Interpreter.cpp | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5f48117dbf3b8..3fbfd3c746bc7 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -155,17 +155,19 @@ static llvm::Error HandleFrontendOptions(const CompilerInstance &CI) { if (FrontendOpts.ShowVersion) { llvm::cl::PrintVersionMessage(); -return llvm::createStringError(llvm::errc::not_supported, "Version displayed"); +return llvm::createStringError(llvm::errc::not_supported, + "Version displayed"); } if (!FrontendOpts.LLVMArgs.empty()) { unsigned NumArgs = FrontendOpts.LLVMArgs.size(); -auto Args = std::make_unique(NumArgs + 2); +auto Args = std::make_unique(NumArgs + 2); Args[0] = "clang-repl (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = FrontendOpts.LLVMArgs[i].c_str(); Args[NumArgs + 1] = nullptr; -llvm::errs() << "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; +llvm::errs() +<< "Parsing LLVM backend options via cl::ParseCommandLineOptions...\n"; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave updated https://github.com/llvm/llvm-project/pull/131969 >From 30678d79b5f7cd91da8eef5251eabe96875c0397 Mon Sep 17 00:00:00 2001 From: David Rivera Date: Sun, 16 Mar 2025 16:20:16 -0400 Subject: [PATCH] [clang-tidy] Add support for Initialization Forwarding in Nested Objects within modernize-use-emplace --- .../clang-tidy/modernize/UseEmplaceCheck.cpp | 109 +++--- clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checkers/modernize/use-emplace.cpp| 26 - 3 files changed, 119 insertions(+), 20 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 430455a38f395..ea449944bb199 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -98,8 +98,8 @@ auto hasWantedType(llvm::ArrayRef TypeNames) { // Matches member call expressions of the named method on the listed container // types. -auto cxxMemberCallExprOnContainer( -StringRef MethodName, llvm::ArrayRef ContainerNames) { +auto cxxMemberCallExprOnContainer(StringRef MethodName, + llvm::ArrayRef ContainerNames) { return cxxMemberCallExpr( hasDeclaration(functionDecl(hasName(MethodName))), on(hasTypeOrPointeeType(hasWantedType(ContainerNames; @@ -174,19 +174,19 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // passed pointer because smart pointer won't be constructed // (and destructed) as in push_back case. auto IsCtorOfSmartPtr = - hasDeclaration(cxxConstructorDecl(ofClass(hasAnyName(SmartPointers; + cxxConstructorDecl(ofClass(hasAnyName(SmartPointers))); // Bitfields binds only to consts and emplace_back take it by universal ref. - auto BitFieldAsArgument = hasAnyArgument( - ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField()); + auto BitFieldAsArgument = + ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(isBitField(); // Initializer list can't be passed to universal reference. - auto InitializerListAsArgument = hasAnyArgument( + auto InitializerListAsArgument = ignoringImplicit(allOf(cxxConstructExpr(isListInitialization()), - unless(cxxTemporaryObjectExpr(); + unless(cxxTemporaryObjectExpr(; // We could have leak of resource. - auto NewExprAsArgument = hasAnyArgument(ignoringImplicit(cxxNewExpr())); + auto NewExprAsArgument = ignoringImplicit(cxxNewExpr()); // We would call another constructor. auto ConstructingDerived = hasParent(implicitCastExpr(hasCastKind(CastKind::CK_DerivedToBase))); @@ -202,11 +202,26 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { // overloaded functions and template names. auto SoughtConstructExpr = cxxConstructExpr( - unless(anyOf(IsCtorOfSmartPtr, HasInitList, BitFieldAsArgument, - InitializerListAsArgument, NewExprAsArgument, - ConstructingDerived, IsPrivateOrProtectedCtor))) + unless(anyOf(hasDeclaration(IsCtorOfSmartPtr), HasInitList, + hasAnyArgument(BitFieldAsArgument), + hasAnyArgument(InitializerListAsArgument), + hasAnyArgument(NewExprAsArgument), ConstructingDerived, + IsPrivateOrProtectedCtor))) .bind("ctor"); - auto HasConstructExpr = has(ignoringImplicit(SoughtConstructExpr)); + + auto IsPrimitiveType = hasType(builtinType()); + + auto AggregateInitExpr = + getLangOpts().CPlusPlus20 + ? initListExpr(unless(anyOf(HasInitList, has(IsCtorOfSmartPtr), + has(BitFieldAsArgument), + has(InitializerListAsArgument), + has(NewExprAsArgument), IsPrimitiveType))) +.bind("agg_init") + : unless(anything()); + + auto HasConstructExpr = + has(ignoringImplicit(anyOf(SoughtConstructExpr, AggregateInitExpr))); // allow for T{} to be replaced, even if no CTOR is declared auto HasConstructInitListExpr = has(initListExpr( @@ -305,6 +320,38 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { this); } +const Expr *unwrapInnerExpression(const Expr *E) { + + while (true) { +if (!E) + break; + +if (llvm::isa(E)) { + return E; +} + +if (const auto *BindTemp = llvm::dyn_cast(E)) { + E = BindTemp->getSubExpr(); + continue; +} + +if (const auto *MaterialTemp = +llvm::dyn_cast(E)) { + E = MaterialTemp->getSubExpr(); + continue; +} + +if (const auto *Cast = llvm::dyn_cast(E)) { + E = Cast->getSubExpr(); + continue; +} + +break; + } + + return nullptr; // No relevant sub-expression found +}
[clang-tools-extra] [clang-doc] [feat] add --repository-line-prefix argument (PR #131280)
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280 >From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 01/10] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 --- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector &References, return Out; } -static std::unique_ptr -writeFileDefinition(const Location &L, -std::optional RepositoryUrl = std::nullopt) { +static std::unique_ptr writeFileDefinition( +const Location &L, std::optional RepositoryUrl = std::nullopt, +std::optional RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); - // The links to a specific line in the source code use the github / - // googlesource notation so it won't work for all hosting pages. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) +LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique(" of file ")); + auto LocFileNode = std::make_unique( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique(")")); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-too
[clang-tools-extra] [clang-doc] [feat] add --repository-line-prefix argument (PR #131280)
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/131280 >From bf9bd4156cb7f652c9cf0477f537e5c58b470448 Mon Sep 17 00:00:00 2001 From: hulxv Date: Fri, 14 Mar 2025 07:39:15 +0200 Subject: [PATCH 01/10] [clang-doc] [feat] add `--repository-line-prefix` argument (fix #59814) --- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 66 --- clang-tools-extra/clang-doc/MDGenerator.cpp | 7 +- .../clang-doc/Representation.cpp | 4 ++ clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 13 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 18a0de826630c..967275f93193b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -491,9 +491,9 @@ genReferencesBlock(const std::vector &References, return Out; } -static std::unique_ptr -writeFileDefinition(const Location &L, -std::optional RepositoryUrl = std::nullopt) { +static std::unique_ptr writeFileDefinition( +const Location &L, std::optional RepositoryUrl = std::nullopt, +std::optional RepositoryLinePrefix = std::nullopt) { if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + @@ -514,17 +514,21 @@ writeFileDefinition(const Location &L, Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); - // The links to a specific line in the source code use the github / - // googlesource notation so it won't work for all hosting pages. - // FIXME: we probably should have a configuration setting for line number - // rendering in the HTML. For example, GitHub uses #L22, while googlesource - // uses #22 for line numbers. - LocNumberNode->Attributes.emplace_back( - "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); + + std::string LineAnchor = "#"; + + if (RepositoryLinePrefix) +LineAnchor += RepositoryLinePrefix.value().str(); + + LineAnchor += std::to_string(L.LineNumber); + + LocNumberNode->Attributes.emplace_back("href", (FileURL + LineAnchor).str()); Node->Children.emplace_back(std::move(LocNumberNode)); Node->Children.emplace_back(std::make_unique(" of file ")); + auto LocFileNode = std::make_unique( HTMLTag::TAG_A, llvm::sys::path::filename(FileURL)); + LocFileNode->Attributes.emplace_back("href", std::string(FileURL)); Node->Children.emplace_back(std::move(LocFileNode)); return Node; @@ -750,11 +754,15 @@ genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) { Out.emplace_back(std::move(Table)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back( - writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -799,11 +807,15 @@ genHTML(const FunctionInfo &I, const ClangDocContext &CDCtx, FunctionHeader->Children.emplace_back(std::make_unique(")")); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; @@ -866,11 +878,15 @@ genHTML(const RecordInfo &I, Index &InfoIndex, const ClangDocContext &CDCtx, Out.emplace_back(std::make_unique(HTMLTag::TAG_H1, InfoTitle)); if (I.DefLoc) { -if (!CDCtx.RepositoryUrl) - Out.emplace_back(writeFileDefinition(*I.DefLoc)); -else - Out.emplace_back(writeFileDefinition( - *I.DefLoc, StringRef{*CDCtx.RepositoryUrl})); +std::optional RepoUrl; +std::optional RepoLinePrefix; + +if (CDCtx.RepositoryUrl) + RepoUrl = StringRef{*CDCtx.RepositoryUrl}; +if (CDCtx.RepositoryLinePrefix) + RepoLinePrefix = StringRef{*CDCtx.RepositoryLinePrefix}; + +Out.emplace_back(writeFileDefinition(*I.DefLoc, RepoUrl, RepoLinePrefix)); } std::string Description; diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-too
[clang-tools-extra] [clang-tidy][C++20] Add support for aggregate types within modernize-use-emplace (PR #131969)
@@ -0,0 +1,86 @@ +// RUN: %check_clang_tidy %s -std=c++20 modernize-use-emplace %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: {modernize-use-emplace.ContainersWithPushBack: \ +// RUN:'::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector', \ +// RUN: modernize-use-emplace.TupleTypes: \ +// RUN:'::std::pair; std::tuple; ::test::Single', \ +// RUN: modernize-use-emplace.TupleMakeFunctions: \ +// RUN:'::std::make_pair; ::std::make_tuple; ::test::MakeSingle'}}" + +namespace std { +template +class initializer_list { +public: + const E *a, *b; + initializer_list() noexcept {} +}; + +template +class vector { +public: + using value_type = T; + + class iterator {}; + class const_iterator {}; + const_iterator begin() { return const_iterator{}; } + + vector() = default; + vector(initializer_list) {} + + void push_back(const T &) {} + void push_back(T &&) {} + + template + void emplace_back(Args &&... args){}; + template + iterator emplace(const_iterator pos, Args &&...args); + ~vector(); +}; + +} // namespace std + +struct InnerType { + InnerType() {} + InnerType(char const*) {} +}; + +//Not aggregate but we should still be able to directly initialize it with emplace_back +struct NonTrivialNoCtor { + InnerType it; +}; + +struct Aggregate { + int a; + int b; +}; + +void testCXX20Cases() { + std::vector v1; + + v1.push_back(Aggregate{1, 2}); RiverDave wrote: Been thinking about this while I've spent some time refining what has been already done. I think It'd be better to target this feature in a different PR since the scope would increase significantly. (Specially in the `check` logic). https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Don't wrap before attributes in parameter lists (PR #132519)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/132519 >From eef6fd8d88c0a4cb22428dd2720af83aef8a7661 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Fri, 21 Mar 2025 21:34:52 -0700 Subject: [PATCH] [clang-format] Don't wrap before attributes in parameter lists Fix #132240 --- clang/lib/Format/TokenAnnotator.cpp | 14 ++ clang/unittests/Format/FormatTest.cpp | 6 ++ 2 files changed, 20 insertions(+) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 35577cd6db7a1..01bf8c3778928 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4078,6 +4078,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { } bool InFunctionDecl = Line.MightBeFunctionDecl; + bool InParameterList = false; for (auto *Current = First->Next; Current; Current = Current->Next) { const FormatToken *Prev = Current->Previous; if (Current->is(TT_LineComment)) { @@ -4132,6 +4133,19 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { Current->CanBreakBefore = Current->MustBreakBefore || canBreakBefore(Line, *Current); + +if (Current->is(TT_FunctionDeclarationLParen)) { + InParameterList = true; +} else if (Current->is(tok::r_paren)) { + const auto *LParen = Current->MatchingParen; + if (LParen && LParen->is(TT_FunctionDeclarationLParen)) +InParameterList = false; +} else if (InParameterList && + Current->endsSequence(TT_AttributeMacro, + TT_PointerOrReference)) { + Current->CanBreakBefore = false; +} + unsigned ChildSize = 0; if (Prev->Children.size() == 1) { FormatToken &LastOfChild = *Prev->Children[0]->Last; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 5df7865f5a629..0b90bd360b758 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -12640,6 +12640,12 @@ TEST_F(FormatTest, UnderstandsAttributes) { AfterType); FormatStyle CustomAttrs = getLLVMStyle(); + CustomAttrs.AttributeMacros.push_back("my_attr_name"); + verifyFormat("void MyGoodOldFunction(\n" + "void *const long_enough = nullptr,\n" + "void *my_attr_name even_longer = nullptr);", + CustomAttrs); + CustomAttrs.AttributeMacros.push_back("__unused"); CustomAttrs.AttributeMacros.push_back("__attr1"); CustomAttrs.AttributeMacros.push_back("__attr2"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
@@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \ +// RUN: %check_clang_tidy %s -std=c++17 modernize-use-emplace %t -- \ RiverDave wrote: Thx for your suggestions, this is really great, this should be addressed now. https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
RiverDave wrote: Removed **Aggregates** from both title and release notes considering my changes can potentially affect non aggregate structs types as well. https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Handle frontend options for clang-repl before calling executeAction (PR #132670)
anutosh491 wrote: I see clang handle 4 types of FrontendOpts before calling ExecuteAction 1) help 2) version 3) Plugins through [LoadRequestedPlugins](https://github.com/llvm/llvm-project/blob/4e4e4a190fb7c74453994935c843b09cc682f4bb/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp#L225) 4) llvmargs We might be interesting in 1, 2 and 4 for clang-repl Also clang-repl uses IncrementalAction unlike FrontendAction so simply calling ExecuteCompilerInvocation won't do the job. So not sure if we can maybe refactor out 1/2/4 and use it from clang itself. https://github.com/llvm/llvm-project/pull/132670 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix various bugs in alias CTAD transform (PR #132061)
@@ -1072,12 +1072,27 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, AliasRhsTemplateArgs, TDeduceInfo, DeduceResults, /*NumberOfArgumentsMustMatch=*/false); + static std::function IsNonDeducedArgument = zyn0217 wrote: Ah sorry I saw the comment 2 days after this got merged - there must be some bugs with the github notification system! https://github.com/llvm/llvm-project/pull/132061 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
https://github.com/RiverDave edited https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][C++20] Add support for Initialization Forwarding in Nested Object Construction (PR #131969)
@@ -0,0 +1,86 @@ +// RUN: %check_clang_tidy %s -std=c++20 modernize-use-emplace %t -- \ RiverDave wrote: File was removed as suggested, will create a new file for future work on designated inits https://github.com/llvm/llvm-project/pull/131969 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/132669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix the assertion condition after b8d1f3d6 (PR #132669)
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/132669 >From 27a42c2b5186b8bd5a71ca7e8bc574439d21e7fd Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 12:43:17 +0800 Subject: [PATCH 1/2] [Clang] Fix the assertion condition after b8d1f3d6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to the example provided by @MagentaTreehouse, I realized the assertion I added didn't cover all valid cases like, when inheriting from a class template specialization, the source of a synthesized template parameter might be an implicit specialization, whose inner function template is thus living at depth 0, for which we don’t want it to overflow too. --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 12 + clang/test/SemaTemplate/deduction-guide.cpp | 26 +++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 9cfdb7596b660..e20130a33f368 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -376,12 +376,14 @@ struct ConvertConstructorToDeductionGuideTransform { if (NestedPattern) Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); auto [Depth, Index] = getDepthAndIndex(Param); -// Depth can still be 0 if FTD belongs to an explicit class template -// specialization with an empty template parameter list. In that case, -// we don't want the NewDepth to overflow, and it should remain 0. +// Depth can be 0 if FTD belongs to a class template specialization with +// an empty template parameter list (i.e. either an explicit full +// specialization or an implicit specialization) In that case, we don't +// want the NewDepth to overflow, and it should remain 0. assert(Depth || - cast(FTD->getDeclContext()) - ->isExplicitSpecialization()); + isa( + cast(FTD->getDeclContext()) + ->getSpecializedTemplateOrPartial())); NamedDecl *NewParam = transformTemplateParameter( SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth ? Depth - 1 : 0); diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index ecd152abebd74..95e740a026550 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -723,3 +723,29 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr // CHECK-NEXT: `-ParmVarDecl {{.+}} 'T' } // namespace GH128691 + +namespace GH132616_DeductionGuide { + +template struct A { + template + A(U); +}; + +template +struct B: A { + using A::A; +}; + +template +B(T) -> B; + +B b(24); + +// CHECK-LABEL: Dumping GH132616_DeductionGuide::: +// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0 +// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U +// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit 'auto (U) -> B' +// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U' + +} // namespace GH132616_DeductionGuide >From 8562b2bc9b1fcc8282ddd4e47e637ee414ef4772 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 24 Mar 2025 13:16:15 +0800 Subject: [PATCH 2/2] Drive-by fix for https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718 --- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 13 + 1 file changed, 13 insertions(+) diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index e20130a33f368..c1f8eb27700e2 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -972,6 +972,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } +bool IsNonDeducedArgument(const TemplateArgument &TA) { + // The following cases indicate the template argument is non-deducible: + // 1. The result is null. E.g. When it comes from a default template + // argument that doesn't appear in the alias declaration. + // 2. The template parameter is a pack and that cannot be deduced from + // the arguments within the alias declaration. + // Non-deducible template parameters will persist in the transformed + // deduction guide. + return TA.isNull() || + (TA.getKind() == TemplateArgument::Pack && + llvm::any_of(TA.pack_elements(), IsNonDeducedArgument)); +} + // Build deduction guides for a type alias template from the given underlying // deduction guide F. FunctionTemplateDecl * ___ cfe-commits mailing list cfe-commits@lists.llvm.org h