[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits

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)

2025-06-28 Thread Felipe de Azevedo Piovezan via cfe-commits

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)

2025-06-28 Thread Prajwal Nadig via cfe-commits

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)

2025-06-28 Thread Prajwal Nadig via cfe-commits

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)

2025-06-28 Thread Prajwal Nadig via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits


@@ -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)

2025-06-28 Thread Marco Vitale via cfe-commits


@@ -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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Henrich Lauko via cfe-commits


@@ -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)

2025-06-28 Thread Amr Hesham via cfe-commits

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)

2025-06-28 Thread Amr Hesham via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Henrich Lauko via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Björn Schäpers via cfe-commits

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)

2025-06-28 Thread Henrich Lauko via cfe-commits

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)

2025-06-28 Thread Henrich Lauko via cfe-commits

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)

2025-06-28 Thread Brian Cain via cfe-commits

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)

2025-06-28 Thread Tom Vijlbrief via cfe-commits

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)

2025-06-28 Thread Ashwin Banwari via cfe-commits

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)

2025-06-28 Thread Ashwin Banwari via cfe-commits

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)

2025-06-28 Thread Owen Pan via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Matt Arsenault via cfe-commits

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)

2025-06-28 Thread via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Owen Pan via cfe-commits

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)

2025-06-28 Thread Ashwin Banwari via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Ashwin Banwari via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits


@@ -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)

2025-06-28 Thread Tom Vijlbrief via cfe-commits

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)

2025-06-28 Thread Michał Górny via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread LLVM Continuous Integration via cfe-commits

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)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Yanzuo Liu via cfe-commits


@@ -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)

2025-06-28 Thread Michał Górny via cfe-commits

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)

2025-06-28 Thread Balazs Benics via cfe-commits
=?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)

2025-06-28 Thread Michał Górny via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Michał Górny via cfe-commits

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)

2025-06-28 Thread Michał Górny via cfe-commits

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)

2025-06-28 Thread Yao Zi via cfe-commits


@@ -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)

2025-06-28 Thread LLVM Continuous Integration via cfe-commits

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)

2025-06-28 Thread Owen Pan via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread LLVM Continuous Integration via cfe-commits

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)

2025-06-28 Thread Amr Hesham via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Marco Vitale via cfe-commits

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)

2025-06-28 Thread Samarth Narang via cfe-commits

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)

2025-06-28 Thread Samarth Narang via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Samarth Narang via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Samarth Narang via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Kazu Hirata via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread Lukas Döllerer via cfe-commits

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)

2025-06-28 Thread via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits


@@ -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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Amr Hesham via cfe-commits

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)

2025-06-28 Thread via cfe-commits

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)

2025-06-28 Thread Owen Pan via cfe-commits

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)

2025-06-28 Thread Amr Hesham via cfe-commits

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)

2025-06-28 Thread via cfe-commits


@@ -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


  1   2   >