[clang] [Sema] Mark alias/ifunc targets used and consider mangled names (PR #87130)

2024-04-01 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

A quick few things I noticed, not nearly a thorough review.

https://github.com/llvm/llvm-project/pull/87130
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)

2024-04-01 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll updated 
https://github.com/llvm/llvm-project/pull/84184

>From 23f4208fb9978370f59cae16db0747acb3e2c906 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov 
Date: Wed, 6 Mar 2024 18:01:35 +0300
Subject: [PATCH 1/7] [clang] Factor out OpenACC part of `Sema`

This patch moves OpenACC parts of `Sema` into a separate class `SemaOpenACC` 
that is placed in a separate header `Sema/SemaOpenACC.h`. This patch is 
intended to be a model of factoring things out of `Sema`, so I picked a small 
OpenACC part.

Goals are the following:
1) Split `Sema` into manageable parts.
2) Make dependencies between parts visible.
3) Improve Clang development cycle by avoiding recompiling unrelated parts of 
the compiler.
4) Avoid compile-time regressions.
5) Avoid notational regressions in the code that uses Sema.
---
 clang/include/clang/Sema/Sema.h| 77 --
 clang/include/clang/Sema/SemaOpenACC.h | 68 +++
 clang/lib/Parse/ParseOpenACC.cpp   | 22 
 clang/lib/Sema/Sema.cpp|  4 +-
 clang/lib/Sema/SemaOpenACC.cpp | 44 ---
 clang/lib/Sema/TreeTransform.h | 11 ++--
 6 files changed, 137 insertions(+), 89 deletions(-)
 create mode 100644 clang/include/clang/Sema/SemaOpenACC.h

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f3d3a57104ee07..932676c52b1f30 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -183,6 +183,7 @@ class Preprocessor;
 class PseudoDestructorTypeStorage;
 class PseudoObjectExpr;
 class QualType;
+class SemaOpenACC;
 class StandardConversionSequence;
 class Stmt;
 class StringLiteral;
@@ -466,9 +467,8 @@ class Sema final {
   // 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp)
   // 38. CUDA (SemaCUDA.cpp)
   // 39. HLSL Constructs (SemaHLSL.cpp)
-  // 40. OpenACC Constructs (SemaOpenACC.cpp)
-  // 41. OpenMP Directives and Clauses (SemaOpenMP.cpp)
-  // 42. SYCL Constructs (SemaSYCL.cpp)
+  // 40. OpenMP Directives and Clauses (SemaOpenMP.cpp)
+  // 41. SYCL Constructs (SemaSYCL.cpp)
 
   /// \name Semantic Analysis
   /// Implementations are in Sema.cpp
@@ -1200,6 +1200,27 @@ class Sema final {
   //
   //
 
+  /// \name Sema Components
+  /// Parts of Sema
+  ///@{
+
+  // Just in this section, private members are followed by public, because
+  // C++ requires us to create (private) objects before (public) references.
+
+private:
+  std::unique_ptr OpenACCPtr;
+
+public:
+  SemaOpenACC 
+
+  ///@}
+
+  //
+  //
+  // -
+  //
+  //
+
   /// \name C++ Access Control
   /// Implementations are in SemaAccess.cpp
   ///@{
@@ -13309,56 +13330,6 @@ class Sema final {
   //
   //
 
-  /// \name OpenACC Constructs
-  /// Implementations are in SemaOpenACC.cpp
-  ///@{
-
-public:
-  /// Called after parsing an OpenACC Clause so that it can be checked.
-  bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
-  SourceLocation StartLoc);
-
-  /// Called after the construct has been parsed, but clauses haven't been
-  /// parsed.  This allows us to diagnose not-implemented, as well as set up 
any
-  /// state required for parsing the clauses.
-  void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc);
-
-  /// Called after the directive, including its clauses, have been parsed and
-  /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
-  /// happen before any associated declarations or statements have been parsed.
-  /// This function is only called when we are parsing a 'statement' context.
-  bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
-  SourceLocation StartLoc);
-
-  /// Called after the directive, including its clauses, have been parsed and
-  /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
-  /// happen before any associated declarations or statements have been parsed.
-  /// This function is only called when we are parsing a 'Decl' context.
-  bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
-  SourceLocation StartLoc);
-  /// Called when we encounter an associated statement for our construct, this
-  /// should check legality of the statement as it appertains to this 
Construct.
-  StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
-StmtResult AssocStmt);
-
-  /// Called after the directive has been completely parsed, including the
-  /// declaration group or associated statement.
-  StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
-  SourceLocation StartLoc,
-  SourceLocation EndLoc,
-  StmtResult AssocStmt);
-  /// Called after the directive has been 

[clang] [clang] Factor out OpenACC part of `Sema` (PR #84184)

2024-04-01 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM, but I think the next steps are two-fold: add a second `Sema` class for 
something else (perhaps OpenMP?) and add a base class for accessing commonly 
used functionality (`getASTContext()`, `Diag()`, etc).

https://github.com/llvm/llvm-project/pull/84184
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Move tailclipping to bitfield allocation (PR #87090)

2024-04-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan converted_to_draft 
https://github.com/llvm/llvm-project/pull/87090
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix bitfield access unit for vbase corner case (PR #87238)

2024-04-01 Thread Nathan Sidwell via cfe-commits

https://github.com/urnathan created 
https://github.com/llvm/llvm-project/pull/87238

This fixes #87227 My change to bitfield access unit allocation (#65742) causes 
an ICE for a corner case of vbase allocation: a class where an unshared (i.e. 
not the nearly-empty base optimization) vbase is placed below nvsize. 
Unfortunately, although there was a testcase for such a class layout, it didn't 
have the immediately preceding bitfield -- the reason the scissor needs to be 
correct.

The fix is to break out the scissor calculation from `accumulateVbases`, and 
have `allocateBitfields` be aware it is creating either the base subobject, or 
the complete object. Then it can call the scissor calculator to get the 
appropriate upper bound. The scissor calculation can cause a base walk, I 
thought it best to cache the result in `allocateBitfields`, as we can reach 
that point multiple times with unfortunately-sized bitfield spans.

In breaking out the scissor calculation, I discovered a couple more member fns 
that could be const qualified -- as before do you want that as a separate PR?

>From 3b0bfce77d6d70bc35316484b39bb83123b8a583 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell 
Date: Sun, 31 Mar 2024 11:11:13 -0400
Subject: [PATCH] [clang] Fix bitfield access unit for vbase corner case

We must account for unshared vbases that are allocated below nvsize.
---
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp   |  57 +++---
 .../test/CodeGenCXX/bitfield-access-tail.cpp  | 104 --
 2 files changed, 113 insertions(+), 48 deletions(-)

diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index e32023aeac1e6f..634a55fec5182e 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -185,9 +185,10 @@ struct CGRecordLowering {
   /// Lowers an ASTRecordLayout to a llvm type.
   void lower(bool NonVirtualBaseType);
   void lowerUnion(bool isNoUniqueAddress);
-  void accumulateFields();
+  void accumulateFields(bool isNonVirtualBaseType);
   RecordDecl::field_iterator
-  accumulateBitFields(RecordDecl::field_iterator Field,
+  accumulateBitFields(bool isNonVirtualBaseType,
+  RecordDecl::field_iterator Field,
   RecordDecl::field_iterator FieldEnd);
   void computeVolatileBitfields();
   void accumulateBases();
@@ -195,8 +196,10 @@ struct CGRecordLowering {
   void accumulateVBases();
   /// Recursively searches all of the bases to find out if a vbase is
   /// not the primary vbase of some base class.
-  bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query);
+  bool hasOwnStorage(const CXXRecordDecl *Decl,
+ const CXXRecordDecl *Query) const;
   void calculateZeroInit();
+  CharUnits calculateTailClippingOffset(bool isNonVirtualBaseType) const;
   /// Lowers bitfield storage types to I8 arrays for bitfields with tail
   /// padding that is or can potentially be used.
   void clipTailPadding();
@@ -287,7 +290,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
 computeVolatileBitfields();
 return;
   }
-  accumulateFields();
+  accumulateFields(NVBaseType);
   // RD implies C++.
   if (RD) {
 accumulateVPtrs();
@@ -378,12 +381,12 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) 
{
 Packed = true;
 }
 
-void CGRecordLowering::accumulateFields() {
+void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
   for (RecordDecl::field_iterator Field = D->field_begin(),
   FieldEnd = D->field_end();
Field != FieldEnd;) {
 if (Field->isBitField()) {
-  Field = accumulateBitFields(Field, FieldEnd);
+  Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
   assert((Field == FieldEnd || !Field->isBitField()) &&
  "Failed to accumulate all the bitfields");
 } else if (Field->isZeroSize(Context)) {
@@ -404,9 +407,12 @@ void CGRecordLowering::accumulateFields() {
 }
 
 // Create members for bitfields. Field is a bitfield, and FieldEnd is the end
-// iterator of the record. Return the first non-bitfield encountered.
+// iterator of the record. Return the first non-bitfield encountered.  We need
+// to know whether this is the base or complete layout, as virtual bases could
+// affect the upper bound of bitfield access unit allocation.
 RecordDecl::field_iterator
-CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
+CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
+  RecordDecl::field_iterator Field,
   RecordDecl::field_iterator FieldEnd) {
   if (isDiscreteBitFieldABI()) {
 // Run stores the first element of the current run of bitfields. FieldEnd 
is
@@ -505,6 +511,10 @@ 
CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
   

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-01 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/87233

>From d8d875271bd47b71701143afb06ea654546e2b7c Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH] [clang][dataflow] Refactor `widen` API to be explicit about
 change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 47 +++---
 .../FlowSensitive/DataflowEnvironment.cpp | 43 ++---
 .../TypeErasedDataflowAnalysisTest.cpp| 48 +++
 3 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..0a37d9d68e2898 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value , const Environment ,
   Value , Environment ) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   ``, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value , const Environment 
,
- Value , Environment ) {
+virtual std::optional widen(QualType Type, Value ,
+ const Environment ,
+ Value ,
+ Environment ) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Same:
-  return 
-case ComparisonResult::Different:
-  return 
-case ComparisonResult::Unknown:
-  return nullptr;
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..8ae51b7cdb444d 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualType Type, Value 
,
   return JoinedVal;
 }
 
-// When widening does not change `Current`, return value will equal ``.
-static Value 

[clang] [RFC][Clang] Enable custom type checking for printf (PR #86801)

2024-04-01 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > I looked at the OpenCL spec for C standard library support and was 
> > surprised that 1) it's only talking about C99 so it's unclear what happens 
> > for C11 (clause 6 says "This document describes the modifications and 
> > restrictions to C99 and C11 in OpenCL C" but 6.11 only talks about C99 
> > headers and leaves `iso646.h`, `math.h`, `stdbool.h`, `stddef.h`, (all in 
> > C99) as well as `stdalign.h`, `stdatomic.h`, `stdnoreturn.h`, `threads.h`, 
> > and `uchar.h` available?), and 2) OpenCL's `printf` is not really the same 
> > function as C's `printf` 
> > (https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html#differences-between-opencl-c-and-c99-printf).
> > #1 is probably more of an oversight than anything, at least with the C11 
> > headers. So maybe this isn't a super slippery slope, but maybe C23 will 
> > change that (I can imagine `stdbit.h` being of use in OpenCL for 
> > bit-bashing operations). However, the fact that the builtin isn't really 
> > `printf` but is `printf`-like makes me think we should make it a separate 
> > builtin to avoid surprises (we do diagnostics based on builtin IDs and we 
> > have special checking logic that we perhaps should be exempting in some 
> > cases).
> 
> Understood. Then I propose the following.
> 
> 1. Currently Builtin TableGen does not seem to support specifying lang 
> address spaces in function prototypes. this needs to be implemented first if 
> not already in development.
> 
> 2. We could have two new macro variants probably named "OCL_BUILTIN" and 
> "OCL_LIB_BUILTIN" which will take the ID's of the form 
> "BI_OCL##". we would also need corresponding TableGen classes 
> (probably named similar to the macros) which can expose such overloaded 
> prototypes when required.
> 
> 
> How does this sound ?

I think that sounds like a reasonable way forward, thank you!

https://github.com/llvm/llvm-project/pull/86801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> Last time I checked, neither GCC nor Clang allowed T[0] to match a partial 
> specialization for `is_array` so the extension isn't very well extended 
> :)

Oh, I agree, I am learning to loathe this extension the more I look into this. 
Did you see this lovely bit:

> Oh wow, and it gets even more surprising... adding a zero-length array to a 
> structure reduces the size of the structure (in C++): 
> https://godbolt.org/z/5E4YsT1Ye

But that's why I'm asking questions about what we *should* be doing with the 
feature overall. As it currently stands, this extension seems like it is broken 
in C++ in multiple ways. Fixing a tiny corner of it is fine, but I'd like to 
know what the overall big picture is so we can know whether the tiny corner 
changes fit or not. We could fix this by changing partial specializations to 
care about zero-sized arrays, too. (Personally, I would love to "fix" this by 
deprecating the extension as the only justification for it I've been able to 
dig up is as a hack for flexible arrays -- deprecating this extension outside 
of GNU89 mode has some appeal, barring other information about its value.)

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Jonathan Wakely via cfe-commits

jwakely wrote:

Last time I checked, neither GCC nor Clang allowed T[0] to match a partial 
specialization for `is_array` so the extension isn't very well extended :)

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-01 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/87233

>From b7f63ed7ca3c503f55eccc215f0a66368e2c5e5e Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH] [clang][dataflow] Refactor `widen` API to be explicit about
 change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 47 ---
 .../FlowSensitive/DataflowEnvironment.cpp | 43 ++---
 2 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..0a37d9d68e2898 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value , const Environment ,
   Value , Environment ) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   ``, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value , const Environment 
,
- Value , Environment ) {
+virtual std::optional widen(QualType Type, Value ,
+ const Environment ,
+ Value ,
+ Environment ) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Same:
-  return 
-case ComparisonResult::Different:
-  return 
-case ComparisonResult::Unknown:
-  return nullptr;
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..8ae51b7cdb444d 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualType Type, Value 
,
   return JoinedVal;
 }
 
-// When widening does not change `Current`, return value will equal ``.
-static Value (QualType Type, Value ,
-  const 

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-01 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 a1a8bb1d3ae9a535526aba9514e87f76e2d040fa 
6889df911a11fc5c27149f138176166aef3e1f73 -- 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 8e4e846e59..0a37d9d68e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -142,12 +142,12 @@ public:
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Unknown:
-  return std::nullopt;
-case ComparisonResult::Same:
-  return WidenResult{, LatticeJoinEffect::Unchanged};
-case ComparisonResult::Different:
-  return WidenResult{, LatticeJoinEffect::Changed};
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index d41f03262e..8ae51b7cdb 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -170,9 +170,10 @@ namespace {
 using WidenResult = Environment::ValueModel::WidenResult;
 }
 
-static WidenResult widenDistinctValues(
-QualType Type, Value , const Environment , Value ,
-Environment , Environment::ValueModel ) {
+static WidenResult widenDistinctValues(QualType Type, Value ,
+   const Environment ,
+   Value , Environment ,
+   Environment::ValueModel ) {
   // Boolean-model widening.
   if (auto *PrevBool = dyn_cast()) {
 if (isa(Prev))

``




https://github.com/llvm/llvm-project/pull/87233
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix __is_array returning true for zero-sized arrays (PR #86652)

2024-04-01 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> As I've just commented at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114479 
> the `__is_array` intrinsic exists to optimize `std::is_array` and so should 
> match its existing behaviour. If you want to change the behaviour of 
> `std::is_array` then please do so via an LWG issue, e.g. requesting 
> clarification of the behaviour for `T[0]`.
> 
> An optimization to speed up compilation of `std::is_array` should not dictate 
> its behaviour.

Errr, I think there's some circular logic here perhaps:

> [dcl.array] says that for T[N] the value "N specifies the array bound, i.e., 
> the
number of elements in the array; N shall be greater than zero."
>
> So T[0] is not a valid array type.

Except `T[0]` is a valid array type because it's supported as a language 
extension in Clang and GCC; that's the whole reason you can spell `T[0]` at all.

This boils down to a fundamental question: what makes something an array type 
in the first place? Is it the declaration syntax or is it the semantics? If 
it's declaration syntax, then `T[0]` is clearly an array type. If it's 
semantics, then `T[0]` is not an array type but `std::vector` is. 
Personally, I think the declaration syntax is what makes something an array 
type per https://eel.is/c++draft/dcl.array#1 saying "a declaration of the 
form". Yes, it says the size shall not be zero, but that's the bit we've 
extended, so it's circular to say "the standard says zero isn't allowed and 
therefore the library behavior is to return false from std::is_array".

So I think I'm arguing for an LWG issue.

https://github.com/llvm/llvm-project/pull/86652
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-01 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Yitzhak Mandelbaum (ymand)


Changes

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.


---
Full diff: https://github.com/llvm/llvm-project/pull/87233.diff


2 Files Affected:

- (modified) clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
(+29-14) 
- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+24-18) 


``diff
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..8e4e846e594f5b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value , const Environment ,
   Value , Environment ) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   ``, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value , const Environment 
,
- Value , Environment ) {
+virtual std::optional widen(QualType Type, Value ,
+ const Environment ,
+ Value ,
+ Environment ) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
+case ComparisonResult::Unknown:
+  return std::nullopt;
 case ComparisonResult::Same:
-  return 
+  return WidenResult{, LatticeJoinEffect::Unchanged};
 case ComparisonResult::Different:
-  return 
-case ComparisonResult::Unknown:
-  return nullptr;
+  return WidenResult{, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..d41f03262ecf4c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,19 @@ static Value *joinDistinctValues(QualType Type, Value 
,
   return JoinedVal;
 }
 
-// When widening does not change `Current`, return value will equal ``.
-static Value (QualType Type, Value ,
-  const Environment , Value ,
-  Environment ,
-  Environment::ValueModel ) {
+namespace {
+using WidenResult = Environment::ValueModel::WidenResult;
+}
+
+static 

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-01 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand created https://github.com/llvm/llvm-project/pull/87233

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.


>From 6889df911a11fc5c27149f138176166aef3e1f73 Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH] [clang][dataflow] Refactor `widen` API to be explicit about
 change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 43 +--
 .../FlowSensitive/DataflowEnvironment.cpp | 42 ++
 2 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..8e4e846e594f5b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value , const Environment ,
   Value , Environment ) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   ``, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value , const Environment 
,
- Value , Environment ) {
+virtual std::optional widen(QualType Type, Value ,
+ const Environment ,
+ Value ,
+ Environment ) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
+case ComparisonResult::Unknown:
+  return std::nullopt;
 case ComparisonResult::Same:
-  return 
+  return WidenResult{, LatticeJoinEffect::Unchanged};
 case ComparisonResult::Different:
-  return 
-case ComparisonResult::Unknown:
-  return nullptr;
+  return WidenResult{, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..d41f03262ecf4c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,19 @@ static Value *joinDistinctValues(QualType Type, Value 
,
   

[clang] [llvm] MIPS: Support -m(no-)unaligned-access for r6 (PR #85174)

2024-04-01 Thread Nathan Sidwell via cfe-commits

urnathan wrote:

#65742 is committed, so MIPS' TargetInfo will need adjusting to propagate the 
unaligned capability. See 7df79ababee8

https://github.com/llvm/llvm-project/pull/85174
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C99] Claim conformance to WG14 N717 (PR #87228)

2024-04-01 Thread via cfe-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
84299df301dc07ea83fa8378051103195c3a7c65...f8e130df9e602662444280346b71a82347ae8a29
 clang/test/C/C99/n717.py
``





View the diff from darker here.


``diff
--- n717.py 2024-04-01 11:27:32.00 +
+++ n717.py 2024-04-01 11:32:12.636120 +
@@ -1,29 +1,41 @@
 print("#define M(arg)")
 
+
 def test(size):
-  Prefix = 'U' if size == 8 else 'u'
-  # [0x to 0x00A0) excluding [0x0020, 0x007F)
-  for val in [val for val in range(0x, 0x00A0) if val < 0x0020 or val >= 
0x007F]:
- print(f'M(\\{Prefix}{val:0{size}X}) // expected-error universal 
character name refers to a control character')
-  print('')
-  
-  # [0x0020 to 0x007F), excluding 0x0024, 0x0040, and 0x0060
-  for val in [val for val in range(0x0020, 0x007F) if val != 0x0024 and val != 
0x0040 and val != 0x0060]:
- print(f"M(\\{Prefix}{val:0{size}X}) // expected-error character 
'{chr(val)}' cannot be specified by a universal character name")
-  print('')
-  
-  # [0xD800 to 0xDFFF]
-  for val in range(0xD800, 0xDFFF + 1):
-print(f'M(\\{Prefix}{val:0{size}X}) // expected-error invalid 
universal character')
-  print('')
-  
-  # Everything in this range should be accepted, though it may produce a
-  # warning diagnostic for things like homoglyphs, whitespace, etc.
-  for val in range(0x00A1, 0xD800):
-print(f'M(\\{Prefix}{val:0{size}X})')
-  print('')
+Prefix = "U" if size == 8 else "u"
+# [0x to 0x00A0) excluding [0x0020, 0x007F)
+for val in [val for val in range(0x, 0x00A0) if val < 0x0020 or val >= 
0x007F]:
+print(
+f"M(\\{Prefix}{val:0{size}X}) // expected-error universal 
character name refers to a control character"
+)
+print("")
+
+# [0x0020 to 0x007F), excluding 0x0024, 0x0040, and 0x0060
+for val in [
+val
+for val in range(0x0020, 0x007F)
+if val != 0x0024 and val != 0x0040 and val != 0x0060
+]:
+print(
+f"M(\\{Prefix}{val:0{size}X}) // expected-error character 
'{chr(val)}' cannot be specified by a universal character name"
+)
+print("")
+
+# [0xD800 to 0xDFFF]
+for val in range(0xD800, 0xDFFF + 1):
+print(
+f"M(\\{Prefix}{val:0{size}X}) // expected-error invalid 
universal character"
+)
+print("")
+
+# Everything in this range should be accepted, though it may produce a
+# warning diagnostic for things like homoglyphs, whitespace, etc.
+for val in range(0x00A1, 0xD800):
+print(f"M(\\{Prefix}{val:0{size}X})")
+print("")
+
 
 # Print \u tests
 test(4)
 # Print \U tests
 test(8)
@@ -32,8 +44,8 @@
 # within the valid (short) range.
 # This is disabled because enabling the test 1) requires using L because u and
 # U don't exist until C11, 2) is questionable in terms of value because the
 # code points could be different if L isn't using a Unicode encoding, and 3)
 # this addition to the test adds 10x the execution time when running the test.
-#for val in range(0x00A1, 0xD800):
+# for val in range(0x00A1, 0xD800):
 #  print(f"_Static_assert(L'\\u{val:04X}' == L'\\U{val:08X}', \"\");")
-#print('')
+# print('')

``




https://github.com/llvm/llvm-project/pull/87228
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C99] Claim conformance to WG14 N717 (PR #87228)

2024-04-01 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)


Changes

This was the paper that added Universal Character Names to C.

---
Full diff: https://github.com/llvm/llvm-project/pull/87228.diff


3 Files Affected:

- (added) clang/test/C/C99/n717.c (+69) 
- (added) clang/test/C/C99/n717.py (+39) 
- (modified) clang/www/c_status.html (+1-1) 


``diff
diff --git a/clang/test/C/C99/n717.c b/clang/test/C/C99/n717.c
new file mode 100644
index 00..cc1aa0fd5d53cf
--- /dev/null
+++ b/clang/test/C/C99/n717.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -std=c99 %s
+// RUN: %clang_cc1 -verify -std=c99 -fno-dollars-in-identifiers %s
+
+/* WG14 N717: Clang 17
+ * Extended identifiers
+ */
+
+// Used as a sink for UCNs.
+#define M(arg)
+
+// C99 6.4.3p1 specifies the grammar for UCNs. A \u must be followed by exactly
+// four hex digits, and \U must be followed by exactly eight.
+M(\u1)// expected-warning {{incomplete universal character name; treating 
as '\' followed by identifier}}
+M(\u12)   // expected-warning {{incomplete universal character name; treating 
as '\' followed by identifier}}
+M(\u123)  // expected-warning {{incomplete universal character name; treating 
as '\' followed by identifier}}
+M(\u1234) // Okay
+M(\u12345)// Okay, two tokens (UCN followed by 5)
+
+M(\U1) // expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U12)// expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U123)   // expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U1234)  // expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}} \
+  expected-note {{did you mean to use '\u'?}}
+M(\U12345) // expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U123456)// expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U1234567)   // expected-warning {{incomplete universal character name; 
treating as '\' followed by identifier}}
+M(\U12345678)  // Okay
+M(\U123456789) // Okay-ish, two tokens (valid-per-spec-but-actually-invalid 
UCN followed by 9)
+
+// C99 6.4.3p2:
+// A universal character name shall not specify a character whose short
+// identifier is less than 00A0 other than 0024 ($), 0040 (@), or 0060 (�), nor
+// one in the range D800 through DFFF inclusive.
+//
+// We use a python script to generate the test contents for the large ranges
+// without edge cases.
+// RUN: %python %S/n717.py >%t.inc
+// RUN: %clang_cc1 -verify -std=c99 -Wno-unicode-whitespace 
-Wno-unicode-homoglyph -Wno-unicode-zero-width 
-Wno-mathematical-notation-identifier-extension %t.inc
+
+// Now test the ones that should work. Note, these work in C17 and earlier but
+// are part of the basic character set in C23 and thus should be diagnosed in
+// that mode. They're valid in a character constant, but not valid in an
+// identifier, except for U+0024 which is allowed if -fdollars-in-identifiers
+// is enabled.
+// FIXME: These three should be handled the same way, and should be accepted
+// when dollar signs are allowed in identifiers, rather than rejected, see
+// GH87106.
+M(\u0024) // expected-error {{character '$' cannot be specified by a universal 
character name}}
+M(\U0024) // expected-error {{character '$' cannot be specified by a 
universal character name}}
+M($)
+
+// These should always be rejected because they're not valid identifier
+// characters.
+// FIXME: the diagnostic could be improved to make it clear this is an issue
+// with forming an identifier rather than a UCN.
+M(\u0040) // expected-error {{character '@' cannot be specified by a universal 
character name}}
+M(\u0060) // expected-error {{character '`' cannot be specified by a universal 
character name}}
+M(\U0040) // expected-error {{character '@' cannot be specified by a 
universal character name}}
+M(\U0060) // expected-error {{character '`' cannot be specified by a 
universal character name}}
+
+// These should always be accepted because they're a valid in a character
+// constant.
+M('\u0024')
+M('\u0040')
+M('\u0060')
+
+M('\U0024')
+M('\U0040')
+M('\U0060')
diff --git a/clang/test/C/C99/n717.py b/clang/test/C/C99/n717.py
new file mode 100644
index 00..8c02d336ff6f60
--- /dev/null
+++ b/clang/test/C/C99/n717.py
@@ -0,0 +1,39 @@
+print("#define M(arg)")
+
+def test(size):
+  Prefix = 'U' if size == 8 else 'u'
+  # [0x to 0x00A0) excluding [0x0020, 0x007F)
+  for val in [val for val in range(0x, 0x00A0) if val < 0x0020 or val >= 
0x007F]:
+ print(f'M(\\{Prefix}{val:0{size}X}) // expected-error universal 
character name refers to a control character')
+  print('')
+  
+  # [0x0020 to 0x007F), excluding 0x0024, 0x0040, and 0x0060
+  for 

[clang] [llvm] [PowerPC] Implement 32-bit expansion for rldimi (PR #86783)

2024-04-01 Thread Kai Luo via cfe-commits

bzEq wrote:

> due to backward compatibility, it needs to be expanded into series of rlwimi 
> in 32-bit environment

Why must be 'series of rlwimi'?

Why don't we just expand it following what ISA describes and let legalizer 
generates code sequence under 32-bit mode?
```
n ← sh5 || sh0:4
r ← ROTL64((RS), n)
b ← mb5 || mb0:4
m ← MASK(b, ¬n) RA ← r | (RA) & ¬m
```

https://github.com/llvm/llvm-project/pull/86783
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2024-04-01 Thread Pol M via cfe-commits
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= 
Message-ID:
In-Reply-To: 



@@ -10895,6 +10899,132 @@ bool VectorExprEvaluator::VisitUnaryOperator(const 
UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue , EvalInfo ,
+   const Expr *E, const QualType ) {
+  if (!Evaluate(Result, Info, E))
+return false;
+
+  if (Result.isLValue()) {
+// Source of the data is an lvalue; Manually handle the lvalue as if
+// it was an rvalue to get the current APValue.
+LValue LValueFound;
+LValueFound.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result))
+  return false;
+  }
+
+  return Result.isVector();
+}
+
+static bool handleVectorConversion(EvalInfo , const FPOptions FPO,
+   const Expr *E, QualType SourceTy,
+   QualType DestTy, APValue const ,
+   APValue ) {
+  if (SourceTy->isIntegerType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = APValue(APFloat(0.0));
+  return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
+  DestTy, Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(
+  HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
+  return true;
+}
+  } else if (SourceTy->isRealFloatingType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = Original;
+  return HandleFloatToFloatCast(Info, E, SourceTy, DestTy,
+Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(APSInt());
+  return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(),
+  DestTy, Result.getInt());
+}
+  }
+  return false;
+}
+
+bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
+  APValue Source;
+  QualType SourceVecType = E->getSrcExpr()->getType();
+  if (!EvaluateVectorOrLValue(Source, Info, E->getSrcExpr(), SourceVecType))
+return false;
+
+  QualType DestTy = E->getType()->castAs()->getElementType();
+  QualType SourceTy = SourceVecType->castAs()->getElementType();
+
+  const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+
+  auto SourceLen = Source.getVectorLength();
+  SmallVector ResultElements;
+  ResultElements.reserve(SourceLen);
+  for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
+APValue Elt;
+if (!handleVectorConversion(Info, FPO, E, SourceTy, DestTy,
+Source.getVectorElt(EltNum), Elt))
+  return false;
+ResultElements.push_back(std::move(Elt));
+  }
+
+  return Success(APValue(ResultElements.data(), ResultElements.size()), E);
+}
+
+static bool handleVectorShuffle(EvalInfo , const ShuffleVectorExpr *E,
+QualType ElemType, APValue const ,
+APValue const , unsigned EltNum,
+APValue ) {
+  unsigned const TotalElementsInAVector = VecVal1.getVectorLength();
+
+  Expr const *IndexExpr = E->getExpr(2 + EltNum);
+  APSInt IndexVal;
+  if (!EvaluateInteger(IndexExpr, IndexVal, Info))
+return false;
+
+  uint32_t index = IndexVal.getZExtValue();
+  // The spec says that -1 should be treated as undef for optimizations,
+  // but in constexpr we need to choose a value. We'll choose 0.
+  if (index >= TotalElementsInAVector * 2)
+index = 0;

Destroyerrrocket wrote:

Great, let's hope operator[] makes it.

The error comes from somewhere in the depths of ExprConst, it intentionally 
tells you that undefined values are indeed illegal in constexpr code. I agree 
with you, a shame it makes sense!

https://github.com/llvm/llvm-project/pull/76615
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2024-04-01 Thread Pol M via cfe-commits
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= 
Message-ID:
In-Reply-To: 



@@ -10895,6 +10899,132 @@ bool VectorExprEvaluator::VisitUnaryOperator(const 
UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue , EvalInfo ,
+   const Expr *E, const QualType ) {
+  if (!Evaluate(Result, Info, E))
+return false;
+
+  if (Result.isLValue()) {
+// Source of the data is an lvalue; Manually handle the lvalue as if
+// it was an rvalue to get the current APValue.
+LValue LValueFound;
+LValueFound.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result))
+  return false;
+  }
+
+  return Result.isVector();
+}
+
+static bool handleVectorConversion(EvalInfo , const FPOptions FPO,
+   const Expr *E, QualType SourceTy,
+   QualType DestTy, APValue const ,
+   APValue ) {
+  if (SourceTy->isIntegerType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = APValue(APFloat(0.0));
+  return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
+  DestTy, Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(
+  HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
+  return true;
+}
+  } else if (SourceTy->isRealFloatingType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = Original;
+  return HandleFloatToFloatCast(Info, E, SourceTy, DestTy,
+Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(APSInt());
+  return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(),
+  DestTy, Result.getInt());
+}
+  }
+  return false;
+}
+
+bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
+  APValue Source;
+  QualType SourceVecType = E->getSrcExpr()->getType();
+  if (!EvaluateVectorOrLValue(Source, Info, E->getSrcExpr(), SourceVecType))
+return false;
+
+  QualType DestTy = E->getType()->castAs()->getElementType();
+  QualType SourceTy = SourceVecType->castAs()->getElementType();
+
+  const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+
+  auto SourceLen = Source.getVectorLength();
+  SmallVector ResultElements;
+  ResultElements.reserve(SourceLen);
+  for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
+APValue Elt;
+if (!handleVectorConversion(Info, FPO, E, SourceTy, DestTy,
+Source.getVectorElt(EltNum), Elt))
+  return false;
+ResultElements.push_back(std::move(Elt));
+  }
+
+  return Success(APValue(ResultElements.data(), ResultElements.size()), E);
+}
+
+static bool handleVectorShuffle(EvalInfo , const ShuffleVectorExpr *E,
+QualType ElemType, APValue const ,
+APValue const , unsigned EltNum,
+APValue ) {
+  unsigned const TotalElementsInAVector = VecVal1.getVectorLength();

Destroyerrrocket wrote:

I see! It seems like Gcc has extra characteristics then. given that at some 
point it could happen that such a thing needs to be supported, let's actually 
rewrite the code to support both sizes. Beware, I won't be able to test it, as 
Sema will prevent it from reaching constexpr. 

https://github.com/llvm/llvm-project/pull/76615
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Constexpr for __builtin_shufflevector and __builtin_convertvector (PR #76615)

2024-04-01 Thread Pol M via cfe-commits
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= ,
Pol Marcet =?utf-8?q?Sardà?= 
Message-ID:
In-Reply-To: 



@@ -10895,6 +10899,132 @@ bool VectorExprEvaluator::VisitUnaryOperator(const 
UnaryOperator *E) {
   return Success(APValue(ResultElements.data(), ResultElements.size()), E);
 }
 
+static bool EvaluateVectorOrLValue(APValue , EvalInfo ,
+   const Expr *E, const QualType ) {
+  if (!Evaluate(Result, Info, E))
+return false;
+
+  if (Result.isLValue()) {
+// Source of the data is an lvalue; Manually handle the lvalue as if
+// it was an rvalue to get the current APValue.
+LValue LValueFound;
+LValueFound.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, Type, LValueFound, Result))
+  return false;
+  }
+
+  return Result.isVector();
+}
+
+static bool handleVectorConversion(EvalInfo , const FPOptions FPO,
+   const Expr *E, QualType SourceTy,
+   QualType DestTy, APValue const ,
+   APValue ) {
+  if (SourceTy->isIntegerType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = APValue(APFloat(0.0));
+  return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(),
+  DestTy, Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(
+  HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt()));
+  return true;
+}
+  } else if (SourceTy->isRealFloatingType()) {
+if (DestTy->isRealFloatingType()) {
+  Result = Original;
+  return HandleFloatToFloatCast(Info, E, SourceTy, DestTy,
+Result.getFloat());
+}
+if (DestTy->isIntegerType()) {
+  Result = APValue(APSInt());
+  return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(),
+  DestTy, Result.getInt());
+}
+  }
+  return false;
+}
+
+bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
+  APValue Source;
+  QualType SourceVecType = E->getSrcExpr()->getType();
+  if (!EvaluateVectorOrLValue(Source, Info, E->getSrcExpr(), SourceVecType))
+return false;
+
+  QualType DestTy = E->getType()->castAs()->getElementType();
+  QualType SourceTy = SourceVecType->castAs()->getElementType();
+
+  const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+
+  auto SourceLen = Source.getVectorLength();
+  SmallVector ResultElements;

Destroyerrrocket wrote:

304 bytes is definitely inside what I'd be slightly worried to allocate without 
thinking into the stack, but having looked at it I think it's going to be fine. 
We're not the only case of smallVectors with APValues, and I'm sure that if it 
ever becomes a problem the default stack size can be modified (or the code can 
be refactored, I'm sure that if that ever happens it's not going to be "just" 
the fault of a smallvector of APValues). I thank you for pointing it out, as I 
simply did not check!

https://github.com/llvm/llvm-project/pull/76615
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-01 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Friendly ping @cor3ntin and @erichkeane if you're back in the offices.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [PowerPC] Implement 32-bit expansion for rldimi (PR #86783)

2024-04-01 Thread Qiu Chaofan via cfe-commits

https://github.com/ecnelises updated 
https://github.com/llvm/llvm-project/pull/86783

>From b886dcf2da25417d9f8cd75ff4aa58686e35139d Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Wed, 27 Mar 2024 17:11:04 +0800
Subject: [PATCH] [PowerPC] Implement 32-bit expansion for rldimi

rldimi is 64-bit instruction, due to backward compatibility, it needs to
be expanded into series of rlwimi in 32-bit environment. In the future,
we may improve bit permutation selector and remove such direct codegen.
---
 clang/lib/Sema/SemaChecking.cpp |   1 -
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 109 --
 llvm/test/CodeGen/PowerPC/rldimi.ll | 366 
 3 files changed, 454 insertions(+), 22 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 11401b6f56c0ea..d2cbe5417d682d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5236,7 +5236,6 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
   case PPC::BI__builtin_ppc_fetch_and_andlp:
   case PPC::BI__builtin_ppc_fetch_and_orlp:
   case PPC::BI__builtin_ppc_fetch_and_swaplp:
-  case PPC::BI__builtin_ppc_rldimi:
 return true;
   }
   return false;
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 7436b202fba0d9..3281a0dfd08729 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -643,6 +643,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine 
,
   // We want to custom lower some of our intrinsics.
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::f64, Custom);
+  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::ppcf128, Custom);
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::v4f32, Custom);
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::v2f64, Custom);
@@ -10757,6 +10758,88 @@ static bool getVectorCompareInfo(SDValue Intrin, int 
,
   return true;
 }
 
+static SDValue getRotateInsert32(SelectionDAG , SDLoc Loc, SDValue Dst,
+ SDValue Src, unsigned SH, unsigned MB,
+ unsigned ME) {
+  assert(SH < 32 && MB < 32 && ME < 32 &&
+ "Invalid argument for rotate insert!");
+  return SDValue(
+  DAG.getMachineNode(PPC::RLWIMI, Loc, MVT::i32,
+ {Dst, Src, DAG.getTargetConstant(SH, Loc, MVT::i32),
+  DAG.getTargetConstant(MB, Loc, MVT::i32),
+  DAG.getTargetConstant(ME, Loc, MVT::i32)}),
+  0);
+}
+
+static SDValue getRotateInsert64(SelectionDAG , SDLoc Loc, SDValue Dst,
+ SDValue Src, unsigned SH, unsigned MB,
+ unsigned ME, bool IsPPC64) {
+  assert(SH < 64 && MB < 64 && ME < 64 &&
+ "Invalid argument for rotate insert!");
+  if (IsPPC64) {
+// rldimi requires ME=63-SH, otherwise rotation is needed before rldimi.
+if (ME < 63 - SH) {
+  Src = DAG.getNode(ISD::ROTL, Loc, MVT::i64, Src,
+DAG.getConstant(ME + SH + 1, Loc, MVT::i32));
+} else if (ME > 63 - SH) {
+  Src = DAG.getNode(ISD::ROTL, Loc, MVT::i64, Src,
+DAG.getConstant(ME + SH - 63, Loc, MVT::i32));
+}
+return SDValue(DAG.getMachineNode(
+   PPC::RLDIMI, Loc, MVT::i64,
+   {Dst, Src, DAG.getTargetConstant(63 - ME, Loc, 
MVT::i32),
+DAG.getTargetConstant(MB, Loc, MVT::i32)}),
+   0);
+  }
+
+  // To implement rldimi(Dst, Src) on 32-bit target, four parts are needed. SH
+  // is adjusted to simplify cases. Invalid ranges will be skipped.
+  // - SrcHi inserted into DstHi with [0, 32-SH)
+  // - SrcLo inserted into DstHi with [32-SH, 32)
+  // - SrcHi inserted into DstLo with [32, 64-SH)
+  // - SrcLo inserted into DstLo with [64-SH, 64)
+  auto [SrcLo, SrcHi] = DAG.SplitScalar(Src, Loc, MVT::i32, MVT::i32);
+  auto [DstLo, DstHi] = DAG.SplitScalar(Dst, Loc, MVT::i32, MVT::i32);
+  if (SH >= 32) {
+SH -= 32;
+std::swap(SrcLo, SrcHi);
+  }
+  auto GetSubInsert = [, , SH](unsigned Left, unsigned Right,
+   SDValue Src, SDValue Dst, unsigned MB,
+   unsigned ME) {
+if (Left > Right)
+  return Dst;
+
+if (MB <= ME) {
+  if (MB <= Right && ME >= Left)
+return getRotateInsert32(DAG, Loc, Dst, Src, SH,
+ std::max(MB, Left) % 32,
+ std::min(ME, Right) % 32);
+} else {
+  if (MB < Left || ME > Right)
+return getRotateInsert32(DAG, Loc, Dst, Src, SH, Left % 32, Right % 
32);
+
+  if (MB <= Right && ME < Left)
+return getRotateInsert32(DAG, Loc, Dst, Src, SH, MB % 32, Right % 

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-04-01 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

I think the support for modules in clangd is pretty important. I posted 
https://discourse.llvm.org/t/rfc-directions-for-modules-support-in-clangd/78072 
and let's see if we can make some progress.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ef0291e - [NFC] [Serialization] Reordering lexcical and visible TU block after type decl offsets

2024-04-01 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-04-01T16:16:03+08:00
New Revision: ef0291e5f4451abbafab0c839bf51a6382f735f3

URL: 
https://github.com/llvm/llvm-project/commit/ef0291e5f4451abbafab0c839bf51a6382f735f3
DIFF: 
https://github.com/llvm/llvm-project/commit/ef0291e5f4451abbafab0c839bf51a6382f735f3.diff

LOG: [NFC] [Serialization] Reordering lexcical and visible TU block after type 
decl offsets

This patch reorder the lexical block for the translation unit, visible update 
block for the TU and
the viisble upaete block for the extern C context after the type decl
offsets block.

This should be a NFC patch.

This is helpful for later optimizations for eliding unreachable
declarations in the global module fragment. See the comments in
https://github.com/llvm/llvm-project/pull/76930.

Simply, if we want to get the reachable sets of declaratins during the
writing process, we need to write the file-level context later than the
process of writing declarations (which is the main process to determine
the reachable set).

Added: 


Modified: 
clang/lib/Serialization/ASTWriter.cpp
clang/test/Modules/language-linkage.cppm

Removed: 




diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 1e5734c9c834eb..2438fbc166062f 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4959,38 +4959,12 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema , 
StringRef isysroot,
 Stream.EmitRecord(METADATA_OLD_FORMAT, Record);
   }
 
-  // Create a lexical update block containing all of the declarations in the
-  // translation unit that do not come from other AST files.
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
-  SmallVector NewGlobalKindDeclPairs;
-  for (const auto *D : TU->noload_decls()) {
-if (!D->isFromASTFile()) {
-  NewGlobalKindDeclPairs.push_back(D->getKind());
-  NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
-}
-  }
-
-  auto Abv = std::make_shared();
-  Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
-  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
-  unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
-  {
-RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
-Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
-  bytes(NewGlobalKindDeclPairs));
-  }
 
-  // And a visible updates block for the translation unit.
-  Abv = std::make_shared();
-  Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
-  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
-  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
-  UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
-  WriteDeclContextVisibleUpdate(TU);
-
-  // If we have any extern "C" names, write out a visible update for them.
-  if (Context.ExternCContext)
-WriteDeclContextVisibleUpdate(Context.ExternCContext);
+  // Force all top level declarations to be emitted.
+  for (const auto *D : TU->noload_decls())
+if (!D->isFromASTFile())
+  GetDeclRef(D);
 
   // If the translation unit has an anonymous namespace, and we don't already
   // have an update block for it, write it as an update block.
@@ -5131,6 +5105,14 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema , 
StringRef isysroot,
   for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
 DeclsToCheckForDeferredDiags.push_back(GetDeclRef(D));
 
+  {
+auto Abv = std::make_shared();
+Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
+Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
+Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
+  }
+
   RecordData DeclUpdatesOffsetsRecord;
 
   // Keep writing types, declarations, and declaration update records
@@ -5158,6 +5140,35 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema , 
StringRef isysroot,
   WriteTypeDeclOffsets();
   if (!DeclUpdatesOffsetsRecord.empty())
 Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
+
+  // Create a lexical update block containing all of the declarations in the
+  // translation unit that do not come from other AST files.
+  {
+SmallVector NewGlobalKindDeclPairs;
+for (const auto *D : TU->noload_decls()) {
+  if (!D->isFromASTFile()) {
+NewGlobalKindDeclPairs.push_back(D->getKind());
+NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
+  }
+}
+
+auto Abv = std::make_shared();
+Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
+Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
+Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
+  bytes(NewGlobalKindDeclPairs));
+  

[clang-tools-extra] [clang-tidy] add new check readability-enum-initial-value (PR #86129)

2024-04-01 Thread Congcong Cai via cfe-commits

https://github.com/HerrCai0907 closed 
https://github.com/llvm/llvm-project/pull/86129
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 3365d62 - [clang-tidy] add new check readability-enum-initial-value (#86129)

2024-04-01 Thread via cfe-commits

Author: Congcong Cai
Date: 2024-04-01T15:53:57+08:00
New Revision: 3365d62179011aad6da3e4cbcb31044eec3462a2

URL: 
https://github.com/llvm/llvm-project/commit/3365d62179011aad6da3e4cbcb31044eec3462a2
DIFF: 
https://github.com/llvm/llvm-project/commit/3365d62179011aad6da3e4cbcb31044eec3462a2.diff

LOG: [clang-tidy] add new check readability-enum-initial-value (#86129)

Fixes: #85243.

Added: 
clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.h
clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c

clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp

Modified: 
clang-tools-extra/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 5728c9970fb65d..dd772d69202548 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -17,6 +17,7 @@ add_clang_library(clangTidyReadabilityModule
   DeleteNullPointerCheck.cpp
   DuplicateIncludeCheck.cpp
   ElseAfterReturnCheck.cpp
+  EnumInitialValueCheck.cpp
   FunctionCognitiveComplexityCheck.cpp
   FunctionSizeCheck.cpp
   IdentifierLengthCheck.cpp

diff  --git 
a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
new file mode 100644
index 00..8f2841c32259a2
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
@@ -0,0 +1,200 @@
+//===--- EnumInitialValueCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "EnumInitialValueCheck.h"
+#include "../utils/LexerUtils.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static bool isNoneEnumeratorsInitialized(const EnumDecl ) {
+  return llvm::all_of(Node.enumerators(), [](const EnumConstantDecl *ECD) {
+return ECD->getInitExpr() == nullptr;
+  });
+}
+
+static bool isOnlyFirstEnumeratorInitialized(const EnumDecl ) {
+  bool IsFirst = true;
+  for (const EnumConstantDecl *ECD : Node.enumerators()) {
+if ((IsFirst && ECD->getInitExpr() == nullptr) ||
+(!IsFirst && ECD->getInitExpr() != nullptr))
+  return false;
+IsFirst = false;
+  }
+  return !IsFirst;
+}
+
+static bool areAllEnumeratorsInitialized(const EnumDecl ) {
+  return llvm::all_of(Node.enumerators(), [](const EnumConstantDecl *ECD) {
+return ECD->getInitExpr() != nullptr;
+  });
+}
+
+/// Check if \p Enumerator is initialized with a (potentially negated) \c
+/// IntegerLiteral.
+static bool isInitializedByLiteral(const EnumConstantDecl *Enumerator) {
+  const Expr *const Init = Enumerator->getInitExpr();
+  if (!Init)
+return false;
+  return Init->isIntegerConstantExpr(Enumerator->getASTContext());
+}
+
+static void cleanInitialValue(DiagnosticBuilder ,
+  const EnumConstantDecl *ECD,
+  const SourceManager ,
+  const LangOptions ) {
+  const SourceRange InitExprRange = ECD->getInitExpr()->getSourceRange();
+  if (InitExprRange.isInvalid() || InitExprRange.getBegin().isMacroID() ||
+  InitExprRange.getEnd().isMacroID())
+return;
+  std::optional EqualToken = 
utils::lexer::findNextTokenSkippingComments(
+  ECD->getLocation(), SM, LangOpts);
+  if (!EqualToken.has_value() ||
+  EqualToken.value().getKind() != tok::TokenKind::equal)
+return;
+  const SourceLocation EqualLoc{EqualToken->getLocation()};
+  if (EqualLoc.isInvalid() || EqualLoc.isMacroID())
+return;
+  Diag << FixItHint::CreateRemoval(EqualLoc)
+   << FixItHint::CreateRemoval(InitExprRange);
+  return;
+}
+
+namespace {
+
+AST_MATCHER(EnumDecl, isMacro) {
+  SourceLocation Loc = Node.getBeginLoc();
+  return Loc.isMacroID();
+}
+
+AST_MATCHER(EnumDecl, hasConsistentInitialValues) {
+  return isNoneEnumeratorsInitialized(Node) ||
+ 

[clang] [llvm] [InstCombiner] Remove trivially dead `llvm.allow.{runtime,ubsan}.check()` (PR #84851)

2024-04-01 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka closed 
https://github.com/llvm/llvm-project/pull/84851
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C++20] [Modules] Introduce -fexperimental-modules-reduced-bmi (PR #85050)

2024-04-01 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

I'd like to land this patch in next week if no objection comes in.

https://github.com/llvm/llvm-project/pull/85050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C++20] [Modules] Introduce -fexperimental-modules-reduced-bmi (PR #85050)

2024-04-01 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

> > Got it. I've renamed the flag as `-fexperimental-modules-reduced-bmi`.
> 
> Thanks.
> 
> > I feel the suggestion like let users to use `-Xclang` options look odd..
> 
> I think the point here is that we want **expert** users to try this out (with 
> understanding that it might not behave exactly as they expect). Because it is 
> experimental, it is not yet ready for "end users" - I would expect expert 
> users to be able to deal with -Xclang x (but I will not insist, it's just 
> a suggestion)

Agreed.

https://github.com/llvm/llvm-project/pull/85050
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)

2024-04-01 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/86629

>From b8a69cbd9e0ee0aa35b38b7e3a78048cbe61447e Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Sat, 16 Mar 2024 23:30:10 +0800
Subject: [PATCH 1/9] [clangd] Support go-to-definition on type hints. The core
 part

---
 clang-tools-extra/clangd/AST.cpp  |   9 +
 clang-tools-extra/clangd/AST.h|   2 +
 clang-tools-extra/clangd/InlayHints.cpp   | 251 +-
 .../clangd/index/IndexAction.cpp  |   9 +-
 .../clangd/unittests/InlayHintTests.cpp   |  22 ++
 5 files changed, 279 insertions(+), 14 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 1b86ea19cf28da..ef87f1bcb8443c 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -1019,5 +1019,14 @@ bool isExpandedFromParameterPack(const ParmVarDecl *D) {
   return getUnderlyingPackType(D) != nullptr;
 }
 
+std::optional toURI(OptionalFileEntryRef File) {
+  if (!File)
+return std::nullopt;
+  auto AbsolutePath = File->getFileEntry().tryGetRealPathName();
+  if (AbsolutePath.empty())
+return std::nullopt;
+  return URI::create(AbsolutePath);
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fb0722d697cd06..3ae624b1ab7415 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -250,6 +250,8 @@ resolveForwardingParameters(const FunctionDecl *D, unsigned 
MaxDepth = 10);
 /// reference to one (e.g. `Args&...` or `Args&&...`).
 bool isExpandedFromParameterPack(const ParmVarDecl *D);
 
+std::optional toURI(OptionalFileEntryRef File);
+
 } // namespace clangd
 } // namespace clang
 
diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index cd4f1931b3ce1d..f9e0a51ddcc9f0 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/SourceManager.h"
@@ -372,6 +373,197 @@ maybeDropCxxExplicitObjectParameters(ArrayRef Params) {
   return Params;
 }
 
+std::optional toLocation(SourceManager , SourceRange Range) {
+  if (Range.isInvalid())
+return std::nullopt;
+  if (auto URI =
+  toURI(SM.getFileEntryRefForID(SM.getFileID(Range.getBegin() {
+Location L;
+L.range.start = sourceLocToPosition(SM, Range.getBegin());
+L.range.end = sourceLocToPosition(SM, Range.getEnd());
+if (auto File = URIForFile::fromURI(*URI, ""))
+  L.uri = File.get();
+return L;
+  }
+  return std::nullopt;
+}
+
+class TypeInlayHintLabelPartBuilder
+: public TypeVisitor {
+  QualType Current;
+  ASTContext 
+  const PrintingPolicy 
+  std::vector 
+
+  bool ShouldAddLinksToTagTypes = false;
+
+  struct CurrentTypeRAII {
+TypeInlayHintLabelPartBuilder 
+QualType PreviousType;
+bool PreviousShouldAddLinksToTagTypes;
+CurrentTypeRAII(TypeInlayHintLabelPartBuilder , QualType New,
+bool ShouldAddLinksToTagTypes)
+: Builder(Builder), PreviousType(Builder.Current) {
+  Builder.Current = New;
+  Builder.ShouldAddLinksToTagTypes = ShouldAddLinksToTagTypes;
+}
+~CurrentTypeRAII() {
+  Builder.Current = PreviousType;
+  Builder.ShouldAddLinksToTagTypes = PreviousShouldAddLinksToTagTypes;
+}
+  };
+
+  void addLabel(llvm::function_ref NamePrinter,
+llvm::function_ref SourceRangeGetter) {
+auto  = LabelChunks.emplace_back();
+llvm::raw_string_ostream OS(Name.value);
+NamePrinter(OS);
+Name.location = toLocation(Context.getSourceManager(), 
SourceRangeGetter());
+  }
+
+  void printTemplateArgumentList(llvm::ArrayRef Args) {
+unsigned Size = Args.size();
+for (unsigned I = 0; I < Size; ++I) {
+  auto  = Args[I];
+  if (PP.SuppressDefaultTemplateArgs && TA.getIsDefaulted())
+continue;
+  if (I)
+LabelChunks.emplace_back(", ");
+  printTemplateArgument(TA);
+}
+  }
+
+  void printTemplateArgument(const TemplateArgument ) {
+if (TA.getKind() == TemplateArgument::Pack)
+  return printTemplateArgumentList(TA.pack_elements());
+if (TA.getKind() == TemplateArgument::Type) {
+  CurrentTypeRAII Guard(*this, TA.getAsType(),
+/*ShouldAddLinksToTagTypes=*/true);
+  return Visit(TA.getAsType().getTypePtr());
+}
+llvm::raw_string_ostream OS(LabelChunks.emplace_back().value);
+TA.print(PP, OS, /*IncludeType=*/true);
+  }
+
+  void
+  processTemplateSpecialization(TemplateName TN,
+llvm::ArrayRef Args,
+SourceRange TemplateNameRange = SourceRange()) 
{
+

[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)

2024-04-01 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/86629

>From b8a69cbd9e0ee0aa35b38b7e3a78048cbe61447e Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Sat, 16 Mar 2024 23:30:10 +0800
Subject: [PATCH 1/8] [clangd] Support go-to-definition on type hints. The core
 part

---
 clang-tools-extra/clangd/AST.cpp  |   9 +
 clang-tools-extra/clangd/AST.h|   2 +
 clang-tools-extra/clangd/InlayHints.cpp   | 251 +-
 .../clangd/index/IndexAction.cpp  |   9 +-
 .../clangd/unittests/InlayHintTests.cpp   |  22 ++
 5 files changed, 279 insertions(+), 14 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 1b86ea19cf28da..ef87f1bcb8443c 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -1019,5 +1019,14 @@ bool isExpandedFromParameterPack(const ParmVarDecl *D) {
   return getUnderlyingPackType(D) != nullptr;
 }
 
+std::optional toURI(OptionalFileEntryRef File) {
+  if (!File)
+return std::nullopt;
+  auto AbsolutePath = File->getFileEntry().tryGetRealPathName();
+  if (AbsolutePath.empty())
+return std::nullopt;
+  return URI::create(AbsolutePath);
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fb0722d697cd06..3ae624b1ab7415 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -250,6 +250,8 @@ resolveForwardingParameters(const FunctionDecl *D, unsigned 
MaxDepth = 10);
 /// reference to one (e.g. `Args&...` or `Args&&...`).
 bool isExpandedFromParameterPack(const ParmVarDecl *D);
 
+std::optional toURI(OptionalFileEntryRef File);
+
 } // namespace clangd
 } // namespace clang
 
diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index cd4f1931b3ce1d..f9e0a51ddcc9f0 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/SourceManager.h"
@@ -372,6 +373,197 @@ maybeDropCxxExplicitObjectParameters(ArrayRef Params) {
   return Params;
 }
 
+std::optional toLocation(SourceManager , SourceRange Range) {
+  if (Range.isInvalid())
+return std::nullopt;
+  if (auto URI =
+  toURI(SM.getFileEntryRefForID(SM.getFileID(Range.getBegin() {
+Location L;
+L.range.start = sourceLocToPosition(SM, Range.getBegin());
+L.range.end = sourceLocToPosition(SM, Range.getEnd());
+if (auto File = URIForFile::fromURI(*URI, ""))
+  L.uri = File.get();
+return L;
+  }
+  return std::nullopt;
+}
+
+class TypeInlayHintLabelPartBuilder
+: public TypeVisitor {
+  QualType Current;
+  ASTContext 
+  const PrintingPolicy 
+  std::vector 
+
+  bool ShouldAddLinksToTagTypes = false;
+
+  struct CurrentTypeRAII {
+TypeInlayHintLabelPartBuilder 
+QualType PreviousType;
+bool PreviousShouldAddLinksToTagTypes;
+CurrentTypeRAII(TypeInlayHintLabelPartBuilder , QualType New,
+bool ShouldAddLinksToTagTypes)
+: Builder(Builder), PreviousType(Builder.Current) {
+  Builder.Current = New;
+  Builder.ShouldAddLinksToTagTypes = ShouldAddLinksToTagTypes;
+}
+~CurrentTypeRAII() {
+  Builder.Current = PreviousType;
+  Builder.ShouldAddLinksToTagTypes = PreviousShouldAddLinksToTagTypes;
+}
+  };
+
+  void addLabel(llvm::function_ref NamePrinter,
+llvm::function_ref SourceRangeGetter) {
+auto  = LabelChunks.emplace_back();
+llvm::raw_string_ostream OS(Name.value);
+NamePrinter(OS);
+Name.location = toLocation(Context.getSourceManager(), 
SourceRangeGetter());
+  }
+
+  void printTemplateArgumentList(llvm::ArrayRef Args) {
+unsigned Size = Args.size();
+for (unsigned I = 0; I < Size; ++I) {
+  auto  = Args[I];
+  if (PP.SuppressDefaultTemplateArgs && TA.getIsDefaulted())
+continue;
+  if (I)
+LabelChunks.emplace_back(", ");
+  printTemplateArgument(TA);
+}
+  }
+
+  void printTemplateArgument(const TemplateArgument ) {
+if (TA.getKind() == TemplateArgument::Pack)
+  return printTemplateArgumentList(TA.pack_elements());
+if (TA.getKind() == TemplateArgument::Type) {
+  CurrentTypeRAII Guard(*this, TA.getAsType(),
+/*ShouldAddLinksToTagTypes=*/true);
+  return Visit(TA.getAsType().getTypePtr());
+}
+llvm::raw_string_ostream OS(LabelChunks.emplace_back().value);
+TA.print(PP, OS, /*IncludeType=*/true);
+  }
+
+  void
+  processTemplateSpecialization(TemplateName TN,
+llvm::ArrayRef Args,
+SourceRange TemplateNameRange = SourceRange()) 
{
+

<    1   2   3   4