[clang] [Clang] restrict use of attribute names reserved by the C++ standard (PR #106036)
https://github.com/a-tarasyuk deleted https://github.com/llvm/llvm-project/pull/106036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] restrict use of attribute names reserved by the C++ standard (PR #106036)
@@ -177,6 +177,26 @@ static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, return false; } +static bool isReservedAttrName(Preprocessor &PP, IdentifierInfo *II) { a-tarasyuk wrote: @Sirraide @AaronBallman @cor3ntin In the context of avoiding hardcoded names., I noticed there's an existing emitter that allows getting `AttrKind` using a string name. Is it okay to use this in this case, or would it be better to add a new emitter that will emit attributes with the new _flag-controlling_ names from the C++ standard? https://github.com/llvm/llvm-project/blob/9edd998e10fabfff067b9e6e5b044f85a24d0dd5/clang/utils/TableGen/ClangAttrEmitter.cpp#L4875 currenly, it's related to `Sema`, but it might need to be moved to `Basic`... https://github.com/llvm/llvm-project/blob/9edd998e10fabfff067b9e6e5b044f85a24d0dd5/clang/include/clang/Sema/CMakeLists.txt#L11-L14 https://github.com/llvm/llvm-project/pull/106036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][bytecode] Add InitLinkScope for temporary variables (PR #106552)
tbaederr wrote: @AaronBallman Can you confirm whether the following behavior is correct? When a `CXXDefaultInitExpr` is the child node of an `InitListExpr`, all `CXXThisExpr` found within that `CXXDefaultInitExpr` point to the `InitListExpr` and not to the actual instance pointer of the current stack frame. To properly implement this, I'd need to create a temporary variable whenever I encounter a `InitListExpr` though, which I'd like to avoid. https://github.com/llvm/llvm-project/pull/106552 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] d68059b - [NFC] [clangd] [Modules] Change the argument type of IsModuleFileUpToDate to reference
Author: Chuanqi Xu Date: 2024-08-30T15:15:24+08:00 New Revision: d68059bcfd1cc27e378c43b1f16019c5baccb06d URL: https://github.com/llvm/llvm-project/commit/d68059bcfd1cc27e378c43b1f16019c5baccb06d DIFF: https://github.com/llvm/llvm-project/commit/d68059bcfd1cc27e378c43b1f16019c5baccb06d.diff LOG: [NFC] [clangd] [Modules] Change the argument type of IsModuleFileUpToDate to reference It is better to use references instead of pointers as the argument type of IsModuleFileUpToDate. Since the PrerequisiteModules is always expected to exist. Added: Modified: clang-tools-extra/clangd/ModulesBuilder.cpp Removed: diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index dd00adc6f6c8d2..1eeff468ef1236 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -129,13 +129,12 @@ struct ModuleFile { bool IsModuleFileUpToDate( PathRef ModuleFilePath, -const PrerequisiteModules *RequisiteModules) { +const PrerequisiteModules &RequisiteModules) { IntrusiveRefCntPtr Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); auto HSOpts = std::make_shared(); - if (RequisiteModules) -RequisiteModules->adjustHeaderSearchOptions(*HSOpts); + RequisiteModules.adjustHeaderSearchOptions(*HSOpts); HSOpts->ForceCheckCXX20ModulesInputFiles = true; HSOpts->ValidateASTInputFilesContent = true; @@ -168,8 +167,8 @@ IntrusiveRefCntPtr Diags = bool IsModuleFilesUpToDate( llvm::SmallVector ModuleFilePaths, -const PrerequisiteModules *RequisiteModules = nullptr) { - return llvm::all_of(ModuleFilePaths, [RequisiteModules](auto ModuleFilePath) { +const PrerequisiteModules &RequisiteModules) { + return llvm::all_of(ModuleFilePaths, [&RequisiteModules](auto ModuleFilePath) { return IsModuleFileUpToDate(ModuleFilePath, RequisiteModules); }); } @@ -348,7 +347,7 @@ bool StandalonePrerequisiteModules::canReuse( SmallVector BMIPaths; for (auto &MF : RequiredModules) BMIPaths.push_back(MF.ModuleFilePath); - return IsModuleFilesUpToDate(BMIPaths, this); + return IsModuleFilesUpToDate(BMIPaths, *this); } } // namespace clangd ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fix kcfi doesn't take effect when callee function has no input parameter (PR #106677)
https://github.com/Zhenhang1213 created https://github.com/llvm/llvm-project/pull/106677 fix #106344 >From 3707b69ebd14be7fb8a88a5550639d1af1948ba6 Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 30 Aug 2024 15:21:12 +0800 Subject: [PATCH] fix kcfi doesn't take effect when callee function has no input parameter --- clang/lib/CodeGen/CodeGenFunction.cpp | 5 + 1 file changed, 5 insertions(+) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index c89eaa0f4e3bfc..4d3fb780243022 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2813,6 +2813,11 @@ void CodeGenFunction::EmitKCFIOperandBundle( Callee.getAbstractInfo().getCalleeFunctionProtoType(); if (FP) Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar())); + else { +ASTContext &context = this->getContext(); +QualType voidType = context.VoidTy; +Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(voidType)); + } } llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fix kcfi doesn't take effect when callee function has no input parameter (PR #106677)
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/106677 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fix kcfi doesn't take effect when callee function has no input parameter (PR #106677)
llvmbot wrote: @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Austin (Zhenhang1213) Changes fix #106344 --- Full diff: https://github.com/llvm/llvm-project/pull/106677.diff 1 Files Affected: - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+5) ``diff diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index c89eaa0f4e3bfc..4d3fb780243022 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2813,6 +2813,11 @@ void CodeGenFunction::EmitKCFIOperandBundle( Callee.getAbstractInfo().getCalleeFunctionProtoType(); if (FP) Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar())); + else { +ASTContext &context = this->getContext(); +QualType voidType = context.VoidTy; +Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(voidType)); + } } llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( `` https://github.com/llvm/llvm-project/pull/106677 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Parser] Fix name lookup of template parameters for out-of-line specializations (PR #101020)
https://github.com/cor3ntin edited https://github.com/llvm/llvm-project/pull/101020 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Parser] Fix name lookup of template parameters for out-of-line specializations (PR #101020)
https://github.com/cor3ntin commented: Thanks for the detailed description! I think the change makes sense, we just might need more tests and a changelog entry https://github.com/llvm/llvm-project/pull/101020 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Parser] Fix name lookup of template parameters for out-of-line specializations (PR #101020)
@@ -151,4 +152,25 @@ namespace SearchClassBetweenTemplateParameterLists { void A::B::k(V) { // expected-error {{does not match}} BB bb; // expected-error {{incomplete type}} } + + int CC; + template struct C; +#if __cplusplus >= 202003L + template struct D; + template concept True = true; +#endif } + +template +struct SearchClassBetweenTemplateParameterLists::C { + void foo(CC) {} // This should find the template type parameter. +}; + +#if __cplusplus >= 202003L + +template +struct SearchClassBetweenTemplateParameterLists::D { + void foo(CC); +}; + cor3ntin wrote: - Can you add a test with NTTP template params? - Do we have tests for that sort of lookup in requires clause / return types? - Maybe a test that check that if both names are a `typename` we find the correct one https://github.com/llvm/llvm-project/pull/101020 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Parser] Fix name lookup of template parameters for out-of-line specializations (PR #101020)
cor3ntin wrote: I am sorry this fell off my radar. Feel free to ping weekly in the future https://github.com/llvm/llvm-project/pull/101020 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][NFC] Consolidate tests for default argument substitution (PR #105617)
https://github.com/cor3ntin approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/105617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
https://github.com/NagyDonat commented: (This is just a quick drive-by correction of the `CallDescription` matching modes. Other parts of the commit seem to be good, but I don't have a firm opinion.) https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
https://github.com/NagyDonat edited https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
@@ -158,12 +160,16 @@ class CStringChecker : public Checker< eval::Call, &CStringChecker::evalStrlcpy}, {{CDM::CLibraryMaybeHardened, {"strcat"}, 2}, &CStringChecker::evalStrcat}, + {{CDM::CLibraryMaybeHardened, {"lstrcat"}, 2}, NagyDonat wrote: ```suggestion {{CDM::CLibrary, {"lstrcat"}, 2}, ``` As above. https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
@@ -150,6 +150,8 @@ class CStringChecker : public Checker< eval::Call, // FIXME: C23 introduces 'memset_explicit', maybe also model that {{CDM::CLibraryMaybeHardened, {"strcpy"}, 2}, &CStringChecker::evalStrcpy}, + {{CDM::CLibraryMaybeHardened, {"lstrcpy"}, 2}, NagyDonat wrote: ```suggestion {{CDM::CLibrary, {"lstrcpy"}, 2}, ``` The matching mode `CLibraryMaybeHardened` was introduced to also recognize references to the "hardened" function variants that are named like `_strcpy_chk` or `__builtin___strcpy_chk` (and may have one or two additional parameters compared to the "regular" function). As `lstrcpy` does not have a hardened variant (according to a google search that produced zero results), we should simply match it with `CDM::CLibrary`. In this case the plain `CLibrary` matching mode is enough, because https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
@@ -158,12 +160,16 @@ class CStringChecker : public Checker< eval::Call, &CStringChecker::evalStrlcpy}, {{CDM::CLibraryMaybeHardened, {"strcat"}, 2}, &CStringChecker::evalStrcat}, + {{CDM::CLibraryMaybeHardened, {"lstrcat"}, 2}, + &CStringChecker::evalStrcat}, {{CDM::CLibraryMaybeHardened, {"strncat"}, 3}, &CStringChecker::evalStrncat}, {{CDM::CLibraryMaybeHardened, {"strlcat"}, 3}, &CStringChecker::evalStrlcat}, {{CDM::CLibraryMaybeHardened, {"strlen"}, 1}, &CStringChecker::evalstrLength}, + {{CDM::CLibraryMaybeHardened, {"lstrlen"}, 1}, NagyDonat wrote: ```suggestion {{CDM::CLibrary, {"lstrlen"}, 1}, ``` As above. https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Catch missing format attributes (PR #105479)
budimirarandjelovichtec wrote: > Can you explain what changes were made to address the various issues which > caused the earlier revert? I've tried diffing the PRs to see what the changes > are, but my git-fu is insufficient to the task. :-D I made changes in several places. Here are major changes: 1) determining first argument index. Here I removed dynamic cast to DeclRefAttr of last function argument. In C++ mode casting to DeclRefAttr resulted in unrecognizing argument type as va_list for several architectures and OS. So, some architectures gave 0 as output and others gave non-zero value. Unrecognizing argument type as va_list was a result of defining canonical va_list type differently depending on architecture. 2) added check if calling function has format attribute before iterating through its format attributes. This check was added because one pointer (AttrType) was initialized in iteration through format attributes and later used to get name if missing attribute was caught. In previous merge this was resulting in throwing error that there were use of uninitialized variable for some architectures. 3) edited some parts of C code where passed arguments were not valid. Examples are passing &args[0] or char * as va_list argument (functions f8() and f41()). Relevant parts of code are reviewed in [#106649 ](https://github.com/llvm/llvm-project/pull/106649/). https://github.com/llvm/llvm-project/pull/105479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] Add function check for windows platform (PR #106581)
https://github.com/NagyDonat edited https://github.com/llvm/llvm-project/pull/106581 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV][NFC] Reimplementation of target attribute override mechanism (PR #106680)
https://github.com/BeMg created https://github.com/llvm/llvm-project/pull/106680 This patch aims to replace the target attribute override mechanism based on `__RISCV_TargetAttrNeedOverride` with the insertion of several negative target features When the target attribute uses the full architecture string ("arch=rv64gc") or specifies the CPU ("cpu=rocket-rv64") as the version, it will override the module-level target feature. Currently, this mechanism is implemented by inserting `__RISCV_TargetAttrNeedOverride` as a dummy target feature immediately before the target attribute's feature. ``` module target features + __RISCV_TargetAttrNeedOverride + target attribute's feature ``` The RISCVTargetInfo::initFeatureMap function will remove the "module target features" and use only the "target attribute's features". This patch changes the process as follows: ``` module target features + negative target feature for all supported extension + target attribute's feature ``` The `module target features` will be disable by `negative target feature for all supported extension` in `TargetInfo::initFeatureMap` >From 31e6abe40b593b0590ca20cb24a0fce5d642e0ad Mon Sep 17 00:00:00 2001 From: Piyou Chen Date: Fri, 30 Aug 2024 00:27:25 -0700 Subject: [PATCH 1/2] [RISCV] Reimplementation of target attribute override mechanism --- clang/lib/Basic/Targets/RISCV.cpp | 32 +-- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 1f8a8cd1462c9d..5e434780f23bf8 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -255,24 +255,6 @@ bool RISCVTargetInfo::initFeatureMap( Features["32bit"] = true; } - // If a target attribute specified a full arch string, override all the ISA - // extension target features. - const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride"); - if (I != FeaturesVec.end()) { -std::vector OverrideFeatures(std::next(I), FeaturesVec.end()); - -// Add back any non ISA extension features, e.g. +relax. -auto IsNonISAExtFeature = [](StringRef Feature) { - assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-')); - StringRef Ext = Feature.substr(1); // drop the +/- - return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext); -}; -llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I), - std::back_inserter(OverrideFeatures), IsNonISAExtFeature); - -return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures); - } - // Otherwise, parse the features and add any implied extensions. std::vector AllFeatures = FeaturesVec; auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); @@ -389,9 +371,20 @@ void RISCVTargetInfo::fillValidTuneCPUList( llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit); } +static void populateNegativeRISCVFeatures(std::vector &Features) { + auto RII = llvm::RISCVISAInfo::parseArchString( + "rv64i", /* EnableExperimentalExtension */ true); + + if (llvm::errorToBool(RII.takeError())) +llvm_unreachable("unsupport rv64i"); + + std::vector FeatStrings = + (*RII)->toFeatures(/* AddAllExtensions */ true); + Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end()); +} + static void handleFullArchString(StringRef FullArchStr, std::vector &Features) { - Features.push_back("__RISCV_TargetAttrNeedOverride"); auto RII = llvm::RISCVISAInfo::parseArchString( FullArchStr, /* EnableExperimentalExtension */ true); if (llvm::errorToBool(RII.takeError())) { @@ -400,6 +393,7 @@ static void handleFullArchString(StringRef FullArchStr, } else { // Append a full list of features, including any negative extensions so that // we override the CPU's features. +populateNegativeRISCVFeatures(Features); std::vector FeatStrings = (*RII)->toFeatures(/* AddAllExtensions */ true); Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end()); >From c79a13109d7d760579a720195150afd706e40ede Mon Sep 17 00:00:00 2001 From: Piyou Chen Date: Fri, 30 Aug 2024 00:47:07 -0700 Subject: [PATCH 2/2] Remove comment --- clang/lib/Basic/Targets/RISCV.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 5e434780f23bf8..b89109e7725d44 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -255,7 +255,6 @@ bool RISCVTargetInfo::initFeatureMap( Features["32bit"] = true; } - // Otherwise, parse the features and add any implied extensions. std::vector AllFeatures = FeaturesVec; auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); if (!ParseResult) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.
[clang] [RISCV][NFC] Reimplementation of target attribute override mechanism (PR #106680)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Piyou Chen (BeMg) Changes This patch aims to replace the target attribute override mechanism based on `__RISCV_TargetAttrNeedOverride` with the insertion of several negative target features When the target attribute uses the full architecture string ("arch=rv64gc") or specifies the CPU ("cpu=rocket-rv64") as the version, it will override the module-level target feature. Currently, this mechanism is implemented by inserting `__RISCV_TargetAttrNeedOverride` as a dummy target feature immediately before the target attribute's feature. ``` module target features + __RISCV_TargetAttrNeedOverride + target attribute's feature ``` The RISCVTargetInfo::initFeatureMap function will remove the "module target features" and use only the "target attribute's features". This patch changes the process as follows: ``` module target features + negative target feature for all supported extension + target attribute's feature ``` The `module target features` will be disable by `negative target feature for all supported extension` in `TargetInfo::initFeatureMap` --- Full diff: https://github.com/llvm/llvm-project/pull/106680.diff 1 Files Affected: - (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-20) ``diff diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 1f8a8cd1462c9d..b89109e7725d44 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -255,25 +255,6 @@ bool RISCVTargetInfo::initFeatureMap( Features["32bit"] = true; } - // If a target attribute specified a full arch string, override all the ISA - // extension target features. - const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride"); - if (I != FeaturesVec.end()) { -std::vector OverrideFeatures(std::next(I), FeaturesVec.end()); - -// Add back any non ISA extension features, e.g. +relax. -auto IsNonISAExtFeature = [](StringRef Feature) { - assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-')); - StringRef Ext = Feature.substr(1); // drop the +/- - return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext); -}; -llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I), - std::back_inserter(OverrideFeatures), IsNonISAExtFeature); - -return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures); - } - - // Otherwise, parse the features and add any implied extensions. std::vector AllFeatures = FeaturesVec; auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec); if (!ParseResult) { @@ -389,9 +370,20 @@ void RISCVTargetInfo::fillValidTuneCPUList( llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit); } +static void populateNegativeRISCVFeatures(std::vector &Features) { + auto RII = llvm::RISCVISAInfo::parseArchString( + "rv64i", /* EnableExperimentalExtension */ true); + + if (llvm::errorToBool(RII.takeError())) +llvm_unreachable("unsupport rv64i"); + + std::vector FeatStrings = + (*RII)->toFeatures(/* AddAllExtensions */ true); + Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end()); +} + static void handleFullArchString(StringRef FullArchStr, std::vector &Features) { - Features.push_back("__RISCV_TargetAttrNeedOverride"); auto RII = llvm::RISCVISAInfo::parseArchString( FullArchStr, /* EnableExperimentalExtension */ true); if (llvm::errorToBool(RII.takeError())) { @@ -400,6 +392,7 @@ static void handleFullArchString(StringRef FullArchStr, } else { // Append a full list of features, including any negative extensions so that // we override the CPU's features. +populateNegativeRISCVFeatures(Features); std::vector FeatStrings = (*RII)->toFeatures(/* AddAllExtensions */ true); Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end()); `` https://github.com/llvm/llvm-project/pull/106680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e0fa2f1 - `__noop` not marked as constexpr #102064 (#105983)
Author: ofAlpaca Date: 2024-08-30T09:52:24+02:00 New Revision: e0fa2f1c2957d9783d21460febf103cecac9e19a URL: https://github.com/llvm/llvm-project/commit/e0fa2f1c2957d9783d21460febf103cecac9e19a DIFF: https://github.com/llvm/llvm-project/commit/e0fa2f1c2957d9783d21460febf103cecac9e19a.diff LOG: `__noop` not marked as constexpr #102064 (#105983) Fixes #102064 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/Builtins.td clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/builtins.cpp Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d3aebdb0b06477..d0ac3b65820b05 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -285,6 +285,13 @@ Bug Fixes in This Version Bug Fixes to Compiler Builtins ^^ +- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330) + +- Clang now allows pointee types of atomic builtin arguments to be complete template types + that was not instantiated elsewhere. + +- ``__noop`` can now be used in a constant expression. (#GH102064) + Bug Fixes to Attribute Support ^^ diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index ac33672a32b336..8668b25661dec8 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -2518,7 +2518,7 @@ def IsoVolatileStore : MSLangBuiltin, Int8_16_32_64Template { def Noop : MSLangBuiltin { let Spellings = ["__noop"]; - let Attributes = [NoThrow]; + let Attributes = [NoThrow, Constexpr]; let Prototype = "int(...)"; } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d46f57521a97d3..e8a4d1d3c74102 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12719,6 +12719,10 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return false; } + case Builtin::BI__noop: + // __noop always evaluates successfully +return true; + case Builtin::BI__builtin_is_constant_evaluated: { const auto *Callee = Info.CurrentCall->getCallee(); if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression && diff --git a/clang/test/SemaCXX/builtins.cpp b/clang/test/SemaCXX/builtins.cpp index 080b4476c7eec1..c6fbb8b514d671 100644 --- a/clang/test/SemaCXX/builtins.cpp +++ b/clang/test/SemaCXX/builtins.cpp @@ -175,3 +175,7 @@ template void test_builtin_complex(int, double); // expected-note {{instantiatio static void __builtin_cpu_init(); // expected-error {{static declaration of '__builtin_cpu_init' follows non-static declaration}} \ expected-note {{'__builtin_cpu_init' is a builtin with type 'void () noexcept'}} #endif + +#ifdef _MSC_VER +constexpr int x = []{ __noop; return 0; }(); // expected-no-diagnostics +#endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] `__noop` not marked as constexpr #102064 (PR #105983)
https://github.com/cor3ntin closed https://github.com/llvm/llvm-project/pull/105983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] `__noop` not marked as constexpr #102064 (PR #105983)
github-actions[bot] wrote: @ofAlpaca Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr). If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! https://github.com/llvm/llvm-project/pull/105983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
https://github.com/budimirarandjelovichtec commented: Here are major changes. https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
@@ -5506,16 +5509,13 @@ Sema::GetMissingFormatAttributes(Stmt *Body, const FunctionDecl *FDecl) { } // Get first argument index -unsigned FirstToCheck = [&]() -> unsigned { +int FirstToCheck = [&]() -> unsigned { if (!FDecl->isVariadic()) return 0; - const auto *FirstToCheckArg = - dyn_cast(Args[NumArgs - 1]->IgnoreParenCasts()); budimirarandjelovichtec wrote: I removed dynamic cast to DeclRefAttr of last function argument. In C++ mode casting to DeclRefAttr resulted in unrecognizing argument type as va_list for several architectures and OS. https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
https://github.com/budimirarandjelovichtec edited https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
@@ -84,16 +81,16 @@ void f7(const char *out, ... /* args */) // #f7 { va_list args; -vscanf(out, &args[0]); // expected-warning@#f7 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f7'}} - // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:6-[[@LINE-5]]:6}:"__attribute__((format(scanf, 1, 0)))" +vscanf(out, args); // expected-warning@#f7 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f7'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:6-[[@LINE-5]]:6}:"__attribute__((format(scanf, 1, 2)))" } void f8(const char *out, ... /* args */) // #f8 { va_list args; -vscanf(out, &args[0]); // expected-no-warning@#f8 -vprintf(out, &args[0]); // expected-no-warning@#f8 budimirarandjelovichtec wrote: Seems that second argument is not passed properly. https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
@@ -387,17 +388,6 @@ void f40(char *out, ... /* args */) // #f40 void f41(char *out, ... /* args */) // #f41 { va_list args; -char *ch; -vscanf("%s", ch); budimirarandjelovichtec wrote: Char * was passed to second parameter which accepts va_list type. https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Update Catch missing format attributes (PR #106649)
@@ -5416,15 +5416,18 @@ Sema::GetMissingFormatAttributes(Stmt *Body, const FunctionDecl *FDecl) { // If child expression is function, check if it is format function. // If it is, check if parent function misses format attributes. +unsigned int ChildFunctionFormatArgumentIndexOffset = +checkIfMethodHasImplicitObjectParameter(ChildFunction) ? 2 : 1; + +if (!ChildFunction->hasAttr()) budimirarandjelovichtec wrote: This check was added because there is llvm::any_of later and one pointer can only be assigned inside llvm::any_of. This pointer is later called if format attribute was caught. This change prevents throwing error that unitialized value was used. https://github.com/llvm/llvm-project/pull/106649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName (PR #106495)
@@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap( // If a target attribute specified a full arch string, override all the ISA // extension target features. - const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride"); + const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride"); BeMg wrote: This feature was used to implement the target attribute override mechanism. I think it could be removed after replacing it with several negative target features. Here is the pull request for this change: https://github.com/llvm/llvm-project/pull/106680 https://github.com/llvm/llvm-project/pull/106495 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName (PR #106495)
https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/106495 >From 64557cf6950c17a92b6d85980530abe1e193e111 Mon Sep 17 00:00:00 2001 From: Piyou Chen Date: Wed, 28 Aug 2024 21:15:57 -0700 Subject: [PATCH 1/3] [Clang][RISCV] Recognize unsupport feature by supporting isValidFeatureName --- clang/lib/Basic/Targets/RISCV.cpp | 18 -- clang/lib/Basic/Targets/RISCV.h | 1 + clang/lib/Sema/SemaDeclAttr.cpp | 15 +++ clang/test/Sema/attr-target-riscv.c | 9 + 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 1f8a8cd1462c9d..1d6f49ca232692 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap( // If a target attribute specified a full arch string, override all the ISA // extension target features. - const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride"); + const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride"); if (I != FeaturesVec.end()) { std::vector OverrideFeatures(std::next(I), FeaturesVec.end()); @@ -391,7 +391,14 @@ void RISCVTargetInfo::fillValidTuneCPUList( static void handleFullArchString(StringRef FullArchStr, std::vector &Features) { - Features.push_back("__RISCV_TargetAttrNeedOverride"); + + // Should be full arch string. + if (!FullArchStr.starts_with("rv")) { +Features.push_back(FullArchStr.str()); +return; + } + + Features.push_back("+__RISCV_TargetAttrNeedOverride"); auto RII = llvm::RISCVISAInfo::parseArchString( FullArchStr, /* EnableExperimentalExtension */ true); if (llvm::errorToBool(RII.takeError())) { @@ -485,3 +492,10 @@ bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const { // __riscv_feature_bits structure. return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second; } + +bool RISCVTargetInfo::isValidFeatureName(StringRef Name) const { + if (Name == "__RISCV_TargetAttrNeedOverride") +return true; + + return llvm::RISCVISAInfo::isSupportedExtensionFeature(Name); +} diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index 626274b8fc437c..b808ccc8e9cfe9 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -130,6 +130,7 @@ class RISCVTargetInfo : public TargetInfo { bool supportsCpuSupports() const override { return getTriple().isOSLinux(); } bool supportsCpuInit() const override { return getTriple().isOSLinux(); } bool validateCpuSupports(StringRef Feature) const override; + bool isValidFeatureName(StringRef Name) const override; }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 1e074298ac5289..81cff8d7362ad5 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2993,10 +2993,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unknown << Tune << ParsedAttrs.Tune << Target; - if (Context.getTargetInfo().getTriple().isRISCV() && - ParsedAttrs.Duplicate != "") -return Diag(LiteralLoc, diag::err_duplicate_target_attribute) - << Duplicate << None << ParsedAttrs.Duplicate << Target; + if (Context.getTargetInfo().getTriple().isRISCV()) { +if (ParsedAttrs.Duplicate != "") + return Diag(LiteralLoc, diag::err_duplicate_target_attribute) + << Duplicate << None << ParsedAttrs.Duplicate << Target; +for (const auto &Feature : ParsedAttrs.Features) { + auto CurFeature = StringRef(Feature); + if (!CurFeature.starts_with("+") && !CurFeature.starts_with("-")) +return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) + << Unsupported << None << AttrStr << Target; +} + } if (ParsedAttrs.Duplicate != "") return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) diff --git a/clang/test/Sema/attr-target-riscv.c b/clang/test/Sema/attr-target-riscv.c index ed4e2915d6c6ef..01d928c1d78e48 100644 --- a/clang/test/Sema/attr-target-riscv.c +++ b/clang/test/Sema/attr-target-riscv.c @@ -4,3 +4,12 @@ int __attribute__((target("arch=rv64g"))) foo(void) { return 0; } //expected-error@+1 {{redefinition of 'foo'}} int __attribute__((target("arch=rv64gc"))) foo(void) { return 0; } + +//expected-warning@+1 {{unsupported 'notafeature' in the 'target' attribute string; 'target' attribute ignored}} +int __attribute__((target("arch=+notafeature"))) UnsupportFeature(void) { return 0; } + +//expected-warning@+1 {{unsupported 'arch=+zba,zbb' in the 'target' attribute string; 'target' attribute ignored}} +int __attribute__((target("arch=+zba,zbb"))) WithoutAddSigned(void) { ret
[clang] [Clang][RISCV] Recognize unsupport target feature by supporting isValidFeatureName (PR #106495)
@@ -2993,10 +2993,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unknown << Tune << ParsedAttrs.Tune << Target; - if (Context.getTargetInfo().getTriple().isRISCV() && - ParsedAttrs.Duplicate != "") -return Diag(LiteralLoc, diag::err_duplicate_target_attribute) - << Duplicate << None << ParsedAttrs.Duplicate << Target; + if (Context.getTargetInfo().getTriple().isRISCV()) { +if (ParsedAttrs.Duplicate != "") + return Diag(LiteralLoc, diag::err_duplicate_target_attribute) + << Duplicate << None << ParsedAttrs.Duplicate << Target; +for (const auto &Feature : ParsedAttrs.Features) { + auto CurFeature = StringRef(Feature); + if (!CurFeature.starts_with("+") && !CurFeature.starts_with("-")) BeMg wrote: Updated. https://github.com/llvm/llvm-project/pull/106495 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert created https://github.com/llvm/llvm-project/pull/106681 For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation >From 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 -- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def| 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +-- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert converted_to_draft https://github.com/llvm/llvm-project/pull/106681 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang-driver Author: Shengchen Kan (KanRobert) Changes For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- Full diff: https://github.com/llvm/llvm-project/pull/106681.diff 14 Files Affected: - (modified) clang/test/Driver/relax.s (+2) - (modified) lld/ELF/Arch/X86_64.cpp (+3) - (modified) lld/test/ELF/x86-64-gotpc-no-relax-err.s (+7-3) - (modified) lld/test/ELF/x86-64-gotpc-relax.s (+1-1) - (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (+1) - (modified) llvm/lib/MC/MCTargetOptionsCommandFlags.cpp (+2-2) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (+6-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+9-10) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp (+5-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp (+2) - (modified) llvm/test/MC/ELF/relocation-alias.s (+3) - (modified) llvm/test/MC/X86/gotpcrelx.s (+34) ``diff diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s movl __stop_data
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
llvmbot wrote: @llvm/pr-subscribers-llvm-binary-utilities Author: Shengchen Kan (KanRobert) Changes For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- Full diff: https://github.com/llvm/llvm-project/pull/106681.diff 14 Files Affected: - (modified) clang/test/Driver/relax.s (+2) - (modified) lld/ELF/Arch/X86_64.cpp (+3) - (modified) lld/test/ELF/x86-64-gotpc-no-relax-err.s (+7-3) - (modified) lld/test/ELF/x86-64-gotpc-relax.s (+1-1) - (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (+1) - (modified) llvm/lib/MC/MCTargetOptionsCommandFlags.cpp (+2-2) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (+6-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+9-10) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp (+5-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp (+2) - (modified) llvm/test/MC/ELF/relocation-alias.s (+3) - (modified) llvm/test/MC/X86/gotpcrelx.s (+34) ``diff diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s movl __stop_data@GOTPCREL(%rip), %eax #
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
llvmbot wrote: @llvm/pr-subscribers-lld Author: Shengchen Kan (KanRobert) Changes For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- Full diff: https://github.com/llvm/llvm-project/pull/106681.diff 14 Files Affected: - (modified) clang/test/Driver/relax.s (+2) - (modified) lld/ELF/Arch/X86_64.cpp (+3) - (modified) lld/test/ELF/x86-64-gotpc-no-relax-err.s (+7-3) - (modified) lld/test/ELF/x86-64-gotpc-relax.s (+1-1) - (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def (+1) - (modified) llvm/lib/MC/MCTargetOptionsCommandFlags.cpp (+2-2) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (+6-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h (+4) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (+9-10) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp (+5-1) - (modified) llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp (+2) - (modified) llvm/test/MC/ELF/relocation-alias.s (+3) - (modified) llvm/test/MC/X86/gotpcrelx.s (+34) ``diff diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s movl __stop_data@GOTPCREL(%rip), %eax # out of range m
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
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 89e6a288674c9fae33aeb5448c7b1fe782b2bf53 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 --extensions h,cpp -- lld/ELF/Arch/X86_64.cpp llvm/lib/MC/MCTargetOptionsCommandFlags.cpp llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index c02338995f..41943fc20b 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -631,7 +631,8 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, - {"reloc_riprel_4byte_movq_load_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"reloc_riprel_4byte_movq_load_rex2", 0, 32, + MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, {"reloc_riprel_4byte_relax_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp index 9fdc62b8c8..9078d1 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -221,7 +221,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, return ELF::R_X86_64_REX_GOTPCRELX; case X86::reloc_riprel_4byte_relax_rex2: case X86::reloc_riprel_4byte_movq_load_rex2: - return ELF::R_X86_64_REX2_GOTPCRELX; + return ELF::R_X86_64_REX2_GOTPCRELX; } llvm_unreachable("unexpected relocation type!"); case MCSymbolRefExpr::VK_GOTPCREL_NORELAX: `` https://github.com/llvm/llvm-project/pull/106681 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/106683 This is the following patch of https://github.com/llvm/llvm-project/pull/66462 to optimize its performance. # Motivation To avoid data races, we choose "per file owns its dependent modules" model. That said, every TU will own all the required module files so that we don't need to worry about thread safety. And it looks like we succeeded that we focus on the interfaces and structure of modules support in clangd. But after all, this model is not good for performance. Image we have 1 TUs import std, we will have 1 std.pcm in the memory. That is terrible both in time and space. Given the current modules support in clangd works pretty well (almost every issue report I received is more or less a clang's issue), I'd like to improve the performance. # High Level Changes After this patch, the built module files will be owned by the module builder and each TU will only have a reference to the built module files. The module builder have a map from module names to built module files. When a new TU ask for a module file, the module builder will check if the module file lives in the map and if the module file are up to date. If yes, the module file will be returned. If no, the module file entry would be erased in the module builder. We use `shared_ptr<>` to track module file here so that the other TU owning the out dated module file won't be affected. The out dated module file will be removed automatically if other TU gets update or closed. (I know the out dated module file may not exist due to the `CanReuse` mechanism. But the design here is natural and can be seen as a redundant design to make it more robust.) When we a build a module, we will use the mutex and the condition variable in the working thread to build it exclusively. All other threads that also want the module file would have to wait for that working thread. It might not sounds great but I think if we want to make it asynchronous, we have to refactor TUScheduler as far as I know. # Code Structure Changes Thanks for the previous hard working reviewing, the interfaces almost don't change in this patch. Almost all the work are isolated in ModulesBuilder.cpp. A outliner is that we convert `ModulesBuilder` to an abstract class since the implementation class needs to own the module files. And the core function to review is `ReusableModulesBuilder::getOrBuildModuleFile`. It implements the core logic to fetch the module file from the cache or build it if the module file is not in the cache or out of date. And other important entities are `BuildingModuleMutexes`, `BuildingModuleCVs`, `BuildingModules` and `ModulesBuildingMutex`. These are mutexes and condition variables to make sure the thread safety. # User experience I've implemented this in our downstream and ask our users to use it. I also sent it https://github.com/ChuanqiXu9/clangd-for-modules here as pre-version. The feedbacks are pretty good. And I didn't receive any bug reports (about the reusable modules builder) yet. # Other potential improvement The are other two potential improvements can be done: 1. Scanning cache and a mechanism to get the required module information more quickly. (Like the module maps in https://github.com/ChuanqiXu9/clangd-for-modules) 2. Persist the module files. So that after we close the vscode and reopen it, we can reuse the built module files since the last invocation. >From 1cd6f553f8c8f0f0a8dc691d3dcb413db9f4c051 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Fri, 30 Aug 2024 15:11:07 +0800 Subject: [PATCH] [clangd] [Modules] Support Reusable Modules Builder --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 4 +- clang-tools-extra/clangd/ClangdLSPServer.h| 2 +- clang-tools-extra/clangd/ModulesBuilder.cpp | 357 ++ clang-tools-extra/clangd/ModulesBuilder.h | 11 +- clang-tools-extra/clangd/tool/Check.cpp | 6 +- .../unittests/PrerequisiteModulesTest.cpp | 70 +++- 6 files changed, 362 insertions(+), 88 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 06573a57554245..53a18bd4ecd1a7 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -567,8 +567,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, std::move(Mangler)); if (Opts.EnableExperimentalModulesSupport) { -ModulesManager.emplace(*CDB); -Opts.ModulesManager = &*ModulesManager; +ModulesManager = ModulesBuilder::getModulesBuilder(*CDB); +Opts.ModulesManager = ModulesManager.get(); } { diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 0b8e4720f53236..4b8f048b430fe9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Chuanqi Xu (ChuanqiXu9) Changes This is the following patch of https://github.com/llvm/llvm-project/pull/66462 to optimize its performance. # Motivation To avoid data races, we choose "per file owns its dependent modules" model. That said, every TU will own all the required module files so that we don't need to worry about thread safety. And it looks like we succeeded that we focus on the interfaces and structure of modules support in clangd. But after all, this model is not good for performance. Image we have 1 TUs import std, we will have 1 std.pcm in the memory. That is terrible both in time and space. Given the current modules support in clangd works pretty well (almost every issue report I received is more or less a clang's issue), I'd like to improve the performance. # High Level Changes After this patch, the built module files will be owned by the module builder and each TU will only have a reference to the built module files. The module builder have a map from module names to built module files. When a new TU ask for a module file, the module builder will check if the module file lives in the map and if the module file are up to date. If yes, the module file will be returned. If no, the module file entry would be erased in the module builder. We use `shared_ptr<>` to track module file here so that the other TU owning the out dated module file won't be affected. The out dated module file will be removed automatically if other TU gets update or closed. (I know the out dated module file may not exist due to the `CanReuse` mechanism. But the design here is natural and can be seen as a redundant design to make it more robust.) When we a build a module, we will use the mutex and the condition variable in the working thread to build it exclusively. All other threads that also want the module file would have to wait for that working thread. It might not sounds great but I think if we want to make it asynchronous, we have to refactor TUScheduler as far as I know. # Code Structure Changes Thanks for the previous hard working reviewing, the interfaces almost don't change in this patch. Almost all the work are isolated in ModulesBuilder.cpp. A outliner is that we convert `ModulesBuilder` to an abstract class since the implementation class needs to own the module files. And the core function to review is `ReusableModulesBuilder::getOrBuildModuleFile`. It implements the core logic to fetch the module file from the cache or build it if the module file is not in the cache or out of date. And other important entities are `BuildingModuleMutexes`, `BuildingModuleCVs`, `BuildingModules` and `ModulesBuildingMutex`. These are mutexes and condition variables to make sure the thread safety. # User experience I've implemented this in our downstream and ask our users to use it. I also sent it https://github.com/ChuanqiXu9/clangd-for-modules here as pre-version. The feedbacks are pretty good. And I didn't receive any bug reports (about the reusable modules builder) yet. # Other potential improvement The are other two potential improvements can be done: 1. Scanning cache and a mechanism to get the required module information more quickly. (Like the module maps in https://github.com/ChuanqiXu9/clangd-for-modules) 2. Persist the module files. So that after we close the vscode and reopen it, we can reuse the built module files since the last invocation. --- Patch is 27.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/106683.diff 6 Files Affected: - (modified) clang-tools-extra/clangd/ClangdLSPServer.cpp (+2-2) - (modified) clang-tools-extra/clangd/ClangdLSPServer.h (+1-1) - (modified) clang-tools-extra/clangd/ModulesBuilder.cpp (+294-63) - (modified) clang-tools-extra/clangd/ModulesBuilder.h (+6-5) - (modified) clang-tools-extra/clangd/tool/Check.cpp (+3-3) - (modified) clang-tools-extra/clangd/unittests/PrerequisiteModulesTest.cpp (+56-14) ``diff diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 06573a57554245..53a18bd4ecd1a7 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -567,8 +567,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, std::move(Mangler)); if (Opts.EnableExperimentalModulesSupport) { -ModulesManager.emplace(*CDB); -Opts.ModulesManager = &*ModulesManager; +ModulesManager = ModulesBuilder::getModulesBuilder(*CDB); +Opts.ModulesManager = ModulesManager.get(); } { diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 0b8e4720f53236..4b8f048b430fe9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -327,7 +327,7 @@ class Cl
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
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 d68059bcfd1cc27e378c43b1f16019c5baccb06d 1cd6f553f8c8f0f0a8dc691d3dcb413db9f4c051 --extensions h,cpp -- clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/ModulesBuilder.cpp clang-tools-extra/clangd/ModulesBuilder.h clang-tools-extra/clangd/tool/Check.cpp clang-tools-extra/clangd/unittests/PrerequisiteModulesTest.cpp `` View the diff from clang-format here. ``diff diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 82aa7d181f..a674e68ca7 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -217,12 +217,11 @@ private: /// Build a module file for module with `ModuleName`. The information of built /// module file are stored in \param BuiltModuleFiles. -llvm::Expected buildModuleFile(llvm::StringRef ModuleName, -PathRef ModuleUnitFileName, -const GlobalCompilationDatabase &CDB, -const ThreadsafeFS &TFS, -PathRef ModuleFilesPrefix, -const ReusablePrerequisiteModules &BuiltModuleFiles) { +llvm::Expected +buildModuleFile(llvm::StringRef ModuleName, PathRef ModuleUnitFileName, +const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS, +PathRef ModuleFilesPrefix, +const ReusablePrerequisiteModules &BuiltModuleFiles) { // Try cheap operation earlier to boil-out cheaply if there are problems. auto Cmd = CDB.getCompileCommand(ModuleUnitFileName); if (!Cmd) @@ -286,9 +285,10 @@ public: buildPrerequisiteModulesFor(PathRef File, const ThreadsafeFS &TFS) override; private: - llvm::Error getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, -ProjectModules &MDB, -ReusablePrerequisiteModules &RequiredModules); + llvm::Error + getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, + ProjectModules &MDB, + ReusablePrerequisiteModules &RequiredModules); std::shared_ptr getValidModuleFile(StringRef ModuleName, ProjectModules &MDB, @@ -318,7 +318,8 @@ private: // an unbuilt module shouldn't be in this set. // This set is helpful to control the behavior of the condition variables. llvm::StringSet<> BuildingModules; - // Lock when we access BuildingModules, BuildingModuleMutexes and BuildingModuleCVs. + // Lock when we access BuildingModules, BuildingModuleMutexes and + // BuildingModuleCVs. std::mutex ModulesBuildingMutex; void startBuildingModule(StringRef ModuleName) { @@ -426,7 +427,7 @@ std::shared_ptr ReusableModulesBuilder::getValidModuleFile( std::unique_ptr ReusableModulesBuilder::buildPrerequisiteModulesFor(PathRef File, -const ThreadsafeFS &TFS) { +const ThreadsafeFS &TFS) { std::unique_ptr MDB = CDB.getProjectModules(File); if (!MDB) { elog("Failed to get Project Modules information for {0}", File); @@ -446,8 +447,8 @@ ReusableModulesBuilder::buildPrerequisiteModulesFor(PathRef File, for (llvm::StringRef RequiredModuleName : RequiredModuleNames) { // Return early if there is any error. -if (llvm::Error Err = -getOrBuildModuleFile(RequiredModuleName, TFS, *MDB.get(), *RequiredModules.get())) { +if (llvm::Error Err = getOrBuildModuleFile( +RequiredModuleName, TFS, *MDB.get(), *RequiredModules.get())) { elog("Failed to build module {0}; due to {1}", RequiredModuleName, toString(std::move(Err))); return std::make_unique(); @@ -460,8 +461,7 @@ ReusableModulesBuilder::buildPrerequisiteModulesFor(PathRef File, } ReusableModulesBuilder::ModuleBuildingSharedOwner -ReusableModulesBuilder::getOrCreateModuleBuildingOwner( -StringRef ModuleName) { +ReusableModulesBuilder::getOrCreateModuleBuildingOwner(StringRef ModuleName) { std::lock_guard _(ModulesBuildingMutex); auto MutexIter = BuildingModuleMutexes.find(ModuleName); @@ -496,13 +496,14 @@ llvm::Error ReusableModulesBuilder::getOrBuildModuleFile( /// third party modules, we should return true instead of false here. /// Currently we simply bail out. if (ModuleUnitFileName.empty()) -return llvm::createStringError(llvm::formatv("Don't get the module unit for module {0}", ModuleName)); +return llvm::createStringError( +llvm::formatv("Don't get the module unit for module {0}", ModuleName)); for (auto &RequiredModuleName : MDB.getRequiredModules(ModuleUnitFileName)) // Return ea
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/106683 >From facbe53b41f90d2b7c94d83aaaec03f83f355735 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Fri, 30 Aug 2024 15:11:07 +0800 Subject: [PATCH] [clangd] [Modules] Support Reusable Modules Builder --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 4 +- clang-tools-extra/clangd/ClangdLSPServer.h| 2 +- clang-tools-extra/clangd/ModulesBuilder.cpp | 364 ++ clang-tools-extra/clangd/ModulesBuilder.h | 11 +- clang-tools-extra/clangd/tool/Check.cpp | 6 +- .../unittests/PrerequisiteModulesTest.cpp | 70 +++- 6 files changed, 367 insertions(+), 90 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 06573a57554245..53a18bd4ecd1a7 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -567,8 +567,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, std::move(Mangler)); if (Opts.EnableExperimentalModulesSupport) { -ModulesManager.emplace(*CDB); -Opts.ModulesManager = &*ModulesManager; +ModulesManager = ModulesBuilder::getModulesBuilder(*CDB); +Opts.ModulesManager = ModulesManager.get(); } { diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 0b8e4720f53236..4b8f048b430fe9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -327,7 +327,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks, // The ClangdServer is created by the "initialize" LSP method. std::optional Server; // Manages to build module files. - std::optional ModulesManager; + std::unique_ptr ModulesManager; }; } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 1eeff468ef1236..a674e68ca7809d 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -12,6 +12,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Serialization/ASTReader.h" +#include "llvm/ADT/ScopeExit.h" namespace clang { namespace clangd { @@ -173,33 +174,27 @@ bool IsModuleFilesUpToDate( }); } -// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all +// ReusablePrerequisiteModules - stands for PrerequisiteModules for which all // the required modules are built successfully. All the module files -// are owned by the StandalonePrerequisiteModules class. -// -// Any of the built module files won't be shared with other instances of the -// class. So that we can avoid worrying thread safety. -// -// We don't need to worry about duplicated module names here since the standard -// guarantees the module names should be unique to a program. -class StandalonePrerequisiteModules : public PrerequisiteModules { +// are owned by the modules builder. +class ReusablePrerequisiteModules : public PrerequisiteModules { public: - StandalonePrerequisiteModules() = default; + ReusablePrerequisiteModules() = default; - StandalonePrerequisiteModules(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules - operator=(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules(StandalonePrerequisiteModules &&) = delete; - StandalonePrerequisiteModules - operator=(StandalonePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules + operator=(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules(ReusablePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules + operator=(ReusablePrerequisiteModules &&) = delete; - ~StandalonePrerequisiteModules() override = default; + ~ReusablePrerequisiteModules() override = default; void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override { // Appending all built module files. for (auto &RequiredModule : RequiredModules) Options.PrebuiltModuleFiles.insert_or_assign( - RequiredModule.ModuleName, RequiredModule.ModuleFilePath); + RequiredModule->ModuleName, RequiredModule->ModuleFilePath); } bool canReuse(const CompilerInvocation &CI, @@ -209,54 +204,30 @@ class StandalonePrerequisiteModules : public PrerequisiteModules { return BuiltModuleNames.contains(ModuleName); } - void addModuleFile(llvm::StringRef ModuleName, - llvm::StringRef ModuleFilePath) { -RequiredModules.emplace_back(ModuleName, ModuleFilePath); -BuiltModuleNames.insert(ModuleName); + void addModuleFile(std::shared_ptr BMI) { +BuiltModuleNames.insert(BMI->ModuleName); +RequiredModules.emplace_back(std::move(BMI)); } pr
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/106681 >From 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH 1/2] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 -- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def| 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +-- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s
[clang] [clang] Don't add DWARF debug info when assembling .s with clang-cl /Z7 (PR #106686)
https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/106686 This fixes a regression from f58330cbe44598eb2de0cca3b812f67fea0a71ca. That commit changed the clang-cl options /Zi and /Z7 to be implemented as aliases of -g rather than having separate handling. This had the unintended effect, that when assembling .s files with clang-cl, the /Z7 option (which implies using CodeView debug info) was treated as a -g option, which causes `ClangAs::ConstructJob` to pick up the option as part of `Args.getLastArg(options::OPT_g_Group)`, which sets the `WantDebug` variable. Within `Clang::ConstructJob`, we check for whether explicit `-gdwarf` or `-gcodeview` options have been set, and if not, we pick the default debug format for the current toolchain. However, in `ClangAs`, if debug info has been enabled, it always adds DWARF debug info. Add similar logic in `ClangAs` - check if the user has explicitly requested either DWARF or CodeView, otherwise look up the toolchain default. If we (either implicitly or explicitly) should be producing CodeView, don't enable the default `ClangAs` DWARF generation. This fixes the issue, where assembling a single `.s` file with clang-cl, with the /Z7 option, causes the file to contain some DWARF sections. This causes the output executable to contain DWARF, in addition to the separate intended main PDB file. By having the output executable contain DWARF sections, LLDB only looks at the (very little) DWARF info in the executable, rather than looking for a separate standalone PDB file. This caused an issue with LLDB's tests, https://github.com/llvm/llvm-project/issues/101710. From ac59e23201dea846b7a2750abeae54b07d81a078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 29 Aug 2024 00:09:28 +0300 Subject: [PATCH] [clang] Don't add DWARF debug info when assembling .s with clang-cl /Z7 This fixes a regression from f58330cbe44598eb2de0cca3b812f67fea0a71ca. That commit changed the clang-cl options /Zi and /Z7 to be implemented as aliases of -g rather than having separate handling. This had the unintended effect, that when assembling .s files with clang-cl, the /Z7 option (which implies using CodeView debug info) was treated as a -g option, which causes `ClangAs::ConstructJob` to pick up the option as part of `Args.getLastArg(options::OPT_g_Group)`, which sets the `WantDebug` variable. Within `Clang::ConstructJob`, we check for whether explicit `-gdwarf` or `-gcodeview` options have been set, and if not, we pick the default debug format for the current toolchain. However, in `ClangAs`, if debug info has been enabled, it always adds DWARF debug info. Add similar logic in `ClangAs` - check if the user has explicitly requested either DWARF or CodeView, otherwise look up the toolchain default. If we (either implicitly or explicitly) should be producing CodeView, don't enable the default `ClangAs` DWARF generation. This fixes the issue, where assembling a single `.s` file with clang-cl, with the /Z7 option, causes the file to contain some DWARF sections. This causes the output executable to contain DWARF, in addition to the separate intended main PDB file. By having the output executable contain DWARF sections, LLDB only looks at the (very little) DWARF info in the executable, rather than looking for a separate standalone PDB file. This caused an issue with LLDB's tests, https://github.com/llvm/llvm-project/issues/101710. --- clang/lib/Driver/ToolChains/Clang.cpp | 26 ++ clang/test/Driver/debug-options-as.c | 17 - 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df86941950e46e..baac1215215b91 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8641,6 +8641,32 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, WantDebug = !A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_ggdb0); + // If a -gdwarf argument appeared, remember it. + bool EmitDwarf = false; + if (const Arg *A = getDwarfNArg(Args)) +EmitDwarf = checkDebugInfoOption(A, Args, D, getToolChain()); + + bool EmitCodeView = false; + if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) +EmitCodeView = checkDebugInfoOption(A, Args, D, getToolChain()); + + // If the user asked for debug info but did not explicitly specify -gcodeview + // or -gdwarf, ask the toolchain for the default format. + if (!EmitCodeView && !EmitDwarf && WantDebug) { +switch (getToolChain().getDefaultDebugFormat()) { +case llvm::codegenoptions::DIF_CodeView: + EmitCodeView = true; + break; +case llvm::codegenoptions::DIF_DWARF: + EmitDwarf = true; + break; +} + } + + // If the arguments don't imply DWARF, don't emit any debug info here. + if (!EmitDwarf) +WantDebug = fal
[clang] [clang] Don't add DWARF debug info when assembling .s with clang-cl /Z7 (PR #106686)
llvmbot wrote: @llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Martin Storsjö (mstorsjo) Changes This fixes a regression from f58330cbe44598eb2de0cca3b812f67fea0a71ca. That commit changed the clang-cl options /Zi and /Z7 to be implemented as aliases of -g rather than having separate handling. This had the unintended effect, that when assembling .s files with clang-cl, the /Z7 option (which implies using CodeView debug info) was treated as a -g option, which causes `ClangAs::ConstructJob` to pick up the option as part of `Args.getLastArg(options::OPT_g_Group)`, which sets the `WantDebug` variable. Within `Clang::ConstructJob`, we check for whether explicit `-gdwarf` or `-gcodeview` options have been set, and if not, we pick the default debug format for the current toolchain. However, in `ClangAs`, if debug info has been enabled, it always adds DWARF debug info. Add similar logic in `ClangAs` - check if the user has explicitly requested either DWARF or CodeView, otherwise look up the toolchain default. If we (either implicitly or explicitly) should be producing CodeView, don't enable the default `ClangAs` DWARF generation. This fixes the issue, where assembling a single `.s` file with clang-cl, with the /Z7 option, causes the file to contain some DWARF sections. This causes the output executable to contain DWARF, in addition to the separate intended main PDB file. By having the output executable contain DWARF sections, LLDB only looks at the (very little) DWARF info in the executable, rather than looking for a separate standalone PDB file. This caused an issue with LLDB's tests, https://github.com/llvm/llvm-project/issues/101710. --- Full diff: https://github.com/llvm/llvm-project/pull/106686.diff 2 Files Affected: - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+26) - (modified) clang/test/Driver/debug-options-as.c (+16-1) ``diff diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index df86941950e46e..baac1215215b91 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8641,6 +8641,32 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, WantDebug = !A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_ggdb0); + // If a -gdwarf argument appeared, remember it. + bool EmitDwarf = false; + if (const Arg *A = getDwarfNArg(Args)) +EmitDwarf = checkDebugInfoOption(A, Args, D, getToolChain()); + + bool EmitCodeView = false; + if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) +EmitCodeView = checkDebugInfoOption(A, Args, D, getToolChain()); + + // If the user asked for debug info but did not explicitly specify -gcodeview + // or -gdwarf, ask the toolchain for the default format. + if (!EmitCodeView && !EmitDwarf && WantDebug) { +switch (getToolChain().getDefaultDebugFormat()) { +case llvm::codegenoptions::DIF_CodeView: + EmitCodeView = true; + break; +case llvm::codegenoptions::DIF_DWARF: + EmitDwarf = true; + break; +} + } + + // If the arguments don't imply DWARF, don't emit any debug info here. + if (!EmitDwarf) +WantDebug = false; + llvm::codegenoptions::DebugInfoKind DebugInfoKind = llvm::codegenoptions::NoDebugInfo; diff --git a/clang/test/Driver/debug-options-as.c b/clang/test/Driver/debug-options-as.c index c83c0cb90431d3..3e1ae109711003 100644 --- a/clang/test/Driver/debug-options-as.c +++ b/clang/test/Driver/debug-options-as.c @@ -19,12 +19,27 @@ // GGDB0-NOT: -debug-info-kind= // Check to make sure clang with -g on a .s file gets passed. -// RUN: %clang -### -c -integrated-as -g -x assembler %s 2>&1 \ +// This requires a target that defaults to DWARF. +// RUN: %clang -### --target=x86_64-linux-gnu -c -integrated-as -g -x assembler %s 2>&1 \ // RUN: | FileCheck %s // // CHECK: "-cc1as" // CHECK: "-debug-info-kind=constructor" +// Check that a plain -g, without any -gdwarf, for a MSVC target, doesn't +// trigger producing DWARF output. +// RUN: %clang -### --target=x86_64-windows-msvc -c -integrated-as -g -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MSVC %s +// +// MSVC: "-cc1as" +// MSVC-NOT: "-debug-info-kind=constructor" + +// Check that clang-cl with the -Z7 option works the same, not triggering +// any DWARF output. +// +// RUN: %clang_cl -### -c -Z7 -x assembler %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MSVC %s + // Check to make sure clang with -g on a .s file gets passed -dwarf-debug-producer. // RUN: %clang -### -c -integrated-as -g -x assembler %s 2>&1 \ // RUN: | FileCheck -check-prefix=P %s `` https://github.com/llvm/llvm-project/pull/106686 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0722b8a - [Clang][NFC] Consolidate tests for default argument substitution (#105617)
Author: Younan Zhang Date: 2024-08-30T16:29:18+08:00 New Revision: 0722b8ab8168d9e1aa3413a62c65878f407225ae URL: https://github.com/llvm/llvm-project/commit/0722b8ab8168d9e1aa3413a62c65878f407225ae DIFF: https://github.com/llvm/llvm-project/commit/0722b8ab8168d9e1aa3413a62c65878f407225ae.diff LOG: [Clang][NFC] Consolidate tests for default argument substitution (#105617) Follow-up on 8ac140f39. The test `SemaTemplate/default-parm-init.cpp` was introduced since the fix #80288 and mainly did the following things: - Ensure the default arguments are properly substituted inside either the primary template & their explicit / out-of-line specializations. - Ensure the strategy doesn't mess up the substitution of a lambda expression as a default argument. The 1st is for the bug of #68490, yet it does some redundant work: each of the member functions is duplicated twice for the `sizeof` and `alignof` operators, respectively, and the principle under the hood are essentially the same. So this patch removes the duplication and reduces the 8 functions to 4 functions that reveal the same thing. The 2nd is presumably testing that the fix in #80288 doesn't impact a complicated substitution. However, that seems unnecessary & unrelated to the original issue. And more importantly, we don't have any problems with that ever. Hence, I'll remove that test from this patch. The test for default arguments is merged into `SemaTemplate/default-arguments.cpp` with a new namespace, and hopefully this could reduce the entropy of our testing cases. Added: Modified: clang/test/SemaTemplate/default-arguments.cpp Removed: clang/test/SemaTemplate/default-parm-init.cpp diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index d5d9687cc90f49..3b1fbda414c12b 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -229,3 +229,55 @@ namespace unevaluated { template int f(int = a); // expected-warning 0-1{{extension}} int k = sizeof(f()); } + +#if __cplusplus >= 201103L +namespace GH68490 { + +template struct S { + template + constexpr int SizeOfU(int param = sizeof(U)) const; + + template + constexpr int SizeOfT(int param = sizeof(T)) const; +}; + +template struct S { + template + constexpr int SizeOfU(int param = sizeof(U)) const; + + template + constexpr int SizeOfT(int param = sizeof(T *)) const; +}; + +template +template +constexpr int S::SizeOfU(int param) const { + return param; +} + +template +template +constexpr int S::SizeOfT(int param) const { + return param; +} + +template <> +template +constexpr int S::SizeOfU(int param) const { + return param; +} + +template <> +template +constexpr int S::SizeOfT(int param) const { + return param; +} + +static_assert(S().SizeOfU() == sizeof(char), ""); +static_assert(S().SizeOfT() == sizeof(int), ""); +static_assert(S().SizeOfU() == sizeof(char), ""); +static_assert(S().SizeOfT() == sizeof(short *), ""); + +} // namespace GH68490 + +#endif diff --git a/clang/test/SemaTemplate/default-parm-init.cpp b/clang/test/SemaTemplate/default-parm-init.cpp deleted file mode 100644 index 73ba8998df6a98..00 --- a/clang/test/SemaTemplate/default-parm-init.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -// expected-no-diagnostics - -namespace std { - -template class function; - -template class invoker_base { -public: - virtual ~invoker_base() { } - virtual R invoke(Args...) = 0; - virtual invoker_base* clone() = 0; -}; - -template -class functor_invoker : public invoker_base { -public: - explicit functor_invoker(const F& f) : f(f) { } - R invoke(Args... args) { return f(args...); } - functor_invoker* clone() { return new functor_invoker(f); } - -private: - F f; -}; - -template -class function { -public: - typedef R result_type; - function() : invoker (0) { } - function(const function& other) : invoker(0) { -if (other.invoker) - invoker = other.invoker->clone(); - } - - template function(const F& f) : invoker(0) { -invoker = new functor_invoker(f); - } - - ~function() { -if (invoker) - delete invoker; - } - - function& operator=(const function& other) { -function(other).swap(*this); -return *this; - } - - template - function& operator=(const F& f) { -function(f).swap(*this); -return *this; - } - - void swap(function& other) { -invoker_base* tmp = invoker; -invoker = other.invoker; -other.invoker = tmp; - } - - result_type operator()(Args... args) const { -return invoker->invoke(args...); - } - -private: - invoker_base* invoker; -}; - -} - -template -struct Problem { - template - constexpr int FuncAlign(int param = alignof(FunctionTemplateParam)); - -
[clang] [Clang][NFC] Consolidate tests for default argument substitution (PR #105617)
https://github.com/zyn0217 closed https://github.com/llvm/llvm-project/pull/105617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/106681 >From 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH 1/3] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 -- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def| 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +-- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s
[clang] [clang][ASTImporter] New fix for default template parameter values. (PR #101836)
https://github.com/balazske updated https://github.com/llvm/llvm-project/pull/101836 From 2e98fc222566c5e746ade4ccaba23de3b59e0a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= Date: Sat, 3 Aug 2024 18:10:34 +0200 Subject: [PATCH 1/3] [clang][ASTImporter] New fix for default template parameter values. Commit e4440b8 added a change that introduced new crash in an incorrectly handled case. This is fixed here. --- clang/lib/AST/ASTImporter.cpp | 12 ++- clang/unittests/AST/ASTImporterTest.cpp | 97 + 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 103235547f482e..7e4a92ccbe40f7 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5972,7 +5972,11 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); -ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); +// The import process can trigger import of the parent template which can +// set the default argument value (to "inherited"). +// In this case do nothing here. +if (!ToD->hasDefaultArgument()) + ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); } return ToD; @@ -6004,7 +6008,8 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); -ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); +if (!ToD->hasDefaultArgument()) + ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); } return ToD; @@ -6041,7 +6046,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); -ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); +if (!ToD->hasDefaultArgument()) + ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); } return ToD; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 57242ff49fe3b8..4c41171deec46a 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -9919,6 +9919,103 @@ TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingVarTemplate) { testImport(FromLastD); } +TEST_P(ImportTemplateParmDeclDefaultValue, + ImportParentTemplateDuringNonTypeTemplateParmDecl) { + // This wants to provoke that during import of 'Y' in "typename T = Y" + // (before this import returns) the later definition of 'X' is imported fully. + const char *Code = + R"( + struct Z; + + struct Y { +Z *z; +static const int x = 1; + }; + + template + struct X; + + template + struct X { +static const int A = 1; + }; + + struct Z { +template +void f(int A = X::A); + }; + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX14); + auto *FromD = FirstDeclMatcher().match( + FromTU, nonTypeTemplateParmDecl(hasName("P"))); + auto *ToD = Import(FromD, Lang_CXX14); + EXPECT_TRUE(ToD); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, + ImportParentTemplateDuringTemplateTypeParmDecl) { + const char *Code = + R"( + struct Z; + + struct Y { +Z *z; + }; + + template + struct X; + + template + struct X { +static const int A = 1; + }; + + struct Z { +template +void f(int A = X::A); + }; + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX14); + auto *FromD = FirstDeclMatcher().match( + FromTU, templateTypeParmDecl(hasName("T"))); + auto *ToD = Import(FromD, Lang_CXX14); + EXPECT_TRUE(ToD); +} + +TEST_P(ImportTemplateParmDeclDefaultValue, + ImportParentTemplateDuringTemplateTemplateParmDecl) { + const char *Code = + R"( + struct Z; + + template + struct Y { +Z *z; + }; + + template class T = Y> + struct X; + + template class T> + struct X { +static const int A = 1; + }; + + struct Z { +template class T> +void f(int A = X::A); + }; + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX14); + auto *FromD = FirstDeclMatcher().match( + FromTU, templateTemplateParmDecl(hasName("T"))); + auto *ToD = Import(FromD, Lang_CXX14); + EXPECT_TRUE(ToD); +} + INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions); From 70ef4f2579bbb91f7babdf62feef0e5c9173fa31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= Date: Fri, 16 Aug 2024 09:58:49 +0200 Su
[clang] [clang-format] Correctly annotate braces in ObjC square brackets (PR #106654)
@@ -3286,6 +3286,14 @@ TEST_F(TokenAnnotatorTest, BlockLBrace) { EXPECT_BRACE_KIND(Tokens[4], BK_Block); EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_BlockLBrace); EXPECT_BRACE_KIND(Tokens[5], BK_Block); + + Tokens = annotate("[foo bar:{{0, 1}}];", getLLVMStyle(FormatStyle::LK_ObjC)); kadircet wrote: i believe this case was already WAI (somehow), can you add another selector after `}}`. e.g: `[foo bar:{{0, 1}} baz: baz];` https://github.com/llvm/llvm-project/pull/106654 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
@@ -750,8 +750,33 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; - - ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); + ExprResult DIE; + { +// Enter a lifetime extension context, then we can support lifetime +// extension of temporary created by aggregate initialization using a +// default member initializer (DR1815 https://wg21.link/CWG1815). +// +// In a lifetime extension context, BuildCXXDefaultInitExpr will clone +// the initializer expression on each use and the temporaries which +// actually bound to a reference member should be extended here. +// +// FIXME: In default member initializer, lifetime extension context will +// collect the MaterializedTemporaryExprs which bound to a reference cor3ntin wrote: ```suggestion // collect the MaterializedTemporaryExprs which are bound to a reference ``` https://github.com/llvm/llvm-project/pull/97308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
@@ -750,8 +750,33 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; - - ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); + ExprResult DIE; + { +// Enter a lifetime extension context, then we can support lifetime +// extension of temporary created by aggregate initialization using a +// default member initializer (DR1815 https://wg21.link/CWG1815). cor3ntin wrote: ```suggestion // default member initializer (CWG1815 https://wg21.link/CWG1815). ``` https://github.com/llvm/llvm-project/pull/97308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
@@ -750,8 +750,33 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; - - ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); + ExprResult DIE; + { +// Enter a lifetime extension context, then we can support lifetime +// extension of temporary created by aggregate initialization using a +// default member initializer (DR1815 https://wg21.link/CWG1815). +// +// In a lifetime extension context, BuildCXXDefaultInitExpr will clone +// the initializer expression on each use and the temporaries which +// actually bound to a reference member should be extended here. +// +// FIXME: In default member initializer, lifetime extension context will +// collect the MaterializedTemporaryExprs which bound to a reference cor3ntin wrote: Maybe we can check whether the evaluation context is PotentiallyEvaluatedIfUsed and skip the check in that case? (or add yet am other flag in EvaluationContextRecord) https://github.com/llvm/llvm-project/pull/97308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
@@ -750,8 +750,33 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; - - ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); + ExprResult DIE; + { +// Enter a lifetime extension context, then we can support lifetime +// extension of temporary created by aggregate initialization using a +// default member initializer (DR1815 https://wg21.link/CWG1815). +// +// In a lifetime extension context, BuildCXXDefaultInitExpr will clone +// the initializer expression on each use and the temporaries which +// actually bound to a reference member should be extended here. cor3ntin wrote: ```suggestion // binds to a reference member should be extended here. ``` https://github.com/llvm/llvm-project/pull/97308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #97308)
@@ -750,8 +750,33 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; - - ExprResult DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field); + ExprResult DIE; + { +// Enter a lifetime extension context, then we can support lifetime +// extension of temporary created by aggregate initialization using a +// default member initializer (DR1815 https://wg21.link/CWG1815). +// +// In a lifetime extension context, BuildCXXDefaultInitExpr will clone +// the initializer expression on each use and the temporaries which cor3ntin wrote: ```suggestion // the initializer expression for each use and the temporaries which ``` https://github.com/llvm/llvm-project/pull/97308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Cleanup IncludeLocMap (PR #106241)
https://github.com/ilya-biryukov edited https://github.com/llvm/llvm-project/pull/106241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Cleanup IncludeLocMap (PR #106241)
https://github.com/ilya-biryukov approved this pull request. LGMT with a small suggestion. Thanks for getting the test in! https://github.com/llvm/llvm-project/pull/106241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Cleanup IncludeLocMap (PR #106241)
@@ -453,6 +454,61 @@ TEST_F(SourceManagerTest, loadedSLocEntryIsInTheSameTranslationUnit) { #if defined(LLVM_ON_UNIX) +TEST_F(SourceManagerTest, ResetsIncludeLocMap) { ilya-biryukov wrote: Suggestion: add a comment explaining what this aims to test at a more detailed level. Something like: ```cpp // Check we clear include loc caches when resetting the source manager. ``` https://github.com/llvm/llvm-project/pull/106241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/106681 >From 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH 1/4] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 -- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def| 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +-- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert edited https://github.com/llvm/llvm-project/pull/106681 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ASTImporter] New fix for default template parameter values. (PR #101836)
@@ -5968,11 +5962,21 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } if (D->hasDefaultArgument()) { +// Default argument can be "inherited" when it has a reference to the +// previous declaration (of the default argument) which is stored only once. +// Here we import the default argument in any case, and the inherited state +// is updated later after the parent template was created. If the +// inherited-from object would be imported here it causes more difficulties +// (parent template may not be created yet and import loops can occur). Expected ToDefaultArgOrErr = import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); -ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); +// The just called import process can trigger import of the parent template +// which can update the default argument value to "inherited". This should +// not be changed. +if (!ToD->hasDefaultArgument()) + ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); balazske wrote: I made a new fix where the original inheritance order does not change. There are new problems with this solution but probably it is acceptable. If there is an existing declaration `template struct X;` and the same code is imported, the declaration is duplicated because it is not a definition (this is how `ASTImporter` generally works). In this case the default value `I = 3` is imported too. The AST is already invalid after this import (default value can be specified only once). With a fix like the previous solution this problem does not exist. Another problem is with existing code ``` template struct X {}; ``` and imported code ``` template struct X {}; template struct X; ``` The second declaration is imported with inherited default argument but the first is not imported, only mapped to the existing one. The "inherited from" value in the second declaration (in the To AST) is not linked to the original one, a new object is created instead that is "invisible" from the AST (only reachable with the `getInheritedFrom` call). https://github.com/llvm/llvm-project/pull/101836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] [MallocChecker] suspect all release functions as candite for supression (PR #104599)
@@ -3648,35 +3648,38 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, return nullptr; } - // See if we're releasing memory while inlining a destructor - // (or one of its callees). This turns on various common - // false positive suppressions. - bool FoundAnyDestructor = false; - for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { -if (const auto *DD = dyn_cast(LC->getDecl())) { - if (isReferenceCountingPointerDestructor(DD)) { -// This immediately looks like a reference-counting destructor. -// We're bad at guessing the original reference count of the object, -// so suppress the report for now. -BR.markInvalid(getTag(), DD); - } else if (!FoundAnyDestructor) { -assert(!ReleaseDestructorLC && +// See if we're releasing memory while inlining a destructor or +// functions that decrement reference counters (or one of its callees). +// This turns on various common false positive suppressions. +bool FoundAnyReleaseFunction = false; +for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { + if (const auto *DD = dyn_cast(LC->getDecl())) { +if (isReferenceCountingPointerDestructor(DD)) { + // This immediately looks like a reference-counting destructor. + // We're bad at guessing the original reference count of the + // object, so suppress the report for now. + BR.markInvalid(getTag(), DD); + continue; +} + } + + if (!FoundAnyReleaseFunction) { pskrgag wrote: Trying to reproduce the behavior you mention, but I cannot. So I wrote following test: ```cpp // Also IntrusivePtr but release is happening out-of-line in desctructor template class IntrusivePtrOutlineRelease { T *Ptr; public: IntrusivePtrOutlineRelease(T *Ptr) : Ptr(Ptr) { Ptr->incRef(); } IntrusivePtrOutlineRelease(const IntrusivePtrOutlineRelease &Other) : Ptr(Other.Ptr) { Ptr->incRef(); } void releasePtr(void) { delete Ptr; } ~IntrusivePtrOutlineRelease() { // We should not take the path on which the object is deleted. if (Ptr->decRef() == 1) releasePtr(); } T *getPtr() const { return Ptr; } // no-warning }; void testDestroyLocalRefPtrWithOutlineRelease() { IntrusivePtrOutlineRelease p1(new RawObj()); { IntrusivePtrOutlineRelease p2(p1); } // p1 still maintains ownership. The object is not deleted. p1.getPtr()->foo(); // no-warning } ``` And there is no warning. Did I get it wrong? https://github.com/llvm/llvm-project/pull/104599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] [MallocChecker] suspect all release functions as candite for supression (PR #104599)
https://github.com/pskrgag edited https://github.com/llvm/llvm-project/pull/104599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
KanRobert wrote: TODO: * [ ] Pass tests lld/test/ELF/x86-64-gotpc-relax.s and lld/test/ELF/x86-64-gotpc-relax-nopic.s https://github.com/llvm/llvm-project/pull/106681 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Correctly annotate braces in ObjC square brackets (PR #106654)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/106654 >From b71f4cf3ae2844583171cd0cc75826b8911a7b2b Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Thu, 29 Aug 2024 19:27:32 -0700 Subject: [PATCH 1/2] [clang-format] Correctly annotate braces in ObjC square brackets See https://github.com/llvm/llvm-project/pull/88238#issuecomment-2316954781. --- clang/lib/Format/UnwrappedLineParser.cpp | 1 + clang/unittests/Format/TokenAnnotatorTest.cpp | 8 2 files changed, 9 insertions(+) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 5b518bf6c859e8..246b29d308bfaf 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2682,6 +2682,7 @@ void UnwrappedLineParser::parseSquare(bool LambdaIntroducer) { break; } case tok::at: +case tok::colon: nextToken(); if (FormatTok->is(tok::l_brace)) { nextToken(); diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 5aa5d93c1cb067..aa6244f9365976 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -3286,6 +3286,14 @@ TEST_F(TokenAnnotatorTest, BlockLBrace) { EXPECT_BRACE_KIND(Tokens[4], BK_Block); EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_BlockLBrace); EXPECT_BRACE_KIND(Tokens[5], BK_Block); + + Tokens = annotate("[foo bar:{{0, 1}}];", getLLVMStyle(FormatStyle::LK_ObjC)); + ASSERT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown); // Not TT_BlockLBrace. + EXPECT_BRACE_KIND(Tokens[4], BK_Unknown); // Not BK_Block. + EXPECT_BRACE_KIND(Tokens[5], BK_BracedInit); + EXPECT_BRACE_KIND(Tokens[9], BK_Unknown); // Not BK_Block. + EXPECT_BRACE_KIND(Tokens[10], BK_Unknown); // Not BK_Block. } TEST_F(TokenAnnotatorTest, SwitchExpression) { >From 73ebdda063c030f932b46244b7c2572b55a6d814 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Fri, 30 Aug 2024 02:27:03 -0700 Subject: [PATCH 2/2] Update unit test --- clang/unittests/Format/TokenAnnotatorTest.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index aa6244f9365976..497b911f4efbba 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -3287,8 +3287,9 @@ TEST_F(TokenAnnotatorTest, BlockLBrace) { EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_BlockLBrace); EXPECT_BRACE_KIND(Tokens[5], BK_Block); - Tokens = annotate("[foo bar:{{0, 1}}];", getLLVMStyle(FormatStyle::LK_ObjC)); - ASSERT_EQ(Tokens.size(), 14u) << Tokens; + Tokens = annotate("[foo bar:{{0, 1}} baz:baz];", +getLLVMStyle(FormatStyle::LK_ObjC)); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown); // Not TT_BlockLBrace. EXPECT_BRACE_KIND(Tokens[4], BK_Unknown); // Not BK_Block. EXPECT_BRACE_KIND(Tokens[5], BK_BracedInit); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b294951 - [clang][bytecode] Fix the handling of address of a vector (#106558)
Author: yronglin Date: 2024-08-30T17:34:00+08:00 New Revision: b294951e3967730ffad14d51297694b1411d7af6 URL: https://github.com/llvm/llvm-project/commit/b294951e3967730ffad14d51297694b1411d7af6 DIFF: https://github.com/llvm/llvm-project/commit/b294951e3967730ffad14d51297694b1411d7af6.diff LOG: [clang][bytecode] Fix the handling of address of a vector (#106558) The PR https://github.com/llvm/llvm-project/pull/105996 broke taking the address of a vector: **compound-literal.c** ```C typedef int v4i32 __attribute((vector_size(16))); v4i32 *y = &(v4i32){1,2,3,4}; ``` That because the current interpreter handle vector unary operator as a fallback when the generic code path fail. but the new interpreter was not. we need to handle `UO_AddrOf` in `Compiler::VisitVectorUnaryOperator`. Signed-off-by: yronglin Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/test/CodeGen/compound-literal.c Removed: diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6a77323d939791..9bd77edb0a550f 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -5324,11 +5324,11 @@ bool Compiler::VisitVectorUnaryOperator(const UnaryOperator *E) { auto UnaryOp = E->getOpcode(); if (UnaryOp != UO_Plus && UnaryOp != UO_Minus && UnaryOp != UO_LNot && - UnaryOp != UO_Not) + UnaryOp != UO_Not && UnaryOp != UO_AddrOf) return this->emitInvalid(E); // Nothing to do here. - if (UnaryOp == UO_Plus) + if (UnaryOp == UO_Plus || UnaryOp == UO_AddrOf) return this->delegate(SubExpr); if (!Initializing) { diff --git a/clang/test/CodeGen/compound-literal.c b/clang/test/CodeGen/compound-literal.c index 5b3cebb7c6ae6a..5fe9594c0f954f 100644 --- a/clang/test/CodeGen/compound-literal.c +++ b/clang/test/CodeGen/compound-literal.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fexperimental-new-constant-interpreter -emit-llvm %s -o - | FileCheck %s // Capture the type and name so matching later is cleaner. struct CompoundTy { int a; }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][bytecode] Fix the handling of address of a vector (PR #106558)
https://github.com/yronglin closed https://github.com/llvm/llvm-project/pull/106558 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)
https://github.com/ilya-biryukov edited https://github.com/llvm/llvm-project/pull/102040 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)
https://github.com/ilya-biryukov commented: I hope folks are ok with me chiming in as a reviewer for this. I've left quite a few comments in the RFC and is also supportive of landing this change and happy to invest into supporting it going forward inside our team. https://github.com/llvm/llvm-project/pull/102040 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)
@@ -1472,3 +1472,25 @@ template struct Outer { }; }; Outer::Inner outerinner; + +void aggregate() { + struct B { +[[clang::explicit_init]] int f1; + }; + + struct S : B { // expected-warning {{uninitialized}} +int f2; +int f3 [[clang::explicit_init]]; + }; + +#if __cplusplus >= 202002L + S a({}, 0); // expected-warning {{'f1' is left uninitialized}} expected-warning {{'f3' is left uninitialized}} +#endif + S b{.f3 = 1}; // expected-warning {{'f1' is left uninitialized}} + S c{.f2 = 5}; // expected-warning {{'f1' is left uninitialized}} expected-warning {{'f3' is left uninitialized}} expected-warning {{'f3' is left uninitialized}} + c = {{}, 0}; // expected-warning {{'f1' is left uninitialized}} expected-warning {{'f3' is left uninitialized}} + S d; // expected-warning {{uninitialized}} expected-note {{constructor}} ilya-biryukov wrote: This is the only example that I'm torn on because it prohibits writing the very common code: ``` S d; d.f1 = 123; d.f3 = 234; // There's nothing wrong with this multi-line initialization style ^^^ ``` While I'm fully on board with the idea that this warning is helpful in cases where aggregate initialization is used, I think I would not restrict the code to use **only** the aggregate initialization. Especially in C++17 and below, where there is no way to spell the names of the fields in aggregate init syntax. WDYT about leaving this out? It would also allow us to get rid of the flag we need to store in the class altogether. Or would this make the warning less useful, to an extent where you don't want to have it? https://github.com/llvm/llvm-project/pull/102040 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)
@@ -1419,6 +1419,28 @@ is not specified. }]; } +def ExplicitInitDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``clang::explicit_init`` attribute indicates that the field must be +initialized explicitly by the caller when the class is constructed. ilya-biryukov wrote: Maybe document that the caveats here? I could see us exploring the extension of this analysis to make sure the "explicit_init" fields are all written before they're read, but that's not what's happening today IIUC. Another caveat, is that the attribute is ignored on non-aggregate classes. ```cpp struct NonAgg { NonAgg() {} int x [[clang::explicit_init]]; // attribute ignored. } ``` And maybe also mention that these warnings do not aim to comprehensively prevent uses of uninitialized memory, but are, rather, supporting tools for aiding to write code in certain code style if people choose to (e.g. using it for parameter objects in combination with C++20 designated initializer). https://github.com/llvm/llvm-project/pull/102040 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adding optin.taint.TaintedDiv checker (PR #106389)
steakhal wrote: I had a look, and I don't think I have more to add to the existing review. https://github.com/llvm/llvm-project/pull/106389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adding optin.taint.TaintedDiv checker (PR #106389)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/106389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adding optin.taint.TaintedDiv checker (PR #106389)
@@ -1053,6 +1053,34 @@ by explicitly marking the ``size`` parameter as sanitized. See the delete[] ptr; } +.. _optin-taint-TaintedDiv: + +optin.taint.TaintedDiv (C, C++, ObjC) +" +This checker warns when the denominator in a division +operation is a tainted (potentially attacker controlled) value. +If the attacker can set the denominator to 0, a runtime error can +be triggered. The checker warns if the analyzer cannot prove +that the denominator is not 0 and it is a tainted value. +This warning is more pessimistic than the :ref:`core-DivideZero` checker +which warns only when it can prove that the denominator is 0. + +.. code-block:: c + + int vulnerable(int n) { +size_t size = 0; +scanf("%zu", &size); +return n/size; // warn: Division by a tainted value, possibly zero + } + + int not_vulnerable(void) { steakhal wrote: ```suggestion int not_vulnerable(int n) { ``` https://github.com/llvm/llvm-project/pull/106389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adding optin.taint.TaintedDiv checker (PR #106389)
@@ -223,6 +223,11 @@ class CheckerManager { return static_cast(CheckerTags[tag]); } + template bool isRegisteredChecker() { +CheckerTag tag = getTag(); +return (CheckerTags.count(tag) != 0); + } steakhal wrote: ```suggestion template bool isRegisteredChecker() { return CheckerTags.contains(getTag()); } ``` https://github.com/llvm/llvm-project/pull/106389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Adding optin.taint.TaintedDiv checker (PR #106389)
https://github.com/steakhal commented: Ah it didn't publish my inline comments. Here they are. https://github.com/llvm/llvm-project/pull/106389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] fix kcfi doesn't take effect when callee function has no input parameter (PR #106677)
https://github.com/Zhenhang1213 updated https://github.com/llvm/llvm-project/pull/106677 >From ed682daff12596b12d03e5d0342d0514e29e9896 Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 30 Aug 2024 15:21:12 +0800 Subject: [PATCH] fix kcfi doesn't take effect when callee function has no input parameter --- clang/lib/CodeGen/CodeGenFunction.cpp | 5 ++ llvm/test/CodeGen/ARM/vmov.ll | 92 +-- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index c89eaa0f4e3bfc..4d3fb780243022 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2813,6 +2813,11 @@ void CodeGenFunction::EmitKCFIOperandBundle( Callee.getAbstractInfo().getCalleeFunctionProtoType(); if (FP) Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar())); + else { +ASTContext &context = this->getContext(); +QualType voidType = context.VoidTy; +Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(voidType)); + } } llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( diff --git a/llvm/test/CodeGen/ARM/vmov.ll b/llvm/test/CodeGen/ARM/vmov.ll index 8835497669b324..86f90869fe7146 100644 --- a/llvm/test/CodeGen/ARM/vmov.ll +++ b/llvm/test/CodeGen/ARM/vmov.ll @@ -7,7 +7,7 @@ define arm_aapcs_vfpcc <8 x i8> @v_movi8() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i8 d0, #0x8 ; CHECK-NEXT:mov pc, lr - ret <8 x i8> < i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8 > +ret <8 x i8> < i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8 > } define arm_aapcs_vfpcc <4 x i16> @v_movi16a() nounwind { @@ -15,7 +15,7 @@ define arm_aapcs_vfpcc <4 x i16> @v_movi16a() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i16 d0, #0x10 ; CHECK-NEXT:mov pc, lr - ret <4 x i16> < i16 16, i16 16, i16 16, i16 16 > +ret <4 x i16> < i16 16, i16 16, i16 16, i16 16 > } define arm_aapcs_vfpcc <4 x i16> @v_movi16b() nounwind { @@ -23,7 +23,7 @@ define arm_aapcs_vfpcc <4 x i16> @v_movi16b() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i16 d0, #0x1000 ; CHECK-NEXT:mov pc, lr - ret <4 x i16> < i16 4096, i16 4096, i16 4096, i16 4096 > +ret <4 x i16> < i16 4096, i16 4096, i16 4096, i16 4096 > } define arm_aapcs_vfpcc <4 x i16> @v_mvni16a() nounwind { @@ -31,7 +31,7 @@ define arm_aapcs_vfpcc <4 x i16> @v_mvni16a() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmvn.i16 d0, #0x10 ; CHECK-NEXT:mov pc, lr - ret <4 x i16> < i16 65519, i16 65519, i16 65519, i16 65519 > +ret <4 x i16> < i16 65519, i16 65519, i16 65519, i16 65519 > } define arm_aapcs_vfpcc <4 x i16> @v_mvni16b() nounwind { @@ -39,7 +39,7 @@ define arm_aapcs_vfpcc <4 x i16> @v_mvni16b() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmvn.i16 d0, #0x1000 ; CHECK-NEXT:mov pc, lr - ret <4 x i16> < i16 61439, i16 61439, i16 61439, i16 61439 > +ret <4 x i16> < i16 61439, i16 61439, i16 61439, i16 61439 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32a() nounwind { @@ -47,7 +47,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32a() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x20 ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 32, i32 32 > +ret <2 x i32> < i32 32, i32 32 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32b() nounwind { @@ -55,7 +55,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32b() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x2000 ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 8192, i32 8192 > +ret <2 x i32> < i32 8192, i32 8192 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32c() nounwind { @@ -63,7 +63,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32c() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x20 ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 2097152, i32 2097152 > +ret <2 x i32> < i32 2097152, i32 2097152 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32d() nounwind { @@ -71,7 +71,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32d() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x2000 ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 536870912, i32 536870912 > +ret <2 x i32> < i32 536870912, i32 536870912 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32e() nounwind { @@ -79,7 +79,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32e() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x20ff ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 8447, i32 8447 > +ret <2 x i32> < i32 8447, i32 8447 > } define arm_aapcs_vfpcc <2 x i32> @v_movi32f() nounwind { @@ -87,7 +87,7 @@ define arm_aapcs_vfpcc <2 x i32> @v_movi32f() nounwind { ; CHECK: @ %bb.0: ; CHECK-NEXT:vmov.i32 d0, #0x20 ; CHECK-NEXT:mov pc, lr - ret <2 x i32> < i32 2162
[clang] fix kcfi doesn't take effect when callee function has no input parameter (PR #106677)
https://github.com/Zhenhang1213 updated https://github.com/llvm/llvm-project/pull/106677 >From 480be809832360293036b88b0fc46dad5838e88a Mon Sep 17 00:00:00 2001 From: Austin Date: Fri, 30 Aug 2024 15:21:12 +0800 Subject: [PATCH] fix kcfi doesn't take effect when callee function has no input parameter --- clang/lib/CodeGen/CodeGenFunction.cpp | 5 + 1 file changed, 5 insertions(+) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index c89eaa0f4e3bfc..4d3fb780243022 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2813,6 +2813,11 @@ void CodeGenFunction::EmitKCFIOperandBundle( Callee.getAbstractInfo().getCalleeFunctionProtoType(); if (FP) Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar())); + else { +ASTContext &context = this->getContext(); +QualType voidType = context.VoidTy; +Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(voidType)); + } } llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Refactor MallocChecker to use `BindExpr` in `evalCall` (PR #106081)
https://github.com/steakhal commented: I didn't really have time to look in depth into this. To me, a switch from eval-call to post-call should be NFC for the most part. It would be nice if we could separate out that NFC part in a PR, and then deal with the breaking changes in a limited PR. That would ease the reviewers job I think. https://github.com/llvm/llvm-project/pull/106081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Refactor MallocChecker to use `BindExpr` in `evalCall` (PR #106081)
pskrgag wrote: > To me, a switch from eval-call to post-call should be NFC for the most part. It is, but it causes `MallocChecker` to no longer look into body of the functions, because of `evalCall` semantics, which is breaking change. So I am not quite sure how to split this PR into two https://github.com/llvm/llvm-project/pull/106081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [X86, lld] Add relocation R_X86_64_REX2_GOTPCRELX (PR #106681)
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/106681 >From 8d8aea0d9d6b85a3b279a1c60b50cf9b859d6919 Mon Sep 17 00:00:00 2001 From: Shengchen Kan Date: Tue, 25 Jun 2024 20:33:10 +0800 Subject: [PATCH 1/5] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX For movname@GOTPCREL(%rip), %reg test %reg, name@GOTPCREL(%rip) binop name@GOTPCREL(%rip), %reg where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions, add R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43 if the instruction starts at 4 bytes before the relocation offset. It similar to R_X86_64_GOTPCRELX. Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX as R_X86_64_GOTPCREL or convert the above instructions to lea name(%rip), %reg mov $name, %reg test$name, %reg binop $name, %reg if the first byte of the instruction at the relocation `offset - 4` is `0xd5` (namely, encoded w/ REX2 prefix) when possible. Binutils patch: https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4 Binutils mailthread: https://sourceware.org/pipermail/binutils/2023-December/131462.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation --- clang/test/Driver/relax.s | 2 ++ lld/ELF/Arch/X86_64.cpp | 3 ++ lld/test/ELF/x86-64-gotpc-no-relax-err.s | 10 -- lld/test/ELF/x86-64-gotpc-relax.s | 2 +- .../llvm/BinaryFormat/ELFRelocs/x86_64.def| 1 + llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 4 +-- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 4 +++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 7 +++- .../Target/X86/MCTargetDesc/X86FixupKinds.h | 4 +++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 19 +-- .../X86/MCTargetDesc/X86MachObjectWriter.cpp | 6 +++- .../MCTargetDesc/X86WinCOFFObjectWriter.cpp | 2 ++ llvm/test/MC/ELF/relocation-alias.s | 3 ++ llvm/test/MC/X86/gotpcrelx.s | 34 +++ 14 files changed, 83 insertions(+), 18 deletions(-) diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s index 154d4db0a31385..b4a696a328eb56 100644 --- a/clang/test/Driver/relax.s +++ b/clang/test/Driver/relax.s @@ -8,5 +8,7 @@ // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s // REL: R_X86_64_REX_GOTPCRELX foo +// REL: R_X86_64_REX2_GOTPCRELX foo movq foo@GOTPCREL(%rip), %rax +movq foo@GOTPCREL(%rip), %r16 diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 65a81fe12f8709..ba5ce68e509199 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: @@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: case R_X86_64_PC32: case R_X86_64_GOTTPOFF: case R_X86_64_PLT32: @@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { break; case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: + case R_X86_64_REX2_GOTPCRELX: if (rel.expr != R_GOT_PC) { relaxGot(loc, rel, val); } else { diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s b/lld/test/ELF/x86-64-gotpc-no-relax-err.s index 618dca47755f41..4280c8fd1dc97e 100644 --- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s +++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s @@ -7,15 +7,19 @@ ## `>>> defined in` for linker synthesized __stop_* symbols (there is no ## associated file or linker script line number). -# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK: error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in # CHECK-EMPTY: -# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out of range: 2147483659 is not in [-2147483648, 2147483647]; references '__stop_data' +# CHECK-NEXT: >>> defined in +# CHECK-EMPTY: +# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX out of range: 2147483651 is not in [-2147483648, 2147483647]; references '__stop_data' # CHECK-NEXT: >>> defined in #--- a.s
[clang] [clang] Cleanup IncludeLocMap (PR #106241)
https://github.com/kadircet updated https://github.com/llvm/llvm-project/pull/106241 From c8c29eae625991ee1ea7dfbfcda4a31f0b19b2e3 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 27 Aug 2024 17:56:47 +0200 Subject: [PATCH] [clang] Cleanup IncludeLocMap CompilerInstance can re-use same SourceManager across multiple frontendactions. During this process it calls `SourceManager::clearIDTables` to reset any caches based on FileIDs. It didn't reset IncludeLocMap, resulting in wrong include locations for workflows that triggered multiple frontend-actions through same CompilerInstance. --- clang/lib/Basic/SourceManager.cpp | 1 + clang/unittests/Basic/SourceManagerTest.cpp | 60 + 2 files changed, 61 insertions(+) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index b0256a8ce9ed04..d6ec26af80aadd 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -350,6 +350,7 @@ void SourceManager::clearIDTables() { LastLineNoContentCache = nullptr; LastFileIDLookup = FileID(); + IncludedLocMap.clear(); if (LineTable) LineTable->clear(); diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index 45840f5188cdcd..0f2476bd8b0612 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -20,6 +20,7 @@ #include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Process.h" #include "gtest/gtest.h" #include @@ -453,6 +454,65 @@ TEST_F(SourceManagerTest, loadedSLocEntryIsInTheSameTranslationUnit) { #if defined(LLVM_ON_UNIX) +// A single SourceManager instance is sometimes reused across multiple +// compilations. This test makes sure we're resetting caches built for tracking +// include locations that are based on FileIDs, to make sure we don't report +// wrong include locations when FileIDs coincide between two different runs. +TEST_F(SourceManagerTest, ResetsIncludeLocMap) { + auto ParseFile = [&] { +TrivialModuleLoader ModLoader; +HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, +Diags, LangOpts, &*Target); +Preprocessor PP(std::make_shared(), Diags, LangOpts, +SourceMgr, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +PP.Initialize(*Target); +PP.EnterMainSourceFile(); +PP.LexTokensUntilEOF(); +EXPECT_FALSE(Diags.hasErrorOccurred()); + }; + + auto Buf = llvm::MemoryBuffer::getMemBuffer(""); + FileEntryRef HeaderFile = + FileMgr.getVirtualFileRef("/foo.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(HeaderFile, std::move(Buf)); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileEntryRef BarFile = + FileMgr.getVirtualFileRef("/bar.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(BarFile, std::move(Buf)); + SourceMgr.createFileID(BarFile, {}, clang::SrcMgr::C_User); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileID MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + auto FooFID = SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User); + auto IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + EXPECT_EQ(IncFID, MFID); + + // Clean up source-manager state before we start next parse. + SourceMgr.clearIDTables(); + + // Set up a new main file. + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp( + // silly comment 42 + #include "/bar.h")cpp"); + MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + // Make sure foo.h got the same file-id in both runs. + EXPECT_EQ(FooFID, +SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User)); + auto BarFID = SourceMgr.getOrCreateFileID(BarFile, clang::SrcMgr::C_User); + IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + // Check that includer is bar.h during this run. + EXPECT_EQ(IncFID, BarFID); +} + TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { const char *header = "#define FM(x,y) x\n"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a2a93f0 - [clang] Cleanup IncludeLocMap (#106241)
Author: kadir çetinkaya Date: 2024-08-30T11:57:37+02:00 New Revision: a2a93f02930e20930d5ef38464ca9c99eb00ff23 URL: https://github.com/llvm/llvm-project/commit/a2a93f02930e20930d5ef38464ca9c99eb00ff23 DIFF: https://github.com/llvm/llvm-project/commit/a2a93f02930e20930d5ef38464ca9c99eb00ff23.diff LOG: [clang] Cleanup IncludeLocMap (#106241) CompilerInstance can re-use same SourceManager across multiple frontendactions. During this process it calls `SourceManager::clearIDTables` to reset any caches based on FileIDs. It didn't reset IncludeLocMap, resulting in wrong include locations for workflows that triggered multiple frontend-actions through same CompilerInstance. Added: Modified: clang/lib/Basic/SourceManager.cpp clang/unittests/Basic/SourceManagerTest.cpp Removed: diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index b0256a8ce9ed04..d6ec26af80aadd 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -350,6 +350,7 @@ void SourceManager::clearIDTables() { LastLineNoContentCache = nullptr; LastFileIDLookup = FileID(); + IncludedLocMap.clear(); if (LineTable) LineTable->clear(); diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index 45840f5188cdcd..0f2476bd8b0612 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -20,6 +20,7 @@ #include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Process.h" #include "gtest/gtest.h" #include @@ -453,6 +454,65 @@ TEST_F(SourceManagerTest, loadedSLocEntryIsInTheSameTranslationUnit) { #if defined(LLVM_ON_UNIX) +// A single SourceManager instance is sometimes reused across multiple +// compilations. This test makes sure we're resetting caches built for tracking +// include locations that are based on FileIDs, to make sure we don't report +// wrong include locations when FileIDs coincide between two diff erent runs. +TEST_F(SourceManagerTest, ResetsIncludeLocMap) { + auto ParseFile = [&] { +TrivialModuleLoader ModLoader; +HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, +Diags, LangOpts, &*Target); +Preprocessor PP(std::make_shared(), Diags, LangOpts, +SourceMgr, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +PP.Initialize(*Target); +PP.EnterMainSourceFile(); +PP.LexTokensUntilEOF(); +EXPECT_FALSE(Diags.hasErrorOccurred()); + }; + + auto Buf = llvm::MemoryBuffer::getMemBuffer(""); + FileEntryRef HeaderFile = + FileMgr.getVirtualFileRef("/foo.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(HeaderFile, std::move(Buf)); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileEntryRef BarFile = + FileMgr.getVirtualFileRef("/bar.h", Buf->getBufferSize(), 0); + SourceMgr.overrideFileContents(BarFile, std::move(Buf)); + SourceMgr.createFileID(BarFile, {}, clang::SrcMgr::C_User); + + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp(#include "/foo.h")cpp"); + FileID MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + auto FooFID = SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User); + auto IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + EXPECT_EQ(IncFID, MFID); + + // Clean up source-manager state before we start next parse. + SourceMgr.clearIDTables(); + + // Set up a new main file. + Buf = llvm::MemoryBuffer::getMemBuffer(R"cpp( + // silly comment 42 + #include "/bar.h")cpp"); + MFID = SourceMgr.createFileID(std::move(Buf)); + SourceMgr.setMainFileID(MFID); + + ParseFile(); + // Make sure foo.h got the same file-id in both runs. + EXPECT_EQ(FooFID, +SourceMgr.getOrCreateFileID(HeaderFile, clang::SrcMgr::C_User)); + auto BarFID = SourceMgr.getOrCreateFileID(BarFile, clang::SrcMgr::C_User); + IncFID = SourceMgr.getDecomposedIncludedLoc(FooFID).first; + // Check that includer is bar.h during this run. + EXPECT_EQ(IncFID, BarFID); +} + TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { const char *header = "#define FM(x,y) x\n"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Cleanup IncludeLocMap (PR #106241)
https://github.com/kadircet closed https://github.com/llvm/llvm-project/pull/106241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] [MallocChecker] suspect all release functions as candite for supression (PR #104599)
@@ -3648,35 +3648,38 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, return nullptr; } - // See if we're releasing memory while inlining a destructor - // (or one of its callees). This turns on various common - // false positive suppressions. - bool FoundAnyDestructor = false; - for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { -if (const auto *DD = dyn_cast(LC->getDecl())) { - if (isReferenceCountingPointerDestructor(DD)) { -// This immediately looks like a reference-counting destructor. -// We're bad at guessing the original reference count of the object, -// so suppress the report for now. -BR.markInvalid(getTag(), DD); - } else if (!FoundAnyDestructor) { -assert(!ReleaseDestructorLC && +// See if we're releasing memory while inlining a destructor or +// functions that decrement reference counters (or one of its callees). +// This turns on various common false positive suppressions. +bool FoundAnyReleaseFunction = false; +for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { + if (const auto *DD = dyn_cast(LC->getDecl())) { +if (isReferenceCountingPointerDestructor(DD)) { + // This immediately looks like a reference-counting destructor. + // We're bad at guessing the original reference count of the + // object, so suppress the report for now. + BR.markInvalid(getTag(), DD); + continue; +} + } + + if (!FoundAnyReleaseFunction) { NagyDonat wrote: > And there is no warning. Did I get it wrong? Your test code differs from the case that I tried to describe in two aspects: 1. The name of the class is recognized by `isReferenceCountingPointerDestructor()` (which does case-insensitive substring checks for several keywords, including "intrustive" and "ptr"), so the use-after-free report is suppressed by that name-based heuristic, which suppresses all use-after-free errors (directly or indirectly) within a destructor of a class whose name is recognized. 2. Your `DecRef()` call is not recognized by the heuristics defined in `MallocBugVisitor::VisitNode` [within the `if (ReleaseDestructorLC && (ReleaseDestructorLC == CurrentLC || ReleaseDestructorLC->isParentOf(CurrentLC)))` block] which searches for either C11 atomic add/sub instructions or methods called on an object whose class name contains "atomic". If you rename the class (to avoid the other heuristic) and replace the abstract/opaque `DecRef` calls with visibly atomic operations then you will get a testcase that: - is suppressed without your commit (because the visitor finds the destructor which contains both the `delete` operation and the atomic call) - is not suppressed with your commit (because the name-based heuristic doesn't trigger AND the visitor only searches for the atomic call within the stack frame that directly contains the `delete` operation, and that doesn't contain an atomic call). (Disclaimer: I didn't test this experimentally, I'm just reasoning based on the source code.) https://github.com/llvm/llvm-project/pull/104599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [include-cleaner] Report refs for enum constants used through namespace aliases (PR #106706)
https://github.com/kadircet created https://github.com/llvm/llvm-project/pull/106706 None From 82ac332a3b94f6f753b706077b13f405ff776882 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Fri, 30 Aug 2024 12:28:02 +0200 Subject: [PATCH] [include-cleaner] Report refs for enum constants used through namespace aliases --- clang-tools-extra/include-cleaner/lib/WalkAST.cpp | 3 ++- clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index f7a2ebd5260681..9663c9916740eb 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -147,7 +147,8 @@ class ASTWalker : public RecursiveASTVisitor { // If it's an enum constant, it must be due to prior decl. Report references // to it when qualifier isn't a type. if (llvm::isa(FD)) { - if (!DRE->getQualifier() || DRE->getQualifier()->getAsNamespace()) + if (!DRE->getQualifier() || DRE->getQualifier()->getAsNamespace() || + DRE->getQualifier()->getAsNamespaceAlias()) report(DRE->getLocation(), FD); } return true; diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 9286758cab081c..9ae9f9a5ddb829 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -534,6 +534,8 @@ TEST(WalkAST, Enums) { testWalk(R"(namespace ns { enum E { A = 42 }; } struct S { using ns::E::A; };)", "int e = S::^A;"); + testWalk(R"(namespace ns { enum E { $explicit^A = 42 }; })", + "namespace z = ns; int e = z::^A;"); } TEST(WalkAST, InitializerList) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [include-cleaner] Report refs for enum constants used through namespace aliases (PR #106706)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: kadir çetinkaya (kadircet) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/106706.diff 2 Files Affected: - (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+2-1) - (modified) clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp (+2) ``diff diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index f7a2ebd5260681..9663c9916740eb 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -147,7 +147,8 @@ class ASTWalker : public RecursiveASTVisitor { // If it's an enum constant, it must be due to prior decl. Report references // to it when qualifier isn't a type. if (llvm::isa(FD)) { - if (!DRE->getQualifier() || DRE->getQualifier()->getAsNamespace()) + if (!DRE->getQualifier() || DRE->getQualifier()->getAsNamespace() || + DRE->getQualifier()->getAsNamespaceAlias()) report(DRE->getLocation(), FD); } return true; diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 9286758cab081c..9ae9f9a5ddb829 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -534,6 +534,8 @@ TEST(WalkAST, Enums) { testWalk(R"(namespace ns { enum E { A = 42 }; } struct S { using ns::E::A; };)", "int e = S::^A;"); + testWalk(R"(namespace ns { enum E { $explicit^A = 42 }; })", + "namespace z = ns; int e = z::^A;"); } TEST(WalkAST, InitializerList) { `` https://github.com/llvm/llvm-project/pull/106706 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] [MallocChecker] suspect all release functions as candite for supression (PR #104599)
@@ -3648,35 +3648,38 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, return nullptr; } - // See if we're releasing memory while inlining a destructor - // (or one of its callees). This turns on various common - // false positive suppressions. - bool FoundAnyDestructor = false; - for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { -if (const auto *DD = dyn_cast(LC->getDecl())) { - if (isReferenceCountingPointerDestructor(DD)) { -// This immediately looks like a reference-counting destructor. -// We're bad at guessing the original reference count of the object, -// so suppress the report for now. -BR.markInvalid(getTag(), DD); - } else if (!FoundAnyDestructor) { -assert(!ReleaseDestructorLC && +// See if we're releasing memory while inlining a destructor or +// functions that decrement reference counters (or one of its callees). +// This turns on various common false positive suppressions. +bool FoundAnyReleaseFunction = false; +for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) { + if (const auto *DD = dyn_cast(LC->getDecl())) { +if (isReferenceCountingPointerDestructor(DD)) { + // This immediately looks like a reference-counting destructor. + // We're bad at guessing the original reference count of the + // object, so suppress the report for now. + BR.markInvalid(getTag(), DD); + continue; +} + } + + if (!FoundAnyReleaseFunction) { pskrgag wrote: Indeed! I totally forgot about suppression logic by name. Hm, ok then. I will try to rework the logic to avoid it. Thank you! https://github.com/llvm/llvm-project/pull/104599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Bring alpha.security.MmapWriteExec checker out of alpha package (PR #102636)
balazske wrote: I have tested it on some of the projects but there are not results from this checker. The detected type of bug looks unlikely so it is difficult to test the checker this way. https://github.com/llvm/llvm-project/pull/102636 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM] musttail fixes (PR #102896)
kiran-isaac wrote: > What's the state of byval handling with the current version of the patch? byval arguments to a tail call are allowed as long as they are not split between register and stack, same as before. My change to this check was incorrect https://github.com/llvm/llvm-project/pull/102896 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix #104794: Fixed sret bugs with `clang::musttail` on 32 bit targets (PR #104795)
@@ -5085,7 +5085,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, RawAddress SRetAlloca = RawAddress::invalid(); llvm::Value *UnusedReturnSizePtr = nullptr; if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { -if (IsVirtualFunctionPointerThunk && RetAI.isIndirect()) { +if ((IsVirtualFunctionPointerThunk && RetAI.isIndirect()) || IsMustTail) { kiran-isaac wrote: Apologies for slow replies on both of my PRs, our fuzzer and some of our downstream testing identified some issues and I had to verify they were unrelated. No none of the tests cover these cases. I am in the process of trying to add some that do. https://github.com/llvm/llvm-project/pull/104795 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Refactor MallocChecker to use `BindExpr` in `evalCall` (PR #106081)
@@ -58,14 +60,14 @@ void testFreeOpNew() { void *p = operator new(0); free(p); // mismatch-warning@-1{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'free()'}} -} // leak-warning{{Potential leak of memory pointed to by 'p'}} +} NagyDonat wrote: > To be clear, these leak-warning s were added during WIP stage of this PR Oops, I was only looking at the "changes since last review" diff and didn't notice this. Based on this, I'd lean toward preserving the old behavior to make this commit closer to being an NFC. (But I'd support adding this leak warning as a separate commit, if you're interested.) https://github.com/llvm/llvm-project/pull/106081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix #104794: Fixed sret bugs with `clang::musttail` on 32 bit targets (PR #104795)
https://github.com/kiran-isaac edited https://github.com/llvm/llvm-project/pull/104795 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Refactor MallocChecker to use `BindExpr` in `evalCall` (PR #106081)
NagyDonat wrote: > To me, a switch from eval-call to post-call should be NFC for the most part. Minor correction: this commit switches from post-call to eval-call, not the other way around. > It would be nice if we could separate out that NFC part in a PR, and then > deal with the breaking changes in a limited PR. The "main" part of this change (the actual post-call -> eval-call switch) is close to being NFC, but is not exactly an NFC because there are subtle differences between the two callback kinds. It would be possible to move a few minor cleanup changes (e.g. the removal of the superfluous argument of `setDynamicExtent` or the correction of the return type of `getConjuredHeapSymbolVal`) into a separate NFC commit but I'm not sure that the reorganization effort is worth it. https://github.com/llvm/llvm-project/pull/106081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM] musttail fixes (PR #102896)
https://github.com/kiran-isaac updated https://github.com/llvm/llvm-project/pull/102896 >From eb7551e83618d8452f5dadae1be4aff8f6c9d23c Mon Sep 17 00:00:00 2001 From: Kiran Date: Thu, 8 Aug 2024 13:07:24 +0100 Subject: [PATCH 1/5] [ARM] musttail fixes Backend: - Caller and callee arguments no longer have to match, just to take up the same space, as they can be changed before the call - Allowed tail calls if callee and callee both (or neither) use sret, wheras before it would be dissalowed if either used sret - Allowed tail calls if byval args are used - Added debug trace for IsEligibleForTailCallOptimisation Frontend (clang): - Do not generate extra alloca if sret is used with musttail, as the space for the sret is allocated already Change-Id: Ic7f246a7eca43c06874922d642d7dc44bdfc98ec --- clang/lib/CodeGen/CGCall.cpp | 2 +- llvm/include/llvm/CodeGen/CallingConvLower.h | 2 + llvm/lib/CodeGen/CallingConvLower.cpp | 61 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp | 141 ++ .../ARM/2013-05-13-AAPCS-byval-padding.ll | 16 +- .../ARM/2013-05-13-AAPCS-byval-padding2.ll| 13 +- llvm/test/CodeGen/ARM/fp-arg-shuffle.ll | 22 + llvm/test/CodeGen/ARM/fp16-vector-argument.ll | 41 +- llvm/test/CodeGen/ARM/struct_byval.ll | 455 -- llvm/test/CodeGen/ARM/tail-call-float.ll | 99 +++- 10 files changed, 661 insertions(+), 191 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index ca2c79b51ac96b..05773f91f986ba 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5086,7 +5086,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, RawAddress SRetAlloca = RawAddress::invalid(); llvm::Value *UnusedReturnSizePtr = nullptr; if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) { -if (IsVirtualFunctionPointerThunk && RetAI.isIndirect()) { +if ((IsVirtualFunctionPointerThunk || IsMustTail) && RetAI.isIndirect()) { SRetPtr = makeNaturalAddressForPointer(CurFn->arg_begin() + IRFunctionArgs.getSRetArgNo(), RetTy, CharUnits::fromQuantity(1)); diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h index d5a63c8dd627a0..12a6df16e279b4 100644 --- a/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -540,6 +540,8 @@ class CCState { }); } + void dump() const; + private: /// MarkAllocated - Mark a register and all of its aliases as allocated. void MarkAllocated(MCPhysReg Reg); diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp index b7152587a9fa05..7ba3ea83115db2 100644 --- a/llvm/lib/CodeGen/CallingConvLower.cpp +++ b/llvm/lib/CodeGen/CallingConvLower.cpp @@ -290,3 +290,64 @@ bool CCState::resultsCompatible(CallingConv::ID CalleeCC, return std::equal(RVLocs1.begin(), RVLocs1.end(), RVLocs2.begin(), RVLocs2.end(), AreCompatible); } + +void CCState::dump() const { + dbgs() << "CCState:\n"; + for (const CCValAssign &Loc : Locs) { +if (Loc.isRegLoc()) { + dbgs() << " Reg " << TRI.getName(Loc.getLocReg()); +} else if (Loc.isMemLoc()) { + dbgs() << " Mem " << Loc.getLocMemOffset(); +} else { + assert(Loc.isPendingLoc()); + dbgs() << " Pend " << Loc.getExtraInfo(); +} + +dbgs() << " ValVT:" << Loc.getValVT(); +dbgs() << " LocVT:" << Loc.getLocVT(); + +if (Loc.needsCustom()) + dbgs() << " custom"; + +switch (Loc.getLocInfo()) { +case CCValAssign::Full: + dbgs() << " Full"; + break; +case CCValAssign::SExt: + dbgs() << " SExt"; + break; +case CCValAssign::ZExt: + dbgs() << " ZExt"; + break; +case CCValAssign::AExt: + dbgs() << " AExt"; + break; +case CCValAssign::SExtUpper: + dbgs() << " SExtUpper"; + break; +case CCValAssign::ZExtUpper: + dbgs() << " ZExtUpper"; + break; +case CCValAssign::AExtUpper: + dbgs() << " AExtUpper"; + break; +case CCValAssign::BCvt: + dbgs() << " BCvt"; + break; +case CCValAssign::Trunc: + dbgs() << " Trunc"; + break; +case CCValAssign::VExt: + dbgs() << " VExt"; + break; +case CCValAssign::FPExt: + dbgs() << " FPExt"; + break; +case CCValAssign::Indirect: + dbgs() << " Indirect"; + break; +} + +dbgs() << "\n"; + } +} diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 853f54943eebf1..b5fdf630a8132d 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -2407,8 +2407,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, isTailCall = false; // For both t
[clang] [llvm] [ARM] musttail fixes (PR #102896)
kiran-isaac wrote: > Please also add a testcase for something like: > > ``` > struct Large { int x[60]; }; > void f(long long a, long long b, Large c, Large d); > void g(long long a, long long b, Large c, Large d) { > [[clang::musttail]] return f(a,b,d,c); > } > ``` added this testcase (compiled to ir), it works with my patch and does not without https://github.com/llvm/llvm-project/pull/102896 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Bring alpha.security.MmapWriteExec checker out of alpha package (PR #102636)
https://github.com/steakhal approved this pull request. Alright, it's probably good enough. https://github.com/llvm/llvm-project/pull/102636 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Catch missing format attributes (PR #105479)
@@ -0,0 +1,393 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,c_diagnostics -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -Wmissing-format-attribute -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s --check-prefixes=CHECK,C-CHECK +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -std=c++2b -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -std=c++23 -Wmissing-format-attribute %s +// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +#ifndef __cplusplus +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +typedef __WCHAR_TYPE__ wchar_t; +#endif + +typedef __SIZE_TYPE__ size_t; +typedef __builtin_va_list va_list; + +__attribute__((__format__(__printf__, 1, 2))) +int printf(const char *, ...); // #printf + +__attribute__((__format__(__scanf__, 1, 2))) +int scanf(const char *, ...); // #scanf + +__attribute__((__format__(__printf__, 1, 0))) +int vprintf(const char *, va_list); // #vprintf + +__attribute__((__format__(__scanf__, 1, 0))) +int vscanf(const char *, va_list); // #vscanf + +__attribute__((__format__(__printf__, 2, 0))) +int vsprintf(char *, const char *, va_list); // #vsprintf + +__attribute__((__format__(__printf__, 3, 0))) +int vsnprintf(char *ch, size_t, const char *, va_list); // #vsnprintf + +__attribute__((__format__(__scanf__, 1, 4))) +void f1(char *out, const size_t len, const char *format, ... /* args */) // #f1 +{ +va_list args; +vsnprintf(out, len, format, args); // expected-no-warning@#f1 +} + +__attribute__((__format__(__printf__, 1, 4))) +void f2(char *out, const size_t len, const char *format, ... /* args */) // #f2 +{ +va_list args; +vsnprintf(out, len, format, args); // expected-warning@#f2 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f2'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:6-[[@LINE-4]]:6}:"__attribute__((format(printf, 3, 4)))" +} + +void f3(char *out, va_list args) // #f3 +{ +vprintf(out, args); // expected-warning@#f3 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f3'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:6-[[@LINE-3]]:6}:"__attribute__((format(printf, 1, 0)))" +} + +void f4(char* out, ... /* args */) // #f4 +{ +va_list args; +vprintf("test", args); // expected-no-warning@#f4 + +const char *ch; +vprintf(ch, args); // expected-no-warning@#f4 +} + +void f5(va_list args) // #f5 +{ +char *ch; +vscanf(ch, args); // expected-no-warning@#f5 +} + +void f6(char *out, va_list args) // #f6 +{ +char *ch; +vprintf(ch, args); // expected-no-warning@#f6 +vprintf("test", args); // expected-no-warning@#f6 +vprintf(out, args); // expected-warning@#f6 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f6'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 0)))" +} + +void f7(const char *out, ... /* args */) // #f7 +{ +va_list args; + +vscanf(out, args); // expected-warning@#f7 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f7'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:6-[[@LINE-5]]:6}:"__attribute__((format(scanf, 1, 2)))" +} + +void f8(const char *out, ... /* args */) // #f8 +{ +va_list args; + +vscanf(out, args); // expected-no-warning@#f8 +vprintf(out, args); // expected-no-warning@#f8 +} + +void f9(const char out[], ... /* args */) // #f9 +{ +va_list args; +char *ch; +vprintf(ch, args); // expected-no-warning +vsprintf(ch, out, args); // expected-warning@#f9 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f9'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 2)))" +} + +void f10(const wchar_t *out, ... /* args */) // #f10 +{ +va_list args; +vscanf(out, args); +#if (defined(__aarch64__) && !defined(_WIN64)) || (defined(__arm__) && !defined(_WIN32)) +// c_diagnostics-warning@-2 {{incompatible pointer types passing 'const wchar_t *' (aka 'const unsigned int *') to parameter of type 'const char *'}} +#elif __SIZEOF_WCHAR_T__ == 4 +// c_diagnostics-warning@-4 {{incompatible pointer types passing 'const wchar_t *' (aka 'const int *') to parameter of type 'const char *'}} +#else +// c_diagnostics-warning@-6 {{incompatible pointer types passing 'const wchar_t *' (aka 'const unsigned short *') to
[clang] [clang] Catch missing format attributes (PR #105479)
@@ -0,0 +1,393 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=expected,c_diagnostics -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -Wmissing-format-attribute -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s --check-prefixes=CHECK,C-CHECK +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -std=c++2b -Wmissing-format-attribute %s +// RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics -std=c++23 -Wmissing-format-attribute %s +// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +#ifndef __cplusplus +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +typedef __WCHAR_TYPE__ wchar_t; +#endif + +typedef __SIZE_TYPE__ size_t; +typedef __builtin_va_list va_list; + +__attribute__((__format__(__printf__, 1, 2))) +int printf(const char *, ...); // #printf + +__attribute__((__format__(__scanf__, 1, 2))) +int scanf(const char *, ...); // #scanf + +__attribute__((__format__(__printf__, 1, 0))) +int vprintf(const char *, va_list); // #vprintf + +__attribute__((__format__(__scanf__, 1, 0))) +int vscanf(const char *, va_list); // #vscanf + +__attribute__((__format__(__printf__, 2, 0))) +int vsprintf(char *, const char *, va_list); // #vsprintf + +__attribute__((__format__(__printf__, 3, 0))) +int vsnprintf(char *ch, size_t, const char *, va_list); // #vsnprintf + +__attribute__((__format__(__scanf__, 1, 4))) +void f1(char *out, const size_t len, const char *format, ... /* args */) // #f1 +{ +va_list args; +vsnprintf(out, len, format, args); // expected-no-warning@#f1 +} + +__attribute__((__format__(__printf__, 1, 4))) +void f2(char *out, const size_t len, const char *format, ... /* args */) // #f2 +{ +va_list args; +vsnprintf(out, len, format, args); // expected-warning@#f2 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f2'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:6-[[@LINE-4]]:6}:"__attribute__((format(printf, 3, 4)))" +} + +void f3(char *out, va_list args) // #f3 +{ +vprintf(out, args); // expected-warning@#f3 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f3'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:6-[[@LINE-3]]:6}:"__attribute__((format(printf, 1, 0)))" +} + +void f4(char* out, ... /* args */) // #f4 +{ +va_list args; +vprintf("test", args); // expected-no-warning@#f4 + +const char *ch; +vprintf(ch, args); // expected-no-warning@#f4 +} + +void f5(va_list args) // #f5 +{ +char *ch; +vscanf(ch, args); // expected-no-warning@#f5 +} + +void f6(char *out, va_list args) // #f6 +{ +char *ch; +vprintf(ch, args); // expected-no-warning@#f6 +vprintf("test", args); // expected-no-warning@#f6 +vprintf(out, args); // expected-warning@#f6 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f6'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 0)))" +} + +void f7(const char *out, ... /* args */) // #f7 +{ +va_list args; + +vscanf(out, args); // expected-warning@#f7 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f7'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:6-[[@LINE-5]]:6}:"__attribute__((format(scanf, 1, 2)))" +} + +void f8(const char *out, ... /* args */) // #f8 +{ +va_list args; + +vscanf(out, args); // expected-no-warning@#f8 +vprintf(out, args); // expected-no-warning@#f8 +} + +void f9(const char out[], ... /* args */) // #f9 +{ +va_list args; +char *ch; +vprintf(ch, args); // expected-no-warning +vsprintf(ch, out, args); // expected-warning@#f9 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f9'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 2)))" +} + +void f10(const wchar_t *out, ... /* args */) // #f10 +{ +va_list args; +vscanf(out, args); AaronBallman wrote: This looks wrong -- `vscanf` takes a `const char *` as the first argument, I think you want `vwscanf` instead, right? https://github.com/llvm/llvm-project/pull/105479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits