[clang] [clang] Add Obj-C bridging-related attributes to C-Index API (PR #69899)

2023-10-23 Thread Jevin Sweval via cfe-commits

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


[clang] [clang][Interp] IndirectMember initializers (PR #69900)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/69900

We need to look at the chain of declarations to initialize the right field.

>From 5b48d59166b013f375682eced512a4da937c458f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 22 Oct 2023 19:47:33 +0200
Subject: [PATCH] [clang][Interp] IndirectMember initializers

---
 clang/lib/AST/Interp/ByteCodeStmtGen.cpp | 66 +++-
 clang/lib/AST/Interp/Interp.h|  7 ++-
 clang/lib/AST/Interp/Opcodes.td  |  6 ++-
 clang/test/AST/Interp/records.cpp| 60 +
 4 files changed, 113 insertions(+), 26 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 509abe3ae867f93..1b9b3069a8f4347 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -142,6 +142,27 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   // Classify the return type.
   ReturnType = this->classify(F->getReturnType());
 
+  auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
+  const Expr *InitExpr) -> bool {
+if (std::optional T = this->classify(InitExpr)) {
+  if (!this->visit(InitExpr))
+return false;
+
+  if (F->isBitField())
+return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
+  return this->emitInitThisField(*T, FieldOffset, InitExpr);
+}
+// Non-primitive case. Get a pointer to the field-to-initialize
+// on the stack and call visitInitialzer() for it.
+if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
+  return false;
+
+if (!this->visitInitializer(InitExpr))
+  return false;
+
+return this->emitPopPtr(InitExpr);
+  };
+
   // Emit custom code if this is a lambda static invoker.
   if (const auto *MD = dyn_cast(F);
   MD && MD->isLambdaStaticInvoker())
@@ -162,29 +183,8 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   if (const FieldDecl *Member = Init->getMember()) {
 const Record::Field *F = R->getField(Member);
 
-if (std::optional T = this->classify(InitExpr)) {
-  if (!this->visit(InitExpr))
-return false;
-
-  if (F->isBitField()) {
-if (!this->emitInitThisBitField(*T, F, InitExpr))
-  return false;
-  } else {
-if (!this->emitInitThisField(*T, F->Offset, InitExpr))
-  return false;
-  }
-} else {
-  // Non-primitive case. Get a pointer to the field-to-initialize
-  // on the stack and call visitInitialzer() for it.
-  if (!this->emitGetPtrThisField(F->Offset, InitExpr))
-return false;
-
-  if (!this->visitInitializer(InitExpr))
-return false;
-
-  if (!this->emitPopPtr(InitExpr))
-return false;
-}
+if (!emitFieldInitializer(F, F->Offset, InitExpr))
+  return false;
   } else if (const Type *Base = Init->getBaseClass()) {
 // Base class initializer.
 // Get This Base and call initializer on it.
@@ -198,6 +198,26 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   return false;
 if (!this->emitInitPtrPop(InitExpr))
   return false;
+  } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
+assert(IFD->getChainingSize() >= 2);
+
+unsigned NestedFieldOffset = 0;
+const Record::Field *NestedField = nullptr;
+for (const NamedDecl *ND : IFD->chain()) {
+  const FieldDecl *FD = cast(ND);
+  const Record *FieldRecord =
+  this->P.getOrCreateRecord(FD->getParent());
+  assert(FieldRecord);
+
+  NestedField = FieldRecord->getField(FD);
+  assert(NestedField);
+
+  NestedFieldOffset += NestedField->Offset;
+}
+assert(NestedField);
+
+if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
+  return false;
   } else {
 assert(Init->isDelegatingInitializer());
 if (!this->emitThis(InitExpr))
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7ef1e344224a3c3..b2777c8a007ea7f 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1069,15 +1069,18 @@ bool InitThisField(InterpState &S, CodePtr OpPC, 
uint32_t I) {
   return true;
 }
 
+// FIXME: The Field pointer here is too much IMO and we could instead just
+// pass an Offset + BitWidth pair.
 template ::T>
-bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
+bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
+  uint32_t FieldOffset) {
   assert(F->isBitField());
   if (S.checkingPotentialConstantExpression())
 return false;
   const Pointer &This = S.Current->getThis();
   if (!CheckT

[clang] [clang][Interp] IndirectMember initializers (PR #69900)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69900

>From 214cb369b518adb6ef0a046731e0e16133740917 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 22 Oct 2023 19:47:33 +0200
Subject: [PATCH] [clang][Interp] IndirectMember initializers

---
 clang/lib/AST/Interp/ByteCodeStmtGen.cpp | 67 
 clang/lib/AST/Interp/Interp.h|  7 ++-
 clang/lib/AST/Interp/Opcodes.td  |  6 ++-
 clang/test/AST/Interp/records.cpp| 60 +
 4 files changed, 114 insertions(+), 26 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 509abe3ae867f93..c22bbd8623e5326 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -142,6 +142,27 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   // Classify the return type.
   ReturnType = this->classify(F->getReturnType());
 
+  auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
+  const Expr *InitExpr) -> bool {
+if (std::optional T = this->classify(InitExpr)) {
+  if (!this->visit(InitExpr))
+return false;
+
+  if (F->isBitField())
+return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
+  return this->emitInitThisField(*T, FieldOffset, InitExpr);
+}
+// Non-primitive case. Get a pointer to the field-to-initialize
+// on the stack and call visitInitialzer() for it.
+if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
+  return false;
+
+if (!this->visitInitializer(InitExpr))
+  return false;
+
+return this->emitPopPtr(InitExpr);
+  };
+
   // Emit custom code if this is a lambda static invoker.
   if (const auto *MD = dyn_cast(F);
   MD && MD->isLambdaStaticInvoker())
@@ -162,29 +183,8 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   if (const FieldDecl *Member = Init->getMember()) {
 const Record::Field *F = R->getField(Member);
 
-if (std::optional T = this->classify(InitExpr)) {
-  if (!this->visit(InitExpr))
-return false;
-
-  if (F->isBitField()) {
-if (!this->emitInitThisBitField(*T, F, InitExpr))
-  return false;
-  } else {
-if (!this->emitInitThisField(*T, F->Offset, InitExpr))
-  return false;
-  }
-} else {
-  // Non-primitive case. Get a pointer to the field-to-initialize
-  // on the stack and call visitInitialzer() for it.
-  if (!this->emitGetPtrThisField(F->Offset, InitExpr))
-return false;
-
-  if (!this->visitInitializer(InitExpr))
-return false;
-
-  if (!this->emitPopPtr(InitExpr))
-return false;
-}
+if (!emitFieldInitializer(F, F->Offset, InitExpr))
+  return false;
   } else if (const Type *Base = Init->getBaseClass()) {
 // Base class initializer.
 // Get This Base and call initializer on it.
@@ -198,6 +198,27 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   return false;
 if (!this->emitInitPtrPop(InitExpr))
   return false;
+  } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
+assert(IFD->getChainingSize() >= 2);
+
+unsigned NestedFieldOffset = 0;
+const Record::Field *NestedField = nullptr;
+for (const NamedDecl *ND : IFD->chain()) {
+  // FIXME: Can this *not* be a FieldDecl?
+  const FieldDecl *FD = cast(ND);
+  const Record *FieldRecord =
+  this->P.getOrCreateRecord(FD->getParent());
+  assert(FieldRecord);
+
+  NestedField = FieldRecord->getField(FD);
+  assert(NestedField);
+
+  NestedFieldOffset += NestedField->Offset;
+}
+assert(NestedField);
+
+if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
+  return false;
   } else {
 assert(Init->isDelegatingInitializer());
 if (!this->emitThis(InitExpr))
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7ef1e344224a3c3..b2777c8a007ea7f 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1069,15 +1069,18 @@ bool InitThisField(InterpState &S, CodePtr OpPC, 
uint32_t I) {
   return true;
 }
 
+// FIXME: The Field pointer here is too much IMO and we could instead just
+// pass an Offset + BitWidth pair.
 template ::T>
-bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
+bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
+  uint32_t FieldOffset) {
   assert(F->isBitField());
   if (S.checkingPotentialConstantExpression())
 return false;
   const Pointer &This = S.Current->getThis();
   if (!CheckThis(S, OpPC, This))
 

[clang] [clang][Interp] IndirectMember initializers (PR #69900)

2023-10-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

We need to look at the chain of declarations to initialize the right field.

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


4 Files Affected:

- (modified) clang/lib/AST/Interp/ByteCodeStmtGen.cpp (+44-23) 
- (modified) clang/lib/AST/Interp/Interp.h (+5-2) 
- (modified) clang/lib/AST/Interp/Opcodes.td (+5-1) 
- (modified) clang/test/AST/Interp/records.cpp (+60) 


``diff
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 509abe3ae867f93..c22bbd8623e5326 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -142,6 +142,27 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   // Classify the return type.
   ReturnType = this->classify(F->getReturnType());
 
+  auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
+  const Expr *InitExpr) -> bool {
+if (std::optional T = this->classify(InitExpr)) {
+  if (!this->visit(InitExpr))
+return false;
+
+  if (F->isBitField())
+return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr);
+  return this->emitInitThisField(*T, FieldOffset, InitExpr);
+}
+// Non-primitive case. Get a pointer to the field-to-initialize
+// on the stack and call visitInitialzer() for it.
+if (!this->emitGetPtrThisField(FieldOffset, InitExpr))
+  return false;
+
+if (!this->visitInitializer(InitExpr))
+  return false;
+
+return this->emitPopPtr(InitExpr);
+  };
+
   // Emit custom code if this is a lambda static invoker.
   if (const auto *MD = dyn_cast(F);
   MD && MD->isLambdaStaticInvoker())
@@ -162,29 +183,8 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   if (const FieldDecl *Member = Init->getMember()) {
 const Record::Field *F = R->getField(Member);
 
-if (std::optional T = this->classify(InitExpr)) {
-  if (!this->visit(InitExpr))
-return false;
-
-  if (F->isBitField()) {
-if (!this->emitInitThisBitField(*T, F, InitExpr))
-  return false;
-  } else {
-if (!this->emitInitThisField(*T, F->Offset, InitExpr))
-  return false;
-  }
-} else {
-  // Non-primitive case. Get a pointer to the field-to-initialize
-  // on the stack and call visitInitialzer() for it.
-  if (!this->emitGetPtrThisField(F->Offset, InitExpr))
-return false;
-
-  if (!this->visitInitializer(InitExpr))
-return false;
-
-  if (!this->emitPopPtr(InitExpr))
-return false;
-}
+if (!emitFieldInitializer(F, F->Offset, InitExpr))
+  return false;
   } else if (const Type *Base = Init->getBaseClass()) {
 // Base class initializer.
 // Get This Base and call initializer on it.
@@ -198,6 +198,27 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   return false;
 if (!this->emitInitPtrPop(InitExpr))
   return false;
+  } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember()) {
+assert(IFD->getChainingSize() >= 2);
+
+unsigned NestedFieldOffset = 0;
+const Record::Field *NestedField = nullptr;
+for (const NamedDecl *ND : IFD->chain()) {
+  // FIXME: Can this *not* be a FieldDecl?
+  const FieldDecl *FD = cast(ND);
+  const Record *FieldRecord =
+  this->P.getOrCreateRecord(FD->getParent());
+  assert(FieldRecord);
+
+  NestedField = FieldRecord->getField(FD);
+  assert(NestedField);
+
+  NestedFieldOffset += NestedField->Offset;
+}
+assert(NestedField);
+
+if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr))
+  return false;
   } else {
 assert(Init->isDelegatingInitializer());
 if (!this->emitThis(InitExpr))
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7ef1e344224a3c3..b2777c8a007ea7f 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1069,15 +1069,18 @@ bool InitThisField(InterpState &S, CodePtr OpPC, 
uint32_t I) {
   return true;
 }
 
+// FIXME: The Field pointer here is too much IMO and we could instead just
+// pass an Offset + BitWidth pair.
 template ::T>
-bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
+bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
+  uint32_t FieldOffset) {
   assert(F->isBitField());
   if (S.checkingPotentialConstantExpression())
 return false;
   const Pointer &This = S.Current->getThis();
   if (!CheckThis(S, OpPC, This))
 return false;
-  const Pointer &Field = This.atField(F->Offset);
+  const Pointer &Field = This.atFiel

[clang-tools-extra] [InstCombine] Convert or concat to fshl if opposite or concat exists (PR #68502)

2023-10-23 Thread via cfe-commits

https://github.com/HaohaiWen updated 
https://github.com/llvm/llvm-project/pull/68502

>From 5b3b1bbb5b263bc5711adde031d85b1461ccbab6 Mon Sep 17 00:00:00 2001
From: Haohai Wen 
Date: Sat, 7 Oct 2023 13:48:32 +0800
Subject: [PATCH 1/4] [InstCombine] Refactor matchFunnelShift to allow more
 pattern (NFC)

Current implementation of matchFunnelShift only allows opposite shift
pattern. Refactor it to allow more pattern.
---
 .../InstCombine/InstCombineAndOrXor.cpp   | 172 ++
 1 file changed, 93 insertions(+), 79 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index cbdab3e9c5fb91d..b04e070fd19d7d1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2732,100 +2732,114 @@ static Instruction *matchFunnelShift(Instruction &Or, 
InstCombinerImpl &IC) {
   // rotate matching code under visitSelect and visitTrunc?
   unsigned Width = Or.getType()->getScalarSizeInBits();
 
-  // First, find an or'd pair of opposite shifts:
-  // or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)
-  BinaryOperator *Or0, *Or1;
-  if (!match(Or.getOperand(0), m_BinOp(Or0)) ||
-  !match(Or.getOperand(1), m_BinOp(Or1)))
-return nullptr;
-
-  Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
-  if (!match(Or0, m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0 
||
-  !match(Or1, m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1 
||
-  Or0->getOpcode() == Or1->getOpcode())
+  Instruction *Or0, *Or1;
+  if (!match(Or.getOperand(0), m_Instruction(Or0)) ||
+  !match(Or.getOperand(1), m_Instruction(Or1)))
 return nullptr;
 
-  // Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
-  if (Or0->getOpcode() == BinaryOperator::LShr) {
-std::swap(Or0, Or1);
-std::swap(ShVal0, ShVal1);
-std::swap(ShAmt0, ShAmt1);
-  }
-  assert(Or0->getOpcode() == BinaryOperator::Shl &&
- Or1->getOpcode() == BinaryOperator::LShr &&
- "Illegal or(shift,shift) pair");
-
-  // Match the shift amount operands for a funnel shift pattern. This always
-  // matches a subtraction on the R operand.
-  auto matchShiftAmount = [&](Value *L, Value *R, unsigned Width) -> Value * {
-// Check for constant shift amounts that sum to the bitwidth.
-const APInt *LI, *RI;
-if (match(L, m_APIntAllowUndef(LI)) && match(R, m_APIntAllowUndef(RI)))
-  if (LI->ult(Width) && RI->ult(Width) && (*LI + *RI) == Width)
-return ConstantInt::get(L->getType(), *LI);
-
-Constant *LC, *RC;
-if (match(L, m_Constant(LC)) && match(R, m_Constant(RC)) &&
-match(L, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) 
&&
-match(R, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, APInt(Width, Width))) 
&&
-match(ConstantExpr::getAdd(LC, RC), m_SpecificIntAllowUndef(Width)))
-  return ConstantExpr::mergeUndefsWith(LC, RC);
-
-// (shl ShVal, X) | (lshr ShVal, (Width - x)) iff X < Width.
-// We limit this to X < Width in case the backend re-expands the intrinsic,
-// and has to reintroduce a shift modulo operation (InstCombine might 
remove
-// it after this fold). This still doesn't guarantee that the final codegen
-// will match this original pattern.
-if (match(R, m_OneUse(m_Sub(m_SpecificInt(Width), m_Specific(L) {
-  KnownBits KnownL = IC.computeKnownBits(L, /*Depth*/ 0, &Or);
-  return KnownL.getMaxValue().ult(Width) ? L : nullptr;
-}
+  bool IsFshl = true; // Sub on LSHR.
+  SmallVector FShiftArgs;
 
-// For non-constant cases, the following patterns currently only work for
-// rotation patterns.
-// TODO: Add general funnel-shift compatible patterns.
-if (ShVal0 != ShVal1)
+  // First, find an or'd pair of opposite shifts:
+  // or (lshr ShVal0, ShAmt0), (shl ShVal1, ShAmt1)
+  if (isa(Or0) && isa(Or1)) {
+Value *ShVal0, *ShVal1, *ShAmt0, *ShAmt1;
+if (!match(Or0,
+   m_OneUse(m_LogicalShift(m_Value(ShVal0), m_Value(ShAmt0 ||
+!match(Or1,
+   m_OneUse(m_LogicalShift(m_Value(ShVal1), m_Value(ShAmt1 ||
+Or0->getOpcode() == Or1->getOpcode())
   return nullptr;
 
-// For non-constant cases we don't support non-pow2 shift masks.
-// TODO: Is it worth matching urem as well?
-if (!isPowerOf2_32(Width))
-  return nullptr;
+// Canonicalize to or(shl(ShVal0, ShAmt0), lshr(ShVal1, ShAmt1)).
+if (Or0->getOpcode() == BinaryOperator::LShr) {
+  std::swap(Or0, Or1);
+  std::swap(ShVal0, ShVal1);
+  std::swap(ShAmt0, ShAmt1);
+}
+assert(Or0->getOpcode() == BinaryOperator::Shl &&
+   Or1->getOpcode() == BinaryOperator::LShr &&
+   "Illegal or(shift,shift) pair");
+
+// Match the shift amount operands for a funnel shift pattern. This always
+// matches a subtraction on the R operand.
+auto matchShiftAmount = [&](Value *L

[clang-tools-extra] [InstCombine] Convert or concat to fshl if opposite or concat exists (PR #68502)

2023-10-23 Thread via cfe-commits


@@ -2840,6 +2841,60 @@ static Instruction *matchFunnelShift(Instruction &Or, 
InstCombinerImpl &IC) {
   return nullptr;
 
 FShiftArgs = {ShVal0, ShVal1, ShAmt};
+  } else if (isa(Or0) || isa(Or1)) {
+// If there are two 'or' instructions concat variables in opposite order:
+//
+// Slot1 and Slot2 are all zero bits.
+// | Slot1 | Low | Slot2 | High |
+// LowHigh = or (shl (zext Low), ZextLowShlAmt), (zext High)
+// | Slot2 | High | Slot1 | Low |
+// HighLow = or (shl (zext High), ZextHighShlAmt), (zext Low)
+//
+// the latter 'or' can be safely convert to
+// -> HighLow = fshl LowHigh, LowHigh, ZextHighShlAmt
+// if ZextLowShlAmt + ZextHighShlAmt == Width.
+if (!isa(Or1))
+  std::swap(Or0, Or1);
+
+Value *High, *ZextHigh, *Low;
+const APInt *ZextHighShlAmt;
+if (!match(Or0,
+   m_OneUse(m_Shl(m_Value(ZextHigh), m_APInt(ZextHighShlAmt)
+  return nullptr;
+
+if (!match(Or1, m_ZExt(m_Value(Low))) ||
+!match(ZextHigh, m_ZExt(m_Value(High
+  return nullptr;
+
+unsigned HighSize = High->getType()->getScalarSizeInBits();
+unsigned LowSize = Low->getType()->getScalarSizeInBits();
+// Make sure High does not overlap with Low and most significant bits of
+// High aren't shifted out.
+if (ZextHighShlAmt->ult(LowSize) || ZextHighShlAmt->ugt(Width - HighSize))

HaohaiWen wrote:

Done

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


[clang-tools-extra] [InstCombine] Convert or concat to fshl if opposite or concat exists (PR #68502)

2023-10-23 Thread via cfe-commits


@@ -2840,6 +2841,60 @@ static Instruction *matchFunnelShift(Instruction &Or, 
InstCombinerImpl &IC) {
   return nullptr;
 
 FShiftArgs = {ShVal0, ShVal1, ShAmt};
+  } else if (isa(Or0) || isa(Or1)) {
+// If there are two 'or' instructions concat variables in opposite order:
+//
+// Slot1 and Slot2 are all zero bits.
+// | Slot1 | Low | Slot2 | High |
+// LowHigh = or (shl (zext Low), ZextLowShlAmt), (zext High)
+// | Slot2 | High | Slot1 | Low |
+// HighLow = or (shl (zext High), ZextHighShlAmt), (zext Low)
+//
+// the latter 'or' can be safely convert to
+// -> HighLow = fshl LowHigh, LowHigh, ZextHighShlAmt
+// if ZextLowShlAmt + ZextHighShlAmt == Width.
+if (!isa(Or1))
+  std::swap(Or0, Or1);
+
+Value *High, *ZextHigh, *Low;
+const APInt *ZextHighShlAmt;
+if (!match(Or0,
+   m_OneUse(m_Shl(m_Value(ZextHigh), m_APInt(ZextHighShlAmt)
+  return nullptr;
+
+if (!match(Or1, m_ZExt(m_Value(Low))) ||
+!match(ZextHigh, m_ZExt(m_Value(High
+  return nullptr;
+
+unsigned HighSize = High->getType()->getScalarSizeInBits();
+unsigned LowSize = Low->getType()->getScalarSizeInBits();
+// Make sure High does not overlap with Low and most significant bits of
+// High aren't shifted out.
+if (ZextHighShlAmt->ult(LowSize) || ZextHighShlAmt->ugt(Width - HighSize))
+  return nullptr;
+
+for (User *U : ZextHigh->users()) {
+  Value *X, *Y;
+  if (!match(U, m_Or(m_Value(X), m_Value(Y
+continue;
+
+  if (!isa(Y))
+std::swap(X, Y);
+
+  const APInt *ZextLowShlAmt;
+  if (!match(X, m_Shl(m_Specific(Or1), m_APInt(ZextLowShlAmt))) ||
+  !match(Y, m_Specific(ZextHigh)) || !DT.dominates(U, &Or))
+continue;
+
+  // Make sure Low does not overlap with High and most significant bits of
+  // Low aren't shifted out and we can rotate shift LowHigh to HighLow.
+  if (ZextLowShlAmt->ult(HighSize) || ZextLowShlAmt->ugt(Width - LowSize) 
||
+  *ZextLowShlAmt + *ZextHighShlAmt != Width)

HaohaiWen wrote:

In fact, non-dominating was already tested:
We checked:
yx = fshl xy, xy,
When instcombine handle first or (combine for xy), it can meet all check expect 
dominance.
If we don't check dominance, if would be convert to xy = fshl yx, yx which is 
absolutely wrong.




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


[clang] 5b189d6 - [clang] Fix designated initializers inside templates (#69712)

2023-10-23 Thread via cfe-commits

Author: Mariya Podchishchaeva
Date: 2023-10-23T10:43:47+02:00
New Revision: 5b189d6f5606b051667b363f7430a7b990afab34

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

LOG: [clang] Fix designated initializers inside templates (#69712)

Skip anonymous members when rebuilding `DesignatedInitExpr` since
designated inits for them are meant to be created during
`InitListChecker::CheckDesignatedInitializer` routine.

Fixes https://github.com/llvm/llvm-project/issues/65143

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/TreeTransform.h
clang/test/SemaCXX/cxx2b-designated-initializers.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index de1ab29d3182f20..d697259f6f5eb9f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -442,6 +442,9 @@ Bug Fixes in This Version
 - Clang no longer permits using the `_BitInt` types as an underlying type for 
an
   enumeration as specified in the C23 Standard.
   Fixes (`#69619 `_)
+- Clang now accepts anonymous members initialized with designated initializers
+  inside templates.
+  Fixes (`#65143 `_)
 
 Bug Fixes to Compiler Builtins
 ^^

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8fafdd4f5caa1ed..094e5efa939f4d1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -11783,8 +11783,6 @@ 
TreeTransform::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
   bool ExprChanged = false;
   for (const DesignatedInitExpr::Designator &D : E->designators()) {
 if (D.isFieldDesignator()) {
-  Desig.AddDesignator(Designator::CreateFieldDesignator(
-  D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
   if (D.getFieldDecl()) {
 FieldDecl *Field = cast_or_null(
 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
@@ -11792,12 +11790,16 @@ 
TreeTransform::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
   // Rebuild the expression when the transformed FieldDecl is
   // 
diff erent to the already assigned FieldDecl.
   ExprChanged = true;
+if (Field->isAnonymousStructOrUnion())
+  continue;
   } else {
 // Ensure that the designator expression is rebuilt when there isn't
 // a resolved FieldDecl in the designator as we don't want to assign
 // a FieldDecl to a pattern designator that will be instantiated again.
 ExprChanged = true;
   }
+  Desig.AddDesignator(Designator::CreateFieldDesignator(
+  D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
   continue;
 }
 

diff  --git a/clang/test/SemaCXX/cxx2b-designated-initializers.cpp 
b/clang/test/SemaCXX/cxx2b-designated-initializers.cpp
index 5588926f419a932..1d9b9183b3679f1 100644
--- a/clang/test/SemaCXX/cxx2b-designated-initializers.cpp
+++ b/clang/test/SemaCXX/cxx2b-designated-initializers.cpp
@@ -9,17 +9,36 @@ union S {
 };
 
 void f(int x, auto) {
-  const S result { // expected-error {{field designator (null) does not refer 
to any field in type 'const S'}}
+  const S result {
 .a = x
   };
 }
 
 void g(void) {
-  f(0, 0); // expected-note {{in instantiation of function template 
specialization 'PR61118::f' requested here}}
+  f(0, 0);
 }
 
 } // end namespace PR61118
 
+namespace GH65143 {
+struct Inner {
+  int a;
+};
+
+struct Outer {
+  struct {
+Inner inner;
+  };
+};
+
+template  void f() {
+  constexpr Outer x{.inner = {val}};
+  static_assert(x.inner.a == val);
+}
+
+void bar() { f<4>(); }
+}
+
 namespace GH62156 {
 union U1 {
int x;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix designated initializers inside templates (PR #69712)

2023-10-23 Thread Mariya Podchishchaeva via cfe-commits

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


[clang-tools-extra] [mlir][tosa] Check for unranked tensors during validation (PR #68509)

2023-10-23 Thread Georgios Pinitas via cfe-commits

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


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


[clang] [mlir][tosa] Check for unranked tensors during validation (PR #68509)

2023-10-23 Thread Georgios Pinitas via cfe-commits

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


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


[clang] [mlir][tosa] Check for unranked tensors during validation (PR #68509)

2023-10-23 Thread Georgios Pinitas via cfe-commits

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


[clang-tools-extra] [mlir][tosa] Check for unranked tensors during validation (PR #68509)

2023-10-23 Thread Georgios Pinitas via cfe-commits

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


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Ilya Biryukov via cfe-commits

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


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -960,18 +960,13 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
 return true;
   }
   // Otherwise the search scope is the namespace scope of which F is a member.
-  LookupResult NonMembers(S, NotEqOp, OpLoc,
-  Sema::LookupNameKind::LookupOperatorName);
-  S.LookupName(NonMembers,
-   S.getScopeForContext(EqFD->getEnclosingNamespaceContext()));
-  NonMembers.suppressAccessDiagnostics();
-  for (NamedDecl *Op : NonMembers) {
-auto *FD = Op->getAsFunction();
-if(auto* UD = dyn_cast(Op))
-  FD = UD->getUnderlyingDecl()->getAsFunction();
-if (FunctionsCorrespond(S.Context, EqFD, FD) &&
-declaresSameEntity(cast(EqFD->getDeclContext()),
-   cast(Op->getDeclContext(
+  for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+auto *NotEqFD = Op->getAsFunction();
+if (auto *UD = dyn_cast(Op))
+  NotEqFD = UD->getUnderlyingDecl()->getAsFunction();
+if (FunctionsCorrespond(S.Context, EqFD, NotEqFD) &&
+declaresSameEntity(cast(EqFD->getEnclosingNamespaceContext()),
+   cast(Op->getLexicalDeclContext(

ilya-biryukov wrote:

Sorry, I missed the `isVisible` call here. I agree with the rest, since this 
only disables reversed operator lookup, extra visibility checks from ADL should 
not be required.

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


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -960,18 +960,13 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
 return true;
   }
   // Otherwise the search scope is the namespace scope of which F is a member.
-  LookupResult NonMembers(S, NotEqOp, OpLoc,
-  Sema::LookupNameKind::LookupOperatorName);
-  S.LookupName(NonMembers,
-   S.getScopeForContext(EqFD->getEnclosingNamespaceContext()));
-  NonMembers.suppressAccessDiagnostics();
-  for (NamedDecl *Op : NonMembers) {
-auto *FD = Op->getAsFunction();
-if(auto* UD = dyn_cast(Op))
-  FD = UD->getUnderlyingDecl()->getAsFunction();
-if (FunctionsCorrespond(S.Context, EqFD, FD) &&
-declaresSameEntity(cast(EqFD->getDeclContext()),
-   cast(Op->getDeclContext(
+  for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+auto *NotEqFD = Op->getAsFunction();

ilya-biryukov wrote:

Ah, getAsFunction picks a primary template. LG and thanks for adding a test!

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


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov approved this pull request.


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


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

Oh, one last thing! @usx95 maybe add a test for the visibility check?
Various tests with modules (search for files with the `.cppm` extension in the 
tests) should give a good starting point.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov created 
https://github.com/llvm/llvm-project/pull/69908

`createExpansionLocImpl` has an assert that checks if we ran out of source 
locations. We have observed this happening on real code and in release builds 
the assertion does not fire and the compiler just keeps running indefinitely 
without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to 
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig further 
why that happens, but until then crashing seems like a better alternative.

>From 6b73e1fbbad1a485ce6266dbd8d3c499956b859a Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Thu, 19 Oct 2023 17:50:38 +0200
Subject: [PATCH] [SourceManager] Report an error and crash on source location
 exhaustion in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
---
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Basic/SourceManager.cpp  | 11 +++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Ilya Biryukov (ilya-biryukov)


Changes

`createExpansionLocImpl` has an assert that checks if we ran out of source 
locations. We have observed this happening on real code and in release builds 
the assertion does not fire and the compiler just keeps running indefinitely 
without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to 
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig further 
why that happens, but until then crashing seems like a better alternative.

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


2 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (+2) 
- (modified) clang/lib/Basic/SourceManager.cpp (+7-4) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

``




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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits


@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();

sam-mccall wrote:

you're not crashing here?

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall commented:

Upgrading this from assert to diag+crash makes sense to me.
Am I missing where the crash happens though?

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits


@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<

sam-mccall wrote:

FWIW, I'm not sure the *why* matters much: this is ~always going to be the sum 
of thousands of tiny things. So we could consider merging 
err_expansions_too_large and err_include_too_large. (And also emitting that in 
ASTReader.cpp above remark_sloc_usage).
But I don't feel strongly.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<

ilya-biryukov wrote:

I also don't feel strongly there. The reason I introduced a new warning is 
because this could theoretically happen without any `#include` and I did not 
want to touch the existing error message.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov updated 
https://github.com/llvm/llvm-project/pull/69908

>From 6b73e1fbbad1a485ce6266dbd8d3c499956b859a Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Thu, 19 Oct 2023 17:50:38 +0200
Subject: [PATCH 1/2] [SourceManager] Report an error and crash on source
 location exhaustion in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
---
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Basic/SourceManager.cpp  | 11 +++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

>From 2180aa94253647f6541c6311224c253be0c0de25 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 12:12:50 +0200
Subject: [PATCH 2/2] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

---
 clang/lib/Basic/SourceManager.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index dcf18c47cbaf9ae..415f0a33358703a 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -665,10 +665,12 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
   if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
   NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
-Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
-Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
-noteSLocAddressSpaceUsage(Diag);
-return SourceLocation();
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.
+// Currently, the call runs indefinitely, so we would first need to fix it.
+// FIXME: return an error instead of crashing. Returning invalid source
+// locations causes compiler to run indefinitely.
+llvm::report_fatal_error("ran out of source locations");
   }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();

ilya-biryukov wrote:

oops, sorry, I forgot to commit before pushing, changes were in the working 
index.
Should be good now.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

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


[clang] [clang][Interp] Fix truncateCast() (PR #69911)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/69911

The added test case used to fail because we converted the LHS to `-1`.

>From 6bae86e6d728996b92b0dfbbd62c254f1f32af9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 23 Oct 2023 11:43:32 +0200
Subject: [PATCH] [clang][Interp] Fix truncateCast()

---
 clang/lib/AST/Interp/IntegralAP.h | 36 +--
 clang/test/AST/Interp/intap.cpp   |  3 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 45e5b49546270aa..98d4dae8fa4df0e 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -35,10 +35,18 @@ template  class IntegralAP final {
   friend IntegralAP;
   APInt V;
 
-  template  static T truncateCast(const APInt &V) {
+  template 
+  static T truncateCast(const APInt &V) {
 constexpr unsigned BitSize = sizeof(T) * 8;
-if (BitSize >= V.getBitWidth())
-  return std::is_signed_v ? V.getSExtValue() : V.getZExtValue();
+if (BitSize >= V.getBitWidth()) {
+  APInt Extended;
+  if constexpr (InputSigned)
+Extended = V.sext(BitSize);
+  else
+Extended = V.zext(BitSize);
+  return std::is_signed_v ? Extended.getSExtValue()
+ : Extended.getZExtValue();
+}
 
 return std::is_signed_v ? V.trunc(BitSize).getSExtValue()
: V.trunc(BitSize).getZExtValue();
@@ -81,14 +89,20 @@ template  class IntegralAP final {
   }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return truncateCast(V); }
-  explicit operator uint8_t() const { return truncateCast(V); }
-  explicit operator int16_t() const { return truncateCast(V); }
-  explicit operator uint16_t() const { return truncateCast(V); }
-  explicit operator int32_t() const { return truncateCast(V); }
-  explicit operator uint32_t() const { return truncateCast(V); }
-  explicit operator int64_t() const { return truncateCast(V); }
-  explicit operator uint64_t() const { return truncateCast(V); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); 
}
+  explicit operator int16_t() const { return truncateCast(V); 
}
+  explicit operator uint16_t() const {
+return truncateCast(V);
+  }
+  explicit operator int32_t() const { return truncateCast(V); 
}
+  explicit operator uint32_t() const {
+return truncateCast(V);
+  }
+  explicit operator int64_t() const { return truncateCast(V); 
}
+  explicit operator uint64_t() const {
+return truncateCast(V);
+  }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 27fae1b904351ce..02a860eb0986c15 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -27,6 +27,9 @@ static_assert(BitIntZero2 == 0, "");
 constexpr unsigned _BitInt(1) UBitIntZero1{};
 static_assert(UBitIntZero1 == 0, "");
 
+constexpr unsigned _BitInt(2) BI1 = 3u;
+static_assert(BI1 == 3, "");
+
 
 #ifdef __SIZEOF_INT128__
 namespace i128 {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix truncateCast() (PR #69911)

2023-10-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

The added test case used to fail because we converted the LHS to `-1`.

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


2 Files Affected:

- (modified) clang/lib/AST/Interp/IntegralAP.h (+25-11) 
- (modified) clang/test/AST/Interp/intap.cpp (+3) 


``diff
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 45e5b49546270aa..98d4dae8fa4df0e 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -35,10 +35,18 @@ template  class IntegralAP final {
   friend IntegralAP;
   APInt V;
 
-  template  static T truncateCast(const APInt &V) {
+  template 
+  static T truncateCast(const APInt &V) {
 constexpr unsigned BitSize = sizeof(T) * 8;
-if (BitSize >= V.getBitWidth())
-  return std::is_signed_v ? V.getSExtValue() : V.getZExtValue();
+if (BitSize >= V.getBitWidth()) {
+  APInt Extended;
+  if constexpr (InputSigned)
+Extended = V.sext(BitSize);
+  else
+Extended = V.zext(BitSize);
+  return std::is_signed_v ? Extended.getSExtValue()
+ : Extended.getZExtValue();
+}
 
 return std::is_signed_v ? V.trunc(BitSize).getSExtValue()
: V.trunc(BitSize).getZExtValue();
@@ -81,14 +89,20 @@ template  class IntegralAP final {
   }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return truncateCast(V); }
-  explicit operator uint8_t() const { return truncateCast(V); }
-  explicit operator int16_t() const { return truncateCast(V); }
-  explicit operator uint16_t() const { return truncateCast(V); }
-  explicit operator int32_t() const { return truncateCast(V); }
-  explicit operator uint32_t() const { return truncateCast(V); }
-  explicit operator int64_t() const { return truncateCast(V); }
-  explicit operator uint64_t() const { return truncateCast(V); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); 
}
+  explicit operator int16_t() const { return truncateCast(V); 
}
+  explicit operator uint16_t() const {
+return truncateCast(V);
+  }
+  explicit operator int32_t() const { return truncateCast(V); 
}
+  explicit operator uint32_t() const {
+return truncateCast(V);
+  }
+  explicit operator int64_t() const { return truncateCast(V); 
}
+  explicit operator uint64_t() const {
+return truncateCast(V);
+  }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 27fae1b904351ce..02a860eb0986c15 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -27,6 +27,9 @@ static_assert(BitIntZero2 == 0, "");
 constexpr unsigned _BitInt(1) UBitIntZero1{};
 static_assert(UBitIntZero1 == 0, "");
 
+constexpr unsigned _BitInt(2) BI1 = 3u;
+static_assert(BI1 == 3, "");
+
 
 #ifdef __SIZEOF_INT128__
 namespace i128 {

``




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


[clang] [clang][Interp] Implement IntegralAP::truncate() (PR #69912)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/69912

None

>From a9e872ec17d31baad095d12a1fdca15a2a5965ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 23 Oct 2023 12:23:45 +0200
Subject: [PATCH] [clang][Interp] Implement IntegralAP::truncate()

---
 clang/lib/AST/Interp/IntegralAP.h |  5 ++---
 clang/test/AST/Interp/intap.cpp   | 16 
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 45e5b49546270aa..f8d47ca183f3a67 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -137,9 +137,8 @@ template  class IntegralAP final {
 return NameStr;
   }
 
-  IntegralAP truncate(unsigned bitWidth) const {
-assert(false);
-return V;
+  IntegralAP truncate(unsigned BitWidth) const {
+return IntegralAP(V.trunc(BitWidth));
   }
 
   IntegralAP toUnsigned() const {
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 27fae1b904351ce..c19e8c1367e9f4f 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -118,4 +118,20 @@ namespace AddSubOffset {
   static_assert(*P2 == 1,"");
 }
 
+namespace Bitfields {
+  struct S1 {
+unsigned _BitInt(128) a : 2;
+  };
+  constexpr S1 s1{100}; // ref-warning {{changes value from 100 to 0}} \
+// expected-warning {{changes value from 100 to 0}}
+  constexpr S1 s12{3};
+  static_assert(s12.a == 3, "");
+
+  struct S2 {
+unsigned __int128 a : 2;
+  };
+  constexpr S2 s2{100}; // ref-warning {{changes value from 100 to 0}} \
+// expected-warning {{changes value from 100 to 0}}
+}
+
 #endif

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

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


[clang] [Driver] Link Flang runtime on FreeBSD, NetBSD, OpenBSD, DragonFly and Haiku (PR #69817)

2023-10-23 Thread Andrzej Warzyński via cfe-commits

banach-space wrote:

These changes make sense to me, but I have no experience with these toolchains 
and feel that somebody more familiar with this corner of LLVM should take a 
look as well.

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


[clang] [clang][Interp] Fix IntAP(s) to IntAP(s) casts (PR #69915)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/69915

None

>From 4bc54275a7180d63450591616dab5660d85a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 23 Oct 2023 12:46:25 +0200
Subject: [PATCH] [clang][Interp] Fix IntAP(s) to IntAP(s) casts

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  7 ++-
 clang/test/AST/Interp/intap.cpp  | 11 +++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index ed971fe0f650f22..d6ce337f642230b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -191,16 +191,13 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 if (!this->visit(SubExpr))
   return false;
 
-if (FromT == ToT) {
-  assert(ToT != PT_IntAP && ToT != PT_IntAPS);
-  return true;
-}
-
 if (ToT == PT_IntAP)
   return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
 if (ToT == PT_IntAPS)
   return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
 
+if (FromT == ToT)
+  return true;
 return this->emitCast(*FromT, *ToT, CE);
   }
 
diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp
index 27fae1b904351ce..b0bf5615f8d8afd 100644
--- a/clang/test/AST/Interp/intap.cpp
+++ b/clang/test/AST/Interp/intap.cpp
@@ -27,6 +27,17 @@ static_assert(BitIntZero2 == 0, "");
 constexpr unsigned _BitInt(1) UBitIntZero1{};
 static_assert(UBitIntZero1 == 0, "");
 
+namespace APCast {
+  constexpr _BitInt(10) A = 1;
+  constexpr _BitInt(11) B = A;
+  static_assert(B == 1, "");
+  constexpr _BitInt(16) B2 = A;
+  static_assert(B2 == 1, "");
+  constexpr _BitInt(32) B3 = A;
+  static_assert(B3 == 1, "");
+  constexpr unsigned _BitInt(32) B4 = A;
+  static_assert(B4 == 1, "");
+}
 
 #ifdef __SIZEOF_INT128__
 namespace i128 {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Correctly emit destructors for multi-dimensional arrays (PR #69140)

2023-10-23 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-23 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Only diagnose null field access in constant contexts (PR #69223)

2023-10-23 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

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


[PATCH] D159351: [Sema] Change order of displayed overloads in diagnostics

2023-10-23 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 557839.
ilya-biryukov marked 4 inline comments as done.
ilya-biryukov added a comment.

- Addressed comments
- Added a release note


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159351/new/

https://reviews.llvm.org/D159351

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp

Index: clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+namespace ambig {
+  struct Foo {
+operator int();
+operator const char *();
+  };
+
+
+  void func(const char*, long);
+  void func(const char*, const char*);
+  void func(int, int);
+
+  bool doit(Foo x) {
+func(x, x); // expected-error {{call to 'func' is ambiguous}}
+// expected-note@* 3{{candidate}}
+// Check that two functions with best conversions are at the top.
+// CHECK: error: call to 'func' is ambiguous
+// CHECK-NEXT: func(x, x)
+// CHECK-NEXT: ^~~~
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(const char*, const char*)
+// CHECK-NEXT: ^
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(int, int)
+  }
+}
+
+namespace bad_conversion {
+  struct Foo {
+operator int();
+operator const char *();
+  };
+
+
+  void func(double*, const char*, long);
+  void func(double*, const char*, const char*);
+  void func(double*, int, int);
+
+  bool doit(Foo x) {
+func((int*)0, x, x); // expected-error {{no matching function for call to 'func'}}
+ // expected-note@* 3{{candidate}}
+// Check that two functions with best conversions are at the top.
+// CHECK: error: no matching function for call to 'func'
+// CHECK-NEXT: func((int*)0, x, x)
+// CHECK-NEXT: ^~~~
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(double*, const char*, const char*)
+// CHECK-NEXT: ^
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(double*, int, int)
+  }
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -38,8 +38,10 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -12009,6 +12011,7 @@
 }
 
 namespace {
+
 struct CompareOverloadCandidatesForDisplay {
   Sema &S;
   SourceLocation Loc;
@@ -12046,13 +12049,9 @@
 if (L->Viable) {
   if (!R->Viable) return true;
 
-  // TODO: introduce a tri-valued comparison for overload
-  // candidates.  Would be more worthwhile if we had a sort
-  // that could exploit it.
-  if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK))
-return true;
-  if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK))
-return false;
+  if (int Ord = CompareConversions(*L, *R))
+return Ord < 0;
+  // Use other tie breakers.
 } else if (R->Viable)
   return false;
 
@@ -12104,30 +12103,8 @@
 }
 
 // If there's any ordering between the defined conversions...
-// FIXME: this might not be transitive.
-assert(L->Conversions.size() == R->Conversions.size());
-
-int leftBetter = 0;
-unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
-for (unsigned E = L->Conversions.size(); I != E; ++I) {
-  switch (CompareImplicitConversionSequences(S, Loc,
- L->Conversions[I],
- R->Conversions[I])) {
-  case ImplicitConversionSequence::Better:
-leftBetter++;
-break;
-
-  case ImplicitConversionSequence::Worse:
-leftBetter--;
-break;
-
-  case ImplicitConversionSequence::Indistinguishable:
-break;
-  }
-}
-if (leftBetter > 0) return true;
-if (leftBetter < 0) return false;
-
+if (int Ord = CompareConversions(*L, *R))
+  return Ord < 0;
   } else if (RFailureKind == ovl_fail_bad_conversion)
 return false;
 
@@ -12149,10 +12126,66 @@
 SourceLocation RLoc = GetLocationForCandidate(R);
 
 // Put candidates without locations (e.g. builtins) at the end.
-if (LLoc.isInvalid()) return false;
-if (RLoc.isInvalid()) return true;
+if (LLoc.isValid() && RLoc.isValid())
+  return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RL

[clang] febf5c9 - [Sema] Change order of displayed overloads in diagnostics

2023-10-23 Thread Ilya Biryukov via cfe-commits

Author: Ilya Biryukov
Date: 2023-10-23T12:59:59+02:00
New Revision: febf5c97bba7910e796041c9518fce01f31ae826

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

LOG: [Sema] Change order of displayed overloads in diagnostics

Make it a strict weak order.

Fixes #64121.

Current implementation uses the definition of ordering from the C++ Standard.
The definition provides only a partial order and cannot be used in sorting
algorithms.

The debug builds of libc++ are capable of detecting that problem
and this failure was found when building Clang with libc++ and
those extra checks enabled, see #64121.

The new ordering is a strict weak order and still
pushes most interesting functions to the start of the list.
In some cases, it leads to better results, e.g.

```
struct Foo {
  operator int();
  operator const char*();
};

void test() { Foo() - Foo(); }
```

Now produces a list with two most relevant builtin operators at the top,
i.e. `operator-(int, int)` and `operator-(const char*, const char*)`.
Previously `operator-(const char*, const char*)` was the first element,
but `operator-(int, int)` was only the 13th element in the output.
This is a consequence of `stable_sort` now being able to compare those
two candidates, which are indistinguishable in the semantic partial order
despite being two local minimums in their respective comparable
subsets.

However, new implementation does not take into account some aspects of
C++ semantics, e.g. which function template is more specialized. This
can also lead to worse ordering sometimes.

Reviewed By: #clang-language-wg, aaron.ballman

Differential Revision: https://reviews.llvm.org/D159351

Added: 
clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaOverload.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d697259f6f5eb9f..3c013835d0b35e9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -356,6 +356,30 @@ Improvements to Clang's diagnostics
   nonportable construct that has 
diff erent semantics from a constant-sized
   array. (`#62836 `_)
 
+- Clang changed the order in which it displays candidate functions on 
overloading failures.
+  Previously, Clang used definition of ordering from the C++ Standard. The 
order defined in
+  the Standard is partial and is not suited for sorting. Instead, Clang now 
uses a strict
+  order that still attempts to push more relevant functions to the top by 
comparing their
+  corresponding conversions. In some cases, this results in better order. 
E.g., for the
+  following code
+
+  .. code-block:: cpp
+  struct Foo {
+operator int();
+operator const char*();
+  };
+
+  void test() { Foo() - Foo(); }
+
+  Clang now produces a list with two most relevant builtin operators at the 
top,
+  i.e. ``operator-(int, int)`` and ``operator-(const char*, const char*)``.
+  Previously ``operator-(const char*, const char*)`` was the first element,
+  but ``operator-(int, int)`` was only the 13th element in the output.
+  However, new implementation does not take into account some aspects of
+  C++ semantics, e.g. which function template is more specialized. This
+  can sometimes lead to worse ordering.
+
+
 Bug Fixes in This Version
 -
 - Fixed an issue where a class template specialization whose declaration is

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d57a7ad8f46859a..d9d7ce59b5fcb35 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -38,8 +38,10 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -12017,6 +12019,7 @@ static unsigned RankDeductionFailure(const 
DeductionFailureInfo &DFI) {
 }
 
 namespace {
+
 struct CompareOverloadCandidatesForDisplay {
   Sema &S;
   SourceLocation Loc;
@@ -12054,13 +12057,9 @@ struct CompareOverloadCandidatesForDisplay {
 if (L->Viable) {
   if (!R->Viable) return true;
 
-  // TODO: introduce a tri-valued comparison for overload
-  // candidates.  Would be more worthwhile if we had a sort
-  // that could exploit it.
-  if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK))
-return true;
-  if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK))
-return false;
+  if (int Ord = CompareConversions(*L, *R))
+return Ord < 0;
+  // Use other tie breakers.
 } else if (R->Viable)
   return false;
 
@@ -1211

[PATCH] D159351: [Sema] Change order of displayed overloads in diagnostics

2023-10-23 Thread Ilya Biryukov via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfebf5c97bba7: [Sema] Change order of displayed overloads in 
diagnostics (authored by ilya-biryukov).

Changed prior to commit:
  https://reviews.llvm.org/D159351?vs=557839&id=557840#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159351/new/

https://reviews.llvm.org/D159351

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp

Index: clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+namespace ambig {
+  struct Foo {
+operator int();
+operator const char *();
+  };
+
+
+  void func(const char*, long);
+  void func(const char*, const char*);
+  void func(int, int);
+
+  bool doit(Foo x) {
+func(x, x); // expected-error {{call to 'func' is ambiguous}}
+// expected-note@* 3{{candidate}}
+// Check that two functions with best conversions are at the top.
+// CHECK: error: call to 'func' is ambiguous
+// CHECK-NEXT: func(x, x)
+// CHECK-NEXT: ^~~~
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(const char*, const char*)
+// CHECK-NEXT: ^
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(int, int)
+  }
+}
+
+namespace bad_conversion {
+  struct Foo {
+operator int();
+operator const char *();
+  };
+
+
+  void func(double*, const char*, long);
+  void func(double*, const char*, const char*);
+  void func(double*, int, int);
+
+  bool doit(Foo x) {
+func((int*)0, x, x); // expected-error {{no matching function for call to 'func'}}
+ // expected-note@* 3{{candidate}}
+// Check that two functions with best conversions are at the top.
+// CHECK: error: no matching function for call to 'func'
+// CHECK-NEXT: func((int*)0, x, x)
+// CHECK-NEXT: ^~~~
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(double*, const char*, const char*)
+// CHECK-NEXT: ^
+// CHECK-NEXT: note: candidate function
+// CHECK-NEXT: void func(double*, int, int)
+  }
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -38,8 +38,10 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -12017,6 +12019,7 @@
 }
 
 namespace {
+
 struct CompareOverloadCandidatesForDisplay {
   Sema &S;
   SourceLocation Loc;
@@ -12054,13 +12057,9 @@
 if (L->Viable) {
   if (!R->Viable) return true;
 
-  // TODO: introduce a tri-valued comparison for overload
-  // candidates.  Would be more worthwhile if we had a sort
-  // that could exploit it.
-  if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK))
-return true;
-  if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK))
-return false;
+  if (int Ord = CompareConversions(*L, *R))
+return Ord < 0;
+  // Use other tie breakers.
 } else if (R->Viable)
   return false;
 
@@ -12112,30 +12111,8 @@
 }
 
 // If there's any ordering between the defined conversions...
-// FIXME: this might not be transitive.
-assert(L->Conversions.size() == R->Conversions.size());
-
-int leftBetter = 0;
-unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
-for (unsigned E = L->Conversions.size(); I != E; ++I) {
-  switch (CompareImplicitConversionSequences(S, Loc,
- L->Conversions[I],
- R->Conversions[I])) {
-  case ImplicitConversionSequence::Better:
-leftBetter++;
-break;
-
-  case ImplicitConversionSequence::Worse:
-leftBetter--;
-break;
-
-  case ImplicitConversionSequence::Indistinguishable:
-break;
-  }
-}
-if (leftBetter > 0) return true;
-if (leftBetter < 0) return false;
-
+if (int Ord = CompareConversions(*L, *R))
+  return Ord < 0;
   } else if (RFailureKind == ovl_fail_bad_conversion)
 return false;
 
@@ -12157,10 +12134,66 @@
 SourceLocation RLoc = GetLocationForCandidate(R);
 
 // Put candidates without locations (e.g. builtins) at the end.
-if (LLoc.isInvalid()

[clang] [clang][NFC] Refactor `Selector` to use `PointerIntPair` inside (PR #69916)

2023-10-23 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll created 
https://github.com/llvm/llvm-project/pull/69916

Refactor `uintptr_t` inside of `clang::Selector` that holds a pointer to 
`IdentifierInfo` or `MultiKeywordSelector` and `IdentifierInfoFlag` enum into 
`PointerIntPair`. This is a part of `PointerIntPair` migration outlined in 
https://github.com/llvm/llvm-project/issues/69835, and a necessary step toward 
the same refactoring of `clang::DeclarationName`.

Unlike `uintpt_t`, `PointerIntPair` required pointee types to be complete, so I 
had to shuffle definitions of `MultiKeywordSelector` and 
`detail::DeclarationNameExtra` around to make them complete at `Selector`. 
Also, there were outdated specializations of `PointerLikeTypeTraits` for 
`IdentifierInfo *`, which are no longer needed, because `alignof` that primary 
template use works just fine. Not just that, but they declared that 
`IdentifierInfo *` has only 1 spare lower bit, but today they are 8-byte 
aligned.

>From 58ebdda4e44b3fa2547d85a6cc9d5b0aa913b22a Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov 
Date: Mon, 23 Oct 2023 13:55:46 +0300
Subject: [PATCH] [clang][NFC] Refactor `Selector` to use `PointerIntPair`
 inside

---
 clang/include/clang/AST/DeclarationName.h   |   3 +-
 clang/include/clang/Basic/IdentifierTable.h | 261 +++-
 clang/lib/Basic/IdentifierTable.cpp |  59 +
 3 files changed, 145 insertions(+), 178 deletions(-)

diff --git a/clang/include/clang/AST/DeclarationName.h 
b/clang/include/clang/AST/DeclarationName.h
index b06931ea3e418f8..c9b01dc53964bd0 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -362,7 +362,8 @@ class DeclarationName {
   }
 
   /// Construct a declaration name from an Objective-C selector.
-  DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
+  DeclarationName(Selector Sel)
+  : Ptr(reinterpret_cast(Sel.InfoPtr.getOpaqueValue())) {}
 
   /// Returns the name for all C++ using-directives.
   static DeclarationName getUsingDirectiveName() {
diff --git a/clang/include/clang/Basic/IdentifierTable.h 
b/clang/include/clang/Basic/IdentifierTable.h
index 1a1ffddf2b1c601..4972e64fee41e23 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -19,6 +19,9 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -794,6 +797,121 @@ enum ObjCStringFormatFamily {
   SFF_CFString
 };
 
+namespace detail {
+
+/// DeclarationNameExtra is used as a base of various uncommon special names.
+/// This class is needed since DeclarationName has not enough space to store
+/// the kind of every possible names. Therefore the kind of common names is
+/// stored directly in DeclarationName, and the kind of uncommon names is
+/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
+/// DeclarationName needs the lower 3 bits to store the kind of common names.
+/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
+/// here is very likely to require changes in DeclarationName(Table).
+class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
+  friend class clang::DeclarationName;
+  friend class clang::DeclarationNameTable;
+
+protected:
+  /// The kind of "extra" information stored in the DeclarationName. See
+  /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
+  /// are used. Note that DeclarationName depends on the numerical values
+  /// of the enumerators in this enum. See DeclarationName::StoredNameKind
+  /// for more info.
+  enum ExtraKind {
+CXXDeductionGuideName,
+CXXLiteralOperatorName,
+CXXUsingDirective,
+ObjCMultiArgSelector
+  };
+
+  /// ExtraKindOrNumArgs has one of the following meaning:
+  ///  * The kind of an uncommon C++ special name. This DeclarationNameExtra
+  ///is in this case in fact either a CXXDeductionGuideNameExtra or
+  ///a CXXLiteralOperatorIdName.
+  ///
+  ///  * It may be also name common to C++ using-directives 
(CXXUsingDirective),
+  ///
+  ///  * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
+  ///the number of arguments in the Objective-C selector, in which
+  ///case the DeclarationNameExtra is also a MultiKeywordSelector.
+  unsigned ExtraKindOrNumArgs;
+
+  DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
+  DeclarationNameExtra(unsigned NumArgs)
+  : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
+
+  /// Return the corresponding ExtraKind.
+  ExtraKind getKind() const {
+return static_cast(ExtraKindOrNumArgs >
+  (unsigned)ObjCMultiArgSelector
+  ? (unsigned)ObjCMultiArgSelector
+   

[clang] [clang][NFC] Refactor `Selector` to use `PointerIntPair` inside (PR #69916)

2023-10-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)


Changes

Refactor `uintptr_t` inside of `clang::Selector` that holds a pointer to 
`IdentifierInfo` or `MultiKeywordSelector` and `IdentifierInfoFlag` enum into 
`PointerIntPair`. This is a part of `PointerIntPair` migration outlined in 
https://github.com/llvm/llvm-project/issues/69835, and a necessary step toward 
the same refactoring of `clang::DeclarationName`.

Unlike `uintpt_t`, `PointerIntPair` required pointee types to be complete, so I 
had to shuffle definitions of `MultiKeywordSelector` and 
`detail::DeclarationNameExtra` around to make them complete at `Selector`. 
Also, there were outdated specializations of `PointerLikeTypeTraits` for 
`IdentifierInfo *`, which are no longer needed, because `alignof` that primary 
template use works just fine. Not just that, but they declared that 
`IdentifierInfo *` has only 1 spare lower bit, but today they are 8-byte 
aligned.

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


3 Files Affected:

- (modified) clang/include/clang/AST/DeclarationName.h (+2-1) 
- (modified) clang/include/clang/Basic/IdentifierTable.h (+142-119) 
- (modified) clang/lib/Basic/IdentifierTable.cpp (+1-58) 


``diff
diff --git a/clang/include/clang/AST/DeclarationName.h 
b/clang/include/clang/AST/DeclarationName.h
index b06931ea3e418f8..c9b01dc53964bd0 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -362,7 +362,8 @@ class DeclarationName {
   }
 
   /// Construct a declaration name from an Objective-C selector.
-  DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
+  DeclarationName(Selector Sel)
+  : Ptr(reinterpret_cast(Sel.InfoPtr.getOpaqueValue())) {}
 
   /// Returns the name for all C++ using-directives.
   static DeclarationName getUsingDirectiveName() {
diff --git a/clang/include/clang/Basic/IdentifierTable.h 
b/clang/include/clang/Basic/IdentifierTable.h
index 1a1ffddf2b1c601..4972e64fee41e23 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -19,6 +19,9 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/TokenKinds.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -794,6 +797,121 @@ enum ObjCStringFormatFamily {
   SFF_CFString
 };
 
+namespace detail {
+
+/// DeclarationNameExtra is used as a base of various uncommon special names.
+/// This class is needed since DeclarationName has not enough space to store
+/// the kind of every possible names. Therefore the kind of common names is
+/// stored directly in DeclarationName, and the kind of uncommon names is
+/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
+/// DeclarationName needs the lower 3 bits to store the kind of common names.
+/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
+/// here is very likely to require changes in DeclarationName(Table).
+class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
+  friend class clang::DeclarationName;
+  friend class clang::DeclarationNameTable;
+
+protected:
+  /// The kind of "extra" information stored in the DeclarationName. See
+  /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
+  /// are used. Note that DeclarationName depends on the numerical values
+  /// of the enumerators in this enum. See DeclarationName::StoredNameKind
+  /// for more info.
+  enum ExtraKind {
+CXXDeductionGuideName,
+CXXLiteralOperatorName,
+CXXUsingDirective,
+ObjCMultiArgSelector
+  };
+
+  /// ExtraKindOrNumArgs has one of the following meaning:
+  ///  * The kind of an uncommon C++ special name. This DeclarationNameExtra
+  ///is in this case in fact either a CXXDeductionGuideNameExtra or
+  ///a CXXLiteralOperatorIdName.
+  ///
+  ///  * It may be also name common to C++ using-directives 
(CXXUsingDirective),
+  ///
+  ///  * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
+  ///the number of arguments in the Objective-C selector, in which
+  ///case the DeclarationNameExtra is also a MultiKeywordSelector.
+  unsigned ExtraKindOrNumArgs;
+
+  DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
+  DeclarationNameExtra(unsigned NumArgs)
+  : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
+
+  /// Return the corresponding ExtraKind.
+  ExtraKind getKind() const {
+return static_cast(ExtraKindOrNumArgs >
+  (unsigned)ObjCMultiArgSelector
+  ? (unsigned)ObjCMultiArgSelector
+  : ExtraKindOrNumArgs);
+  }
+
+  /// Return the number of arguments in an ObjC selector. Only valid when this
+  /// is 

[clang] [ConstantRange] Handle `Intrinsic::cttz` (PR #67917)

2023-10-23 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

@nikic Any comments about this PR?

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


[clang-tools-extra] [ConstantRange] Handle `Intrinsic::cttz` (PR #67917)

2023-10-23 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

@nikic Any comments about this PR?

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


[clang] [clang] Add clang::preferred_type attribute for bitfields (PR #69104)

2023-10-23 Thread Vlad Serebrennikov via cfe-commits


@@ -5910,6 +5910,30 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D,
   D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
 }
 
+static void handleDebugInfoTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!AL.hasParsedType()) {
+S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
+return;
+  }
+
+  TypeSourceInfo *ParmTSI = nullptr;
+  QualType type = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
+  assert(ParmTSI && "no type source info for attribute argument");
+
+  if (type->isEnumeralType()) {
+QualType BitfieldType = llvm::cast(D)->getType();
+QualType EnumUnderlyingType =
+type->getAs()->getDecl()->getIntegerType();
+if (EnumUnderlyingType != BitfieldType) {

Endilll wrote:

With `typedef` and sign-ness issues fixed, I consider this done.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall approved this pull request.

LG but would be great if we could fix the note!

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits


@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<

sam-mccall wrote:

SGTM (but the current version is also OK with me)

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits


@@ -663,10 +663,15 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.

sam-mccall wrote:

hm, this makes the diag *significantly* less useful.

I suppose this change is still better than the status quo, but any idea what 
causes it?

If it's the new LocalSLocEntryTable entry (which seems plausible), it seems you 
could just move the check above it?

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


[clang] [OpenMP][OMPIRBuilder] Add support to omp target parallel (PR #67000)

2023-10-23 Thread Dominik Adamski via cfe-commits

https://github.com/DominikAdamski updated 
https://github.com/llvm/llvm-project/pull/67000

>From e801022968ea4a42632fbcf4c5ba03e67a32c7ae Mon Sep 17 00:00:00 2001
From: Dominik Adamski 
Date: Mon, 11 Sep 2023 05:31:37 -0400
Subject: [PATCH] [OpenMP][OMPIRBuilder] Add support to omp target parallel

Added support for LLVM IR code generation which is used for handling
omp target parallel code. The call for __kmpc_parallel_51 is generated
and the parallel region is outlined to separate function.

The proper setup of kmpc_target_init mode is not included in the commit.
It is assumed that the SPMD mode for target init is properly set by other
codegen functions.
---
 clang/test/OpenMP/cancel_codegen.cpp  |  20 +-
 clang/test/OpenMP/parallel_codegen.cpp|   4 +-
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 314 +-
 llvm/lib/Transforms/IPO/OpenMPOpt.cpp |   1 +
 .../Frontend/OpenMPIRBuilderTest.cpp  | 139 +++-
 5 files changed, 378 insertions(+), 100 deletions(-)

diff --git a/clang/test/OpenMP/cancel_codegen.cpp 
b/clang/test/OpenMP/cancel_codegen.cpp
index 53580e0c2b0293f..03024cf331b2717 100644
--- a/clang/test/OpenMP/cancel_codegen.cpp
+++ b/clang/test/OpenMP/cancel_codegen.cpp
@@ -1026,25 +1026,25 @@ for (int i = 0; i < argc; ++i) {
 // CHECK3-NEXT:call void @llvm.experimental.noalias.scope.decl(metadata 
[[META8:![0-9]+]])
 // CHECK3-NEXT:call void @llvm.experimental.noalias.scope.decl(metadata 
[[META10:![0-9]+]])
 // CHECK3-NEXT:call void @llvm.experimental.noalias.scope.decl(metadata 
[[META12:![0-9]+]])
-// CHECK3-NEXT:store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, 
!noalias !14
-// CHECK3-NEXT:store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, 
!noalias !14
-// CHECK3-NEXT:store ptr null, ptr [[DOTPRIVATES__ADDR_I]], align 8, 
!noalias !14
-// CHECK3-NEXT:store ptr null, ptr [[DOTCOPY_FN__ADDR_I]], align 8, 
!noalias !14
-// CHECK3-NEXT:store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, 
!noalias !14
-// CHECK3-NEXT:store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, 
!noalias !14
-// CHECK3-NEXT:[[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, 
!noalias !14
+// CHECK3-NEXT:store i32 [[TMP2]], ptr [[DOTGLOBAL_TID__ADDR_I]], align 4, 
!noalias ![[NOALIAS0:[0-9]+]]
+// CHECK3-NEXT:store ptr [[TMP5]], ptr [[DOTPART_ID__ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
+// CHECK3-NEXT:store ptr null, ptr [[DOTPRIVATES__ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
+// CHECK3-NEXT:store ptr null, ptr [[DOTCOPY_FN__ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
+// CHECK3-NEXT:store ptr [[TMP3]], ptr [[DOTTASK_T__ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
+// CHECK3-NEXT:store ptr [[TMP7]], ptr [[__CONTEXT_ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
+// CHECK3-NEXT:[[TMP8:%.*]] = load ptr, ptr [[__CONTEXT_ADDR_I]], align 8, 
!noalias ![[NOALIAS0]]
 // CHECK3-NEXT:[[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 
@__kmpc_global_thread_num(ptr @[[GLOB12:[0-9]+]])
 // CHECK3-NEXT:[[TMP9:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 
[[OMP_GLOBAL_THREAD_NUM_I]], i32 4)
 // CHECK3-NEXT:[[TMP10:%.*]] = icmp ne i32 [[TMP9]], 0
 // CHECK3-NEXT:br i1 [[TMP10]], label [[DOTCANCEL_EXIT_I:%.*]], label 
[[DOTCANCEL_CONTINUE_I:%.*]]
 // CHECK3:   .cancel.exit.i:
-// CHECK3-NEXT:store i32 1, ptr [[CLEANUP_DEST_SLOT_I]], align 4, !noalias 
!14
+// CHECK3-NEXT:store i32 1, ptr [[CLEANUP_DEST_SLOT_I]], align 4, !noalias 
![[NOALIAS1:[0-9]+]]
 // CHECK3-NEXT:br label [[DOTOMP_OUTLINED__EXIT:%.*]]
 // CHECK3:   .cancel.continue.i:
-// CHECK3-NEXT:store i32 0, ptr [[CLEANUP_DEST_SLOT_I]], align 4, !noalias 
!14
+// CHECK3-NEXT:store i32 0, ptr [[CLEANUP_DEST_SLOT_I]], align 4, !noalias 
![[NOALIAS1]]
 // CHECK3-NEXT:br label [[DOTOMP_OUTLINED__EXIT]]
 // CHECK3:   .omp_outlined..exit:
-// CHECK3-NEXT:[[CLEANUP_DEST_I:%.*]] = load i32, ptr 
[[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14
+// CHECK3-NEXT:[[CLEANUP_DEST_I:%.*]] = load i32, ptr 
[[CLEANUP_DEST_SLOT_I]], align 4, !noalias ![[NOALIAS1]]
 // CHECK3-NEXT:ret i32 0
 //
 //
diff --git a/clang/test/OpenMP/parallel_codegen.cpp 
b/clang/test/OpenMP/parallel_codegen.cpp
index 5c98761be0808ef..d545b4a9d9fa887 100644
--- a/clang/test/OpenMP/parallel_codegen.cpp
+++ b/clang/test/OpenMP/parallel_codegen.cpp
@@ -812,7 +812,7 @@ int main (int argc, char **argv) {
 //
 //
 // CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIPPcEiT_..omp_par
-// CHECK3-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], 
ptr [[TMP0:%.*]]) #[[ATTR1]] {
+// CHECK3-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], 
ptr [[TMP0:%.*]]) #[[ATTR2:[0-9]+]]
 // CHECK3-NEXT:  omp.par.entry:
 // CHECK3-NEXT:[[GEP__RELOADED:%.*]] = getelementptr { ptr, ptr }, ptr 
[[TMP0]], i32 0, i32 0
 // CHECK3-NEXT:[[LOADGEP__RELOADED:%.*]] = load ptr, ptr 
[[GEP__RELOADED]], align 8
@@ -

[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -663,10 +663,15 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.

ilya-biryukov wrote:

I actually tried moving the sloc entry below this check, but it did not help.
So no idea what causes it, and I thought having the change as is is better than 
the current state, so I decided to sent the PR before figuring this one out.

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


[clang] [OpenMP][OMPIRBuilder] Add support to omp target parallel (PR #67000)

2023-10-23 Thread Dominik Adamski via cfe-commits

DominikAdamski wrote:

@shraiysh `ParallelSimpleGPU` tests only the LLVM IR for the target device. 
`kmpc_parallel_51` is the function which needs to be executed on the GPU. The 
aim of this patch is to add GPU code generation for `omp target parallel 
pragma`.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<

ilya-biryukov wrote:

I have reused the existing diagnostic and updated it to remove a mention of 
include.

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov updated 
https://github.com/llvm/llvm-project/pull/69908

>From 6b73e1fbbad1a485ce6266dbd8d3c499956b859a Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Thu, 19 Oct 2023 17:50:38 +0200
Subject: [PATCH 1/4] [SourceManager] Report an error and crash on source
 location exhaustion in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
---
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Basic/SourceManager.cpp  | 11 +++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

>From 2180aa94253647f6541c6311224c253be0c0de25 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 12:12:50 +0200
Subject: [PATCH 2/4] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

---
 clang/lib/Basic/SourceManager.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index dcf18c47cbaf9ae..415f0a33358703a 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -665,10 +665,12 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
   if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
   NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
-Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
-Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
-noteSLocAddressSpaceUsage(Diag);
-return SourceLocation();
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.
+// Currently, the call runs indefinitely, so we would first need to fix it.
+// FIXME: return an error instead of crashing. Returning invalid source
+// locations causes compiler to run indefinitely.
+llvm::report_fatal_error("ran out of source locations");
   }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;

>From 1344a7a687b1a3147820c1b4406f9e974924c676 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 13:52:15 +0200
Subject: [PATCH 3/4] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

- Unify the error when running out of slocs in includes and macro
- Use `SourceLocation()` instead of `

[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67990

>From 0056d67f145fd0d5f8056325bc70246314c9b117 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 16:26:46 +0200
Subject: [PATCH] [clang][Interp] Only emit function_param_value_unknown in
 C++11

---
 clang/lib/AST/Interp/Interp.cpp | 8 ++--
 clang/test/SemaCXX/offsetof.cpp | 7 +++
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index a4d6844ebe61722..8b0e7beb4a1acc1 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -555,8 +555,12 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const 
DeclRefExpr *DR) {
   const SourceInfo &E = S.Current->getSource(OpPC);
 
   if (isa(D)) {
-S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
-S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+if (S.getLangOpts().CPlusPlus11) {
+  S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
+  S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+} else {
+  S.FFDiag(E);
+}
   } else if (const auto *VD = dyn_cast(D)) {
 if (!VD->getType().isConstQualified()) {
   S.FFDiag(E,
diff --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp
index cb91f2bed0b9224..f54ee06c43147dd 100644
--- a/clang/test/SemaCXX/offsetof.cpp
+++ b/clang/test/SemaCXX/offsetof.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected,new-interp %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
 
 struct NonPOD {
   virtual void f();
@@ -25,10 +25,9 @@ struct HasArray {
 };
 
 // Constant and non-constant offsetof expressions
-void test_ice(int i) { // new-interp-note {{declared here}}
+void test_ice(int i) {
   int array0[__builtin_offsetof(HasArray, array[5])];
-  int array1[__builtin_offsetof(HasArray, array[i])]; // expected-warning 
{{variable length arrays in C++ are a Clang extension}} \
- new-interp-note 
{{function parameter 'i' with unknown value cannot be used in a constant 
expression}}
+  int array1[__builtin_offsetof(HasArray, array[i])]; // expected-warning 
{{variable length arrays in C++ are a Clang extension}}
 }
 
 // Bitfields

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits


@@ -663,10 +663,15 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.

ilya-biryukov wrote:

Another caveat: `Info.getSpellingLoc` can sometimes return one of the expansion 
locations and this causes the diagnostic printing to run indefinitely too!

So I had to report an error with invalid `SourceLocation()`. The crash stack 
trace helpfully points at tokens that were being processed, so it does give 
some context.

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


[clang] [clang-format] unexpected break after binOp '<<' (PR #69859)

2023-10-23 Thread Tsarkov Maksim via cfe-commits

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


[clang] [clang-format] unexpected break after binOp '<<' (PR #69859)

2023-10-23 Thread Tsarkov Maksim via cfe-commits

https://github.com/s1Sharp updated 
https://github.com/llvm/llvm-project/pull/69859

>From a5c62614113b4c42e9051905bb6165331192ded0 Mon Sep 17 00:00:00 2001
From: Tsarkov Maksim 
Date: Sun, 22 Oct 2023 02:09:21 +0300
Subject: [PATCH] [clang-format] unexpected break after binOp '<<'

the problem occurred while checking for the correctness of the break after 
binary operators.
The output statement 'tok::lessless' is then break line every possible time,
which is not expected with the BreakBeforeBinaryOperators: None

Fixes https://github.com/llvm/llvm-project/issues/59797
Fixes https://github.com/llvm/llvm-project/issues/44363
---
 clang/lib/Format/TokenAnnotator.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index a457ced9f886846..fea5b809824d3e3 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5118,7 +5118,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine 
&Line,
   if (Left.IsUnterminatedLiteral)
 return true;
   if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
-  Right.Next->is(tok::string_literal)) {
+  Right.Next->is(tok::string_literal) &&
+  (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
+   Style.BreakBeforeBinaryOperators == FormatStyle::BOS_NonAssignment)) {
 return true;
   }
   if (Right.is(TT_RequiresClause)) {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/68922

>From 8aa439a97a56ef80bfc9ccc90a9f093680e455f5 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Sun, 22 Oct 2023 11:11:53 +0200
Subject: [PATCH 1/3] rebase...

---
 clang/docs/ReleaseNotes.rst   |  4 +
 clang/lib/Sema/SemaOverload.cpp   | 19 ++---
 .../over.match.oper/p3-2a.cpp | 78 +++
 3 files changed, 89 insertions(+), 12 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3a9a67f7451c092..cef857244387e8b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -85,6 +85,10 @@ C/C++ Language Potentially Breaking Changes
 ``__has_c_attribute(warn_unused_result)``,  202003, 0
 ``__has_c_attribute(gnu::warn_unused_result)``, 202003, 1
 
+- Fixed a bug in finding matching `operator!=` while adding reversed 
`operator==` as
+  outlined in "The Equality Operator You Are Looking For" (`P2468 
`_).
+  Fixes (`#68901: `_).
+
 C++ Specific Potentially Breaking Changes
 -
 - The name mangling rules for function templates has been changed to take into
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d57a7ad8f46859a..75e4184c8aa6cb8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -960,18 +960,13 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
 return true;
   }
   // Otherwise the search scope is the namespace scope of which F is a member.
-  LookupResult NonMembers(S, NotEqOp, OpLoc,
-  Sema::LookupNameKind::LookupOperatorName);
-  S.LookupName(NonMembers,
-   S.getScopeForContext(EqFD->getEnclosingNamespaceContext()));
-  NonMembers.suppressAccessDiagnostics();
-  for (NamedDecl *Op : NonMembers) {
-auto *FD = Op->getAsFunction();
-if(auto* UD = dyn_cast(Op))
-  FD = UD->getUnderlyingDecl()->getAsFunction();
-if (FunctionsCorrespond(S.Context, EqFD, FD) &&
-declaresSameEntity(cast(EqFD->getDeclContext()),
-   cast(Op->getDeclContext(
+  for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+auto *NotEqFD = Op->getAsFunction();
+if (auto *UD = dyn_cast(Op))
+  NotEqFD = UD->getUnderlyingDecl()->getAsFunction();
+if (FunctionsCorrespond(S.Context, EqFD, NotEqFD) &&
+declaresSameEntity(cast(EqFD->getEnclosingNamespaceContext()),
+   cast(Op->getLexicalDeclContext(
   return false;
   }
   return true;
diff --git 
a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index 5727d506fe5e61d..9dc5ee8db565341 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -374,6 +374,84 @@ bool fine(A a, B b) { return a == b; } // Ok. Found a 
matching operator!=.
 }
 }
 
+
+namespace ADL_GH68901{
+namespace A {
+struct S {};
+bool operator==(S, int); // expected-note {{no known conversion from 'int' to 
'S' for 1st argument}}
+bool operator!=(S, int);
+} // namespace A
+bool a = 0 == A::S(); // expected-error {{invalid operands to binary 
expression ('int' and 'A::S')}}
+
+namespace B {
+struct Derived {};
+struct Base : Derived {};
+
+bool operator==(Derived& a, Base& b);
+bool operator!=(Derived& a, Base& b);
+}  // namespace B
+
+void foo() {
+  // B::Base{} == B::Base{};
+  B::Base a,b;
+  bool v = a == b;
+}
+
+namespace ns {
+template 
+struct A {
+};
+
+template 
+struct B : A {
+};
+
+template  bool operator == (B, A); // expected-note {{candidate 
template ignored: could not match 'B' against 'A'}}
+template  bool operator != (B, A);
+}
+
+void test() {
+ns::A a;
+ns::B b;
+a == b; // expected-error {{invalid operands to binary expression}}
+}
+
+
+} //namespace ADL_GH68901
+
+namespace function_scope_operator_eqeq {
+// For non-members, we always lookup for matching operator!= in the namespace 
scope of
+// operator== (and not in the scope of operator==).
+struct X { operator int(); };
+namespace test1{
+bool h(X x) {
+  bool operator==(X, int); // expected-note {{reversed}}
+  return x == x; // expected-warning {{ambiguous}}
+}
+
+bool g(X x) {
+  bool operator==(X, int); // expected-note {{reversed}}
+  bool operator!=(X, int);
+  return x == x;  // expected-warning {{ambiguous}}
+}
+} // namespace test1
+
+namespace test2 {
+bool operator!=(X, int);
+
+bool h(X x) {
+  bool operator==(X, int);
+  return x == x;
+}
+
+bool i(X x) {
+  bool operator==(X, int);
+  bool operator!=(X, int);
+  return x == x;
+}
+} // namespace test2
+} // namespace function_scope_operator_eqeq
+
 namespace non_member_

[clang] f8d448d - Correct behavior of VLA extension diagnostic in C89 mode

2023-10-23 Thread Aaron Ballman via cfe-commits

Author: Aaron Ballman
Date: 2023-10-23T08:07:59-04:00
New Revision: f8d448d5e587a23886c3226957f880146a4d8c69

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

LOG: Correct behavior of VLA extension diagnostic in C89 mode

Post-commit feedback (https://reviews.llvm.org/D156565#4654773) found
that the changes in 84a3aadf0f2483dde0acfc4e79f2a075a5f35bd1 caused us
to diagnose use of VLAs in C89 mode by default which was an unintended
change.

This adds -Wvla-cxx-extension as a warning group and adds the C++-
specific warnings to it while leaving the C warnings under
-Wvla-extension. -Wvla-cxx-extension is then added to -Wall.

Added: 
clang/test/Sema/vla-ext.c

Modified: 
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/test/Misc/warning-wall.c

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index dcdae38013d2aaa..4cb792132d6e09d 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -849,7 +849,8 @@ def VariadicMacros : DiagGroup<"variadic-macros">;
 def VectorConversion : DiagGroup<"vector-conversion">;  // clang specific
 def VexingParse : DiagGroup<"vexing-parse">;
 def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">;
-def VLAExtension : DiagGroup<"vla-extension", [VLAUseStaticAssert]>;
+def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>;
+def VLAExtension : DiagGroup<"vla-extension", [VLACxxExtension]>;
 def VLA : DiagGroup<"vla", [VLAExtension]>;
 def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def Visibility : DiagGroup<"visibility">;
@@ -1086,7 +1087,8 @@ def Consumed   : DiagGroup<"consumed">;
 // warning should be active _only_ when -Wall is passed in, mark it as
 // DefaultIgnore in addition to putting it here.
 def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool,
-MisleadingIndentation, PackedNonPod, 
VLAExtension]>;
+MisleadingIndentation, PackedNonPod,
+VLACxxExtension]>;
 
 // Warnings that should be in clang-cl /w4.
 def : DiagGroup<"CL4", [All, Extra]>;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a4c1cb08de9401a..3bcbb003d6dee19 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -141,9 +141,9 @@ def ext_vla : Extension<"variable length arrays are a C99 
feature">,
 // language modes, we warn as an extension but add the warning group to -Wall.
 def ext_vla_cxx : ExtWarn<
   "variable length arrays in C++ are a Clang extension">,
-  InGroup;
+  InGroup;
 def ext_vla_cxx_in_gnu_mode : Extension,
-  InGroup;
+  InGroup;
 def ext_vla_cxx_static_assert : ExtWarn<
   "variable length arrays in C++ are a Clang extension; did you mean to use "
   "'static_assert'?">, InGroup;

diff  --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c
index c0cf8324e6e162e..05a82770e26de69 100644
--- a/clang/test/Misc/warning-wall.c
+++ b/clang/test/Misc/warning-wall.c
@@ -105,7 +105,7 @@ CHECK-NEXT:  -Wswitch
 CHECK-NEXT:  -Wswitch-bool
 CHECK-NEXT:  -Wmisleading-indentation
 CHECK-NEXT:  -Wpacked-non-pod
-CHECK-NEXT:  -Wvla-extension
+CHECK-NEXT:  -Wvla-cxx-extension
 CHECK-NEXT:-Wvla-extension-static-assert
 
 CHECK-NOT:-W

diff  --git a/clang/test/Sema/vla-ext.c b/clang/test/Sema/vla-ext.c
new file mode 100644
index 000..4ad96d97901c9e5
--- /dev/null
+++ b/clang/test/Sema/vla-ext.c
@@ -0,0 +1,24 @@
+/* RUN: %clang_cc1 -verify=off -std=c89 %s
+ * RUN: %clang_cc1 -verify=off -Wall -std=c89 %s
+ * RUN: %clang_cc1 -verify -pedantic -std=c89 %s
+ * RUN: %clang_cc1 -verify -Wvla-extension -std=c89 %s
+ * RUN: %clang_cc1 -verify=off -Wvla-cxx-extension -std=c89 %s
+ * RUN: %clang_cc1 -verify=off -pedantic -std=c99 %s
+ * RUN: %clang_cc1 -verify=off -Wall -std=c99 %s
+ * RUN: %clang_cc1 -verify=off -std=c99 -Wvla-extension %s
+ * The next run line still issues the extension warning because VLAs are an
+ * extension in C89, but the line after it will issue the congratulatory
+ * diagnostic.
+ * RUN: %clang_cc1 -verify -Wvla -std=c89 %s
+ * RUN: %clang_cc1 -verify=wvla -Wvla -std=c99 %s
+ */
+
+/* off-no-diagnostics */
+
+void func(int n) {
+  int array[n]; /* expected-warning {{variable length arrays are a C99 
feature}}
+   wvla-warning {{variable length array used}}
+ */
+  (void)array;
+}
+



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailm

[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits


@@ -663,10 +663,15 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.

sam-mccall wrote:

This really sounds like the SourceManager is corrupt at this point, would be 
good to find out why but this is already an improvement

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall approved this pull request.


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


[clang] 596b598 - Fix Clang sphinx build

2023-10-23 Thread Aaron Ballman via cfe-commits

Author: Aaron Ballman
Date: 2023-10-23T08:08:50-04:00
New Revision: 596b59883d49efc7f41f05ebcae8b4f77e6792ef

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

LOG: Fix Clang sphinx build

Added: 


Modified: 
clang/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3c013835d0b35e9..39e9b9998aa662c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -364,6 +364,7 @@ Improvements to Clang's diagnostics
   following code
 
   .. code-block:: cpp
+
   struct Foo {
 operator int();
 operator const char*();



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156565: Diagnose use of VLAs in C++ by default

2023-10-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D156565#4654820 , @cor3ntin wrote:

>> Any concerns with this approach?
>
> Sounds reasonable to me

Thanks for the double-check! This should now be fixed in 
https://github.com/llvm/llvm-project/commit/f8d448d5e587a23886c3226957f880146a4d8c69,
 sorry for the hassle!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156565/new/

https://reviews.llvm.org/D156565

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 9330261 - Use the correct namespace for looking up matching operator!= (#68922)

2023-10-23 Thread via cfe-commits

Author: Utkarsh Saxena
Date: 2023-10-23T14:10:06+02:00
New Revision: 9330261143ccbe947ef0687fd20747ba47f26879

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

LOG: Use the correct namespace for looking up matching operator!= (#68922)

`S.getScopeForContext` determins the **active** scope associated with
the given `declContext`.
This fails to find the matching `operator!=` if candidate `operator==`
was found via ADL since that scope is not active.

Instead, just directly lookup using the namespace decl of `operator==`

Fixes #68901

Added: 
clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p2468R2.cppm

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaOverload.cpp
clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 39e9b9998aa662c..1315eaffcd4850e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -85,6 +85,10 @@ C/C++ Language Potentially Breaking Changes
 ``__has_c_attribute(warn_unused_result)``,  202003, 0
 ``__has_c_attribute(gnu::warn_unused_result)``, 202003, 1
 
+- Fixed a bug in finding matching `operator!=` while adding reversed 
`operator==` as
+  outlined in "The Equality Operator You Are Looking For" (`P2468 
`_).
+  Fixes (`#68901: `_).
+
 C++ Specific Potentially Breaking Changes
 -
 - The name mangling rules for function templates has been changed to take into

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d9d7ce59b5fcb35..d2475459fa4f4f7 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -962,18 +962,13 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
 return true;
   }
   // Otherwise the search scope is the namespace scope of which F is a member.
-  LookupResult NonMembers(S, NotEqOp, OpLoc,
-  Sema::LookupNameKind::LookupOperatorName);
-  S.LookupName(NonMembers,
-   S.getScopeForContext(EqFD->getEnclosingNamespaceContext()));
-  NonMembers.suppressAccessDiagnostics();
-  for (NamedDecl *Op : NonMembers) {
-auto *FD = Op->getAsFunction();
-if(auto* UD = dyn_cast(Op))
-  FD = UD->getUnderlyingDecl()->getAsFunction();
-if (FunctionsCorrespond(S.Context, EqFD, FD) &&
-declaresSameEntity(cast(EqFD->getDeclContext()),
-   cast(Op->getDeclContext(
+  for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+auto *NotEqFD = Op->getAsFunction();
+if (auto *UD = dyn_cast(Op))
+  NotEqFD = UD->getUnderlyingDecl()->getAsFunction();
+if (FunctionsCorrespond(S.Context, EqFD, NotEqFD) && S.isVisible(NotEqFD) 
&&
+declaresSameEntity(cast(EqFD->getEnclosingNamespaceContext()),
+   cast(Op->getLexicalDeclContext(
   return false;
   }
   return true;

diff  --git 
a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p2468R2.cppm 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p2468R2.cppm
new file mode 100644
index 000..05891618991da07
--- /dev/null
+++ 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p2468R2.cppm
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/p2468r2.cpp 
-verify
+
+//--- A.cppm
+module;
+export module A;
+export {
+namespace NS {
+struct S {};
+bool operator==(S, int);
+} // namespace NS
+}
+
+namespace NS { bool operator!=(S, int); } // Not visible.
+
+
+//--- p2468r2.cpp
+// expected-no-diagnostics
+import A;
+bool x = 0 == NS::S(); // Ok. operator!= from module A is not visible.

diff  --git 
a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index 5727d506fe5e61d..016eaf7f52876d5 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -374,6 +374,109 @@ bool fine(A a, B b) { return a == b; } // Ok. Found a 
matching operator!=.
 }
 }
 
+
+namespace ADL_GH68901{
+namespace test1 {
+namespace A {
+struct S {};
+bool operator==(S, int); // expected-note {{no known conversion from 'int' to 
'S' for 1st argument}}
+bool a = 0 == A::S(); // Ok. Operator!= not visible.
+bool operator!=(S, int);
+} // namespace A
+bool a = 0 == A::S(); // expected-er

[clang] Use the correct namespace for looking up matching operator!= (PR #68922)

2023-10-23 Thread Utkarsh Saxena via cfe-commits

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


[clang] [clang][Sema] Avoid non-empty unexpanded pack assertion for FunctionParmPackExpr (PR #69224)

2023-10-23 Thread Timm Baeder via cfe-commits


@@ -402,6 +402,20 @@ bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
   if (!E->containsUnexpandedParameterPack())
 return false;
 
+  // Exception: The `CollectUnexpandedParameterPacksVisitor` collects nothing
+  // from a FunctionParmPackExpr. In the context where the collector is being
+  // used such as `collectUnexpandedParameterPacks`, this type of expression
+  // is not expected to be collected.
+  //
+  // Nonetheless, this function for diagnosis is still called anyway during
+  // template instantiation, with an expression of such a type if we're inside 
a
+  // lambda with unexpanded parameters.
+  //
+  // Rule out this case to prevent the assertion failure.
+  if (auto *Expr = dyn_cast(E);
+  Expr && getEnclosingLambda())

tbaederr wrote:

```suggestion
  if (isa(E) && getEnclosingLambda())
```

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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov updated 
https://github.com/llvm/llvm-project/pull/69908

>From 6b73e1fbbad1a485ce6266dbd8d3c499956b859a Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Thu, 19 Oct 2023 17:50:38 +0200
Subject: [PATCH 1/5] [SourceManager] Report an error and crash on source
 location exhaustion in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
---
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Basic/SourceManager.cpp  | 11 +++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

>From 2180aa94253647f6541c6311224c253be0c0de25 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 12:12:50 +0200
Subject: [PATCH 2/5] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

---
 clang/lib/Basic/SourceManager.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index dcf18c47cbaf9ae..415f0a33358703a 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -665,10 +665,12 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
   if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
   NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
-Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
-Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
-noteSLocAddressSpaceUsage(Diag);
-return SourceLocation();
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.
+// Currently, the call runs indefinitely, so we would first need to fix it.
+// FIXME: return an error instead of crashing. Returning invalid source
+// locations causes compiler to run indefinitely.
+llvm::report_fatal_error("ran out of source locations");
   }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;

>From 1344a7a687b1a3147820c1b4406f9e974924c676 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 13:52:15 +0200
Subject: [PATCH 3/5] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

- Unify the error when running out of slocs in includes and macro
- Use `SourceLocation()` instead of `

[clang] [clang][Interp] Fix `ArrayInitLoopExpr` handling (PR #67886)

2023-10-23 Thread Timm Baeder via cfe-commits

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


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


[clang] [clang][Interp] Only evaluate the source array initialization of an `ArrayInitLoopExpr` once (PR #68039)

2023-10-23 Thread Timm Baeder via cfe-commits

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


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


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

https://github.com/ilya-biryukov updated 
https://github.com/llvm/llvm-project/pull/69908

>From 8767d9b2cbe699d8b160140bf168eca0f82f1c64 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Thu, 19 Oct 2023 17:50:38 +0200
Subject: [PATCH 1/5] [SourceManager] Report an error and crash on source
 location exhaustion in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
---
 clang/include/clang/Basic/DiagnosticCommonKinds.td |  2 ++
 clang/lib/Basic/SourceManager.cpp  | 11 +++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while 
processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+noteSLocAddressSpaceUsage(Diag);
+return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

>From 776c5300cb2aadaf92c39001e5686f088757c485 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 12:12:50 +0200
Subject: [PATCH 2/5] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

---
 clang/lib/Basic/SourceManager.cpp | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index dcf18c47cbaf9ae..415f0a33358703a 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -665,10 +665,12 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
   if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
   NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
-Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
-Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
-noteSLocAddressSpaceUsage(Diag);
-return SourceLocation();
+Diag.Report(Info.getSpellingLoc(), diag::err_expansions_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users.
+// Currently, the call runs indefinitely, so we would first need to fix it.
+// FIXME: return an error instead of crashing. Returning invalid source
+// locations causes compiler to run indefinitely.
+llvm::report_fatal_error("ran out of source locations");
   }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;

>From 1ae846e7550c89f7f5a023d0981bc0e2c7c58831 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 23 Oct 2023 13:52:15 +0200
Subject: [PATCH 3/5] fixup! [SourceManager] Report an error and crash on
 source location exhaustion in macros

- Unify the error when running out of slocs in includes and macro
- Use `SourceLocation()` instead of `

[clang] [Clang] Handle real and imaginary parts of complex lvalue in `APValue::printPretty` (PR #69252)

2023-10-23 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw updated 
https://github.com/llvm/llvm-project/pull/69252

>From 8f0ebe5b5cfed069c8274c0761559d6595d4dea8 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:17:17 +0800
Subject: [PATCH 1/3] [Clang] Add pre-commit tests for PR69218. NFC.

---
 clang/test/CodeGen/complex.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index 6233529a18f8b8d..b50d607d00c0167 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -113,3 +113,8 @@ void t92(void) {
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
 
+// PR69218
+int t10(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

>From c76a511cf1ad72eff3725bf24700f00a2f6fc014 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:19:11 +0800
Subject: [PATCH 2/3] [Clang] Handle real and imaginary part of complex lvalue
 in `APValue::printPretty`

---
 clang/lib/AST/APValue.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index ef424215182280b..d08c2936b56dd45 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -841,6 +841,10 @@ void APValue::printPretty(raw_ostream &Out, const 
PrintingPolicy &Policy,
   Out << *VD;
   ElemTy = VD->getType();
 }
+  } else if (ElemTy->isAnyComplexType()) {
+// The lvalue refers to a complex type
+Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");
+ElemTy = ElemTy->castAs()->getElementType();
   } else {
 // The lvalue must refer to an array.
 Out << '[' << Path[I].getAsArrayIndex() << ']';

>From f4a026599226b1742f9bab4c6899bffc6cae92de Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Mon, 23 Oct 2023 20:20:40 +0800
Subject: [PATCH 3/3] fixup! [Clang] Handle real and imaginary part of complex
 lvalue in `APValue::printPretty`

Add release notes.
Move the test from CodeGen to Sema.
---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/test/CodeGen/complex.c   | 6 --
 clang/test/Sema/complex-imag.c | 6 ++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9782c123f4c9372..a49162f2845e802 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -397,6 +397,8 @@ Bug Fixes in This Version
   operator in C. No longer issuing a confusing diagnostic along the lines of
   "incompatible operand types ('foo' and 'foo')" with extensions such as matrix
   types. Fixes (`#69008 `_)
+- Fix crash in formatting the real/imaginary part of a complex lvalue.
+  Fixes (`#69218 `_)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index b50d607d00c0167..455c81abb86fd2a 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -112,9 +112,3 @@ void t92(void) {
   // Check for proper codegen
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
-
-// PR69218
-int t10(void) {
-  float _Complex a;
-  return (0 < &__real__ a) && (0 < &__imag__ a);
-}
diff --git a/clang/test/Sema/complex-imag.c b/clang/test/Sema/complex-imag.c
index 69121271f4b7876..8014addf4d3a40c 100644
--- a/clang/test/Sema/complex-imag.c
+++ b/clang/test/Sema/complex-imag.c
@@ -27,3 +27,9 @@ void f4(void) {
   double *c = &__real a;
   double *d = &__imag a;
 }
+
+// PR69218
+int f5(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

I will land this, but happy to follow up if Aaron or anyone else will have 
comments.

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


[clang] [Clang] Handle real and imaginary parts of complex lvalue in `APValue::printPretty` (PR #69252)

2023-10-23 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw updated 
https://github.com/llvm/llvm-project/pull/69252

>From 8f0ebe5b5cfed069c8274c0761559d6595d4dea8 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:17:17 +0800
Subject: [PATCH 1/3] [Clang] Add pre-commit tests for PR69218. NFC.

---
 clang/test/CodeGen/complex.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index 6233529a18f8b8d..b50d607d00c0167 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -113,3 +113,8 @@ void t92(void) {
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
 
+// PR69218
+int t10(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

>From c76a511cf1ad72eff3725bf24700f00a2f6fc014 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:19:11 +0800
Subject: [PATCH 2/3] [Clang] Handle real and imaginary part of complex lvalue
 in `APValue::printPretty`

---
 clang/lib/AST/APValue.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index ef424215182280b..d08c2936b56dd45 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -841,6 +841,10 @@ void APValue::printPretty(raw_ostream &Out, const 
PrintingPolicy &Policy,
   Out << *VD;
   ElemTy = VD->getType();
 }
+  } else if (ElemTy->isAnyComplexType()) {
+// The lvalue refers to a complex type
+Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");
+ElemTy = ElemTy->castAs()->getElementType();
   } else {
 // The lvalue must refer to an array.
 Out << '[' << Path[I].getAsArrayIndex() << ']';

>From 5020b3ffbaedc0b9bb6e820259b69ccbb6f95436 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Mon, 23 Oct 2023 20:20:40 +0800
Subject: [PATCH 3/3] fixup! [Clang] Handle real and imaginary part of complex
 lvalue in `APValue::printPretty`

Add release notes.
Move the test from CodeGen to Sema.
---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/test/CodeGen/complex.c   | 5 -
 clang/test/Sema/complex-imag.c | 6 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9782c123f4c9372..a49162f2845e802 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -397,6 +397,8 @@ Bug Fixes in This Version
   operator in C. No longer issuing a confusing diagnostic along the lines of
   "incompatible operand types ('foo' and 'foo')" with extensions such as matrix
   types. Fixes (`#69008 `_)
+- Fix crash in formatting the real/imaginary part of a complex lvalue.
+  Fixes (`#69218 `_)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index b50d607d00c0167..6233529a18f8b8d 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -113,8 +113,3 @@ void t92(void) {
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
 
-// PR69218
-int t10(void) {
-  float _Complex a;
-  return (0 < &__real__ a) && (0 < &__imag__ a);
-}
diff --git a/clang/test/Sema/complex-imag.c b/clang/test/Sema/complex-imag.c
index 69121271f4b7876..8014addf4d3a40c 100644
--- a/clang/test/Sema/complex-imag.c
+++ b/clang/test/Sema/complex-imag.c
@@ -27,3 +27,9 @@ void f4(void) {
   double *c = &__real a;
   double *d = &__imag a;
 }
+
+// PR69218
+int f5(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 324d1bb - [Clang] Report an error and crash on source location exhaustion in macros (#69908)

2023-10-23 Thread via cfe-commits

Author: Ilya Biryukov
Date: 2023-10-23T14:29:00+02:00
New Revision: 324d1bb35aefec737ef381d98211f7771c4b0ab5

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

LOG: [Clang] Report an error and crash on source location exhaustion in macros 
(#69908)

`createExpansionLocImpl` has an assert that checks if we ran out of
source locations. We have observed this happening on real code and in
release builds the assertion does not fire and the compiler just keeps
running indefinitely without giving any indication that something went
wrong.

Diagnose this problem and reliably crash to make sure the problem is
easy to detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/lib/Basic/SourceManager.cpp
clang/test/Lexer/SourceLocationsOverflow.c

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..9f0ccd255a32148 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,9 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
-def err_include_too_large : Error<
-  "sorry, this include generates a translation unit too large for"
-  " Clang to process.">, DefaultFatal;
+def err_sloc_space_too_large : Error<
+  "sorry, the translation unit is too large for Clang to process: ran out of 
source locations">, DefaultFatal;
 def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
   "encoding is not supported">, DefaultFatal;
 def err_unable_to_rename_temp : Error<

diff  --git a/clang/lib/Basic/SourceManager.cpp 
b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..d627c233a3aa094 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -605,7 +605,7 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, 
StringRef Filename,
   unsigned FileSize = File.getSize();
   if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
-Diag.Report(IncludePos, diag::err_include_too_large);
+Diag.Report(IncludePos, diag::err_sloc_space_too_large);
 noteSLocAddressSpaceUsage(Diag);
 return FileID();
   }
@@ -663,10 +663,16 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo 
&Info,
 return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
- NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+  NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+Diag.Report(SourceLocation(), diag::err_sloc_space_too_large);
+// FIXME: call `noteSLocAddressSpaceUsage` to report details to users and
+// use a source location from `Info` to point at an error.
+// Currently, both cause Clang to run indefinitely, this needs to be fixed.
+// FIXME: return an error instead of crashing. Returning invalid source
+// locations causes compiler to run indefinitely.
+llvm::report_fatal_error("ran out of source locations");
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

diff  --git a/clang/test/Lexer/SourceLocationsOverflow.c 
b/clang/test/Lexer/SourceLocationsOverflow.c
index 2b838ca4e861d08..c42f648fedf5018 100644
--- a/clang/test/Lexer/SourceLocationsOverflow.c
+++ b/clang/test/Lexer/SourceLocationsOverflow.c
@@ -1,6 +1,6 @@
 // RUN: not %clang %s -S -o - 2>&1 | FileCheck %s
 // CHECK: In file included from {{.*}}SourceLocationsOverflow.c
-// CHECK-NEXT: inc1.h{{.*}}: fatal error: sorry, this include generates a 
translation unit too large for Clang to process.
+// CHECK-NEXT: inc1.h{{.*}}: fatal error: sorry, the translation unit is too 
large for Clang to process: ran out of source locations
 // CHECK-NEXT: #include "inc2.h"
 // CHECK-NEXT:  ^
 // CHECK-NEXT: note: 214{{...}}B in local locations, 0B in locations 
loaded from AST files, for a total of 214{{...}}B (99% of available space)



__

[clang] [Clang] Report an error and crash on source location exhaustion in macros (PR #69908)

2023-10-23 Thread Ilya Biryukov via cfe-commits

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


[clang] [Clang] Handle real and imaginary parts of complex lvalue in `APValue::printPretty` (PR #69252)

2023-10-23 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw updated 
https://github.com/llvm/llvm-project/pull/69252

>From 6e34e74e8e8046aaa086869e8a8aecb781dd3b3b Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:17:17 +0800
Subject: [PATCH 1/3] [Clang] Add pre-commit tests for PR69218. NFC.

---
 clang/test/CodeGen/complex.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index 6233529a18f8b8d..b50d607d00c0167 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -113,3 +113,8 @@ void t92(void) {
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
 
+// PR69218
+int t10(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

>From 07a9bd8da0602bedc7603752a3af26f89d3e9a2b Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Tue, 17 Oct 2023 05:19:11 +0800
Subject: [PATCH 2/3] [Clang] Handle real and imaginary part of complex lvalue
 in `APValue::printPretty`

---
 clang/lib/AST/APValue.cpp | 4 
 1 file changed, 4 insertions(+)

diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index ef424215182280b..d08c2936b56dd45 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -841,6 +841,10 @@ void APValue::printPretty(raw_ostream &Out, const 
PrintingPolicy &Policy,
   Out << *VD;
   ElemTy = VD->getType();
 }
+  } else if (ElemTy->isAnyComplexType()) {
+// The lvalue refers to a complex type
+Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");
+ElemTy = ElemTy->castAs()->getElementType();
   } else {
 // The lvalue must refer to an array.
 Out << '[' << Path[I].getAsArrayIndex() << ']';

>From b6ad30530cba4aaa94002691b97208abdb24533e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Mon, 23 Oct 2023 20:20:40 +0800
Subject: [PATCH 3/3] fixup! [Clang] Handle real and imaginary part of complex
 lvalue in `APValue::printPretty`

Add release notes.
Move the test from CodeGen to Sema.
---
 clang/docs/ReleaseNotes.rst| 2 ++
 clang/test/CodeGen/complex.c   | 5 -
 clang/test/Sema/complex-imag.c | 6 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1315eaffcd4850e..c292e012c4548d9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -474,6 +474,8 @@ Bug Fixes in This Version
 - Clang now accepts anonymous members initialized with designated initializers
   inside templates.
   Fixes (`#65143 `_)
+- Fix crash in formatting the real/imaginary part of a complex lvalue.
+  Fixes (`#69218 `_)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index b50d607d00c0167..6233529a18f8b8d 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -113,8 +113,3 @@ void t92(void) {
   (0 ? (_Complex double) 2.0f : 2.0f);
 }
 
-// PR69218
-int t10(void) {
-  float _Complex a;
-  return (0 < &__real__ a) && (0 < &__imag__ a);
-}
diff --git a/clang/test/Sema/complex-imag.c b/clang/test/Sema/complex-imag.c
index 69121271f4b7876..8014addf4d3a40c 100644
--- a/clang/test/Sema/complex-imag.c
+++ b/clang/test/Sema/complex-imag.c
@@ -27,3 +27,9 @@ void f4(void) {
   double *c = &__real a;
   double *d = &__imag a;
 }
+
+// PR69218
+int f5(void) {
+  float _Complex a;
+  return (0 < &__real__ a) && (0 < &__imag__ a);
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][dataflow] Remove `declToLocConsistent()` assertion. (PR #69819)

2023-10-23 Thread via cfe-commits

https://github.com/martinboehme updated 
https://github.com/llvm/llvm-project/pull/69819

>From ad60ea756566853a16b5d4e5ae9ebe61bc7fefbf Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Sat, 21 Oct 2023 08:38:35 +
Subject: [PATCH] [clang][dataflow] Remove `declToLocConsistent()` assertion.

As described [here](https://discourse.llvm.org/t/70086/6), there are legitimate
non-bug scenarios where two `DeclToLoc` maps to be joined contain different
storage locations for the same declaration. This patch also adds a test
containing an example of such a situation. (The test fails without the other
changes in this patch.)

With the assertion removed, the existing logic in `intersectDenseMaps()` will
remove the corresponding declaration from the joined DeclToLoc map.

We also remove `removeDecl()`'s precondition (that the declaration must be
associated with a storage location) because this may no longer hold if the
declaration was previously removed during a join, as described above.
---
 .../FlowSensitive/DataflowEnvironment.h   |  6 +--
 .../FlowSensitive/DataflowEnvironment.cpp | 16 ---
 .../Analysis/FlowSensitive/TransferTest.cpp   | 44 +++
 3 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 9ac2cb90ccc4d4a..33e9f0fba02bc77 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -260,11 +260,7 @@ class Environment {
   /// if `D` isn't assigned a storage location in the environment.
   StorageLocation *getStorageLocation(const ValueDecl &D) const;
 
-  /// Removes the location assigned to `D` in the environment.
-  ///
-  /// Requirements:
-  ///
-  ///  `D` must have a storage location assigned in the environment.
+  /// Removes the location assigned to `D` in the environment (if any).
   void removeDecl(const ValueDecl &D);
 
   /// Assigns `Loc` as the storage location of the glvalue `E` in the
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 01c6cc69e2b9fac..c08cb2d7deb2d81 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -35,20 +35,6 @@ namespace dataflow {
 static constexpr int MaxCompositeValueDepth = 3;
 static constexpr int MaxCompositeValueSize = 1000;
 
-/// Returns whether all declarations that `DeclToLoc1` and `DeclToLoc2` have in
-/// common map to the same storage location in both maps.
-bool declToLocConsistent(
-const llvm::DenseMap &DeclToLoc1,
-const llvm::DenseMap &DeclToLoc2) {
-  for (auto &Entry : DeclToLoc1) {
-auto It = DeclToLoc2.find(Entry.first);
-if (It != DeclToLoc2.end() && Entry.second != It->second)
-  return false;
-  }
-
-  return true;
-}
-
 /// Returns a map consisting of key-value entries that are present in both 
maps.
 template 
 llvm::DenseMap intersectDenseMaps(const llvm::DenseMap &Map1,
@@ -662,7 +648,6 @@ Environment Environment::join(const Environment &EnvA, 
const Environment &EnvB,
   else
 JoinedEnv.ReturnLoc = nullptr;
 
-  assert(declToLocConsistent(EnvA.DeclToLoc, EnvB.DeclToLoc));
   JoinedEnv.DeclToLoc = intersectDenseMaps(EnvA.DeclToLoc, EnvB.DeclToLoc);
 
   JoinedEnv.ExprToLoc = intersectDenseMaps(EnvA.ExprToLoc, EnvB.ExprToLoc);
@@ -715,7 +700,6 @@ StorageLocation *Environment::getStorageLocation(const 
ValueDecl &D) const {
 }
 
 void Environment::removeDecl(const ValueDecl &D) {
-  assert(DeclToLoc.contains(&D));
   DeclToLoc.erase(&D);
 }
 
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index f5d9c785b63976f..0c2106777560ee6 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -6236,4 +6236,48 @@ TEST(TransferTest, LambdaCaptureThis) {
   });
 }
 
+TEST(TransferTest, DifferentReferenceLocInJoin) {
+  // This test triggers a case where the storage location for a reference-type
+  // variable is different for two states being joined. We used to believe this
+  // could not happen and therefore had an assertion disallowing this; this 
test
+  // exists to demonstrate that we can handle this condition without a failing
+  // assertion. See also the discussion here:
+  // https://discourse.llvm.org/t/70086/6
+  std::string Code = R"(
+namespace std {
+  template  struct initializer_list {
+const T* begin();
+const T* end();
+  };
+}
+
+void target(char* p, char* end) {
+  while (p != end) {
+if (*p == ' ') {
+  p++;
+  continue;
+}
+
+auto && range = {1, 2};
+for (auto b = range.begin(), e = range.end(); b != e; ++b) {
+}
+  

[clang] [clang][dataflow] Remove `declToLocConsistent()` assertion. (PR #69819)

2023-10-23 Thread via cfe-commits

https://github.com/martinboehme updated 
https://github.com/llvm/llvm-project/pull/69819

>From 4d25701821240818f2459a036703b4be3ec93435 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Sat, 21 Oct 2023 08:38:35 +
Subject: [PATCH] [clang][dataflow] Remove `declToLocConsistent()` assertion.

As described [here](https://discourse.llvm.org/t/70086/6), there are legitimate
non-bug scenarios where two `DeclToLoc` maps to be joined contain different
storage locations for the same declaration. This patch also adds a test
containing an example of such a situation. (The test fails without the other
changes in this patch.)

With the assertion removed, the existing logic in `intersectDenseMaps()` will
remove the corresponding declaration from the joined DeclToLoc map.

We also remove `removeDecl()`'s precondition (that the declaration must be
associated with a storage location) because this may no longer hold if the
declaration was previously removed during a join, as described above.
---
 .../FlowSensitive/DataflowEnvironment.h   |  6 +--
 .../FlowSensitive/DataflowEnvironment.cpp | 20 +
 .../Analysis/FlowSensitive/TransferTest.cpp   | 44 +++
 3 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 9ac2cb90ccc4d4a..33e9f0fba02bc77 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -260,11 +260,7 @@ class Environment {
   /// if `D` isn't assigned a storage location in the environment.
   StorageLocation *getStorageLocation(const ValueDecl &D) const;
 
-  /// Removes the location assigned to `D` in the environment.
-  ///
-  /// Requirements:
-  ///
-  ///  `D` must have a storage location assigned in the environment.
+  /// Removes the location assigned to `D` in the environment (if any).
   void removeDecl(const ValueDecl &D);
 
   /// Assigns `Loc` as the storage location of the glvalue `E` in the
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 01c6cc69e2b9fac..00e56ce51c530b3 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -35,20 +35,6 @@ namespace dataflow {
 static constexpr int MaxCompositeValueDepth = 3;
 static constexpr int MaxCompositeValueSize = 1000;
 
-/// Returns whether all declarations that `DeclToLoc1` and `DeclToLoc2` have in
-/// common map to the same storage location in both maps.
-bool declToLocConsistent(
-const llvm::DenseMap &DeclToLoc1,
-const llvm::DenseMap &DeclToLoc2) {
-  for (auto &Entry : DeclToLoc1) {
-auto It = DeclToLoc2.find(Entry.first);
-if (It != DeclToLoc2.end() && Entry.second != It->second)
-  return false;
-  }
-
-  return true;
-}
-
 /// Returns a map consisting of key-value entries that are present in both 
maps.
 template 
 llvm::DenseMap intersectDenseMaps(const llvm::DenseMap &Map1,
@@ -662,7 +648,6 @@ Environment Environment::join(const Environment &EnvA, 
const Environment &EnvB,
   else
 JoinedEnv.ReturnLoc = nullptr;
 
-  assert(declToLocConsistent(EnvA.DeclToLoc, EnvB.DeclToLoc));
   JoinedEnv.DeclToLoc = intersectDenseMaps(EnvA.DeclToLoc, EnvB.DeclToLoc);
 
   JoinedEnv.ExprToLoc = intersectDenseMaps(EnvA.ExprToLoc, EnvB.ExprToLoc);
@@ -714,10 +699,7 @@ StorageLocation *Environment::getStorageLocation(const 
ValueDecl &D) const {
   return Loc;
 }
 
-void Environment::removeDecl(const ValueDecl &D) {
-  assert(DeclToLoc.contains(&D));
-  DeclToLoc.erase(&D);
-}
+void Environment::removeDecl(const ValueDecl &D) { DeclToLoc.erase(&D); }
 
 void Environment::setStorageLocation(const Expr &E, StorageLocation &Loc) {
   // `DeclRefExpr`s to builtin function types aren't glvalues, for some reason,
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index f5d9c785b63976f..0c2106777560ee6 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -6236,4 +6236,48 @@ TEST(TransferTest, LambdaCaptureThis) {
   });
 }
 
+TEST(TransferTest, DifferentReferenceLocInJoin) {
+  // This test triggers a case where the storage location for a reference-type
+  // variable is different for two states being joined. We used to believe this
+  // could not happen and therefore had an assertion disallowing this; this 
test
+  // exists to demonstrate that we can handle this condition without a failing
+  // assertion. See also the discussion here:
+  // https://discourse.llvm.org/t/70086/6
+  std::string Code = R"(
+namespace std {
+  template  struct initializer_list {
+const T* begin();
+const T* end();
+  };
+}
+
+vo

[clang] [clang] Add clang::preferred_type attribute for bitfields (PR #69104)

2023-10-23 Thread Aaron Ballman via cfe-commits

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


[clang] [clang] Add clang::preferred_type attribute for bitfields (PR #69104)

2023-10-23 Thread Aaron Ballman via cfe-commits


@@ -7219,6 +7219,31 @@ its underlying representation to be a WebAssembly 
``funcref``.
   }];
 }
 
+def PreferredTypeDocumentation : Documentation {
+  let Category = DocCatField;
+  let Content = [{
+This attribute allows adjusting the type of a bit-field in debug information.
+This can be helpful when a bit-field is intended to store an enumeration value,
+but has to be specified as having the enumeration's underlying type in order to
+facilitate compiler optimizations or bit-field packing behavior. Normally, the
+underlying type is what is emitted in debug information, which can make it hard
+for debuggers to know to map a bit-field's value back to a particular 
enumeration.
+
+.. code-block:: c++
+
+enum Colors { Red, Green, Blue };
+
+struct S {
+  [[clang::preferred_type(Colors)]] unsigned ColorVal : 2;
+  [[clang::preferred_type(bool)]] unsigned UseAlternateColorSpace : 1;
+} s = { Green, false };
+
+Without the attribute, a debugger is likely to display the value `1` for 
`ColorVal`
+and `0` for `UseAlternateColorSpace`. With the attribute, the debugger may now
+display `Green` and `false` instead.
+  }];

AaronBallman wrote:

We should add additional documentation now that we've not limited this to just 
enumeration types. Maybe something along the lines of:
```

This can be used to map a bit-field to an arbitrary type that isn't integral or 
an enumeration type. For example:

.. code-block:: c++

struct A {
  short a1;
  short a2;
};

struct B {
  [[clang::preferred_type(A)]] unsigned b1 : 32 = 0x000F'000C;
};

will associate the type ``A`` with the ``b1`` bit-field and is intended to 
display something like this in the debugger:

.. code-block:: text

Process 2755547 stopped
* thread #1, name = 'test-preferred-', stop reason = step in
frame #0: 0x5148 test-preferred-type`main at test.cxx:13:14
   10   int main()
   11   {
   12   B b;
-> 13   return b.b1;
   14   }
(lldb) v -T
(B) b = {
  (A:32) b1 = {
(short) a1 = 12
(short) a2 = 15
  }
}

Note that debuggers may not be able to handle more complex mappings and so this 
usage is debugger-dependent.
```

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


[clang] [clang] Add clang::preferred_type attribute for bitfields (PR #69104)

2023-10-23 Thread Aaron Ballman via cfe-commits


@@ -7219,6 +7219,31 @@ its underlying representation to be a WebAssembly 
``funcref``.
   }];
 }
 
+def PreferredTypeDocumentation : Documentation {
+  let Category = DocCatField;
+  let Content = [{
+This attribute allows adjusting the type of a bit-field in debug information.
+This can be helpful when a bit-field is intended to store an enumeration value,
+but has to be specified as having the enumeration's underlying type in order to
+facilitate compiler optimizations or bit-field packing behavior. Normally, the
+underlying type is what is emitted in debug information, which can make it hard
+for debuggers to know to map a bit-field's value back to a particular 
enumeration.
+
+.. code-block:: c++
+
+enum Colors { Red, Green, Blue };
+
+struct S {
+  [[clang::preferred_type(Colors)]] unsigned ColorVal : 2;
+  [[clang::preferred_type(bool)]] unsigned UseAlternateColorSpace : 1;
+} s = { Green, false };
+
+Without the attribute, a debugger is likely to display the value `1` for 
`ColorVal`
+and `0` for `UseAlternateColorSpace`. With the attribute, the debugger may now
+display `Green` and `false` instead.

AaronBallman wrote:

```suggestion
Without the attribute, a debugger is likely to display the value ``1`` for 
``ColorVal``
and ``0`` for ``UseAlternateColorSpace``. With the attribute, the debugger may 
now
display ``Green`` and ``false`` instead.
```

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


[clang] [clang] Add clang::preferred_type attribute for bitfields (PR #69104)

2023-10-23 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

The changes should also come with a release note, but I'm generally happy with 
the code. I did have some suggestions for changes to documentation though.

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


[clang] [APINotes] Upstream APINotesReader (PR #66769)

2023-10-23 Thread Egor Zhdan via cfe-commits

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


[clang] [APINotes] Upstream APINotesReader (PR #66769)

2023-10-23 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,202 @@
+//===--- APINotesReader.h - API Notes Reader *- C++ 
-*-===//
+//
+// 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
+//
+//===--===//
+//
+// This file defines the \c APINotesReader class that reads source API notes
+// data providing additional information about source code as a separate input,
+// such as the non-nil/nilable annotations for method parameters.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_APINOTES_READER_H
+#define LLVM_CLANG_APINOTES_READER_H
+
+#include "clang/APINotes/Types.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VersionTuple.h"
+#include 
+
+namespace clang {
+namespace api_notes {
+
+/// A class that reads API notes data from a binary file that was written by
+/// the \c APINotesWriter.
+class APINotesReader {
+  class Implementation;
+  std::unique_ptr Implementation;
+
+  APINotesReader(llvm::MemoryBuffer *InputBuffer,
+ llvm::VersionTuple SwiftVersion, bool &Failed);
+
+public:
+  /// Create a new API notes reader from the given member buffer, which
+  /// contains the contents of a binary API notes file.
+  ///
+  /// \returns the new API notes reader, or null if an error occurred.
+  static std::unique_ptr
+  get(std::unique_ptr InputBuffer,
+  llvm::VersionTuple SwiftVersion);
+
+  ~APINotesReader();
+
+  APINotesReader(const APINotesReader &) = delete;
+  APINotesReader &operator=(const APINotesReader &) = delete;
+
+  /// Captures the completed versioned information for a particular part of
+  /// API notes, including both unversioned API notes and each versioned API
+  /// note for that particular entity.
+  template  class VersionedInfo {
+/// The complete set of results.
+llvm::SmallVector, 1> Results;
+
+/// The index of the result that is the "selected" set based on the desired
+/// Swift version, or \c Results.size() if nothing matched.
+unsigned Selected;
+
+  public:
+/// Form an empty set of versioned information.
+VersionedInfo(std::nullopt_t) : Selected(0) {}
+
+/// Form a versioned info set given the desired version and a set of
+/// results.
+VersionedInfo(
+llvm::VersionTuple Version,
+llvm::SmallVector, 1> Results);
+
+/// Retrieve the selected index in the result set.
+std::optional getSelected() const {
+  if (Selected == Results.size())
+return std::nullopt;
+  return Selected;
+}
+
+/// Return the number of versioned results we know about.
+unsigned size() const { return Results.size(); }
+
+/// Access all versioned results.
+const std::pair *begin() const {
+  return Results.begin();
+}
+const std::pair *end() const {
+  return Results.end();
+}
+
+/// Access a specific versioned result.
+const std::pair &operator[](unsigned index) const {
+  return Results[index];
+}
+  };
+
+  /// Look for the context ID of the given Objective-C class.
+  ///
+  /// \param Name The name of the class we're looking for.
+  ///
+  /// \returns The ID, if known.
+  std::optional lookupObjCClassID(llvm::StringRef Name);
+
+  /// Look for information regarding the given Objective-C class.
+  ///
+  /// \param Name The name of the class we're looking for.
+  ///
+  /// \returns The information about the class, if known.
+  VersionedInfo lookupObjCClassInfo(llvm::StringRef Name);
+
+  /// Look for the context ID of the given Objective-C protocol.
+  ///
+  /// \param Name The name of the protocol we're looking for.
+  ///
+  /// \returns The ID of the protocol, if known.
+  std::optional lookupObjCProtocolID(llvm::StringRef Name);
+
+  /// Look for information regarding the given Objective-C protocol.
+  ///
+  /// \param Name The name of the protocol we're looking for.
+  ///
+  /// \returns The information about the protocol, if known.
+  VersionedInfo lookupObjCProtocolInfo(llvm::StringRef Name);
+
+  /// Look for information regarding the given Objective-C property in
+  /// the given context.
+  ///
+  /// \param CtxID The ID that references the context we are looking for.
+  /// \param Name The name of the property we're looking for.
+  /// \param IsInstance Whether we are looking for an instance property (vs.
+  /// a class property).
+  ///
+  /// \returns Information about the property, if known.
+  VersionedInfo
+  lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance);

egorzhdan wrote:

Sorry I'm still not getting it 🙂
What specifically do you think we should move to `ObjCPropertyInfo`? Is it 
`Name`, or `IsInstance` flag, or the entire method?

https://github.com/llvm/llvm-project/pull/66769

[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-23 Thread Aaron Ballman via cfe-commits

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

LGTM

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


[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-23 Thread Aaron Ballman via cfe-commits


@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected,new-interp %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter

AaronBallman wrote:

```suggestion
// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98 -fexperimental-new-constant-interpreter
```

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


[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-23 Thread Aaron Ballman via cfe-commits

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


[clang] [clang][Interp] Only diagnose null field access in constant contexts (PR #69223)

2023-10-23 Thread Aaron Ballman via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -295,7 +295,7 @@ class Pointer {
   bool isUnion() const;
 
   /// Checks if the storage is extern.
-  bool isExtern() const { return Pointee->isExtern(); }
+  bool isExtern() const { return Pointee && Pointee->isExtern(); }

AaronBallman wrote:

If we need to care that `Pointee` can be null, we need to care consistently, 
don't we?

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


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-23 Thread Aaron Ballman via cfe-commits

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

LGTM

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


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-23 Thread Aaron Ballman via cfe-commits


@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, 
const Pointer &Ptr) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState &S, const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) {
+  assert(S.Current);
+  const Function *CurFunc = S.Current->getFunction();
+  assert(CurFunc);
+
+  // Certain builtin functions are declared as func-name(...), so the
+  // parameters are checked in Sema and only available through the CallExpr.
+  // The interp::Function we create for them has 0 parameters, so we need to
+  // remove them from the stack by checking the CallExpr.
+  // FIXME: This is potentially just a special case and could be handled more
+  // generally with the code just below?
+  if (CurFunc->needsRuntimeArgPop(S.getCtx())) {
+const CallExpr *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState &S, CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  if (S.Current->Caller && CurFunc->isVariadic()) {
+// CallExpr we're look for is at the return PC of the current function, 
i.e.
+// in the caller.
+// This code path should be executed very rarely.
+const CallExpr *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));

AaronBallman wrote:

```suggestion
const auto *CE =
cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
```

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


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-23 Thread Aaron Ballman via cfe-commits

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


[clang] [clang][Interp] Correctly emit destructors for multi-dimensional arrays (PR #69140)

2023-10-23 Thread Aaron Ballman via cfe-commits

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

LGTM

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


[clang] [clang-format] Don't break between string literal operands of << (PR #69871)

2023-10-23 Thread Tsarkov Maksim via cfe-commits

s1Sharp wrote:

this is good to be respectful. Please, lets check my mr 
https://github.com/llvm/llvm-project/pull/69859 also

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


[clang] [clang-format] unexpected break after binOp '<<' (PR #69859)

2023-10-23 Thread Tsarkov Maksim via cfe-commits

https://github.com/s1Sharp updated 
https://github.com/llvm/llvm-project/pull/69859

>From 5bbff07c636c2fc8b0432e5ca615d4cd7fd0c2b1 Mon Sep 17 00:00:00 2001
From: Tsarkov Maksim 
Date: Sun, 22 Oct 2023 02:09:21 +0300
Subject: [PATCH] [clang-format] unexpected break after binOp '<<'

the problem occurred while checking for the correctness of the break after 
binary operators.
The output statement 'tok::lessless' is then break line every possible time,
which is not expected with the BreakBeforeBinaryOperators: None

Fixes https://github.com/llvm/llvm-project/issues/59797
Fixes https://github.com/llvm/llvm-project/issues/44363
---
 clang/lib/Format/TokenAnnotator.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 7f85f48de2ed2ed..6db1e826e11d234 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5119,7 +5119,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine 
&Line,
   if (Left.IsUnterminatedLiteral)
 return true;
   if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
-  Right.Next->is(tok::string_literal)) {
+  Right.Next->is(tok::string_literal) &&
+  (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_All ||
+   Style.BreakBeforeBinaryOperators == FormatStyle::BOS_NonAssignment)) {
 return true;
   }
   if (Right.is(TT_RequiresClause)) {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix IntAP(s) to IntAP(s) casts (PR #69915)

2023-10-23 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

A bit more description about what the issue is and why this solves it would be 
helpful.

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


[clang] [clang][Interp] Implement IntegralAP::truncate() (PR #69912)

2023-10-23 Thread Aaron Ballman via cfe-commits

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

LGTM!

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


[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-23 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67990

>From 0056d67f145fd0d5f8056325bc70246314c9b117 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 16:26:46 +0200
Subject: [PATCH 1/2] [clang][Interp] Only emit function_param_value_unknown in
 C++11

---
 clang/lib/AST/Interp/Interp.cpp | 8 ++--
 clang/test/SemaCXX/offsetof.cpp | 7 +++
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index a4d6844ebe61722..8b0e7beb4a1acc1 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -555,8 +555,12 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const 
DeclRefExpr *DR) {
   const SourceInfo &E = S.Current->getSource(OpPC);
 
   if (isa(D)) {
-S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
-S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+if (S.getLangOpts().CPlusPlus11) {
+  S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
+  S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+} else {
+  S.FFDiag(E);
+}
   } else if (const auto *VD = dyn_cast(D)) {
 if (!VD->getType().isConstQualified()) {
   S.FFDiag(E,
diff --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp
index cb91f2bed0b9224..f54ee06c43147dd 100644
--- a/clang/test/SemaCXX/offsetof.cpp
+++ b/clang/test/SemaCXX/offsetof.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected,new-interp %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
 
 struct NonPOD {
   virtual void f();
@@ -25,10 +25,9 @@ struct HasArray {
 };
 
 // Constant and non-constant offsetof expressions
-void test_ice(int i) { // new-interp-note {{declared here}}
+void test_ice(int i) {
   int array0[__builtin_offsetof(HasArray, array[5])];
-  int array1[__builtin_offsetof(HasArray, array[i])]; // expected-warning 
{{variable length arrays in C++ are a Clang extension}} \
- new-interp-note 
{{function parameter 'i' with unknown value cannot be used in a constant 
expression}}
+  int array1[__builtin_offsetof(HasArray, array[i])]; // expected-warning 
{{variable length arrays in C++ are a Clang extension}}
 }
 
 // Bitfields

>From d1c4e6dd573ac38d0190286e263c03e00fdee49b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 23 Oct 2023 15:21:13 +0200
Subject: [PATCH 2/2] Remove =expected from test case

---
 clang/test/SemaCXX/offsetof.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/offsetof.cpp b/clang/test/SemaCXX/offsetof.cpp
index f54ee06c43147dd..1722b91fafc8696 100644
--- a/clang/test/SemaCXX/offsetof.cpp
+++ b/clang/test/SemaCXX/offsetof.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only 
-verify=expected %s -Winvalid-offsetof -std=c++98 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -verify %s 
-Winvalid-offsetof -std=c++98 -fexperimental-new-constant-interpreter
 
 struct NonPOD {
   virtual void f();

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-23 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67814

>From 7437589c0c37b40633b81184102202c2e01bb423 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 16:43:59 +0200
Subject: [PATCH] [clang][Interp] Handle variadic functions

Similarly to the code we already had for builtin functions, we need to
check the call expression for the arguments passed.
---
 clang/lib/AST/Interp/Function.cpp   |  2 +-
 clang/lib/AST/Interp/Function.h |  3 ++
 clang/lib/AST/Interp/Interp.cpp | 49 +++--
 clang/lib/AST/Interp/Interp.h   | 18 +++
 clang/test/AST/Interp/functions.cpp | 21 +
 5 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 0b7cfc4e28883f0..357aff7fe6229b9 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -24,7 +24,7 @@ Function::Function(Program &P, const FunctionDecl *F, 
unsigned ArgSize,
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index b93477c56346a9d..be9b1733635f725 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -173,6 +173,8 @@ class Function final {
   /// Checks if the function is defined.
   bool isDefined() const { return Defined; }
 
+  bool isVariadic() const { return Variadic; }
+
   unsigned getBuiltinID() const { return F->getBuiltinID(); }
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -251,6 +253,7 @@ class Function final {
   /// If we've already compiled the function's body.
   bool HasBody = false;
   bool Defined = false;
+  bool Variadic = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index a4d6844ebe61722..3523f057c54a525 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, 
const Pointer &Ptr) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState &S, const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) {
+  assert(S.Current);
+  const Function *CurFunc = S.Current->getFunction();
+  assert(CurFunc);
+
+  // Certain builtin functions are declared as func-name(...), so the
+  // parameters are checked in Sema and only available through the CallExpr.
+  // The interp::Function we create for them has 0 parameters, so we need to
+  // remove them from the stack by checking the CallExpr.
+  // FIXME: This is potentially just a special case and could be handled more
+  // generally with the code just below?
+  if (CurFunc->needsRuntimeArgPop(S.getCtx())) {
+const auto *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState &S, CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  if (S.Current->Caller && CurFunc->isVariadic()) {
+// CallExpr we're look for is at the return PC of the current function, 
i.e.
+// in the caller.
+// This code path should be executed very rarely.
+const auto *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
+unsigned FixedParams = CurFunc->getNumParams();
+int32_t ArgsToPop = CE->getNumArgs() - FixedParams;
+assert(ArgsToPop >= 0);
+for (int32_t I = ArgsToPop - 1; I >= 0; --I) {
+  const Expr *A = CE->getArg(FixedParams + I);
+  popArg(S, A);
+}
   }
-  return true;
+  // And in any case, remove the fixed parameters (the non-variadic ones)
+  // at the end.
+  S.Current->popArgs();
 }
 
 bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index e3e6a4cec63b194..5c78ee9e53acfb3 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -200,8 +200,7 @@ enum class ArithOp { Add, Sub };
 // Returning values

[clang] [clang][Interp] Fix truncateCast() (PR #69911)

2023-10-23 Thread Aaron Ballman via cfe-commits


@@ -81,14 +89,20 @@ template  class IntegralAP final {
   }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return truncateCast(V); }
-  explicit operator uint8_t() const { return truncateCast(V); }
-  explicit operator int16_t() const { return truncateCast(V); }
-  explicit operator uint16_t() const { return truncateCast(V); }
-  explicit operator int32_t() const { return truncateCast(V); }
-  explicit operator uint32_t() const { return truncateCast(V); }
-  explicit operator int64_t() const { return truncateCast(V); }
-  explicit operator uint64_t() const { return truncateCast(V); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); 
}
+  explicit operator int16_t() const { return truncateCast(V); 
}
+  explicit operator uint16_t() const {
+return truncateCast(V);
+  }
+  explicit operator int32_t() const { return truncateCast(V); 
}
+  explicit operator uint32_t() const {
+return truncateCast(V);
+  }
+  explicit operator int64_t() const { return truncateCast(V); 
}
+  explicit operator uint64_t() const {
+return truncateCast(V);
+  }

AaronBallman wrote:

This might be a terrible idea, but I wish we could remove the duplication with 
something along the lines of:
```
template >>
explicit operator Ty() const { return truncateCast(V); }
```
instead of having to repeat ourselves so much. CC @cor3ntin 

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


  1   2   3   4   >