[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)
vogelsgesang wrote: Note that this also influences Swift. The new labels will also be available in Swift. I hope this might also be useful for Swift to improve debugging experience, and hence is actually a good thing? Not sure, though. If you want, I could also skip emitting those labels for Swift. CC @adrian-prantl https://github.com/llvm/llvm-project/pull/141937 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)
felipepiovezan wrote: > ~Note that this also influences Swift. The new labels will also be available > in Swift. I hope this might also be useful for Swift to improve debugging > experience, and hence is actually a good thing?~ > > > > ~Not sure, though. If you want, I could also skip emitting those labels for > Swift.~ > > > > ~CC @adrian-prantl~ > > > > Nevermind, I got confused. This code path does not influence Swift, afaict Yup, Swift bypasses the problem by not having a common entry point for all continuation points; instead, the continuation is always the start of a unique function with a line table entry that also points to the correct line number. https://github.com/llvm/llvm-project/pull/141937 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ExtractAPI] Format pointers in params correctly (PR #146182)
https://github.com/snprajwal updated https://github.com/llvm/llvm-project/pull/146182 >From 398c55dd352e0f38f5dc5b85a9f6dca836706597 Mon Sep 17 00:00:00 2001 From: Prajwal Nadig Date: Sat, 28 Jun 2025 01:33:42 +0100 Subject: [PATCH] [ExtractAPI] Format pointer types correctly Pointer types in function signatures must place the asterisk before the identifier without a space in between. This patch removes the space and also ensures that pointers to pointers are formatted correctly. rdar://131780418 rdar://154533037 --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 29 +- clang/test/ExtractAPI/global_record.c | 4 +- .../test/ExtractAPI/global_record_multifile.c | 4 +- clang/test/ExtractAPI/macro_undefined.c | 4 +- clang/test/ExtractAPI/pointers.c | 388 ++ 5 files changed, 412 insertions(+), 17 deletions(-) create mode 100644 clang/test/ExtractAPI/pointers.c diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 348e7588690a2..52349324d7829 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -324,10 +324,15 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( // Declaration fragments of a pointer type is the declaration fragments of // the pointee type followed by a `*`, - if (T->isPointerType() && !T->isFunctionPointerType()) -return Fragments -.append(getFragmentsForType(T->getPointeeType(), Context, After)) -.append(" *", DeclarationFragments::FragmentKind::Text); + if (T->isPointerType() && !T->isFunctionPointerType()) { +QualType PointeeT = T->getPointeeType(); +Fragments.append(getFragmentsForType(PointeeT, Context, After)); +// If the pointee is itself a pointer, we do not want to insert a space +// before the `*` as the preceding character in the type name is a `*`. +if (!PointeeT->isAnyPointerType()) + Fragments.appendSpace(); +return Fragments.append("*", DeclarationFragments::FragmentKind::Text); + } // For Objective-C `id` and `Class` pointers // we do not spell out the `*`. @@ -631,7 +636,7 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { DeclarationFragments::FragmentKind::InternalParam); } else { Fragments.append(std::move(TypeFragments)); -if (!T->isBlockPointerType()) +if (!T->isAnyPointerType() && !T->isBlockPointerType()) Fragments.appendSpace(); Fragments .append(Param->getName(), @@ -706,18 +711,20 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { // FIXME: Is `after` actually needed here? DeclarationFragments After; + QualType ReturnType = Func->getReturnType(); auto ReturnValueFragment = - getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After); + getFragmentsForType(ReturnType, Func->getASTContext(), After); if (StringRef(ReturnValueFragment.begin()->Spelling) .starts_with("type-parameter")) { -std::string ProperArgName = Func->getReturnType().getAsString(); +std::string ProperArgName = ReturnType.getAsString(); ReturnValueFragment.begin()->Spelling.swap(ProperArgName); } - Fragments.append(std::move(ReturnValueFragment)) - .appendSpace() - .append(Func->getNameAsString(), - DeclarationFragments::FragmentKind::Identifier); + Fragments.append(std::move(ReturnValueFragment)); + if (!ReturnType->isAnyPointerType()) +Fragments.appendSpace(); + Fragments.append(Func->getNameAsString(), + DeclarationFragments::FragmentKind::Identifier); if (Func->getTemplateSpecializationInfo()) { Fragments.append("<", DeclarationFragments::FragmentKind::Text); diff --git a/clang/test/ExtractAPI/global_record.c b/clang/test/ExtractAPI/global_record.c index a08d51d21f955..287fa24c4c64e 100644 --- a/clang/test/ExtractAPI/global_record.c +++ b/clang/test/ExtractAPI/global_record.c @@ -185,7 +185,7 @@ char unavailable __attribute__((unavailable)); }, { "kind": "text", - "spelling": " * " + "spelling": " *" }, { "kind": "internalParam", @@ -341,7 +341,7 @@ char unavailable __attribute__((unavailable)); }, { "kind": "text", -"spelling": " * " +"spelling": " *" }, { "kind": "internalParam", diff --git a/clang/test/ExtractAPI/global_record_multifile.c b/clang/test/ExtractAPI/global_record_multifile.c index ffdfbcb7eb808..b98cd27b1601e 100644 --- a/clang/test/ExtractAPI/global_record_multifile.c +++ b/clang/test/ExtractAPI/global_record_multifile.c @@ -187,7 +187,7 @@ char unavailable __attribute__((unavailable)); }, { "kind": "text", - "spelling": " * " +
[clang] [ExtractAPI] Format pointer types correctly (PR #146182)
https://github.com/snprajwal edited https://github.com/llvm/llvm-project/pull/146182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ExtractAPI] Format pointer types correctly (PR #146182)
https://github.com/snprajwal edited https://github.com/llvm/llvm-project/pull/146182 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field (PR #145066)
https://github.com/Tedlion updated https://github.com/llvm/llvm-project/pull/145066 >From 03004d9a9348e365a2d2d05e69f83fc404ddb605 Mon Sep 17 00:00:00 2001 From: tangwy Date: Sat, 21 Jun 2025 00:22:10 +0800 Subject: [PATCH 1/5] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field For the following code: struct B{ int i :2; int:30; // unnamed bit-field }; extern void consume_B(B); void bitfield_B_init(void) { B b1; b1.i = 1; // b1 is initialized consume_B(b1); } The current clang static analyzer gives false positive warning "Passed-by-value struct argument contains uninitialized data (e.g., field: '') [core.CallAndMessage]" when taking the source as C code. However, no such warning is generated when clang takes the source as C++ code. After comparing the CallAndMessageChecker's different behaviors between C and C++, the reason is found: When FindUninitializedField::Find(const TypedValueRegion *R) is invoked, the concrete type of R is different. In C, 'b1' is considered to be a 'StackLocalsSpaceRegion', which makes 'StoreMgr.getBinding(store, loc::MemRegionVal(FR))' return an 'UndefinedVal'. While in c++, 'b1' is considered to be a 'tackArgumentsSpaceRegion', which finally makes the 'getBinding' return a SymbolVal. I am not quite sure about the region difference, maybe in C++ there is an implicit copy constructor function? Anyway, the unnamed bit-field is undefined, for it cannot be written unless using memory operation such as 'memset'. So a special check FD->isUnnamedBitField() is added in RegionStoreManager::getBindingForField in file RegionStore.cpp. To handle the false warning, a check isUnnamedBitField is also added in FindUninitializedField::Find in file CallAndMessageChecker.cpp. Testcases of unnamed bit-field are added in file call-and-message.c and call-and-message.cpp. I do not know what to do on the hash, so it may be updated? --- .../Checkers/CallAndMessageChecker.cpp| 2 +- clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 15 ++- clang/test/Analysis/call-and-message.c| 27 ++- clang/test/Analysis/call-and-message.cpp | 16 +++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 86476b32309c3..677cc6ee57ad2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -259,7 +259,7 @@ class FindUninitializedField { if (T->getAsStructureType()) { if (Find(FR)) return true; -} else { +} else if (!I->isUnnamedBitField()){ SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); if (V.isUndef()) return true; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 388034b087789..1208036700f32 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2122,8 +2122,21 @@ SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B, if (const std::optional &V = B.getDirectBinding(R)) return *V; - // If the containing record was initialized, try to get its constant value. + // UnnamedBitField is always Undefined unless using memory operation such + // as 'memset'. + // For example, for code + //typedef struct { + // int i :2; + // int:30; // unnamed bit-field + //} A; + //A a = {1}; + // The bits of the unnamed bit-field in local variable a can be anything. const FieldDecl *FD = R->getDecl(); + if (FD->isUnnamedBitField()) { + return UndefinedVal(); + } + + // If the containing record was initialized, try to get its constant value. QualType Ty = FD->getType(); const MemRegion* superR = R->getSuperRegion(); if (const auto *VR = dyn_cast(superR)) { diff --git a/clang/test/Analysis/call-and-message.c b/clang/test/Analysis/call-and-message.c index b79ec8c344b6c..e2fba55d3343d 100644 --- a/clang/test/Analysis/call-and-message.c +++ b/clang/test/Analysis/call-and-message.c @@ -1,12 +1,19 @@ // RUN: %clang_analyze_cc1 %s -verify \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=true \ +// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false \ // RUN: -analyzer-output=plist -o %t.plist // RUN: cat %t.plist | FileCheck %s // RUN: %clang_analyze_cc1 %s -verify=no-pointee \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false +// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \ +// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false + +// RUN: %clang_analyze_cc1 %s -verify=arg-init \ +// RU
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
https://github.com/mrcvtl updated https://github.com/llvm/llvm-project/pull/145164 >From b5146278ce5059b6bf0312f18f509022de5fd661 Mon Sep 17 00:00:00 2001 From: Marco Vitale Date: Sat, 21 Jun 2025 14:01:53 +0200 Subject: [PATCH 1/2] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 C++23 mandates that temporaries used in range-based for loops are lifetime-extended to cover the full loop. This patch adds a check for loop variables and compiler- generated `__range` bindings to apply the correct extension. Includes test cases based on examples from CWG900/P2644R1. --- clang/docs/ReleaseNotes.rst | 4 +++ clang/lib/Sema/CheckExprLifetime.cpp | 5 clang/lib/Sema/SemaStmt.cpp | 3 +++ .../test/SemaCXX/range-for-lifetime-cxx23.cpp | 27 +++ 4 files changed, 39 insertions(+) create mode 100644 clang/test/SemaCXX/range-for-lifetime-cxx23.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d9847fadc21e5..d79df8c9184be 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -648,6 +648,10 @@ Improvements to Clang's diagnostics #GH142457, #GH139913, #GH138850, #GH137867, #GH137860, #GH107840, #GH93308, #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490, #GH36703, #GH32903, #GH23312, #GH69874. + +- Clang no longer emits a spurious -Wdangling-gsl warning in C++23 when + iterating over an element of a temporary container in a range-based + for loop.(#GH109793, #GH145164) - Clang now avoids issuing `-Wreturn-type` warnings in some cases where the final statement of a non-void function is a `throw` expression, or diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 060ba31660556..114e4f989ed9f 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -57,6 +57,7 @@ enum LifetimeKind { }; using LifetimeResult = llvm::PointerIntPair; + } // namespace /// Determine the declaration which an initialized entity ultimately refers to, @@ -1341,6 +1342,10 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, } if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) { +if (SemaRef.getLangOpts().CPlusPlus23 && +SemaRef.isInLifetimeExtendingContext()) + return false; + SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange; return false; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 923a9e81fbd6a..633f73946b729 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2374,6 +2374,9 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SemaRef.ObjC().inferObjCARCLifetime(Decl)) Decl->setInvalidDecl(); + if (SemaRef.getLangOpts().CPlusPlus23) +SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true; + SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false); SemaRef.FinalizeDeclaration(Decl); SemaRef.CurContext->addHiddenDecl(Decl); diff --git a/clang/test/SemaCXX/range-for-lifetime-cxx23.cpp b/clang/test/SemaCXX/range-for-lifetime-cxx23.cpp new file mode 100644 index 0..c36fd6c246347 --- /dev/null +++ b/clang/test/SemaCXX/range-for-lifetime-cxx23.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +using size_t = decltype(sizeof(void *)); + +namespace std { +template struct vector { + T &operator[](size_t I); +}; + +struct string { + const char *begin(); + const char *end(); +}; + +} // namespace std + +std::vector getData(); + +void foo() { + // Verifies we don't trigger a diagnostic from -Wdangling-gsl + // when iterating over a temporary in C++23. + for (auto c : getData()[0]) { +(void)c; + } +} + +// expected-no-diagnostics >From b2e1333c2b9e61ffb8b85d1613c137f8f96a73e4 Mon Sep 17 00:00:00 2001 From: Marco Vitale Date: Sat, 28 Jun 2025 00:25:33 +0200 Subject: [PATCH 2/2] Add as a flag in VarDecl --- clang/include/clang/AST/Decl.h| 19 +++ clang/lib/Sema/CheckExprLifetime.cpp | 9 ++--- clang/lib/Sema/SemaStmt.cpp | 1 + clang/lib/Serialization/ASTReaderDecl.cpp | 1 + clang/lib/Serialization/ASTWriterDecl.cpp | 2 ++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index c4202f1f3d07e..eee925b01d9e8 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1086,6 +1086,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { LLVM_PREFERRED_TYPE(bool) unsigned IsCXXCondDecl : 1; + +/// Whether this variable is the implicit __range variable in a for-range +/// loop. +LLVM_PREFERRED_TYPE(bool) +unsigned IsCXXForRangeImplicitVar : 1; }; union { @@ -1585
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
mrcvtl wrote: > > but why can’t we use InLifetimeExtendingContext flag here? > > Is there a subtle difference I’m missing? > > This flag will tiger subroutines to collect `MaterializedTemporaryExpr` and > rebuild default init/arg。 All we need to know here is that `ExtendingDecl` is > a C++ `__range` var in for-range-loop, so I think we should introduce a new > flag in VarDecl. We may need to also modify handling of VarDecl in ASTWriter > and ASTReader to ensure that the AST serialization is correct. WDYT? Agreed. My last commit should implement this. Let me know if something is wrong! https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
@@ -2740,6 +2741,7 @@ void ASTWriter::WriteDeclAbbrevs() { // isInline, isInlineSpecified, isConstexpr, // isInitCapture, isPrevDeclInSameScope, hasInitWithSideEffects, // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl +// isCXXForRangeDecl mrcvtl wrote: This should be `IsCXXForRangeImplicitVar` https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
@@ -1585,6 +1590,20 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.IsCXXCondDecl = true; } + /// Determine whether this variable is the compiler-generated '__range' + /// variable used to hold the range expression in a C++11 and later for-range + /// statement. + bool isCXXForRangeImplicitVar() const { +return isa(this) ? false + : NonParmVarDeclBits.IsCXXForRangeImplicitVar; + } + + void setCXXForRangeImplicitVar(bool FRV) { +assert(!isa(this) && + "Cannot set IsCXXForRangeRangeVar on ParmVarDecl"); mrcvtl wrote: Also here should be `Cannot set IsCXXForRangeRangeVar...`. https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
https://github.com/mrcvtl deleted https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
https://github.com/mrcvtl deleted https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
https://github.com/mrcvtl updated https://github.com/llvm/llvm-project/pull/145164 >From 37c57131c397d4aeaef7fe5b860d1983f1e4bdc2 Mon Sep 17 00:00:00 2001 From: Marco Vitale Date: Sat, 21 Jun 2025 14:01:53 +0200 Subject: [PATCH] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 C++23 mandates that temporaries used in range-based for loops are lifetime-extended to cover the full loop. This patch adds a check for loop variables and compiler- generated `__range` bindings to apply the correct extension. Includes test cases based on examples from CWG900/P2644R1. --- clang/docs/ReleaseNotes.rst | 4 +++ clang/include/clang/AST/Decl.h| 19 + clang/lib/Sema/CheckExprLifetime.cpp | 8 ++ clang/lib/Sema/SemaStmt.cpp | 4 +++ clang/lib/Serialization/ASTReaderDecl.cpp | 1 + clang/lib/Serialization/ASTWriterDecl.cpp | 2 ++ .../test/SemaCXX/range-for-lifetime-cxx23.cpp | 27 +++ 7 files changed, 65 insertions(+) create mode 100644 clang/test/SemaCXX/range-for-lifetime-cxx23.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 89d86c3371247..184d1f0b188be 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -643,6 +643,10 @@ Improvements to Clang's diagnostics #GH142457, #GH139913, #GH138850, #GH137867, #GH137860, #GH107840, #GH93308, #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490, #GH36703, #GH32903, #GH23312, #GH69874. + +- Clang no longer emits a spurious -Wdangling-gsl warning in C++23 when + iterating over an element of a temporary container in a range-based + for loop.(#GH109793, #GH145164) Improvements to Clang's time-trace diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 0da940883b6f5..ab23346cc2fad 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1085,6 +1085,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { LLVM_PREFERRED_TYPE(bool) unsigned IsCXXCondDecl : 1; + +/// Whether this variable is the implicit __range variable in a for-range +/// loop. +LLVM_PREFERRED_TYPE(bool) +unsigned IsCXXForRangeImplicitVar : 1; }; union { @@ -1584,6 +1589,20 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.IsCXXCondDecl = true; } + /// Determine whether this variable is the compiler-generated '__range' + /// variable used to hold the range expression in a C++11 and later for-range + /// statement. + bool isCXXForRangeImplicitVar() const { +return isa(this) ? false + : NonParmVarDeclBits.IsCXXForRangeImplicitVar; + } + + void setCXXForRangeImplicitVar(bool FRV) { +assert(!isa(this) && + "Cannot set IsCXXForRangeImplicitVar on ParmVarDecl"); +NonParmVarDeclBits.IsCXXForRangeImplicitVar = FRV; + } + /// Determines if this variable's alignment is dependent. bool hasDependentAlignment() const; diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 060ba31660556..fc52de1e6bd89 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -57,6 +57,7 @@ enum LifetimeKind { }; using LifetimeResult = llvm::PointerIntPair; + } // namespace /// Determine the declaration which an initialized entity ultimately refers to, @@ -1341,6 +1342,13 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, } if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) { + +if (SemaRef.getLangOpts().CPlusPlus23) { + if (const VarDecl *VD = cast(InitEntity->getDecl()); + VD && VD->isCXXForRangeImplicitVar()) +return false; +} + SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange; return false; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 923a9e81fbd6a..ef0aff1b2838f 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2374,6 +2374,9 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SemaRef.ObjC().inferObjCARCLifetime(Decl)) Decl->setInvalidDecl(); + if (SemaRef.getLangOpts().CPlusPlus23) +SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true; + SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false); SemaRef.FinalizeDeclaration(Decl); SemaRef.CurContext->addHiddenDecl(Decl); @@ -2423,6 +2426,7 @@ VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc, VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); Decl->setImplicit(); + Decl->setCXXForRangeImplicitVar(true); return Decl; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp
[clang] 0ba456f - [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (#138391)
Author: Yao Zi Date: 2025-06-28T16:47:05+08:00 New Revision: 0ba456fcc6b1c8504f1596f6f5cb2c188a869ac7 URL: https://github.com/llvm/llvm-project/commit/0ba456fcc6b1c8504f1596f6f5cb2c188a869ac7 DIFF: https://github.com/llvm/llvm-project/commit/0ba456fcc6b1c8504f1596f6f5cb2c188a869ac7.diff LOG: [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (#138391) There're four possible formats to refer a register in inline assembly, 1. Numeric name without dollar sign ("f0") 2. Numeric name with dollar sign ("$f0") 3. ABI name without dollar sign ("fa0") 4. ABI name with dollar sign ("$fa0") LoongArch GCC accepts 1 and 2 for FPRs before r15-8284[1] and all these formats after the chagne. But Clang supports only 2 and 4 for FPRs. The inconsistency has caused compatibility issues, such as QEMU's case[2]. This patch follows 0bbf3ddf5fea ("[Clang][LoongArch] Add GPR alias handling without `$` prefix") and accepts FPRs without dollar sign prefixes as well to keep aligned with GCC, avoiding future compatibility problems. Link: https://gcc.gnu.org/cgit/gcc/commit/?id=d0110185eb78f14a8e485f410bee237c9c71548d [1] Link: https://lore.kernel.org/qemu-devel/20250314033150.53268-3-zi...@disroot.org/ [2] Added: Modified: clang/lib/Basic/Targets/LoongArch.cpp clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c clang/test/CodeGen/LoongArch/inline-asm-gcc-regs.c Removed: diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 5312767498d96..f6915df1520b7 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -81,38 +81,46 @@ LoongArchTargetInfo::getGCCRegAliases() const { {{"s6", "$s6", "r29"}, "$r29"}, {{"s7", "$s7", "r30"}, "$r30"}, {{"s8", "$s8", "r31"}, "$r31"}, - {{"$fa0"}, "$f0"}, - {{"$fa1"}, "$f1"}, - {{"$fa2"}, "$f2"}, - {{"$fa3"}, "$f3"}, - {{"$fa4"}, "$f4"}, - {{"$fa5"}, "$f5"}, - {{"$fa6"}, "$f6"}, - {{"$fa7"}, "$f7"}, - {{"$ft0"}, "$f8"}, - {{"$ft1"}, "$f9"}, - {{"$ft2"}, "$f10"}, - {{"$ft3"}, "$f11"}, - {{"$ft4"}, "$f12"}, - {{"$ft5"}, "$f13"}, - {{"$ft6"}, "$f14"}, - {{"$ft7"}, "$f15"}, - {{"$ft8"}, "$f16"}, - {{"$ft9"}, "$f17"}, - {{"$ft10"}, "$f18"}, - {{"$ft11"}, "$f19"}, - {{"$ft12"}, "$f20"}, - {{"$ft13"}, "$f21"}, - {{"$ft14"}, "$f22"}, - {{"$ft15"}, "$f23"}, - {{"$fs0"}, "$f24"}, - {{"$fs1"}, "$f25"}, - {{"$fs2"}, "$f26"}, - {{"$fs3"}, "$f27"}, - {{"$fs4"}, "$f28"}, - {{"$fs5"}, "$f29"}, - {{"$fs6"}, "$f30"}, - {{"$fs7"}, "$f31"}, + {{"fa0", "$fa0", "f0"}, "$f0"}, + {{"fa1", "$fa1", "f1"}, "$f1"}, + {{"fa2", "$fa2", "f2"}, "$f2"}, + {{"fa3", "$fa3", "f3"}, "$f3"}, + {{"fa4", "$fa4", "f4"}, "$f4"}, + {{"fa5", "$fa5", "f5"}, "$f5"}, + {{"fa6", "$fa6", "f6"}, "$f6"}, + {{"fa7", "$fa7", "f7"}, "$f7"}, + {{"ft0", "$ft0", "f8"}, "$f8"}, + {{"ft1", "$ft1", "f9"}, "$f9"}, + {{"ft2", "$ft2", "f10"}, "$f10"}, + {{"ft3", "$ft3", "f11"}, "$f11"}, + {{"ft4", "$ft4", "f12"}, "$f12"}, + {{"ft5", "$ft5", "f13"}, "$f13"}, + {{"ft6", "$ft6", "f14"}, "$f14"}, + {{"ft7", "$ft7", "f15"}, "$f15"}, + {{"ft8", "$ft8", "f16"}, "$f16"}, + {{"ft9", "$ft9", "f17"}, "$f17"}, + {{"ft10", "$ft10", "f18"}, "$f18"}, + {{"ft11", "$ft11", "f19"}, "$f19"}, + {{"ft12", "$ft12", "f20"}, "$f20"}, + {{"ft13", "$ft13", "f21"}, "$f21"}, + {{"ft14", "$ft14", "f22"}, "$f22"}, + {{"ft15", "$ft15", "f23"}, "$f23"}, + {{"fs0", "$fs0", "f24"}, "$f24"}, + {{"fs1", "$fs1", "f25"}, "$f25"}, + {{"fs2", "$fs2", "f26"}, "$f26"}, + {{"fs3", "$fs3", "f27"}, "$f27"}, + {{"fs4", "$fs4", "f28"}, "$f28"}, + {{"fs5", "$fs5", "f29"}, "$f29"}, + {{"fs6", "$fs6", "f30"}, "$f30"}, + {{"fs7", "$fs7", "f31"}, "$f31"}, + {{"fcc0"}, "$fcc0"}, + {{"fcc1"}, "$fcc1"}, + {{"fcc2"}, "$fcc2"}, + {{"fcc3"}, "$fcc3"}, + {{"fcc4"}, "$fcc4"}, + {{"fcc5"}, "$fcc5"}, + {{"fcc6"}, "$fcc6"}, + {{"fcc7"}, "$fcc7"}, }; return llvm::ArrayRef(GCCRegAliases); } diff --git a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c index c5ecf0c929af8..cab6182ac61c3 100644 --- a/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c +++ b/clang/test/CodeGen/LoongArch/inline-asm-gcc-regs-error.c @@ -8,13 +8,4 @@ void test(void) { register float a1 asm ("$f32"); // CHECK: :[[#@LINE+1]]:24: error: unknown register name '$foo' in asm register int a2 asm ("$foo"); - -/// Names not prefixed with '$' are invalid. - -// CHECK: :[[#@LINE+1]]:26: error: unknown register name 'f0' in asm - register float a5 asm ("f0"); -// CHECK: :
[clang] [CIR] Implement NotEqualOp for ComplexType (PR #146129)
@@ -901,13 +901,9 @@ class ScalarExprEmitter : public StmtVisitor { assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE); BinOpInfo boInfo = emitBinOps(e); - if (e->getOpcode() == BO_EQ) { -result = -builder.create(loc, boInfo.lhs, boInfo.rhs); - } else { -result = -builder.create(loc, boInfo.lhs, boInfo.rhs); - } + cir::CmpOpKind opKind = + e->getOpcode() == BO_EQ ? cir::CmpOpKind::eq : cir::CmpOpKind::ne; + result = builder.create(loc, opKind, boInfo.lhs, boInfo.rhs); xlauko wrote: ```suggestion result = builder.create(loc, kind, boInfo.lhs, boInfo.rhs); ``` https://github.com/llvm/llvm-project/pull/146129 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Implement NotEqualOp for ComplexType (PR #146129)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/146129 >From 964a930b9f96423d04155b9972bfd8540c59d911 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Fri, 27 Jun 2025 20:10:48 +0200 Subject: [PATCH 1/4] [CIR] Implement NotEqualOp for ComplexType --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 25 +++ clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp| 5 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 38 ++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 10 +++ clang/test/CIR/CodeGen/complex.cpp| 72 +++ 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4daff74cbae5a..b58ebd2dfe509 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2481,6 +2481,31 @@ def ComplexEqualOp : CIR_Op<"complex.eq", [Pure, SameTypeOperands]> { }]; } +//===--===// +// ComplexNotEqualOp +//===--===// + +def ComplexNotEqualOp : CIR_Op<"complex.neq", [Pure, SameTypeOperands]> { + + let summary = "Computes whether two complex values are not equal"; + let description = [{ + The `complex.equal` op takes two complex numbers and returns whether + they are not equal. + +```mlir +%r = cir.complex.neq %a, %b : !cir.complex +``` + }]; + + let results = (outs CIR_BoolType:$result); + let arguments = (ins CIR_ComplexType:$lhs, CIR_ComplexType:$rhs); + + let assemblyFormat = [{ +$lhs `,` $rhs +`:` qualified(type($lhs)) attr-dict + }]; +} + //===--===// // Assume Operations //===--===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..0ba653add826f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -905,9 +905,8 @@ class ScalarExprEmitter : public StmtVisitor { result = builder.create(loc, boInfo.lhs, boInfo.rhs); } else { -assert(!cir::MissingFeatures::complexType()); -cgf.cgm.errorNYI(loc, "complex not equal"); -result = builder.getBool(false, loc); +result = +builder.create(loc, boInfo.lhs, boInfo.rhs); } } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 1034b8780c03c..598283eeaf518 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1903,6 +1903,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMComplexCreateOpLowering, CIRToLLVMComplexEqualOpLowering, CIRToLLVMComplexImagOpLowering, + CIRToLLVMComplexNotEqualOpLowering, CIRToLLVMComplexRealOpLowering, CIRToLLVMConstantOpLowering, CIRToLLVMExpectOpLowering, @@ -2282,6 +2283,43 @@ mlir::LogicalResult CIRToLLVMComplexEqualOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMComplexNotEqualOpLowering::matchAndRewrite( +cir::ComplexNotEqualOp op, OpAdaptor adaptor, +mlir::ConversionPatternRewriter &rewriter) const { + mlir::Value lhs = adaptor.getLhs(); + mlir::Value rhs = adaptor.getRhs(); + + auto complexType = mlir::cast(op.getLhs().getType()); + mlir::Type complexElemTy = + getTypeConverter()->convertType(complexType.getElementType()); + + mlir::Location loc = op.getLoc(); + auto lhsReal = + rewriter.create(loc, complexElemTy, lhs, 0); + auto lhsImag = + rewriter.create(loc, complexElemTy, lhs, 1); + auto rhsReal = + rewriter.create(loc, complexElemTy, rhs, 0); + auto rhsImag = + rewriter.create(loc, complexElemTy, rhs, 1); + + if (complexElemTy.isInteger()) { +auto realCmp = rewriter.create( +loc, mlir::LLVM::ICmpPredicate::ne, lhsReal, rhsReal); +auto imagCmp = rewriter.create( +loc, mlir::LLVM::ICmpPredicate::ne, lhsImag, rhsImag); +rewriter.replaceOpWithNewOp(op, realCmp, imagCmp); +return mlir::success(); + } + + auto realCmp = rewriter.create( + loc, mlir::LLVM::FCmpPredicate::une, lhsReal, rhsReal); + auto imagCmp = rewriter.create( + loc, mlir::LLVM::FCmpPredicate::une, lhsImag, rhsImag); + rewriter.replaceOpWithNewOp(op, realCmp, imagCmp); + return mlir::success(); +} + std::unique_ptr createConvertCIRToLLVMPass() { return std::make_unique(); } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index 25cf218cf8b6c..5cd1d09b88c00 100644 ---
[clang] [CIR] Implement NotEqualOp for ComplexType (PR #146129)
@@ -901,13 +901,9 @@ class ScalarExprEmitter : public StmtVisitor { assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE); BinOpInfo boInfo = emitBinOps(e); - if (e->getOpcode() == BO_EQ) { -result = -builder.create(loc, boInfo.lhs, boInfo.rhs); - } else { -result = -builder.create(loc, boInfo.lhs, boInfo.rhs); - } + cir::CmpOpKind opKind = + e->getOpcode() == BO_EQ ? cir::CmpOpKind::eq : cir::CmpOpKind::ne; + result = builder.create(loc, opKind, boInfo.lhs, boInfo.rhs); AmrDeveloper wrote: Thanks :D https://github.com/llvm/llvm-project/pull/146129 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (PR #138391)
github-actions[bot] wrote: @ziyao233 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/138391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (PR #138391)
https://github.com/heiher approved this pull request. LGTM. https://github.com/llvm/llvm-project/pull/138391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Comma Operator for ComplexType (PR #146204)
https://github.com/xlauko approved this pull request. lgtm https://github.com/llvm/llvm-project/pull/146204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (PR #138391)
https://github.com/heiher closed https://github.com/llvm/llvm-project/pull/138391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Fix a bug in `ReflowComments: Always` (PR #146202)
https://github.com/HazardyKnusperkeks approved this pull request. https://github.com/llvm/llvm-project/pull/146202 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream GenericSelectionExpr (PR #146211)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/146211 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream GenericSelectionExpr (PR #146211)
https://github.com/xlauko approved this pull request. lgtm https://github.com/llvm/llvm-project/pull/146211 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Hexagon] NFC: Reduce the amount of version-specific code (PR #145812)
androm3da wrote: @quic-akaryaki maybe this would fix the `MemorySanitizer: use-of-uninitialized-value`? ``` diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index ecc1b5d2ebe3..5e92ee284769 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -75,6 +75,7 @@ static cl::opt EnableCheckBankConflict( HexagonSubtarget::HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const TargetMachine &TM) : HexagonGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), + HexagonArchVersion(Hexagon::ArchEnum::NoArch), OptLevel(TM.getOptLevel()), CPUString(std::string(Hexagon_MC::selectHexagonCPU(CPU))), TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)), ``` https://github.com/llvm/llvm-project/pull/145812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AVR] Handle flash RO data mapped to data space for newer devices (PR #146244)
https://github.com/tomtor updated https://github.com/llvm/llvm-project/pull/146244 >From a08a6a071db9bf553bb64fcfa39d2ed80e000fe6 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Fri, 27 Jun 2025 17:16:35 +0200 Subject: [PATCH] [AVR] Handle mapped RO data for newer devices --- clang/include/clang/Driver/Options.td | 4 ++ clang/lib/Basic/Targets/AVR.cpp | 6 +++ clang/lib/Driver/ToolChains/AVR.cpp | 15 ++- llvm/lib/Target/AVR/AVRAsmPrinter.cpp | 14 +-- llvm/lib/Target/AVR/AVRDevices.td | 56 --- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0ffd8c40da7da..3a6f1bb2669a1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4886,6 +4886,10 @@ def mguard_EQ : Joined<["-"], "mguard=">, Group, HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">, Values<"none,cf,cf-nochecks">; def mmcu_EQ : Joined<["-"], "mmcu=">, Group; +def mflmap : Flag<["-"], "mflmap">, Group, + HelpText<"Use AVR mapped memory for RO data">; +def mrodata_in_ram : Flag<["-"], "mrodata-in-ram">, Group, + HelpText<"Copy RO data to ram">; def msim : Flag<["-"], "msim">, Group; def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group; def mieee_fp : Flag<["-"], "mieee-fp">, Group; diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index bbe7b01ca036d..4a36bf9cdb132 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -418,6 +418,10 @@ static MCUInfo AVRMcus[] = { } // namespace targets } // namespace clang +static bool ArchHasFLMAP(StringRef Name) { + return Name.starts_with("avr64") || Name.starts_with("avr128"); +} + static bool ArchHasELPM(StringRef Arch) { return llvm::StringSwitch(Arch) .Cases("31", "51", "6", true) @@ -529,6 +533,8 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR_ARCH__", Arch); // TODO: perhaps we should use the information from AVRDevices.td instead? + if (ArchHasFLMAP(DefineName)) +Builder.defineMacro("__AVR_HAVE_FLMAP__"); if (ArchHasELPM(Arch)) Builder.defineMacro("__AVR_HAVE_ELPM__"); if (ArchHasELPMX(Arch)) diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 731076d9754a9..645f9214f091f 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -651,8 +651,19 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger // than the bare minimum supports. - if (Linker.find("avr-ld") != std::string::npos && FamilyName) -CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + if (Linker.find("avr-ld") != std::string::npos && FamilyName) { +// Option to use mapped memory for modern devices with >32kB flash. +// This is the only option for modern devices with <= 32kB flash, +// but the larger default to a copy from flash to RAM (avr-ld version < 14) +// or map the highest 32kB to RAM (avr-ld version >= 14). +if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) { + CmdArgs.push_back( + Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); + CmdArgs.push_back(Args.MakeArgString(std::string("-u"))); + CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init"))); +} else + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + } C.addCommand(std::make_unique( JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index ad8aa5717fb42..decfcc4b67f5d 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -263,11 +263,17 @@ bool AVRAsmPrinter::doFinalization(Module &M) { auto *Section = cast(TLOF.SectionForGlobal(&GO, TM)); if (Section->getName().starts_with(".data")) NeedsCopyData = true; -else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM()) +else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM()) { // AVRs that have a separate program memory (that's most AVRs) store - // .rodata sections in RAM. - NeedsCopyData = true; -else if (Section->getName().starts_with(".bss")) + // .rodata sections in RAM, + // but XMEGA3 family maps all flash in the data space. + // Invoking __do_copy_data with 0 bytes to copy will crash, + // so we let the loader handle this for newer devices. + if (!(SubTM->hasFeatureSetFamilyXMEGA2() || +SubTM->hasFeatureSetFamilyXMEGA3() || +SubTM->hasFeatureSetFamilyXMEGA4())) +
[clang] [clang] [modules] add err_main_in_named_module (PR #146247)
https://github.com/ashwinbanwari edited https://github.com/llvm/llvm-project/pull/146247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [modules] Add err_main_in_named_module (PR #146247)
https://github.com/ashwinbanwari updated https://github.com/llvm/llvm-project/pull/146247 >From f2ed0c7989d7e181004237a4fa2ba7ae1efe44ed Mon Sep 17 00:00:00 2001 From: Ashwin Banwari Date: Sat, 28 Jun 2025 16:19:55 -0700 Subject: [PATCH 1/3] add err_main_in_named_module --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 1 + clang/lib/Sema/SemaDecl.cpp | 8 2 files changed, 9 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5062505cf3c01..94f08300c3dcb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,6 +1062,7 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; +def err_main_in_named_module : Error<"'main' cannot be attached to a named module">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e1cccf068b5aa..c4ddfda9f447f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12490,6 +12490,14 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { : FixItHint()); FD->setInvalidDecl(true); } + +// In C++ [basic.start.main]p3, it is said a program attaching main to a +// named module is ill-formed. +if (FD->isInNamedModule()) { + Diag(FD->getTypeSpecStartLoc(), diag::err_main_in_named_module) + << FixItHint(); + FD->setInvalidDecl(true); +} } // Treat protoless main() as nullary. >From b721f8ff73a67cb3485876e4b4c0de48cc59d194 Mon Sep 17 00:00:00 2001 From: Ashwin Banwari Date: Sat, 28 Jun 2025 16:32:20 -0700 Subject: [PATCH 2/3] git clang-format HEAD~1 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 94f08300c3dcb..ce9017ded0087 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,7 +1062,8 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; -def err_main_in_named_module : Error<"'main' cannot be attached to a named module">; +def err_main_in_named_module +: Error<"'main' cannot be attached to a named module">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; >From 6130b53fc4051a618c612f1d852c7d85557644d2 Mon Sep 17 00:00:00 2001 From: Ashwin Banwari Date: Sat, 28 Jun 2025 16:47:02 -0700 Subject: [PATCH 3/3] don't need FixItHint() ? --- clang/lib/Sema/SemaDecl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c4ddfda9f447f..064e145ff502f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12494,8 +12494,7 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { // In C++ [basic.start.main]p3, it is said a program attaching main to a // named module is ill-formed. if (FD->isInNamedModule()) { - Diag(FD->getTypeSpecStartLoc(), diag::err_main_in_named_module) - << FixItHint(); + Diag(FD->getTypeSpecStartLoc(), diag::err_main_in_named_module); FD->setInvalidDecl(true); } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Make EndsInComma in ContinuationIndenter consistent (PR #146256)
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/146256 None >From b7dd2cee0b6064f29e1f9562d26675152bb2756b Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sat, 28 Jun 2025 18:13:43 -0700 Subject: [PATCH] [clang-format] Make EndsInComma in ContinuationIndenter consistent --- clang/lib/Format/ContinuationIndenter.cpp | 17 + clang/unittests/Format/FormatTest.cpp | 14 -- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b4745477b96ef..4010f7fbd25be 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1929,6 +1929,15 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, return; } + const bool EndsInComma = [](const FormatToken *Tok) { +if (!Tok) + return false; +const auto *Prev = Tok->getPreviousNonComment(); +if (!Prev) + return false; +return Prev->is(tok::comma); + }(Current.MatchingParen); + unsigned NewIndent; unsigned LastSpace = CurrentState.LastSpace; bool AvoidBinPacking; @@ -1948,9 +1957,6 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth; } const FormatToken *NextNonComment = Current.getNextNonComment(); -bool EndsInComma = Current.MatchingParen && - Current.MatchingParen->Previous && - Current.MatchingParen->Previous->is(tok::comma); AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() || !Style.BinPackArguments || (NextNonComment && NextNonComment->isOneOf( @@ -1984,11 +1990,6 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, LastSpace = std::max(LastSpace, CurrentState.Indent); } -bool EndsInComma = -Current.MatchingParen && -Current.MatchingParen->getPreviousNonComment() && -Current.MatchingParen->getPreviousNonComment()->is(tok::comma); - // If ObjCBinPackProtocolList is unspecified, fall back to BinPackParameters // for backwards compatibility. bool ObjCBinPackProtocolList = diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index a05bf8305716b..944e7c3fb152a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -27953,13 +27953,6 @@ TEST_F(FormatTest, AlignArrayOfStructuresLeftAlignmentNonSquare) { "};", Style); verifyFormat("void foo() {\n" - " auto thing = test{\n" - " {\n" - " {13}, {something}, // A\n" - " }\n" - " };\n" - "}", - "void foo() {\n" " auto thing = test{\n" " {\n" " {13},\n" @@ -28017,13 +28010,6 @@ TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { "};", Style); verifyFormat("void foo() {\n" - " auto thing = test{\n" - " {\n" - " {13}, {something}, // A\n" - " }\n" - " };\n" - "}", - "void foo() {\n" " auto thing = test{\n" " {\n" " {13},\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Make EndsInComma in ContinuationIndenter consistent (PR #146256)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: Owen Pan (owenca) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/146256.diff 2 Files Affected: - (modified) clang/lib/Format/ContinuationIndenter.cpp (+9-8) - (modified) clang/unittests/Format/FormatTest.cpp (-14) ``diff diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index b4745477b96ef..4010f7fbd25be 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1929,6 +1929,15 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, return; } + const bool EndsInComma = [](const FormatToken *Tok) { +if (!Tok) + return false; +const auto *Prev = Tok->getPreviousNonComment(); +if (!Prev) + return false; +return Prev->is(tok::comma); + }(Current.MatchingParen); + unsigned NewIndent; unsigned LastSpace = CurrentState.LastSpace; bool AvoidBinPacking; @@ -1948,9 +1957,6 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, NewIndent = CurrentState.LastSpace + Style.ContinuationIndentWidth; } const FormatToken *NextNonComment = Current.getNextNonComment(); -bool EndsInComma = Current.MatchingParen && - Current.MatchingParen->Previous && - Current.MatchingParen->Previous->is(tok::comma); AvoidBinPacking = EndsInComma || Current.is(TT_DictLiteral) || Style.isProto() || !Style.BinPackArguments || (NextNonComment && NextNonComment->isOneOf( @@ -1984,11 +1990,6 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, LastSpace = std::max(LastSpace, CurrentState.Indent); } -bool EndsInComma = -Current.MatchingParen && -Current.MatchingParen->getPreviousNonComment() && -Current.MatchingParen->getPreviousNonComment()->is(tok::comma); - // If ObjCBinPackProtocolList is unspecified, fall back to BinPackParameters // for backwards compatibility. bool ObjCBinPackProtocolList = diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index a05bf8305716b..944e7c3fb152a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -27953,13 +27953,6 @@ TEST_F(FormatTest, AlignArrayOfStructuresLeftAlignmentNonSquare) { "};", Style); verifyFormat("void foo() {\n" - " auto thing = test{\n" - " {\n" - " {13}, {something}, // A\n" - " }\n" - " };\n" - "}", - "void foo() {\n" " auto thing = test{\n" " {\n" " {13},\n" @@ -28017,13 +28010,6 @@ TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { "};", Style); verifyFormat("void foo() {\n" - " auto thing = test{\n" - " {\n" - " {13}, {something}, // A\n" - " }\n" - " };\n" - "}", - "void foo() {\n" " auto thing = test{\n" " {\n" " {13},\n" `` https://github.com/llvm/llvm-project/pull/146256 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Remove unused includes (NFC) (PR #146254)
https://github.com/arsenm approved this pull request. https://github.com/llvm/llvm-project/pull/146254 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream get_bitfield operation to load bit-field members from structs (PR #145971)
@@ -2244,6 +2245,54 @@ mlir::LogicalResult CIRToLLVMComplexImagOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMGetBitfieldOpLowering::matchAndRewrite( +cir::GetBitfieldOp op, OpAdaptor adaptor, +mlir::ConversionPatternRewriter &rewriter) const { + + mlir::OpBuilder::InsertionGuard guard(rewriter); + rewriter.setInsertionPoint(op); + + cir::BitfieldInfoAttr info = op.getBitfieldInfo(); + uint64_t size = info.getSize(); + uint64_t offset = info.getOffset(); + mlir::Type storageType = info.getStorageType(); + mlir::MLIRContext *context = storageType.getContext(); + unsigned storageSize = 0; + + if (auto arTy = mlir::dyn_cast(storageType)) Andres-Salamanca wrote: Yes, we can still produce arrays when clipping. Here's an example: https://godbolt.org/z/sGae8vcze. The CodeGen explanation for this case is here: https://github.com/llvm/llvm-project/blob/fb24b4d46a0a8278031f42c1cba6c030eb6c6010/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp#L44C1-L49C27 Also, clipping can occur when the target does not support unaligned bitfield access, when `!astContext.getTargetInfo().hasCheapUnalignedBitFieldAccess()` is true. However, for our case, that's currently NYI. https://github.com/llvm/llvm-project/pull/145971 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AVR] Handle flash RO data mapped to data space for newer devices (PR #146244)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Tom Vijlbrief (tomtor) Changes Newer AVR devices map (part of the) flash to a 32kB window at 0x8000 in the data/IO space. The linker correctly loads readonly data at 0x8000, but we currently always pull in `__do_copy_data` when we encounter RO data. This fails when we have no other initialized data in `.data` because the copy loop expects to copy at least 1 byte. When the size is `0` it tries to copy 0x1 bytes. Newer versions of `avr-ld` (invoked via `avr-gcc`) handle this correctly, and users of newer devices must always install recent `avr-ld` and `avr-lib` versions to gain access to loader spec files and `crt` files. For older devices and older `avr-ld` the old approach remains unchanged. Also add some support for devices with an `flmap` register (xmega2 and xmega4 with >= 64kB flash). --- Full diff: https://github.com/llvm/llvm-project/pull/146244.diff 5 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+4) - (modified) clang/lib/Basic/Targets/AVR.cpp (+6) - (modified) clang/lib/Driver/ToolChains/AVR.cpp (+13-2) - (modified) llvm/lib/Target/AVR/AVRAsmPrinter.cpp (+10-4) - (modified) llvm/lib/Target/AVR/AVRDevices.td (+34-22) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0ffd8c40da7da..3a6f1bb2669a1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4886,6 +4886,10 @@ def mguard_EQ : Joined<["-"], "mguard=">, Group, HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">, Values<"none,cf,cf-nochecks">; def mmcu_EQ : Joined<["-"], "mmcu=">, Group; +def mflmap : Flag<["-"], "mflmap">, Group, + HelpText<"Use AVR mapped memory for RO data">; +def mrodata_in_ram : Flag<["-"], "mrodata-in-ram">, Group, + HelpText<"Copy RO data to ram">; def msim : Flag<["-"], "msim">, Group; def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group; def mieee_fp : Flag<["-"], "mieee-fp">, Group; diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index bbe7b01ca036d..448e72206776f 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -418,6 +418,10 @@ static MCUInfo AVRMcus[] = { } // namespace targets } // namespace clang +static bool ArchHasFLMAP(StringRef Name) { + return Name.starts_with("avr64") or Name.starts_with("avr128"); +} + static bool ArchHasELPM(StringRef Arch) { return llvm::StringSwitch(Arch) .Cases("31", "51", "6", true) @@ -529,6 +533,8 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR_ARCH__", Arch); // TODO: perhaps we should use the information from AVRDevices.td instead? + if (ArchHasFLMAP(DefineName)) +Builder.defineMacro("__AVR_HAVE_FLMAP__"); if (ArchHasELPM(Arch)) Builder.defineMacro("__AVR_HAVE_ELPM__"); if (ArchHasELPMX(Arch)) diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 731076d9754a9..155e0d812c95f 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -651,8 +651,19 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger // than the bare minimum supports. - if (Linker.find("avr-ld") != std::string::npos && FamilyName) -CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + if (Linker.find("avr-ld") != std::string::npos && FamilyName) { +// Option to use mapped memory for modern devices with >32kB flash. +// This is the only option for modern devices with <= 32kB flash, +// but the larger default to a copy from flash to RAM (avr-ld version < 14) +// or map the highest 32kB to RAM (avr-ld version >= 14). +if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) { + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); + CmdArgs.push_back(Args.MakeArgString(std::string("-u"))); + CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init"))); +} +else + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + } C.addCommand(std::make_unique( JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index ad8aa5717fb42..decfcc4b67f5d 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -263,11 +263,17 @@ bool AVRAsmPrinter::doFinalization(Module &M) { auto *Section = cast(TLOF.SectionForGlobal(&GO, TM)); if (Section->getName().starts_with(".data")) NeedsCopyData = true; -else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM()) +
[clang] [llvm] [AVR] Handle flash RO data mapped to data space for newer devices (PR #146244)
llvmbot wrote: @llvm/pr-subscribers-clang-driver Author: Tom Vijlbrief (tomtor) Changes Newer AVR devices map (part of the) flash to a 32kB window at 0x8000 in the data/IO space. The linker correctly loads readonly data at 0x8000, but we currently always pull in `__do_copy_data` when we encounter RO data. This fails when we have no other initialized data in `.data` because the copy loop expects to copy at least 1 byte. When the size is `0` it tries to copy 0x1 bytes. Newer versions of `avr-ld` (invoked via `avr-gcc`) handle this correctly, and users of newer devices must always install recent `avr-ld` and `avr-lib` versions to gain access to loader spec files and `crt` files. For older devices and older `avr-ld` the old approach remains unchanged. Also add some support for devices with an `flmap` register (xmega2 and xmega4 with >= 64kB flash). --- Full diff: https://github.com/llvm/llvm-project/pull/146244.diff 5 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+4) - (modified) clang/lib/Basic/Targets/AVR.cpp (+6) - (modified) clang/lib/Driver/ToolChains/AVR.cpp (+13-2) - (modified) llvm/lib/Target/AVR/AVRAsmPrinter.cpp (+10-4) - (modified) llvm/lib/Target/AVR/AVRDevices.td (+34-22) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0ffd8c40da7da..3a6f1bb2669a1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4886,6 +4886,10 @@ def mguard_EQ : Joined<["-"], "mguard=">, Group, HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">, Values<"none,cf,cf-nochecks">; def mmcu_EQ : Joined<["-"], "mmcu=">, Group; +def mflmap : Flag<["-"], "mflmap">, Group, + HelpText<"Use AVR mapped memory for RO data">; +def mrodata_in_ram : Flag<["-"], "mrodata-in-ram">, Group, + HelpText<"Copy RO data to ram">; def msim : Flag<["-"], "msim">, Group; def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group; def mieee_fp : Flag<["-"], "mieee-fp">, Group; diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index bbe7b01ca036d..448e72206776f 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -418,6 +418,10 @@ static MCUInfo AVRMcus[] = { } // namespace targets } // namespace clang +static bool ArchHasFLMAP(StringRef Name) { + return Name.starts_with("avr64") or Name.starts_with("avr128"); +} + static bool ArchHasELPM(StringRef Arch) { return llvm::StringSwitch(Arch) .Cases("31", "51", "6", true) @@ -529,6 +533,8 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR_ARCH__", Arch); // TODO: perhaps we should use the information from AVRDevices.td instead? + if (ArchHasFLMAP(DefineName)) +Builder.defineMacro("__AVR_HAVE_FLMAP__"); if (ArchHasELPM(Arch)) Builder.defineMacro("__AVR_HAVE_ELPM__"); if (ArchHasELPMX(Arch)) diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 731076d9754a9..155e0d812c95f 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -651,8 +651,19 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger // than the bare minimum supports. - if (Linker.find("avr-ld") != std::string::npos && FamilyName) -CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + if (Linker.find("avr-ld") != std::string::npos && FamilyName) { +// Option to use mapped memory for modern devices with >32kB flash. +// This is the only option for modern devices with <= 32kB flash, +// but the larger default to a copy from flash to RAM (avr-ld version < 14) +// or map the highest 32kB to RAM (avr-ld version >= 14). +if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) { + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); + CmdArgs.push_back(Args.MakeArgString(std::string("-u"))); + CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init"))); +} +else + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + } C.addCommand(std::make_unique( JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index ad8aa5717fb42..decfcc4b67f5d 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -263,11 +263,17 @@ bool AVRAsmPrinter::doFinalization(Module &M) { auto *Section = cast(TLOF.SectionForGlobal(&GO, TM)); if (Section->getName().starts_with(".data")) NeedsCopyData = true; -else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM()
[clang] [llvm] [AVR] Handle flash RO data mapped to data space for newer devices (PR #146244)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp -- clang/lib/Basic/Targets/AVR.cpp clang/lib/Driver/ToolChains/AVR.cpp llvm/lib/Target/AVR/AVRAsmPrinter.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 155e0d812..645f9214f 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -657,11 +657,11 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, // but the larger default to a copy from flash to RAM (avr-ld version < 14) // or map the highest 32kB to RAM (avr-ld version >= 14). if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) { - CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); + CmdArgs.push_back( + Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); CmdArgs.push_back(Args.MakeArgString(std::string("-u"))); CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init"))); -} -else +} else CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); } `` https://github.com/llvm/llvm-project/pull/146244 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f771d08 - [clang-format] Fix a bug in `ReflowComments: Always` (#146202)
Author: Owen Pan Date: 2025-06-28T15:23:00-07:00 New Revision: f771d08a24762dada69bf426016f5fd1cf83a437 URL: https://github.com/llvm/llvm-project/commit/f771d08a24762dada69bf426016f5fd1cf83a437 DIFF: https://github.com/llvm/llvm-project/commit/f771d08a24762dada69bf426016f5fd1cf83a437.diff LOG: [clang-format] Fix a bug in `ReflowComments: Always` (#146202) Fixes #39150 Added: Modified: clang/lib/Format/BreakableToken.cpp clang/unittests/Format/FormatTestComments.cpp Removed: diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 5317c05f3a460..def0d73e77539 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -158,8 +158,7 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, return BreakableToken::Split(StringRef::npos, 0); StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks); StringRef AfterCut = Text.substr(SpaceOffset); -// Don't trim the leading blanks if it would create a */ after the break. -if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/') +if (!DecorationEndsWithStar) AfterCut = AfterCut.ltrim(Blanks); return BreakableToken::Split(BeforeCut.size(), AfterCut.begin() - BeforeCut.end()); diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 5eefd767706a3..a16fbffb76270 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2486,7 +2486,7 @@ TEST_F(FormatTestComments, BlockComments) { EXPECT_EQ("/*\n" "**\n" "* aa\n" -"*aa\n" +"* aa\n" "*/", format("/*\n" "**\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Fix a bug in `ReflowComments: Always` (PR #146202)
https://github.com/owenca closed https://github.com/llvm/llvm-project/pull/146202 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [modules] add err_main_in_named_module (PR #146247)
https://github.com/ashwinbanwari created https://github.com/llvm/llvm-project/pull/146247 Close https://github.com/llvm/llvm-project/issues/146229 As the issue said, main shouldn't be in any modules. New Error Output: ``` /my/code/directory/main.cpp:3:1: error: 'main' cannot be attached to a named module 3 | int main() { | ^ 1 error generated. ``` >From f2ed0c7989d7e181004237a4fa2ba7ae1efe44ed Mon Sep 17 00:00:00 2001 From: Ashwin Banwari Date: Sat, 28 Jun 2025 16:19:55 -0700 Subject: [PATCH 1/2] add err_main_in_named_module --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 1 + clang/lib/Sema/SemaDecl.cpp | 8 2 files changed, 9 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5062505cf3c01..94f08300c3dcb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,6 +1062,7 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; +def err_main_in_named_module : Error<"'main' cannot be attached to a named module">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e1cccf068b5aa..c4ddfda9f447f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12490,6 +12490,14 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { : FixItHint()); FD->setInvalidDecl(true); } + +// In C++ [basic.start.main]p3, it is said a program attaching main to a +// named module is ill-formed. +if (FD->isInNamedModule()) { + Diag(FD->getTypeSpecStartLoc(), diag::err_main_in_named_module) + << FixItHint(); + FD->setInvalidDecl(true); +} } // Treat protoless main() as nullary. >From b721f8ff73a67cb3485876e4b4c0de48cc59d194 Mon Sep 17 00:00:00 2001 From: Ashwin Banwari Date: Sat, 28 Jun 2025 16:32:20 -0700 Subject: [PATCH 2/2] git clang-format HEAD~1 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 94f08300c3dcb..ce9017ded0087 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,7 +1062,8 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; -def err_main_in_named_module : Error<"'main' cannot be attached to a named module">; +def err_main_in_named_module +: Error<"'main' cannot be attached to a named module">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [modules] add err_main_in_named_module (PR #146247)
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/146247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [modules] Add err_main_in_named_module (PR #146247)
https://github.com/ashwinbanwari edited https://github.com/llvm/llvm-project/pull/146247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [modules] add err_main_in_named_module (PR #146247)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Ashwin Banwari (ashwinbanwari) Changes Close https://github.com/llvm/llvm-project/issues/146229 As the issue said, main shouldn't be in any modules. New Error Output: ``` /my/code/directory/main.cpp:3:1: error: 'main' cannot be attached to a named module 3 | int main() { | ^ 1 error generated. ``` --- Full diff: https://github.com/llvm/llvm-project/pull/146247.diff 2 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) - (modified) clang/lib/Sema/SemaDecl.cpp (+8) ``diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5062505cf3c01..ce9017ded0087 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1062,6 +1062,8 @@ def err_constexpr_main : Error< "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; +def err_main_in_named_module +: Error<"'main' cannot be attached to a named module">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">, InGroup; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e1cccf068b5aa..c4ddfda9f447f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12490,6 +12490,14 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { : FixItHint()); FD->setInvalidDecl(true); } + +// In C++ [basic.start.main]p3, it is said a program attaching main to a +// named module is ill-formed. +if (FD->isInNamedModule()) { + Diag(FD->getTypeSpecStartLoc(), diag::err_main_in_named_module) + << FixItHint(); + FD->setInvalidDecl(true); +} } // Treat protoless main() as nullary. `` https://github.com/llvm/llvm-project/pull/146247 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream get_bitfield operation to load bit-field members from structs (PR #145971)
@@ -405,6 +406,16 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { return createGlobal(module, loc, uniqueName, type, linkage); } + + mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType, +mlir::Value addr, mlir::Type storageType, +const CIRGenBitFieldInfo &info, +bool isLvalueVolatile, bool useVolatile) { +unsigned int offset = useVolatile ? info.volatileOffset : info.offset; Andres-Salamanca wrote: Yes, I agree that’s why I was always calling this function with `useVolatile = false`. I'm going to remove this for now and always use info.offset https://github.com/llvm/llvm-project/pull/145971 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AVR] Handle flash RO data mapped to data space for newer devices (PR #146244)
https://github.com/tomtor created https://github.com/llvm/llvm-project/pull/146244 Newer AVR devices map (part of the) flash to a 32kB window at 0x8000 in the data/IO space. The linker correctly loads readonly data at 0x8000, but we currently always pull in `__do_copy_data` when we encounter RO data. This fails when we have no other initialized data in `.data` because the copy loop expects to copy at least 1 byte. When the size is `0` it tries to copy 0x1 bytes. Newer versions of `avr-ld` (invoked via `avr-gcc`) handle this correctly, and users of newer devices must always install recent `avr-ld` and `avr-lib` versions to gain access to loader spec files and `crt` files. For older devices and older `avr-ld` the old approach remains unchanged. Also add some support for devices with an `flmap` register (xmega2 and xmega4 with >= 64kB flash). >From 47e76c16b4352d968b0194bd7a046da3f83b37e3 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Fri, 27 Jun 2025 17:16:35 +0200 Subject: [PATCH] [AVR] Handle mapped RO data for newer devices --- clang/include/clang/Driver/Options.td | 4 ++ clang/lib/Basic/Targets/AVR.cpp | 6 +++ clang/lib/Driver/ToolChains/AVR.cpp | 15 ++- llvm/lib/Target/AVR/AVRAsmPrinter.cpp | 14 +-- llvm/lib/Target/AVR/AVRDevices.td | 56 --- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0ffd8c40da7da..3a6f1bb2669a1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4886,6 +4886,10 @@ def mguard_EQ : Joined<["-"], "mguard=">, Group, HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">, Values<"none,cf,cf-nochecks">; def mmcu_EQ : Joined<["-"], "mmcu=">, Group; +def mflmap : Flag<["-"], "mflmap">, Group, + HelpText<"Use AVR mapped memory for RO data">; +def mrodata_in_ram : Flag<["-"], "mrodata-in-ram">, Group, + HelpText<"Copy RO data to ram">; def msim : Flag<["-"], "msim">, Group; def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group; def mieee_fp : Flag<["-"], "mieee-fp">, Group; diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index bbe7b01ca036d..448e72206776f 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -418,6 +418,10 @@ static MCUInfo AVRMcus[] = { } // namespace targets } // namespace clang +static bool ArchHasFLMAP(StringRef Name) { + return Name.starts_with("avr64") or Name.starts_with("avr128"); +} + static bool ArchHasELPM(StringRef Arch) { return llvm::StringSwitch(Arch) .Cases("31", "51", "6", true) @@ -529,6 +533,8 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR_ARCH__", Arch); // TODO: perhaps we should use the information from AVRDevices.td instead? + if (ArchHasFLMAP(DefineName)) +Builder.defineMacro("__AVR_HAVE_FLMAP__"); if (ArchHasELPM(Arch)) Builder.defineMacro("__AVR_HAVE_ELPM__"); if (ArchHasELPMX(Arch)) diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index 731076d9754a9..155e0d812c95f 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -651,8 +651,19 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger // than the bare minimum supports. - if (Linker.find("avr-ld") != std::string::npos && FamilyName) -CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + if (Linker.find("avr-ld") != std::string::npos && FamilyName) { +// Option to use mapped memory for modern devices with >32kB flash. +// This is the only option for modern devices with <= 32kB flash, +// but the larger default to a copy from flash to RAM (avr-ld version < 14) +// or map the highest 32kB to RAM (avr-ld version >= 14). +if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) { + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap")); + CmdArgs.push_back(Args.MakeArgString(std::string("-u"))); + CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init"))); +} +else + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + } C.addCommand(std::make_unique( JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp index ad8aa5717fb42..decfcc4b67f5d 100644 --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -263,11 +263,17 @@ bool AVRAsmPrinter::doFinalization(Module &M) { auto *Section = cast(TLOF.SectionForGlobal(&GO, TM)); if (Section->getName().sta
[clang] [llvm] [NFC][analyzer] Remove Z3-as-constraint-manager hacks from lit test code (PR #145731)
mgorny wrote: Unfortunately, after fixing the immediate issue I'm hitting another issue: `%host_cxx` is compiling a 64-bit library when doing `-m32` build for x86 — meaning the test run now fails due to ABI mismatch: ``` FAIL: Clang :: Analysis/z3-crosscheck-max-attempts.cpp (1537 of 21645) TEST 'Clang :: Analysis/z3-crosscheck-max-attempts.cpp' FAILED Exit Code: 1 Command Output (stderr): -- /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/clang -cc1 -internal-isystem /var/tmp/portage/llvm-core/ clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/../../../../lib/clang/21/include -nostdsysteminc -analyze -setup-static-analyzer -a nalyzer-checker=debug.ConfigDumper 2>&1 | /usr/lib/llvm/21/bin/FileCheck /var/tmp/portage/llvm-core/clang-21.0.0./work/clang/test/ Analysis/z3-crosscheck-max-attempts.cpp --match-full-lines # RUN: at line 2 + /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/clang -cc1 -internal-isystem /var/tmp/portage/llvm-cor e/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/../../../../lib/clang/21/include -nostdsysteminc -analyze -setup-static-analyzer -analyzer-checker=debug.ConfigDumper + /usr/lib/llvm/21/bin/FileCheck /var/tmp/portage/llvm-core/clang-21.0.0./work/clang/test/Analysis/z3-crosscheck-max-attempts.cpp - -match-full-lines rm -rf /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts.cpp.t mp && mkdir /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts. cpp.tmp # RUN: at line 6 + rm -rf /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts.cpp .tmp + mkdir /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts.cpp. tmp /usr/lib/ccache/bin/x86_64-pc-linux-gnu-g++ -shared -fPIC -I /usr/include /var/tmp/portage/llvm-core/clang-21.0.0./work/c lang/test/Analysis/z3/Inputs/MockZ3_solver_check.cpp -o /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x 86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts.cpp.tmp/MockZ3_solver_check.so # RUN: at line 7 + /usr/lib/ccache/bin/x86_64-pc-linux-gnu-g++ -shared -fPIC -I /usr/include /var/tmp/portage/llvm-core/clang-21.0.0./work/clang/tes t/Analysis/z3/Inputs/MockZ3_solver_check.cpp -o /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysi s/Output/z3-crosscheck-max-attempts.cpp.tmp/MockZ3_solver_check.so not /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/clang -cc1 -internal-isystem /var/tmp/portage/llvm-c ore/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/../../../../lib/clang/21/include -nostdsysteminc -analyze -setup-static-analyze r -analyzer-config crosscheck-with-z3-max-attempts-per-query=0 2>&1 | /usr/lib/llvm/21/bin/FileCheck /var/tmp/portage/llvm-core/clang-2 1.0.0./work/clang/test/Analysis/z3-crosscheck-max-attempts.cpp --check-prefix=VERIFY-INVALID # RUN: at line 19 + not /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/clang -cc1 -internal-isystem /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/../../../../lib/clang/21/include -nostdsysteminc -analyze -setup-static-analyzer -analyzer-config crosscheck-with-z3-max-attempts-per-query=0 + /usr/lib/llvm/21/bin/FileCheck /var/tmp/portage/llvm-core/clang-21.0.0./work/clang/test/Analysis/z3-crosscheck-max-attempts.cpp --check-prefix=VERIFY-INVALID Z3_SOLVER_RESULTS="UNDEF" LD_PRELOAD="/var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosscheck-max-attempts.cpp.tmp/MockZ3_solver_check.so" /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/clang -cc1 -internal-isystem /var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/bin/../../../../lib/clang/21/include -nostdsysteminc /var/tmp/portage/llvm-core/clang-21.0.0./work/clang/test/Analysis/z3-crosscheck-max-attempts.cpp -analyze -setup-static-analyzer -analyzer-config crosscheck-with-z3=true -analyzer-checker=core -analyzer-config crosscheck-with-z3-max-attempts-per-query=1 -verify=refuted # RUN: at line 22 + Z3_SOLVER_RESULTS=UNDEF + LD_PRELOAD=/var/tmp/portage/llvm-core/clang-21.0.0./work/x/y/clang-abi_x86_32.x86/test/Analysis/Output/z3-crosschec
[clang] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field (PR #145066)
https://github.com/Tedlion updated https://github.com/llvm/llvm-project/pull/145066 >From 03004d9a9348e365a2d2d05e69f83fc404ddb605 Mon Sep 17 00:00:00 2001 From: tangwy Date: Sat, 21 Jun 2025 00:22:10 +0800 Subject: [PATCH 1/6] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field For the following code: struct B{ int i :2; int:30; // unnamed bit-field }; extern void consume_B(B); void bitfield_B_init(void) { B b1; b1.i = 1; // b1 is initialized consume_B(b1); } The current clang static analyzer gives false positive warning "Passed-by-value struct argument contains uninitialized data (e.g., field: '') [core.CallAndMessage]" when taking the source as C code. However, no such warning is generated when clang takes the source as C++ code. After comparing the CallAndMessageChecker's different behaviors between C and C++, the reason is found: When FindUninitializedField::Find(const TypedValueRegion *R) is invoked, the concrete type of R is different. In C, 'b1' is considered to be a 'StackLocalsSpaceRegion', which makes 'StoreMgr.getBinding(store, loc::MemRegionVal(FR))' return an 'UndefinedVal'. While in c++, 'b1' is considered to be a 'tackArgumentsSpaceRegion', which finally makes the 'getBinding' return a SymbolVal. I am not quite sure about the region difference, maybe in C++ there is an implicit copy constructor function? Anyway, the unnamed bit-field is undefined, for it cannot be written unless using memory operation such as 'memset'. So a special check FD->isUnnamedBitField() is added in RegionStoreManager::getBindingForField in file RegionStore.cpp. To handle the false warning, a check isUnnamedBitField is also added in FindUninitializedField::Find in file CallAndMessageChecker.cpp. Testcases of unnamed bit-field are added in file call-and-message.c and call-and-message.cpp. I do not know what to do on the hash, so it may be updated? --- .../Checkers/CallAndMessageChecker.cpp| 2 +- clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 15 ++- clang/test/Analysis/call-and-message.c| 27 ++- clang/test/Analysis/call-and-message.cpp | 16 +++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 86476b32309c3..677cc6ee57ad2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -259,7 +259,7 @@ class FindUninitializedField { if (T->getAsStructureType()) { if (Find(FR)) return true; -} else { +} else if (!I->isUnnamedBitField()){ SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); if (V.isUndef()) return true; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 388034b087789..1208036700f32 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2122,8 +2122,21 @@ SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B, if (const std::optional &V = B.getDirectBinding(R)) return *V; - // If the containing record was initialized, try to get its constant value. + // UnnamedBitField is always Undefined unless using memory operation such + // as 'memset'. + // For example, for code + //typedef struct { + // int i :2; + // int:30; // unnamed bit-field + //} A; + //A a = {1}; + // The bits of the unnamed bit-field in local variable a can be anything. const FieldDecl *FD = R->getDecl(); + if (FD->isUnnamedBitField()) { + return UndefinedVal(); + } + + // If the containing record was initialized, try to get its constant value. QualType Ty = FD->getType(); const MemRegion* superR = R->getSuperRegion(); if (const auto *VR = dyn_cast(superR)) { diff --git a/clang/test/Analysis/call-and-message.c b/clang/test/Analysis/call-and-message.c index b79ec8c344b6c..e2fba55d3343d 100644 --- a/clang/test/Analysis/call-and-message.c +++ b/clang/test/Analysis/call-and-message.c @@ -1,12 +1,19 @@ // RUN: %clang_analyze_cc1 %s -verify \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=true \ +// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false \ // RUN: -analyzer-output=plist -o %t.plist // RUN: cat %t.plist | FileCheck %s // RUN: %clang_analyze_cc1 %s -verify=no-pointee \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false +// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=false \ +// RUN: -analyzer-config core.CallAndMessage:ArgInitializedness=false + +// RUN: %clang_analyze_cc1 %s -verify=arg-init \ +// RU
[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `clangd-ubuntu-tsan` running on `clangd-ubuntu-clang` while building `clang` at step 5 "build-clangd-clangd-index-server-clangd-indexer". Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/21502 Here is the relevant piece of the build log for the reference ``` Step 5 (build-clangd-clangd-index-server-clangd-indexer) failure: build (failure) 0.008 [3320/18/1] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o FAILED: lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o ccache /usr/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/lib/Demangle -I/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/llvm-project/llvm/lib/Demangle -I/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/include -I/vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fno-omit-frame-pointer -gline-tables-only -fsanitize=thread -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o -MF lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o.d -o lib/Demangle/CMakeFiles/LLVMDemangle.dir/DLangDemangle.cpp.o -c /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/llvm-project/llvm/lib/Demangle/DLangDemangle.cpp ccache: error: /vol/ccache/ccache.conf: No such file or directory 0.010 [3320/17/2] Creating /vol/worker/clangd-ubuntu-clang/clangd-ubuntu-tsan/build/NATIVE... 0.083 [3320/16/3] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/ABIBreak.cpp.o 0.594 [3320/15/4] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/Demangle.cpp.o 1.115 [3320/14/5] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/RustDemangle.cpp.o 1.176 [3320/13/6] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/ARMBuildAttributes.cpp.o 1.180 [3320/12/7] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/InstructionCost.cpp.o 1.194 [3320/11/8] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/HexagonAttributes.cpp.o 1.425 [3320/10/9] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/APSInt.cpp.o 1.515 [3320/9/10] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangleNodes.cpp.o 1.557 [3320/8/11] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/HexagonAttributeParser.cpp.o 1.638 [3320/7/12] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/InitLLVM.cpp.o 2.120 [3320/6/13] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/APFixedPoint.cpp.o 2.275 [3320/5/14] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/MicrosoftDemangle.cpp.o 2.463 [3320/4/15] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/AMDGPUMetadata.cpp.o 4.152 [3320/3/16] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/APInt.cpp.o 4.356 [3320/2/17] Building CXX object lib/Support/CMakeFiles/LLVMSupport.dir/APFloat.cpp.o 5.127 [3320/1/18] Building CXX object lib/Demangle/CMakeFiles/LLVMDemangle.dir/ItaniumDemangle.cpp.o ninja: build stopped: subcommand failed. ``` https://github.com/llvm/llvm-project/pull/142651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)
https://github.com/vogelsgesang closed https://github.com/llvm/llvm-project/pull/142651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b8f1228 - [docs][coroutines] Revamp "Debugging C++ coroutines" (#142651)
Author: Adrian Vogelsgesang Date: 2025-06-28T15:27:55+02:00 New Revision: b8f122812e0ac4f262e98cf2661f4495553791e6 URL: https://github.com/llvm/llvm-project/commit/b8f122812e0ac4f262e98cf2661f4495553791e6 DIFF: https://github.com/llvm/llvm-project/commit/b8f122812e0ac4f262e98cf2661f4495553791e6.diff LOG: [docs][coroutines] Revamp "Debugging C++ coroutines" (#142651) This commit is a major overhaul of the documentation on debugging C++ coroutines with the following goals: * Make it more accessible to casual C++ programmers, i.e. non-toolchain developers. Move the low-level details around ABI further down, and instead start with real-life examples and copy-paste-friendly code, first. * Cover LLDB in addition to GCC. Provide copy-pasteable scripts for LLDB and not only GCC. * Cover additional topics, such as: * single-stepping into a coroutine * using `__builtin_return_address` for tracking suspension points (inspired by Folly's blog series on coroutine debugging) * Document LLDB's support for devirtualization of `std::coroutine_handle`, both from an end user perspective as well as its internal implementation Added: clang/docs/coro-async-task-continuations.png clang/docs/coro-generator-suspended.png clang/docs/coro-generator-variables.png Modified: clang/docs/DebuggingCoroutines.rst Removed: diff --git a/clang/docs/DebuggingCoroutines.rst b/clang/docs/DebuggingCoroutines.rst index 80df321340724..c47579bc62e51 100644 --- a/clang/docs/DebuggingCoroutines.rst +++ b/clang/docs/DebuggingCoroutines.rst @@ -8,288 +8,722 @@ Debugging C++ Coroutines Introduction -For performance and other architectural reasons, the C++ Coroutines feature in -the Clang compiler is implemented in two parts of the compiler. Semantic -analysis is performed in Clang, and Coroutine construction and optimization -takes place in the LLVM middle-end. +Coroutines in C++ were introduced in C++20, and the user experience for +debugging them can still be challenging. This document guides you how to most +efficiently debug coroutines and how to navigate existing shortcomings in +debuggers and compilers. + +Coroutines are generally used either as generators or for asynchronous +programming. In this document, we will discuss both use cases. Even if you are +using coroutines for asynchronous programming, you should still read the +generators section, as it will introduce foundational debugging techniques also +applicable to the debugging of asynchronous programs. + +Both compilers (clang, gcc, ...) and debuggers (lldb, gdb, ...) are +still improving their support for coroutines. As such, we recommend using the +latest available version of your toolchain. + +This document focuses on clang and lldb. The screenshots show +[lldb-dap](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.lldb-dap) +in combination with VS Code. The same techniques can also be used in other +IDEs. + +Debugging clang-compiled binaries with gdb is possible, but requires more +scripting. This guide comes with a basic GDB script for coroutine debugging. + +This guide will first showcase the more polished, bleeding-edge experience, but +will also show you how to debug coroutines with older toolchains. In general, +the older your toolchain, the deeper you will have to dive into the +implementation details of coroutines (such as their ABI). The further down in +this document you go, the more low-level, technical the content will become. If +you are on an up-to-date toolchain, you will hopefully be able to stop reading +earlier. + +Debugging generators + + +One of the two major use cases for coroutines in C++ are generators, i.e., +functions which can produce values via ``co_yield``. Values are produced +lazily, on-demand. For that purpose, every time a new value is requested the +coroutine gets resumed. As soon as it reaches a ``co_yield`` and thereby +returns the requested value, the coroutine is suspended again. + +This logic is encapsulated in a ``generator`` type similar to this one: -However, this design forces us to generate insufficient debugging information. -Typically, the compiler generates debug information in the Clang frontend, as -debug information is highly language specific. However, this is not possible -for Coroutine frames because the frames are constructed in the LLVM middle-end. - -To mitigate this problem, the LLVM middle end attempts to generate some debug -information, which is unfortunately incomplete, since much of the language -specific information is missing in the middle end. +.. code-block:: c++ -This document describes how to use this debug information to better debug -coroutines. + // generator.hpp + #include -Terminology -=== + // `generator` is a stripped down, minimal generator type. + template + struct generator { +struct promi
[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)
@@ -8,470 +8,966 @@ Debugging C++ Coroutines Introduction -For performance and other architectural reasons, the C++ Coroutines feature in -the Clang compiler is implemented in two parts of the compiler. Semantic -analysis is performed in Clang, and Coroutine construction and optimization -takes place in the LLVM middle-end. vogelsgesang wrote: I merged this now, since I want to be able to point people to the documentation from a discourse thread. Let me know if I missed anything. Happy to update this further also post-commit https://github.com/llvm/llvm-project/pull/142651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` (PR #146212)
https://github.com/flovent created https://github.com/llvm/llvm-project/pull/146212 Bounded string functions takes smallest of two values as it's copy size (`amountCopied` variable in `evalStrcpyCommon`), and it's used to decided whether this operation will cause out-of-bound access and invalidate it's super region if it does. for `strlcat`: `amountCopied = min (size - dstLen - 1 , srcLen)` for others: `amountCopied = min (srcLen, size)` Currently when one of two values is unknown or `SValBuilder` can't decide which one is smaller, `amountCopied` will remain `UnknownVal`, which will invalidate copy destination's super region unconditionally. This patch add check to see if one of these two values is definitely in-bound, if so `amountCopied` has to be in-bound too, because it‘s less than or equal to them, we can avoid the invalidation of super region and some related false positives in this situation. Closes #143807. >From 9da53c788fc01cd3fc2dd4c178b836035b5d380b Mon Sep 17 00:00:00 2001 From: flovent Date: Sat, 28 Jun 2025 20:58:43 +0800 Subject: [PATCH] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` --- .../Checkers/CStringChecker.cpp | 77 - .../cstring-should-not-invalidate.cpp | 107 ++ 2 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 clang/test/Analysis/cstring-should-not-invalidate.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 4d12fdcec1f1a..433fd2ce5f292 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -272,7 +272,8 @@ class CStringChecker : public Checker< eval::Call, static ProgramStateRef invalidateDestinationBufferBySize(CheckerContext &C, ProgramStateRef S, const Expr *BufE, ConstCFGElementRef Elem, -SVal BufV, SVal SizeV, QualType SizeTy); +SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound = true); /// Operation never overflows, do not invalidate the super region. static ProgramStateRef invalidateDestinationBufferNeverOverflows( @@ -1211,14 +1212,17 @@ bool CStringChecker::isFirstBufInBound(CheckerContext &C, ProgramStateRef State, ProgramStateRef CStringChecker::invalidateDestinationBufferBySize( CheckerContext &C, ProgramStateRef S, const Expr *BufE, -ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy) { +ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound) { auto InvalidationTraitOperations = - [&C, S, BufTy = BufE->getType(), BufV, SizeV, - SizeTy](RegionAndSymbolInvalidationTraits &ITraits, const MemRegion *R) { + [&C, S, BufTy = BufE->getType(), BufV, SizeV, SizeTy, + CouldAccessOutOfBound](RegionAndSymbolInvalidationTraits &ITraits, + const MemRegion *R) { // If destination buffer is a field region and access is in bound, do // not invalidate its super region. if (MemRegion::FieldRegionKind == R->getKind() && -isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy)) { +(!CouldAccessOutOfBound || + isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy))) { ITraits.setTrait( R, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); @@ -2223,6 +2227,67 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, Result = lastElement; } +// For bounded method, amountCopied take the minimum of two values, +// for ConcatFnKind::strlcat: +// amountCopied = min (size - dstLen - 1 , srcLen) +// for others: +// amountCopied = min (srcLen, size) +// So even if we don't know about amountCopied, as long as one of them will +// not cause an out-of-bound access, the whole function's operation will not +// too, that will avoid invalidating the superRegion of data member in that +// situation. +bool CouldAccessOutOfBound = true; +if (IsBounded && amountCopied.isUnknown()) { + // Get the max number of characters to copy. + SizeArgExpr lenExpr = {{Call.getArgExpr(2), 2}}; + SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); + + // Protect against misdeclared strncpy(). + lenVal = + svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType()); + + std::optional lenValNL = lenVal.getAs(); + + auto CouldAccessOutOfBoundForSVal = [&](NonLoc Val) -> bool { +return !isFirstBufInBound(C, state, C.getSVal(Dst.Expression), + Dst.Expression->getType(), Val, + C.getASTContext().getSizeType()); + }; + +
[clang] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` (PR #146212)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: None (flovent) Changes Bounded string functions takes smallest of two values as it's copy size (`amountCopied` variable in `evalStrcpyCommon`), and it's used to decided whether this operation will cause out-of-bound access and invalidate it's super region if it does. for `strlcat`: `amountCopied = min (size - dstLen - 1 , srcLen)` for others: `amountCopied = min (srcLen, size)` Currently when one of two values is unknown or `SValBuilder` can't decide which one is smaller, `amountCopied` will remain `UnknownVal`, which will invalidate copy destination's super region unconditionally. This patch add check to see if one of these two values is definitely in-bound, if so `amountCopied` has to be in-bound too, because it‘s less than or equal to them, we can avoid the invalidation of super region and some related false positives in this situation. Closes #143807. --- Full diff: https://github.com/llvm/llvm-project/pull/146212.diff 2 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (+71-6) - (added) clang/test/Analysis/cstring-should-not-invalidate.cpp (+107) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 4d12fdcec1f1a..433fd2ce5f292 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -272,7 +272,8 @@ class CStringChecker : public Checker< eval::Call, static ProgramStateRef invalidateDestinationBufferBySize(CheckerContext &C, ProgramStateRef S, const Expr *BufE, ConstCFGElementRef Elem, -SVal BufV, SVal SizeV, QualType SizeTy); +SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound = true); /// Operation never overflows, do not invalidate the super region. static ProgramStateRef invalidateDestinationBufferNeverOverflows( @@ -1211,14 +1212,17 @@ bool CStringChecker::isFirstBufInBound(CheckerContext &C, ProgramStateRef State, ProgramStateRef CStringChecker::invalidateDestinationBufferBySize( CheckerContext &C, ProgramStateRef S, const Expr *BufE, -ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy) { +ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound) { auto InvalidationTraitOperations = - [&C, S, BufTy = BufE->getType(), BufV, SizeV, - SizeTy](RegionAndSymbolInvalidationTraits &ITraits, const MemRegion *R) { + [&C, S, BufTy = BufE->getType(), BufV, SizeV, SizeTy, + CouldAccessOutOfBound](RegionAndSymbolInvalidationTraits &ITraits, + const MemRegion *R) { // If destination buffer is a field region and access is in bound, do // not invalidate its super region. if (MemRegion::FieldRegionKind == R->getKind() && -isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy)) { +(!CouldAccessOutOfBound || + isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy))) { ITraits.setTrait( R, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); @@ -2223,6 +2227,67 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, Result = lastElement; } +// For bounded method, amountCopied take the minimum of two values, +// for ConcatFnKind::strlcat: +// amountCopied = min (size - dstLen - 1 , srcLen) +// for others: +// amountCopied = min (srcLen, size) +// So even if we don't know about amountCopied, as long as one of them will +// not cause an out-of-bound access, the whole function's operation will not +// too, that will avoid invalidating the superRegion of data member in that +// situation. +bool CouldAccessOutOfBound = true; +if (IsBounded && amountCopied.isUnknown()) { + // Get the max number of characters to copy. + SizeArgExpr lenExpr = {{Call.getArgExpr(2), 2}}; + SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); + + // Protect against misdeclared strncpy(). + lenVal = + svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType()); + + std::optional lenValNL = lenVal.getAs(); + + auto CouldAccessOutOfBoundForSVal = [&](NonLoc Val) -> bool { +return !isFirstBufInBound(C, state, C.getSVal(Dst.Expression), + Dst.Expression->getType(), Val, + C.getASTContext().getSizeType()); + }; + + if (strLengthNL) { +CouldAccessOutOfBound = CouldAccessOutOfBoundForSVal(*strLengthNL); + } + + if (CouldAccessOutOfBound && lenValNL) { +switch (appendK) { +case ConcatFnKind::none: +
[clang] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` (PR #146212)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (flovent) Changes Bounded string functions takes smallest of two values as it's copy size (`amountCopied` variable in `evalStrcpyCommon`), and it's used to decided whether this operation will cause out-of-bound access and invalidate it's super region if it does. for `strlcat`: `amountCopied = min (size - dstLen - 1 , srcLen)` for others: `amountCopied = min (srcLen, size)` Currently when one of two values is unknown or `SValBuilder` can't decide which one is smaller, `amountCopied` will remain `UnknownVal`, which will invalidate copy destination's super region unconditionally. This patch add check to see if one of these two values is definitely in-bound, if so `amountCopied` has to be in-bound too, because it‘s less than or equal to them, we can avoid the invalidation of super region and some related false positives in this situation. Closes #143807. --- Full diff: https://github.com/llvm/llvm-project/pull/146212.diff 2 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (+71-6) - (added) clang/test/Analysis/cstring-should-not-invalidate.cpp (+107) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 4d12fdcec1f1a..433fd2ce5f292 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -272,7 +272,8 @@ class CStringChecker : public Checker< eval::Call, static ProgramStateRef invalidateDestinationBufferBySize(CheckerContext &C, ProgramStateRef S, const Expr *BufE, ConstCFGElementRef Elem, -SVal BufV, SVal SizeV, QualType SizeTy); +SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound = true); /// Operation never overflows, do not invalidate the super region. static ProgramStateRef invalidateDestinationBufferNeverOverflows( @@ -1211,14 +1212,17 @@ bool CStringChecker::isFirstBufInBound(CheckerContext &C, ProgramStateRef State, ProgramStateRef CStringChecker::invalidateDestinationBufferBySize( CheckerContext &C, ProgramStateRef S, const Expr *BufE, -ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy) { +ConstCFGElementRef Elem, SVal BufV, SVal SizeV, QualType SizeTy, +bool CouldAccessOutOfBound) { auto InvalidationTraitOperations = - [&C, S, BufTy = BufE->getType(), BufV, SizeV, - SizeTy](RegionAndSymbolInvalidationTraits &ITraits, const MemRegion *R) { + [&C, S, BufTy = BufE->getType(), BufV, SizeV, SizeTy, + CouldAccessOutOfBound](RegionAndSymbolInvalidationTraits &ITraits, + const MemRegion *R) { // If destination buffer is a field region and access is in bound, do // not invalidate its super region. if (MemRegion::FieldRegionKind == R->getKind() && -isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy)) { +(!CouldAccessOutOfBound || + isFirstBufInBound(C, S, BufV, BufTy, SizeV, SizeTy))) { ITraits.setTrait( R, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); @@ -2223,6 +2227,67 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, Result = lastElement; } +// For bounded method, amountCopied take the minimum of two values, +// for ConcatFnKind::strlcat: +// amountCopied = min (size - dstLen - 1 , srcLen) +// for others: +// amountCopied = min (srcLen, size) +// So even if we don't know about amountCopied, as long as one of them will +// not cause an out-of-bound access, the whole function's operation will not +// too, that will avoid invalidating the superRegion of data member in that +// situation. +bool CouldAccessOutOfBound = true; +if (IsBounded && amountCopied.isUnknown()) { + // Get the max number of characters to copy. + SizeArgExpr lenExpr = {{Call.getArgExpr(2), 2}}; + SVal lenVal = state->getSVal(lenExpr.Expression, LCtx); + + // Protect against misdeclared strncpy(). + lenVal = + svalBuilder.evalCast(lenVal, sizeTy, lenExpr.Expression->getType()); + + std::optional lenValNL = lenVal.getAs(); + + auto CouldAccessOutOfBoundForSVal = [&](NonLoc Val) -> bool { +return !isFirstBufInBound(C, state, C.getSVal(Dst.Expression), + Dst.Expression->getType(), Val, + C.getASTContext().getSizeType()); + }; + + if (strLengthNL) { +CouldAccessOutOfBound = CouldAccessOutOfBoundForSVal(*strLengthNL); + } + + if (CouldAccessOutOfBound && lenValNL) { +switch (appendK) { +case ConcatFnKind::none: +case ConcatFn
[clang] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field (PR #145066)
Tedlion wrote: @steakhal I've reverted my change in RegionStore.cpp, since now I realize it is more complicated than I thought. Considring the costum copy construction and direct memory operations(such as the memset), simply considering the unnamed bit-field is an UndefinedVal may be wrong , even though the UndefinedVal in my case. Thank you a lot for discussion. I may work on this afterwards, but leaving the RegionStore unchanged maybe the best choice now. https://github.com/llvm/llvm-project/pull/145066 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` (PR #146212)
https://github.com/flovent edited https://github.com/llvm/llvm-project/pull/146212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Avoid unnecessary super region invalidation in `CStringChecker` (PR #146212)
https://github.com/flovent edited https://github.com/llvm/llvm-project/pull/146212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)
@@ -301,177 +735,284 @@ optimized to the equivalent of: std::cout << a+5 << "\n"; } -It should now be obvious why the value of `__int_32_0` remains unchanged -throughout the function. It is important to recognize that `__int_32_0` -does not directly correspond to `a`, but is instead a variable generated -to assist the compiler in code generation. The variables in an optimized -coroutine frame should not be thought of as directly representing the -variables in the C++ source. - -Get the suspended points - - -An important requirement for debugging coroutines is to understand suspended -points, which are where the coroutine is currently suspended and awaiting. - -For simple cases like the above, inspecting the value of the `__coro_index` -variable in the coroutine frame works well. +It should now be obvious why the value of ``__int_32_0`` remains unchanged +throughout the function. It is important to recognize that ``__int_32_0`` does +not directly correspond to ``a``, but is instead a variable generated to assist +the compiler in code generation. The variables in an optimized coroutine frame +should not be thought of as directly representing the variables in the C++ +source. -However, it is not quite so simple in really complex situations. In these -cases, it is necessary to use the coroutine libraries to insert the -line-number. -For example: - -.. code-block:: c++ +Resources += - // For all the promise_type we want: - class promise_type { -... - + unsigned line_number = 0x; - }; +.. _lldb-script: - #include +LLDB Debugger Script + - // For all the awaiter types we need: - class awaiter { -... -template -void await_suspend(std::coroutine_handle handle, - std::source_location sl = std::source_location::current()) { - ... - handle.promise().line_number = sl.line(); -} - }; +The following script provides the ``coro bt`` and ``coro in-flight`` commands +discussed above. It can be loaded into LLDB using ``command script import +lldb_coro_debugging.py``. To load this by default, add this command to your +``~/.lldbinit`` file. -In this case, we use `std::source_location` to store the line number of the -await inside the `promise_type`. Since we can locate the coroutine function -from the address of the coroutine, we can identify suspended points this way -as well. +Note that this script requires LLDB 21.0 or newer. -The downside here is that this comes at the price of additional runtime cost. -This is consistent with the C++ philosophy of "Pay for what you use". - -Get the asynchronous stack -== - -Another important requirement to debug a coroutine is to print the asynchronous -stack to identify the asynchronous caller of the coroutine. As many -implementations of coroutine types store `std::coroutine_handle<> continuation` -in the promise type, identifying the caller should be trivial. The -`continuation` is typically the awaiting coroutine for the current coroutine. -That is, the asynchronous parent. - -Since the `promise_type` is obtainable from the address of a coroutine and -contains the corresponding continuation (which itself is a coroutine with a -`promise_type`), it should be trivial to print the entire asynchronous stack. - -This logic should be quite easily captured in a debugger script. - -Examples to print asynchronous stack - - -Here is an example to print the asynchronous stack for the normal task implementation. +.. code-block:: python -.. code-block:: c++ + # lldb_coro_debugging.py + import lldb + from lldb.plugins.parsed_cmd import ParsedCommand + + def _get_first_var_path(v, paths): + """ + Tries multiple variable paths via `GetValueForExpressionPath` + and returns the first one that succeeds, or None if none succeed. + """ + for path in paths: + var = v.GetValueForExpressionPath(path) + if var.error.Success(): + return var + return None + + + def _print_async_bt(coro_hdl, result, *, curr_idx, start, limit, continuation_paths, prefix=""): + """ + Prints a backtrace for an async coroutine stack starting from `coro_hdl`, + using the given `continuation_paths` to get the next coroutine from the promise. + """ + target = coro_hdl.GetTarget() + while curr_idx < limit and coro_hdl is not None and coro_hdl.error.Success(): + # Print the stack frame, if in range + if curr_idx >= start: + # Figure out the function name + destroy_func_var = coro_hdl.GetValueForExpressionPath(".destroy") + destroy_addr = target.ResolveLoadAddress(destroy_func_var.GetValueAsAddress()) + func_name = destroy_addr.function.name + # Figure out the line entry to show + suspension_addr_var = coro_hdl.
[clang] [llvm] [NFC][analyzer] Remove Z3-as-constraint-manager hacks from lit test code (PR #145731)
mgorny wrote: I'm going to try moving the shared object build into CMake. https://github.com/llvm/llvm-project/pull/145731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [NFC][analyzer] Remove Z3-as-constraint-manager hacks from lit test code (PR #145731)
=?utf-8?q?Donát?= Nagy , =?utf-8?q?Donát?= Nagy , =?utf-8?q?Donát?= Nagy , =?utf-8?q?Donát?= Nagy Message-ID: In-Reply-To: steakhal wrote: I dont think we should (or you) invest too much. We can just mark this special case with UNSUPPORTED and move on. Is this issue caused by the standalone builds? We could detect and ignore the test in that case. Or we can do the opposite and allow the test only on a specific setup that is tested in the CI. Note that in the past these tests were disabled before we recently enabled then. So i dont think it would count as regression if its unconditionally disabled. https://github.com/llvm/llvm-project/pull/145731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [NFC][analyzer] Remove Z3-as-constraint-manager hacks from lit test code (PR #145731)
mgorny wrote: It's rather caused by doing a multilib build — in general you can't really use `CMAKE_CXX_COMPILER` outside CMake, since CMake is doing some toolchain magic on that, and you can't reproduce it right in lit. Unfortunately, I can't think of a good way of determining whether to run that, and I think actually switching to compile the library via CMake is easier — I'm already almost done, just need to wait for some free resources to start testing. https://github.com/llvm/llvm-project/pull/145731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e34e021 - [clang] Fix tests requiring Z3 headers in standalone builds (#146200)
Author: Michał Górny Date: 2025-06-28T09:10:49+02:00 New Revision: e34e02128ec5eb89e36a8f0f7307dcbcfecabbee URL: https://github.com/llvm/llvm-project/commit/e34e02128ec5eb89e36a8f0f7307dcbcfecabbee DIFF: https://github.com/llvm/llvm-project/commit/e34e02128ec5eb89e36a8f0f7307dcbcfecabbee.diff LOG: [clang] Fix tests requiring Z3 headers in standalone builds (#146200) Fix running tests that require Z3 headers in standalone build. They were wrongly relying on `Z3_INCLUDE_DIR` being passed through from LLVM, which is not the case for a standalone build. Instead, perform `find_package(Z3)` again to find Z3 development files and set `Z3_INCLUDE_DIR`. While at it, handle the possibility that Z3 development package is no longer installed -- run the tests only if both LLVM has been built against Z3, and the headers are still available. https://github.com/llvm/llvm-project/pull/145731#issuecomment-3009487525 Signed-off-by: Michał Górny Added: Modified: clang/CMakeLists.txt clang/test/Analysis/z3-crosscheck-max-attempts.cpp clang/test/Analysis/z3/D83660.c clang/test/CMakeLists.txt clang/test/lit.cfg.py clang/test/lit.site.cfg.py.in Removed: diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 94607a8e8473c..1bb73599970c1 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -150,6 +150,12 @@ if(CLANG_BUILT_STANDALONE) endif() umbrella_lit_testsuite_begin(check-all) + +# If LLVM was built with Z3, check if we still have the headers around. +# They are used by a few tests. +if (LLVM_WITH_Z3) + find_package(Z3 4.8.9) +endif() endif() # LLVM_INCLUDE_TESTS endif() # standalone diff --git a/clang/test/Analysis/z3-crosscheck-max-attempts.cpp b/clang/test/Analysis/z3-crosscheck-max-attempts.cpp index 572e452fdcac2..312e442f23f4f 100644 --- a/clang/test/Analysis/z3-crosscheck-max-attempts.cpp +++ b/clang/test/Analysis/z3-crosscheck-max-attempts.cpp @@ -32,7 +32,7 @@ // RUN: Z3_SOLVER_RESULTS="UNDEF,UNDEF,SAT" %{mocked_clang} %{attempts}=3 -verify=accepted -// REQUIRES: z3, asserts, shell, system-linux +// REQUIRES: z3, z3-devel, asserts, shell, system-linux // refuted-no-diagnostics diff --git a/clang/test/Analysis/z3/D83660.c b/clang/test/Analysis/z3/D83660.c index 0a7c8bab8e345..2ca4a4d0b53e9 100644 --- a/clang/test/Analysis/z3/D83660.c +++ b/clang/test/Analysis/z3/D83660.c @@ -8,7 +8,7 @@ // RUN: %clang_cc1 -analyze -analyzer-constraints=z3 -setup-static-analyzer \ // RUN: -analyzer-checker=core %s -verify // -// REQUIRES: z3, asserts, shell, system-linux +// REQUIRES: z3, z3-devel, asserts, shell, system-linux // // Works only with the z3 constraint manager. // expected-no-diagnostics diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index e5b4a3bb84645..8baea5b0ca937 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -29,6 +29,14 @@ llvm_canonicalize_cmake_booleans( LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS ) +# Run tests requiring Z3 headers only if LLVM was built with Z3 +# and the headers are available while building Clang -- the latter may +# not be the case when building standalone against installed LLVM. +set(TEST_WITH_Z3_DEVEL 0) +if(LLVM_WITH_Z3 AND Z3_FOUND) + set(TEST_WITH_Z3_DEVEL 1) +endif() + configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index bbd95ef4b77de..6375e73f5df82 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -201,9 +201,11 @@ def have_host_clang_repl_cuda(): if config.clang_staticanalyzer_z3: config.available_features.add("z3") -config.substitutions.append( -("%z3_include_dir", config.clang_staticanalyzer_z3_include_dir) -) +if config.clang_staticanalyzer_z3_devel: +config.available_features.add("z3-devel") +config.substitutions.append( +("%z3_include_dir", config.clang_staticanalyzer_z3_include_dir) +) else: config.available_features.add("no-z3") diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 00480d34852da..ec0e4aa10ed79 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -27,6 +27,7 @@ config.clang_default_pie_on_linux = @CLANG_DEFAULT_PIE_ON_LINUX@ config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@" config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@ config.clang_staticanalyzer_z3 = @LLVM_WITH_Z3@ +config.clang_staticanalyzer_z3_devel = @TEST_WITH_Z3_DEVEL@ config.clang_staticanalyzer_z3_include_dir = "@Z3_INCLUDE_DIR@" config.clang_enable_cir = @CLANG_ENABLE_CIR@ config.clang_examples = @CLANG_BUILD_EXAMPLES@ ___ cfe-comm
[clang] [clang] Fix tests requiring Z3 headers in standalone builds (PR #146200)
mgorny wrote: Thanks for the prompt review! https://github.com/llvm/llvm-project/pull/146200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix tests requiring Z3 headers in standalone builds (PR #146200)
https://github.com/mgorny closed https://github.com/llvm/llvm-project/pull/146200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][LoongArch] Match GCC behaviour when parsing FPRs in asm clobbers (PR #138391)
@@ -5,6 +5,7 @@ // CHECK-LABEL: @test_r0 // CHECK: call void asm sideeffect "", "{$r0}"(i32 undef) +// CHECK: call void asm sideeffect "", "{$r0}"(i32 undef) ziyao233 wrote: Thanks for the hint, I've adapted the scheme :) https://github.com/llvm/llvm-project/pull/138391 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema][clangd] add noexcept to override functions during code completion (PR #75937)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-remote-linux-ubuntu` running on `as-builder-9` while building `clang` at step 16 "test-check-lldb-api". Full details are available at: https://lab.llvm.org/buildbot/#/builders/195/builds/11073 Here is the relevant piece of the build log for the reference ``` Step 16 (test-check-lldb-api) failure: Test just built components: check-lldb-api completed (failure) ... PASS: lldb-api :: types/TestIntegerType.py (1282 of 1291) PASS: lldb-api :: python_api/watchpoint/watchlocation/TestTargetWatchAddress.py (1283 of 1291) PASS: lldb-api :: types/TestRecursiveTypes.py (1284 of 1291) PASS: lldb-api :: types/TestIntegerTypeExpr.py (1285 of 1291) UNSUPPORTED: lldb-api :: windows/launch/missing-dll/TestMissingDll.py (1286 of 1291) PASS: lldb-api :: types/TestShortType.py (1287 of 1291) PASS: lldb-api :: types/TestLongTypes.py (1288 of 1291) PASS: lldb-api :: types/TestShortTypeExpr.py (1289 of 1291) PASS: lldb-api :: types/TestLongTypesExpr.py (1290 of 1291) TIMEOUT: lldb-api :: python_api/process/cancel_attach/TestCancelAttach.py (1291 of 1291) TEST 'lldb-api :: python_api/process/cancel_attach/TestCancelAttach.py' FAILED Script: -- /usr/bin/python3.12 /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./bin --libcxx-include-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/include/c++/v1 --libcxx-include-target-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/include/aarch64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./lib/aarch64-unknown-linux-gnu --arch aarch64 --build-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./bin/lldb --compiler /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/bin/clang --dsymutil /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./bin --lldb-obj-root /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/tools/lldb --lldb-libs-dir /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/./lib --cmake-build-type Release --platform-url connect://jetson-agx-2198.lab.llvm.org:1234 --platform-working-dir /home/ubuntu/lldb-tests --sysroot /mnt/fs/jetson-agx-ubuntu --env ARCH_CFLAGS=-mcpu=cortex-a78 --platform-name remote-linux --skip-category=lldb-server /home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/llvm-project/lldb/test/API/python_api/process/cancel_attach -p TestCancelAttach.py -- Exit Code: -9 Timeout: Reached timeout of 600 seconds Command Output (stdout): -- lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 3c4e7308028e31aef21e50730145ba7f9b439363) clang revision 3c4e7308028e31aef21e50730145ba7f9b439363 llvm revision 3c4e7308028e31aef21e50730145ba7f9b439363 -- Command Output (stderr): -- WARNING:root:Custom libc++ is not supported for remote runs: ignoring --libcxx arguments FAIL: LLDB (/home/buildbot/worker/as-builder-9/lldb-remote-linux-ubuntu/build/bin/clang-aarch64) :: test_scripted_implementation (TestCancelAttach.AttachCancelTestCase.test_scripted_implementation) -- Slowest Tests: -- 600.04s: lldb-api :: python_api/process/cancel_attach/TestCancelAttach.py 123.33s: lldb-api :: functionalities/progress_reporting/TestProgressReporting.py 70.58s: lldb-api :: commands/process/attach/TestProcessAttach.py 60.85s: lldb-api :: commands/command/script_alias/TestCommandScriptAlias.py 39.35s: lldb-api :: functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py 36.23s: lldb-api :: functionalities/single-thread-step/TestSingleThreadStepTimeout.py 35.21s: lldb-api :: functionalities/completion/TestCompletion.py 25.78s: lldb-api :: python_api/watchpoint/watchlocation/TestTargetWatchAddress.py 25.13s: lldb-api :: commands/statistics/basic/TestStats.py 21.41s: lldb-api :: functionalities/gdb_remote_client/TestGDBRemot
[clang] [clang-format] Fix a bug in `ReflowComments: Always` (PR #146202)
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/146202 Fixes #39150 >From 00c0c25a5f17a0077cfc8660020391684aa5 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Sat, 28 Jun 2025 00:25:02 -0700 Subject: [PATCH] [clang-format] Fix a bug in `ReflowComments: Always` Fixes #39150 --- clang/lib/Format/BreakableToken.cpp | 3 +-- clang/unittests/Format/FormatTestComments.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 5317c05f3a460..def0d73e77539 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -158,8 +158,7 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, return BreakableToken::Split(StringRef::npos, 0); StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks); StringRef AfterCut = Text.substr(SpaceOffset); -// Don't trim the leading blanks if it would create a */ after the break. -if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/') +if (!DecorationEndsWithStar) AfterCut = AfterCut.ltrim(Blanks); return BreakableToken::Split(BeforeCut.size(), AfterCut.begin() - BeforeCut.end()); diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 5eefd767706a3..a16fbffb76270 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2486,7 +2486,7 @@ TEST_F(FormatTestComments, BlockComments) { EXPECT_EQ("/*\n" "**\n" "* aa\n" -"*aa\n" +"* aa\n" "*/", format("/*\n" "**\n" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Fix a bug in `ReflowComments: Always` (PR #146202)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: Owen Pan (owenca) Changes Fixes #39150 --- Full diff: https://github.com/llvm/llvm-project/pull/146202.diff 2 Files Affected: - (modified) clang/lib/Format/BreakableToken.cpp (+1-2) - (modified) clang/unittests/Format/FormatTestComments.cpp (+1-1) ``diff diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp index 5317c05f3a460..def0d73e77539 100644 --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -158,8 +158,7 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn, return BreakableToken::Split(StringRef::npos, 0); StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks); StringRef AfterCut = Text.substr(SpaceOffset); -// Don't trim the leading blanks if it would create a */ after the break. -if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/') +if (!DecorationEndsWithStar) AfterCut = AfterCut.ltrim(Blanks); return BreakableToken::Split(BeforeCut.size(), AfterCut.begin() - BeforeCut.end()); diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 5eefd767706a3..a16fbffb76270 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -2486,7 +2486,7 @@ TEST_F(FormatTestComments, BlockComments) { EXPECT_EQ("/*\n" "**\n" "* aa\n" -"*aa\n" +"* aa\n" "*/", format("/*\n" "**\n" `` https://github.com/llvm/llvm-project/pull/146202 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema][clangd] add noexcept to override functions during code completion (PR #75937)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-aarch64-ubuntu` running on `linaro-lldb-aarch64-ubuntu` while building `clang` at step 6 "test". Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/20116 Here is the relevant piece of the build log for the reference ``` Step 6 (test) failure: build (failure) ... PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/8/12 (2270 of 2279) PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/9/12 (2271 of 2279) PASS: lldb-unit :: Utility/./UtilityTests/4/9 (2272 of 2279) PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/0/2 (2273 of 2279) PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/1/2 (2274 of 2279) PASS: lldb-unit :: Target/./TargetTests/11/14 (2275 of 2279) PASS: lldb-unit :: Host/./HostTests/6/8 (2276 of 2279) PASS: lldb-unit :: Host/./HostTests/4/8 (2277 of 2279) PASS: lldb-unit :: Process/gdb-remote/./ProcessGdbRemoteTests/8/9 (2278 of 2279) UNRESOLVED: lldb-api :: tools/lldb-server/TestLldbGdbServer.py (2279 of 2279) TEST 'lldb-api :: tools/lldb-server/TestLldbGdbServer.py' FAILED Script: -- /usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --cmake-build-type Release /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/tools/lldb-server -p TestLldbGdbServer.py -- Exit Code: 1 Command Output (stdout): -- lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 3c4e7308028e31aef21e50730145ba7f9b439363) clang revision 3c4e7308028e31aef21e50730145ba7f9b439363 llvm revision 3c4e7308028e31aef21e50730145ba7f9b439363 Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc'] -- Command Output (stderr): -- UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_another_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_minus_one_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_zero_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_writes_all_gpr_registers_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any ca
[clang] [CIR] Upstream GenericSelectionExpr (PR #146211)
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/146211 Upstream GenericSelectionExpr for ScalarExpr >From 351422fe7f124351b06048048dfa28dd03ca35e5 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 28 Jun 2025 15:10:36 +0200 Subject: [PATCH] [CIR] Upstream GenericSelectionExpr --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 4 clang/test/CIR/CodeGen/generic-selection.c | 24 ++ 2 files changed, 28 insertions(+) create mode 100644 clang/test/CIR/CodeGen/generic-selection.c diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..038df2115f73c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -127,6 +127,10 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); } + mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *ge) { +return Visit(ge->getResultExpr()); + } + /// Emits the address of the l-value, then loads and returns the result. mlir::Value emitLoadOfLValue(const Expr *e) { LValue lv = cgf.emitLValue(e); diff --git a/clang/test/CIR/CodeGen/generic-selection.c b/clang/test/CIR/CodeGen/generic-selection.c new file mode 100644 index 0..c1659382a7059 --- /dev/null +++ b/clang/test/CIR/CodeGen/generic-selection.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +void foo() { + int a; + int r = _Generic(a, double: 1, float: 2, int: 3, default: 4); +} + +// CIR: %[[A:.*]] = cir.alloca !s32i, !cir.ptr, ["a"] +// CIR: %[[RES:.*]] = cir.alloca !s32i, !cir.ptr, ["r", init] +// CIR: %[[RES_VAL:.*]] = cir.const #cir.int<3> : !s32i +// CIR: cir.store{{.*}} %[[RES_VAL]], %[[RES]] : !s32i, !cir.ptr + +// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RES:.*]] = alloca i32, i64 1, align 4 +// LLVM: store i32 3, ptr %[[RES]], align 4 + +// OGCG: %[[A:.*]] = alloca i32, align 4 +// OGCG: %[[RES:.*]] = alloca i32, align 4 +// OGCG: store i32 3, ptr %[[RES]], align 4 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream GenericSelectionExpr (PR #146211)
llvmbot wrote: @llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) Changes Upstream GenericSelectionExpr for ScalarExpr --- Full diff: https://github.com/llvm/llvm-project/pull/146211.diff 2 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+4) - (added) clang/test/CIR/CodeGen/generic-selection.c (+24) ``diff diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..038df2115f73c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -127,6 +127,10 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); } + mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *ge) { +return Visit(ge->getResultExpr()); + } + /// Emits the address of the l-value, then loads and returns the result. mlir::Value emitLoadOfLValue(const Expr *e) { LValue lv = cgf.emitLValue(e); diff --git a/clang/test/CIR/CodeGen/generic-selection.c b/clang/test/CIR/CodeGen/generic-selection.c new file mode 100644 index 0..c1659382a7059 --- /dev/null +++ b/clang/test/CIR/CodeGen/generic-selection.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +void foo() { + int a; + int r = _Generic(a, double: 1, float: 2, int: 3, default: 4); +} + +// CIR: %[[A:.*]] = cir.alloca !s32i, !cir.ptr, ["a"] +// CIR: %[[RES:.*]] = cir.alloca !s32i, !cir.ptr, ["r", init] +// CIR: %[[RES_VAL:.*]] = cir.const #cir.int<3> : !s32i +// CIR: cir.store{{.*}} %[[RES_VAL]], %[[RES]] : !s32i, !cir.ptr + +// LLVM: %[[A:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RES:.*]] = alloca i32, i64 1, align 4 +// LLVM: store i32 3, ptr %[[RES]], align 4 + +// OGCG: %[[A:.*]] = alloca i32, align 4 +// OGCG: %[[RES:.*]] = alloca i32, align 4 +// OGCG: store i32 3, ptr %[[RES]], align 4 `` https://github.com/llvm/llvm-project/pull/146211 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
https://github.com/Lukasdoe converted_to_draft https://github.com/llvm/llvm-project/pull/146230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
https://github.com/Lukasdoe edited https://github.com/llvm/llvm-project/pull/146230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
https://github.com/mrcvtl updated https://github.com/llvm/llvm-project/pull/145164 >From 37c57131c397d4aeaef7fe5b860d1983f1e4bdc2 Mon Sep 17 00:00:00 2001 From: Marco Vitale Date: Sat, 21 Jun 2025 14:01:53 +0200 Subject: [PATCH 1/2] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 C++23 mandates that temporaries used in range-based for loops are lifetime-extended to cover the full loop. This patch adds a check for loop variables and compiler- generated `__range` bindings to apply the correct extension. Includes test cases based on examples from CWG900/P2644R1. --- clang/docs/ReleaseNotes.rst | 4 +++ clang/include/clang/AST/Decl.h| 19 + clang/lib/Sema/CheckExprLifetime.cpp | 8 ++ clang/lib/Sema/SemaStmt.cpp | 4 +++ clang/lib/Serialization/ASTReaderDecl.cpp | 1 + clang/lib/Serialization/ASTWriterDecl.cpp | 2 ++ .../test/SemaCXX/range-for-lifetime-cxx23.cpp | 27 +++ 7 files changed, 65 insertions(+) create mode 100644 clang/test/SemaCXX/range-for-lifetime-cxx23.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 89d86c3371247..184d1f0b188be 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -643,6 +643,10 @@ Improvements to Clang's diagnostics #GH142457, #GH139913, #GH138850, #GH137867, #GH137860, #GH107840, #GH93308, #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490, #GH36703, #GH32903, #GH23312, #GH69874. + +- Clang no longer emits a spurious -Wdangling-gsl warning in C++23 when + iterating over an element of a temporary container in a range-based + for loop.(#GH109793, #GH145164) Improvements to Clang's time-trace diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 0da940883b6f5..ab23346cc2fad 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1085,6 +1085,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { LLVM_PREFERRED_TYPE(bool) unsigned IsCXXCondDecl : 1; + +/// Whether this variable is the implicit __range variable in a for-range +/// loop. +LLVM_PREFERRED_TYPE(bool) +unsigned IsCXXForRangeImplicitVar : 1; }; union { @@ -1584,6 +1589,20 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.IsCXXCondDecl = true; } + /// Determine whether this variable is the compiler-generated '__range' + /// variable used to hold the range expression in a C++11 and later for-range + /// statement. + bool isCXXForRangeImplicitVar() const { +return isa(this) ? false + : NonParmVarDeclBits.IsCXXForRangeImplicitVar; + } + + void setCXXForRangeImplicitVar(bool FRV) { +assert(!isa(this) && + "Cannot set IsCXXForRangeImplicitVar on ParmVarDecl"); +NonParmVarDeclBits.IsCXXForRangeImplicitVar = FRV; + } + /// Determines if this variable's alignment is dependent. bool hasDependentAlignment() const; diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 060ba31660556..fc52de1e6bd89 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -57,6 +57,7 @@ enum LifetimeKind { }; using LifetimeResult = llvm::PointerIntPair; + } // namespace /// Determine the declaration which an initialized entity ultimately refers to, @@ -1341,6 +1342,13 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, } if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) { + +if (SemaRef.getLangOpts().CPlusPlus23) { + if (const VarDecl *VD = cast(InitEntity->getDecl()); + VD && VD->isCXXForRangeImplicitVar()) +return false; +} + SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer) << DiagRange; return false; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 923a9e81fbd6a..ef0aff1b2838f 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2374,6 +2374,9 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SemaRef.ObjC().inferObjCARCLifetime(Decl)) Decl->setInvalidDecl(); + if (SemaRef.getLangOpts().CPlusPlus23) +SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true; + SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false); SemaRef.FinalizeDeclaration(Decl); SemaRef.CurContext->addHiddenDecl(Decl); @@ -2423,6 +2426,7 @@ VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc, VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); Decl->setImplicit(); + Decl->setCXXForRangeImplicitVar(true); return Decl; } diff --git a/clang/lib/Serialization/ASTReaderDecl.c
[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)
mrcvtl wrote: Old clang tidy test failing seems flaky, locally builds correctly. If it continue to fail I can rebase on upstream. https://github.com/llvm/llvm-project/pull/145164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
https://github.com/snarang181 created https://github.com/llvm/llvm-project/pull/146234 Fixes https://github.com/llvm/llvm-project/issues/146223. >From 6f450c2686e4c4900234ac9aae9dd085966eff64 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 28 Jun 2025 15:31:37 -0400 Subject: [PATCH] Emit a suggestion to explicitly mark the function with [[noreturn]] if -Wmissing-noreturn is enabled. --- clang/docs/ReleaseNotes.rst | 3 +-- clang/lib/Sema/SemaDeclAttr.cpp | 6 + .../SemaCXX/wmissing-noreturn-suggestion.cpp | 23 +++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d9847fadc21e5..73a2618bb580c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -654,9 +654,8 @@ Improvements to Clang's diagnostics a call to a function that is trivially known to always throw (i.e., its body consists solely of a `throw` statement). This avoids certain false positives in exception-heavy code, though only simple patterns - are currently recognized. + are currently recognized. Additionally, if -Wmissing-noreturn is enabled, emit a suggestion to explicitly mark the function with [[noreturn]]. - Improvements to Clang's time-trace -- diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 52313e6a15ff1..cadaddc2d5b6d 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1979,6 +1979,12 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) { if (!FD->hasAttr() && !FD->hasAttr() && isKnownToAlwaysThrow(FD)) { NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context)); + +// Conditionally, emit the suggestion warning. +if (!Diags.isIgnored(diag::warn_suggest_noreturn_function, FD->getLocation())) { + S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) + << 0 << FD; +} } } diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp new file mode 100644 index 0..7548ba8904a71 --- /dev/null +++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Wmissing-noreturn -verify %s + +namespace std { + class string { + public: +string(const char*); + }; + class runtime_error { + public: +runtime_error(const string&); + }; +} + +// This function always throws. Suggest [[noreturn]]. +void throwError(const std::string& msg) { // expected-warning {{function 'throwError' could be declared with attribute 'noreturn'}} + throw std::runtime_error(msg); +} + +// The non-void caller should not warn about missing return. +int ensureZero(int i) { + if (i == 0) return 0; + throwError("ERROR"); // no-warning +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/146234 >From c6b4a421c0087a06111df3a6f79b929e7285644b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 28 Jun 2025 15:31:37 -0400 Subject: [PATCH] Emit a suggestion to explicitly mark the function with [[noreturn]] if -Wmissing-noreturn is enabled. --- clang/docs/ReleaseNotes.rst | 3 +-- clang/lib/Sema/SemaDeclAttr.cpp | 7 ++ .../SemaCXX/wmissing-noreturn-suggestion.cpp | 23 +++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d9847fadc21e5..73a2618bb580c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -654,9 +654,8 @@ Improvements to Clang's diagnostics a call to a function that is trivially known to always throw (i.e., its body consists solely of a `throw` statement). This avoids certain false positives in exception-heavy code, though only simple patterns - are currently recognized. + are currently recognized. Additionally, if -Wmissing-noreturn is enabled, emit a suggestion to explicitly mark the function with [[noreturn]]. - Improvements to Clang's time-trace -- diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 52313e6a15ff1..e7da8e673a9ec 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1979,6 +1979,13 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) { if (!FD->hasAttr() && !FD->hasAttr() && isKnownToAlwaysThrow(FD)) { NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context)); + +// Conditionally, emit the suggestion warning. +if (!Diags.isIgnored(diag::warn_suggest_noreturn_function, + FD->getLocation())) { + S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) + << 0 << FD; +} } } diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp new file mode 100644 index 0..7548ba8904a71 --- /dev/null +++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Wmissing-noreturn -verify %s + +namespace std { + class string { + public: +string(const char*); + }; + class runtime_error { + public: +runtime_error(const string&); + }; +} + +// This function always throws. Suggest [[noreturn]]. +void throwError(const std::string& msg) { // expected-warning {{function 'throwError' could be declared with attribute 'noreturn'}} + throw std::runtime_error(msg); +} + +// The non-void caller should not warn about missing return. +int ensureZero(int i) { + if (i == 0) return 0; + throwError("ERROR"); // no-warning +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] `--header-insertion` CLI fix (PR #146235)
https://github.com/MythreyaK created https://github.com/llvm/llvm-project/pull/146235 In PR #128503, CLI option overwrites only if it was set to `never`. This commit ensures that CLI options always overwrite any config option. Thanks to the fix from @HighCommander4 [here](https://github.com/llvm/llvm-project/pull/128503#issuecomment-2823259618)! >From 41987cabfbbc951f46d62b17cbd6ddb4118e62e5 Mon Sep 17 00:00:00 2001 From: Mythreya Kuricheti Date: Sat, 28 Jun 2025 12:27:36 -0700 Subject: [PATCH] [clangd] `--header-insertion` CLI fix In PR #128503, CLI option overwrites only if it was set to `never`. This commit ensures that CLI options always overwrite any config option. --- clang-tools-extra/clangd/tool/ClangdMain.cpp | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index b11d194da04db..f287439f10cab 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -668,7 +668,6 @@ class FlagsConfigProvider : public config::Provider { std::optional IndexSpec; std::optional BGPolicy; std::optional ArgumentLists; -std::optional HeaderInsertionPolicy; // If --compile-commands-dir arg was invoked, check value and override // default path. @@ -713,11 +712,6 @@ class FlagsConfigProvider : public config::Provider { BGPolicy = Config::BackgroundPolicy::Skip; } -// If CLI has set never, use that regardless of what the config files have -if (HeaderInsertion == Config::HeaderInsertionPolicy::NeverInsert) { - HeaderInsertionPolicy = Config::HeaderInsertionPolicy::NeverInsert; -} - if (std::optional Enable = shouldEnableFunctionArgSnippets()) { ArgumentLists = *Enable ? Config::ArgumentListsPolicy::FullPlaceholders : Config::ArgumentListsPolicy::Delimiters; @@ -732,8 +726,8 @@ class FlagsConfigProvider : public config::Provider { C.Index.Background = *BGPolicy; if (ArgumentLists) C.Completion.ArgumentLists = *ArgumentLists; - if (HeaderInsertionPolicy) -C.Completion.HeaderInsertion = *HeaderInsertionPolicy; + if (HeaderInsertion.getNumOccurrences()) +C.Completion.HeaderInsertion = HeaderInsertion; if (AllScopesCompletion.getNumOccurrences()) C.Completion.AllScopes = AllScopesCompletion; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] `--header-insertion` CLI fix (PR #146235)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra Author: Mythreya (MythreyaK) Changes In PR #128503, CLI option overwrites only if it was set to `never`. This commit ensures that CLI options always overwrite any config option. Thanks to the fix from @HighCommander4 [here](https://github.com/llvm/llvm-project/pull/128503#issuecomment-2823259618)! --- Full diff: https://github.com/llvm/llvm-project/pull/146235.diff 1 Files Affected: - (modified) clang-tools-extra/clangd/tool/ClangdMain.cpp (+2-8) ``diff diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index b11d194da04db..f287439f10cab 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -668,7 +668,6 @@ class FlagsConfigProvider : public config::Provider { std::optional IndexSpec; std::optional BGPolicy; std::optional ArgumentLists; -std::optional HeaderInsertionPolicy; // If --compile-commands-dir arg was invoked, check value and override // default path. @@ -713,11 +712,6 @@ class FlagsConfigProvider : public config::Provider { BGPolicy = Config::BackgroundPolicy::Skip; } -// If CLI has set never, use that regardless of what the config files have -if (HeaderInsertion == Config::HeaderInsertionPolicy::NeverInsert) { - HeaderInsertionPolicy = Config::HeaderInsertionPolicy::NeverInsert; -} - if (std::optional Enable = shouldEnableFunctionArgSnippets()) { ArgumentLists = *Enable ? Config::ArgumentListsPolicy::FullPlaceholders : Config::ArgumentListsPolicy::Delimiters; @@ -732,8 +726,8 @@ class FlagsConfigProvider : public config::Provider { C.Index.Background = *BGPolicy; if (ArgumentLists) C.Completion.ArgumentLists = *ArgumentLists; - if (HeaderInsertionPolicy) -C.Completion.HeaderInsertion = *HeaderInsertionPolicy; + if (HeaderInsertion.getNumOccurrences()) +C.Completion.HeaderInsertion = HeaderInsertion; if (AllScopesCompletion.getNumOccurrences()) C.Completion.AllScopes = AllScopesCompletion; `` https://github.com/llvm/llvm-project/pull/146235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] `--header-insertion` CLI fix (PR #146235)
llvmbot wrote: @llvm/pr-subscribers-clangd Author: Mythreya (MythreyaK) Changes In PR #128503, CLI option overwrites only if it was set to `never`. This commit ensures that CLI options always overwrite any config option. Thanks to the fix from @HighCommander4 [here](https://github.com/llvm/llvm-project/pull/128503#issuecomment-2823259618)! --- Full diff: https://github.com/llvm/llvm-project/pull/146235.diff 1 Files Affected: - (modified) clang-tools-extra/clangd/tool/ClangdMain.cpp (+2-8) ``diff diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index b11d194da04db..f287439f10cab 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -668,7 +668,6 @@ class FlagsConfigProvider : public config::Provider { std::optional IndexSpec; std::optional BGPolicy; std::optional ArgumentLists; -std::optional HeaderInsertionPolicy; // If --compile-commands-dir arg was invoked, check value and override // default path. @@ -713,11 +712,6 @@ class FlagsConfigProvider : public config::Provider { BGPolicy = Config::BackgroundPolicy::Skip; } -// If CLI has set never, use that regardless of what the config files have -if (HeaderInsertion == Config::HeaderInsertionPolicy::NeverInsert) { - HeaderInsertionPolicy = Config::HeaderInsertionPolicy::NeverInsert; -} - if (std::optional Enable = shouldEnableFunctionArgSnippets()) { ArgumentLists = *Enable ? Config::ArgumentListsPolicy::FullPlaceholders : Config::ArgumentListsPolicy::Delimiters; @@ -732,8 +726,8 @@ class FlagsConfigProvider : public config::Provider { C.Index.Background = *BGPolicy; if (ArgumentLists) C.Completion.ArgumentLists = *ArgumentLists; - if (HeaderInsertionPolicy) -C.Completion.HeaderInsertion = *HeaderInsertionPolicy; + if (HeaderInsertion.getNumOccurrences()) +C.Completion.HeaderInsertion = HeaderInsertion; if (AllScopesCompletion.getNumOccurrences()) C.Completion.AllScopes = AllScopesCompletion; `` https://github.com/llvm/llvm-project/pull/146235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] `--header-insertion` CLI fix (PR #146235)
MythreyaK wrote: I tested these locally and seems to work as expected. Please do double-check, just in case I missed something! | config | cli |outcome | |--||| | IWYU| iwyu | inserted | | IWYU| never | not inserted | | Never | iwyu | inserted | | Never | never | not inserted | | Never | [no opt] | not inserted | | IWYU| [no opt] | inserted | | [no opt] | iwyu | inserted | | [no opt] | never | not inserted | | [no opt] | [no opt] | inserted | https://github.com/llvm/llvm-project/pull/146235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
https://github.com/snarang181 ready_for_review https://github.com/llvm/llvm-project/pull/146234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Samarth Narang (snarang181) Changes Implements https://github.com/llvm/llvm-project/issues/146223. --- Full diff: https://github.com/llvm/llvm-project/pull/146234.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1-2) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+7) - (added) clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp (+23) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d9847fadc21e5..73a2618bb580c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -654,9 +654,8 @@ Improvements to Clang's diagnostics a call to a function that is trivially known to always throw (i.e., its body consists solely of a `throw` statement). This avoids certain false positives in exception-heavy code, though only simple patterns - are currently recognized. + are currently recognized. Additionally, if -Wmissing-noreturn is enabled, emit a suggestion to explicitly mark the function with [[noreturn]]. - Improvements to Clang's time-trace -- diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 52313e6a15ff1..e7da8e673a9ec 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1979,6 +1979,13 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) { if (!FD->hasAttr() && !FD->hasAttr() && isKnownToAlwaysThrow(FD)) { NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context)); + +// Conditionally, emit the suggestion warning. +if (!Diags.isIgnored(diag::warn_suggest_noreturn_function, + FD->getLocation())) { + S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) + << 0 << FD; +} } } diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp new file mode 100644 index 0..7548ba8904a71 --- /dev/null +++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Wmissing-noreturn -verify %s + +namespace std { + class string { + public: +string(const char*); + }; + class runtime_error { + public: +runtime_error(const string&); + }; +} + +// This function always throws. Suggest [[noreturn]]. +void throwError(const std::string& msg) { // expected-warning {{function 'throwError' could be declared with attribute 'noreturn'}} + throw std::runtime_error(msg); +} + +// The non-void caller should not warn about missing return. +int ensureZero(int i) { + if (i == 0) return 0; + throwError("ERROR"); // no-warning +} `` https://github.com/llvm/llvm-project/pull/146234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/146234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 402baea - [modularize] Use std::tie to implement operator< (NFC) (#146220)
Author: Kazu Hirata Date: 2025-06-28T13:04:00-07:00 New Revision: 402baea0a9ff7894565449e41f700c4e6a3f99cb URL: https://github.com/llvm/llvm-project/commit/402baea0a9ff7894565449e41f700c4e6a3f99cb DIFF: https://github.com/llvm/llvm-project/commit/402baea0a9ff7894565449e41f700c4e6a3f99cb.diff LOG: [modularize] Use std::tie to implement operator< (NFC) (#146220) std::tie clearly expresses the intent while slightly shortening the code. Added: Modified: clang-tools-extra/modularize/Modularize.cpp Removed: diff --git a/clang-tools-extra/modularize/Modularize.cpp b/clang-tools-extra/modularize/Modularize.cpp index 2a90c5e3f6782..1da531a4aefa4 100644 --- a/clang-tools-extra/modularize/Modularize.cpp +++ b/clang-tools-extra/modularize/Modularize.cpp @@ -459,7 +459,7 @@ struct HeaderEntry { return !(X == Y); } friend bool operator<(const HeaderEntry &X, const HeaderEntry &Y) { -return X.Loc < Y.Loc || (X.Loc == Y.Loc && X.Name < Y.Name); +return std::tie(X.Loc, X.Name) < std::tie(Y.Loc, Y.Name); } friend bool operator>(const HeaderEntry &X, const HeaderEntry &Y) { return Y < X; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [modularize] Use std::tie to implement operator< (NFC) (PR #146220)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/146220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
https://github.com/Lukasdoe updated https://github.com/llvm/llvm-project/pull/146230 From 4cb790f228c9578be163d9cca01e9232b1ca2239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=B6llerer?= Date: Sat, 28 Jun 2025 21:53:09 +0200 Subject: [PATCH] [LLVM][WebAssembly] Implement branch hinting proposal This commit implements the WebAssembly branch hinting proposal, as detailed at https://webassembly.github.io/branch-hinting/metadata/code/binary.html. This proposal introduces a mechanism to convey branch likelihood information to the WebAssembly engine, allowing for more effective performance optimizations. The proposal specifies a new custom section named `metadata.code.branch_hint`. This section can contain a sequence of hints, where each hint is a single byte that applies to a corresponding `br_if` or `if` instruction. The hint values are: - `0x00` (`unlikely`): The branch is unlikely to be taken. - `0x01` (`likely`): The branch is likely to be taken. This implementation includes the following changes: - Addition of the "branch-hinting" feature (flag) - Collection of edge probabilities in CFGStackify pass - Outputting of `metadata.code.branch_hint` section in WebAssemblyAsmPrinter - Addition of the `WebAssembly::Specifier::S_DEBUG_REF` symbol ref specifier - Custom relaxation of leb128 fragments for storage of uleb128 encoded function indices and instruction offsets - Custom handling of code metadata sections in lld, required since the proposal requires code metadata sections to start with a combined count of function hints, followed by an ordered list of function hints. This change is purely an optimization and does not alter the semantics of WebAssembly programs. --- clang/include/clang/Driver/Options.td | 2 + clang/lib/Basic/Targets/WebAssembly.cpp | 12 +++ clang/lib/Basic/Targets/WebAssembly.h | 1 + lld/test/wasm/Inputs/branch-hints.ll | 29 +++ lld/test/wasm/code-metadata-branch-hints.ll | 37 + lld/wasm/OutputSections.cpp | 56 + lld/wasm/OutputSections.h | 9 +++ lld/wasm/Writer.cpp | 13 +-- .../MCTargetDesc/WebAssemblyAsmBackend.cpp| 25 ++ .../MCTargetDesc/WebAssemblyMCAsmInfo.h | 1 + .../WebAssemblyWasmObjectWriter.cpp | 6 +- llvm/lib/Target/WebAssembly/WebAssembly.td| 6 +- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 69 .../WebAssembly/WebAssemblyAsmPrinter.h | 9 +++ .../WebAssembly/WebAssemblyCFGStackify.cpp| 20 - .../WebAssembly/WebAssemblyInstrInfo.td | 4 + .../WebAssemblyMachineFunctionInfo.h | 2 + .../Target/WebAssembly/WebAssemblySubtarget.h | 2 + ...branch-hints-custom-high-low-thresholds.ll | 79 +++ llvm/test/MC/WebAssembly/branch-hints.ll | 66 20 files changed, 440 insertions(+), 8 deletions(-) create mode 100644 lld/test/wasm/Inputs/branch-hints.ll create mode 100644 lld/test/wasm/code-metadata-branch-hints.ll create mode 100644 llvm/test/MC/WebAssembly/branch-hints-custom-high-low-thresholds.ll create mode 100644 llvm/test/MC/WebAssembly/branch-hints.ll diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9911d752966e3..31274aca2a25b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5276,6 +5276,8 @@ def mtail_call : Flag<["-"], "mtail-call">, Group; def mno_tail_call : Flag<["-"], "mno-tail-call">, Group; def mwide_arithmetic : Flag<["-"], "mwide-arithmetic">, Group; def mno_wide_arithmetic : Flag<["-"], "mno-wide-arithmetic">, Group; +def mbranch_hinting : Flag<["-"], "mbranch-hinting">, Group; +def mno_branch_hinting : Flag<["-"], "mno-branch-hinting">, Group; def mexec_model_EQ : Joined<["-"], "mexec-model=">, Group, Values<"command,reactor">, HelpText<"Execution model (WebAssembly only)">, diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index f19c57f1a3a50..14c9d501bc1fa 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -69,6 +69,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { .Case("simd128", SIMDLevel >= SIMD128) .Case("tail-call", HasTailCall) .Case("wide-arithmetic", HasWideArithmetic) + .Case("branch-hinting", HasBranchHinting) .Default(false); } @@ -116,6 +117,8 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__wasm_tail_call__"); if (HasWideArithmetic) Builder.defineMacro("__wasm_wide_arithmetic__"); + if (HasBranchHinting) +Builder.defineMacro("__wasm_branch_hinting__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -194,6 +197,7 @@
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
https://github.com/Lukasdoe ready_for_review https://github.com/llvm/llvm-project/pull/146230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
Lukasdoe wrote: edit: rebased https://github.com/llvm/llvm-project/pull/146230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lld] [llvm] [LLVM][WebAssembly] Implement branch hinting proposal (PR #146230)
Lukasdoe wrote: @yuri91 @sbc100 https://github.com/llvm/llvm-project/pull/146230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
@@ -1516,6 +1516,23 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, MSGuidTagDecl = buildImplicitRecord("_GUID"); getTranslationUnitDecl()->addDecl(MSGuidTagDecl); } + + // size_t (C99TC3 6.5.3.4), signed size_t (C++23 5.13.2) and + // ptrdiff_t (C99TC3 6.5.6) Although these types are not built-in, they are + // part of the core language and are widely used. + if (!LangOpts.HLSL) { +// Using PredefinedSugarType makes these types as named sugar types rather +// than standard integer types, enabling better hints and diagnostics. +using Kind = PredefinedSugarType::Kind; +SizeType = getPredefinedSugarType(llvm::to_underlying(Kind::SizeT)); +SignedSizeType = +getPredefinedSugarType(llvm::to_underlying(Kind::SignedSizeT)); +PtrdiffType = getPredefinedSugarType(llvm::to_underlying(Kind::PtrdiffT)); + } else { +SizeType = getFromTargetType(Target.getSizeType()); +SignedSizeType = getFromTargetType(Target.getSignedSizeType()); +PtrdiffType = getFromTargetType(Target.getPtrDiffType(LangAS::Default)); + } YexuanXiao wrote: I have restored HLSL support, and the tests now pass. https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
@@ -7248,6 +7250,22 @@ QualType TreeTransform::TransformDependentBitIntType( return Result; } +template +QualType TreeTransform::TransformPredefinedSugarType( +TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) { + const PredefinedSugarType *EIT = TL.getTypePtr(); + QualType Result = TL.getType(); + + if (getDerived().AlwaysRebuild()) { +Result = getDerived().RebuildPredefinedSugarType( +llvm::to_underlying(EIT->getKind())); + } + + PredefinedSugarTypeLoc NewTL = TLB.push(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; +} YexuanXiao wrote: https://github.com/llvm/llvm-project/blob/f90025ebd930a4719f3d7ac61d802ce948f9f433/clang/lib/Sema/TreeTransform.h#L671 declares it. https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
https://github.com/YexuanXiao edited https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
@@ -2767,6 +2767,10 @@ class DependentBitIntTypeLoc final : public InheritingConcreteTypeLoc {}; +class PredefinedSugarTypeLoc final +: public InheritingConcreteTypeLoc {}; YexuanXiao wrote: https://github.com/llvm/llvm-project/blob/f90025ebd930a4719f3d7ac61d802ce948f9f433/clang/include/clang/AST/TypeLoc.h#L49-L53 declares it. https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
https://github.com/YexuanXiao deleted https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [libcxx] [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (PR #143653)
https://github.com/YexuanXiao edited https://github.com/llvm/llvm-project/pull/143653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream PackIndexingExpr for ScalarExpr (PR #146239)
llvmbot wrote: @llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) Changes Upstream PackIndexingExpr for ScalarExpr --- Full diff: https://github.com/llvm/llvm-project/pull/146239.diff 2 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+4) - (added) clang/test/CIR/CodeGen/pack-indexing.cpp (+49) ``diff diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..c5f54023cbe61 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -125,6 +125,10 @@ class ScalarExprEmitter : public StmtVisitor { return {}; } + mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) { +return Visit(e->getSelectedExpr()); + } + mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); } /// Emits the address of the l-value, then loads and returns the result. diff --git a/clang/test/CIR/CodeGen/pack-indexing.cpp b/clang/test/CIR/CodeGen/pack-indexing.cpp new file mode 100644 index 0..8b12b505164f8 --- /dev/null +++ b/clang/test/CIR/CodeGen/pack-indexing.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +int pack_indexing(auto... p) { return p...[0]; } + +// CIR: %[[P_0:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_1:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_2:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.load{{.*}} %[[P_0]] : !cir.ptr, !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[P_0:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_1:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_2:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[P_0:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_1:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_2:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] + +int foo() { return pack_indexing(1, 2, 3); } + +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.call @_Z13pack_indexingIJiiiEEiDpT_({{.*}}, {{.*}}, {{.*}}) : (!s32i, !s32i, !s32i) -> !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = call i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 1, i32 2, i32 3) +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[CALL:.*]] = call noundef i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 noundef 1, i32 noundef 2, i32 noundef 3) +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] `` https://github.com/llvm/llvm-project/pull/146239 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream PackIndexingExpr for ScalarExpr (PR #146239)
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/146239 Upstream PackIndexingExpr for ScalarExpr >From addc4c8be7497ca61f6a78891da1ce7a5fa9ea69 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 28 Jun 2025 22:54:55 +0200 Subject: [PATCH] [CIR] Upstream PackIndexingExpr for ScalarExpr --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 4 ++ clang/test/CIR/CodeGen/pack-indexing.cpp | 49 ++ 2 files changed, 53 insertions(+) create mode 100644 clang/test/CIR/CodeGen/pack-indexing.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..c5f54023cbe61 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -125,6 +125,10 @@ class ScalarExprEmitter : public StmtVisitor { return {}; } + mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) { +return Visit(e->getSelectedExpr()); + } + mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); } /// Emits the address of the l-value, then loads and returns the result. diff --git a/clang/test/CIR/CodeGen/pack-indexing.cpp b/clang/test/CIR/CodeGen/pack-indexing.cpp new file mode 100644 index 0..8b12b505164f8 --- /dev/null +++ b/clang/test/CIR/CodeGen/pack-indexing.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +int pack_indexing(auto... p) { return p...[0]; } + +// CIR: %[[P_0:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_1:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_2:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.load{{.*}} %[[P_0]] : !cir.ptr, !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[P_0:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_1:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_2:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[P_0:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_1:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_2:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] + +int foo() { return pack_indexing(1, 2, 3); } + +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.call @_Z13pack_indexingIJiiiEEiDpT_({{.*}}, {{.*}}, {{.*}}) : (!s32i, !s32i, !s32i) -> !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = call i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 1, i32 2, i32 3) +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[CALL:.*]] = call noundef i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 noundef 1, i32 noundef 2, i32 noundef 3) +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream PackIndexingExpr for ScalarExpr (PR #146239)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) Changes Upstream PackIndexingExpr for ScalarExpr --- Full diff: https://github.com/llvm/llvm-project/pull/146239.diff 2 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+4) - (added) clang/test/CIR/CodeGen/pack-indexing.cpp (+49) ``diff diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..c5f54023cbe61 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -125,6 +125,10 @@ class ScalarExprEmitter : public StmtVisitor { return {}; } + mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) { +return Visit(e->getSelectedExpr()); + } + mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); } /// Emits the address of the l-value, then loads and returns the result. diff --git a/clang/test/CIR/CodeGen/pack-indexing.cpp b/clang/test/CIR/CodeGen/pack-indexing.cpp new file mode 100644 index 0..8b12b505164f8 --- /dev/null +++ b/clang/test/CIR/CodeGen/pack-indexing.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++2c -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +int pack_indexing(auto... p) { return p...[0]; } + +// CIR: %[[P_0:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_1:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[P_2:.*]] = cir.alloca !s32i, !cir.ptr, ["p", init] +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.load{{.*}} %[[P_0]] : !cir.ptr, !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[P_0:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_1:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[P_2:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[P_0:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_1:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[P_2:.*]] = alloca i32, align 4 +// OGCG-DAG: %[[RESULT:.*]] = load i32, ptr %[[P_0]], align 4 +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] + +int foo() { return pack_indexing(1, 2, 3); } + +// CIR: %[[RET_VAL:.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] +// CIR: %[[RESULT:.*]] = cir.call @_Z13pack_indexingIJiiiEEiDpT_({{.*}}, {{.*}}, {{.*}}) : (!s32i, !s32i, !s32i) -> !s32i +// CIR: cir.store %[[RESULT]], %[[RET_VAL]] : !s32i, !cir.ptr +// CIR: %[[TMP:.*]] = cir.load %[[RET_VAL]] : !cir.ptr, !s32i +// CIR: cir.return %[[TMP]] : !s32i + +// LLVM: %[[RET_VAL:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = call i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 1, i32 2, i32 3) +// LLVM: store i32 %[[RESULT]], ptr %[[RET_VAL]], align 4 +// LLVM: %[[TMP:.*]] = load i32, ptr %[[RET_VAL]], align 4 +// LLVM: ret i32 %[[TMP]] + +// OGCG-DAG: %[[CALL:.*]] = call noundef i32 @_Z13pack_indexingIJiiiEEiDpT_(i32 noundef 1, i32 noundef 2, i32 noundef 3) +// OGCG-DAG-NEXT: ret i32 %[[RESULT]] `` https://github.com/llvm/llvm-project/pull/146239 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Fix an off-by-1 bug with -length option (PR #143302)
https://github.com/owenca edited https://github.com/llvm/llvm-project/pull/143302 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Implement NotEqualOp for ComplexType (PR #146129)
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/146129 >From 964a930b9f96423d04155b9972bfd8540c59d911 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Fri, 27 Jun 2025 20:10:48 +0200 Subject: [PATCH 1/3] [CIR] Implement NotEqualOp for ComplexType --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 25 +++ clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp| 5 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 38 ++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 10 +++ clang/test/CIR/CodeGen/complex.cpp| 72 +++ 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4daff74cbae5a..b58ebd2dfe509 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2481,6 +2481,31 @@ def ComplexEqualOp : CIR_Op<"complex.eq", [Pure, SameTypeOperands]> { }]; } +//===--===// +// ComplexNotEqualOp +//===--===// + +def ComplexNotEqualOp : CIR_Op<"complex.neq", [Pure, SameTypeOperands]> { + + let summary = "Computes whether two complex values are not equal"; + let description = [{ + The `complex.equal` op takes two complex numbers and returns whether + they are not equal. + +```mlir +%r = cir.complex.neq %a, %b : !cir.complex +``` + }]; + + let results = (outs CIR_BoolType:$result); + let arguments = (ins CIR_ComplexType:$lhs, CIR_ComplexType:$rhs); + + let assemblyFormat = [{ +$lhs `,` $rhs +`:` qualified(type($lhs)) attr-dict + }]; +} + //===--===// // Assume Operations //===--===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 955bb5ffc4395..0ba653add826f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -905,9 +905,8 @@ class ScalarExprEmitter : public StmtVisitor { result = builder.create(loc, boInfo.lhs, boInfo.rhs); } else { -assert(!cir::MissingFeatures::complexType()); -cgf.cgm.errorNYI(loc, "complex not equal"); -result = builder.getBool(false, loc); +result = +builder.create(loc, boInfo.lhs, boInfo.rhs); } } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 1034b8780c03c..598283eeaf518 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1903,6 +1903,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMComplexCreateOpLowering, CIRToLLVMComplexEqualOpLowering, CIRToLLVMComplexImagOpLowering, + CIRToLLVMComplexNotEqualOpLowering, CIRToLLVMComplexRealOpLowering, CIRToLLVMConstantOpLowering, CIRToLLVMExpectOpLowering, @@ -2282,6 +2283,43 @@ mlir::LogicalResult CIRToLLVMComplexEqualOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMComplexNotEqualOpLowering::matchAndRewrite( +cir::ComplexNotEqualOp op, OpAdaptor adaptor, +mlir::ConversionPatternRewriter &rewriter) const { + mlir::Value lhs = adaptor.getLhs(); + mlir::Value rhs = adaptor.getRhs(); + + auto complexType = mlir::cast(op.getLhs().getType()); + mlir::Type complexElemTy = + getTypeConverter()->convertType(complexType.getElementType()); + + mlir::Location loc = op.getLoc(); + auto lhsReal = + rewriter.create(loc, complexElemTy, lhs, 0); + auto lhsImag = + rewriter.create(loc, complexElemTy, lhs, 1); + auto rhsReal = + rewriter.create(loc, complexElemTy, rhs, 0); + auto rhsImag = + rewriter.create(loc, complexElemTy, rhs, 1); + + if (complexElemTy.isInteger()) { +auto realCmp = rewriter.create( +loc, mlir::LLVM::ICmpPredicate::ne, lhsReal, rhsReal); +auto imagCmp = rewriter.create( +loc, mlir::LLVM::ICmpPredicate::ne, lhsImag, rhsImag); +rewriter.replaceOpWithNewOp(op, realCmp, imagCmp); +return mlir::success(); + } + + auto realCmp = rewriter.create( + loc, mlir::LLVM::FCmpPredicate::une, lhsReal, rhsReal); + auto imagCmp = rewriter.create( + loc, mlir::LLVM::FCmpPredicate::une, lhsImag, rhsImag); + rewriter.replaceOpWithNewOp(op, realCmp, imagCmp); + return mlir::success(); +} + std::unique_ptr createConvertCIRToLLVMPass() { return std::make_unique(); } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index 25cf218cf8b6c..5cd1d09b88c00 100644 ---
[clang] [clang][analyzer] Fix the false positive ArgInitializedness warning on unnamed bit-field (PR #145066)
@@ -2122,8 +2122,21 @@ SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B, if (const std::optional &V = B.getDirectBinding(R)) return *V; - // If the containing record was initialized, try to get its constant value. + // UnnamedBitField is always Undefined unless using memory operation such + // as 'memset'. + // For example, for code + //typedef struct { + // int i :2; + // int:30; // unnamed bit-field + //} A; + //A a = {1}; + // The bits of the unnamed bit-field in local variable a can be anything. const FieldDecl *FD = R->getDecl(); + if (FD->isUnnamedBitField()) { + return UndefinedVal(); + } + + // If the containing record was initialized, try to get its constant value. Tedlion wrote: I can provide some evidence where the `UndefinedVal`(in c) and the `SymbolVal`(in c++) are from. After **reverting all my changes** in CallAndMessageChecker.cpp and RegionStore.cpp, I use watchpoints to find where the return values of the invoking `StoreMgr.getBinding(store, loc::MemRegionVal(FR))` from: Following is the test code: ```c // unnamed.c struct B { int i : 2; int : 30; // unnamed bit-field }; extern void consume_B(struct B); void bitfield_B_init(void) { struct B b1; b1.i = 1; // b1 is initialized consume_B(b1); } ``` When analyzing the test code as c, via `clang -cc1 -x c -analyze -analyzer-checker=core unnamed.c`, I get the stackframes: ``` 1# RegionStoreManager::getBindingForFieldOrElementCommon(const RegionBindingsRef &, const clang::ento::TypedValueRegion *, QualType) RegionStore.cpp:2312 2# RegionStoreManager::getBindingForField(const RegionBindingsRef &, const clang::ento::FieldRegion *) RegionStore.cpp:2170 3# RegionStoreManager::getBinding(const RegionBindingsRef &, Loc, QualType) RegionStore.cpp:1617 4# RegionStoreManager::getBinding(const void *, Loc, QualType) RegionStore.cpp:711 5# FindUninitializedField::Find(const clang::ento::TypedValueRegion *) CallAndMessageChecker.cpp:263 .. ``` ```cpp // in FindUninitializedField::Find for (const auto *I : RD->fields()) { const FieldRegion *FR = MrMgr.getFieldRegion(I, R); FieldChain.push_back(I); T = I->getType(); if (T->getAsStructureType()) { if (Find(FR)) return true; } else { SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR)); if (V.isUndef()) return true; } FieldChain.pop_back(); } ``` When I switching to frame 5 and print the `FR->getRawMemorySpace()`, I get the type `clang::ento::StackLocalsSpaceRegion *` While analyzing the test code as c++, via `clang -cc1 -x c ++-analyze -analyzer-checker=core unnamed.c`, I get the stackframes: ``` RegionStoreManager::getBindingForFieldOrElementCommon(const RegionBindingsRef &, const clang::ento::TypedValueRegion *, QualType) RegionStore.cpp:2317 RegionStoreManager::getBindingForField(const RegionBindingsRef &, const clang::ento::FieldRegion *) RegionStore.cpp:2170 RegionStoreManager::getBinding(const RegionBindingsRef &, Loc, QualType) RegionStore.cpp:1617 RegionStoreManager::getBinding(const void *, Loc, QualType) RegionStore.cpp:711 FindUninitializedField::Find(const clang::ento::TypedValueRegion *) CallAndMessageChecker.cpp:263 ``` When I switching to frame 5 and print the `FR->getRawMemorySpace()`, I get the type `clang::ento::StackArgumentsSpaceRegion *` The raw memory space of `b1` is different in c and c++, I wonder it due to the implicit copy constructor in c++? And the difference on `FR->getRawMemorySpace()` finally reaches the if check in `RegionStoreManager::getBindingForFieldOrElementCommon` and returns a different result. ```cpp // line 2288 in RegionStore.cpp if (isa(R->getRawMemorySpace())) { if (isa(R)) { ``` The last statement in `getBindingForFieldOrElementCommon` seems a default handle, where the c++ unnamed bit-field gets its binding. ```cpp // All other values are symbolic. return svalBuilder.getRegionValueSymbolVal(R); ``` https://github.com/llvm/llvm-project/pull/145066 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits