[clang] [clang][Interp] Handle virtual calls with covariant return types (PR #101218)

2024-07-31 Thread Timm Baeder via cfe-commits

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-31 Thread Timm Baeder via cfe-commits

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


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


[clang] [clang][Interp] Handle virtual calls with covariant return types (PR #101218)

2024-07-31 Thread Timm Baeder via cfe-commits

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

>From 78961fbfbd791844b1622aa305664199e3451260 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 30 Jul 2024 20:11:37 +0200
Subject: [PATCH] [clang][Interp] Handle virtual calls with covariant return
 types

---
 clang/lib/AST/Interp/Interp.h   | 24 +++-
 clang/test/AST/Interp/cxx2a.cpp | 21 +
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index d128988a480e1..63e9966b831db 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2628,7 +2628,29 @@ inline bool CallVirt(InterpState , CodePtr OpPC, const 
Function *Func,
 }
   }
 
-  return Call(S, OpPC, Func, VarArgSize);
+  if (!Call(S, OpPC, Func, VarArgSize))
+return false;
+
+  // Covariant return types. The return type of Overrider is a pointer
+  // or reference to a class type.
+  if (Overrider != InitialFunction &&
+  Overrider->getReturnType()->isPointerOrReferenceType() &&
+  InitialFunction->getReturnType()->isPointerOrReferenceType()) {
+QualType OverriderPointeeType =
+Overrider->getReturnType()->getPointeeType();
+QualType InitialPointeeType =
+InitialFunction->getReturnType()->getPointeeType();
+// We've called Overrider above, but calling code expects us to return what
+// InitialFunction returned. According to the rules for covariant return
+// types, what InitialFunction returns needs to be a base class of what
+// Overrider returns. So, we need to do an upcast here.
+unsigned Offset = S.getContext().collectBaseOffset(
+InitialPointeeType->getAsRecordDecl(),
+OverriderPointeeType->getAsRecordDecl());
+return GetPtrBasePop(S, OpPC, Offset);
+  }
+
+  return true;
 }
 
 inline bool CallBI(InterpState , CodePtr , const Function *Func,
diff --git a/clang/test/AST/Interp/cxx2a.cpp b/clang/test/AST/Interp/cxx2a.cpp
index 27d1aa1a27f75..ad021b30cfd3c 100644
--- a/clang/test/AST/Interp/cxx2a.cpp
+++ b/clang/test/AST/Interp/cxx2a.cpp
@@ -13,3 +13,24 @@ consteval int aConstevalFunction() { // both-error 
{{consteval function never pr
   return 0;
 }
 /// We're NOT calling the above function. The diagnostics should appear anyway.
+
+namespace Covariant {
+  struct A {
+virtual constexpr char f() const { return 'Z'; }
+char a = f();
+  };
+
+  struct D : A {};
+  struct Covariant1 {
+D d;
+virtual const A *f() const;
+  };
+
+  struct Covariant3 : Covariant1 {
+constexpr virtual const D *f() const { return >d; }
+  };
+
+  constexpr Covariant3 cb;
+  constexpr const Covariant1 *cb1 = 
+  static_assert(cb1->f()->a == 'Z');
+}

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


[clang] [clang][NFC] Add Type::isPointerOrReferenceType() (PR #101206)

2024-07-31 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Handle virtual calls with covariant return types (PR #101218)

2024-07-30 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID: 
In-Reply-To:


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

None

>From 2f54449a650b094a47309e3230557df1f195d384 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 30 Jul 2024 19:10:41 +0200
Subject: [PATCH 1/2] [clang][NFC] Add Type::isPointerOrReferenceType()

---
 clang/include/clang/AST/Type.h|  5 +
 clang/include/clang/Sema/Overload.h   |  2 +-
 clang/lib/AST/ExprCXX.cpp |  2 +-
 clang/lib/AST/Interp/Context.cpp  |  2 +-
 clang/lib/AST/ItaniumMangle.cpp   |  2 +-
 clang/lib/AST/Type.cpp|  2 +-
 clang/lib/Analysis/Consumed.cpp   | 10 +++---
 clang/lib/Analysis/ThreadSafetyCommon.cpp |  2 +-
 clang/lib/Sema/SemaDecl.cpp   |  6 +++---
 clang/lib/Sema/SemaDeclAttr.cpp   |  2 +-
 clang/lib/Sema/SemaExprCXX.cpp|  2 +-
 clang/lib/Sema/SemaTemplate.cpp   |  2 +-
 12 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 89a74ff1fb285..dec51e032158e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2509,6 +2509,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isPointerOrReferenceType() const;
   bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
@@ -7996,6 +7997,10 @@ inline bool Type::isPointerType() const {
   return isa(CanonicalType);
 }
 
+inline bool Type::isPointerOrReferenceType() const {
+  return isPointerType() || isReferenceType();
+}
+
 inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 26ffe057c74a2..d6a6cee62a752 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -984,7 +984,7 @@ class Sema;
 unsigned getNumParams() const {
   if (IsSurrogate) {
 QualType STy = Surrogate->getConversionType();
-while (STy->isPointerType() || STy->isReferenceType())
+while (STy->isPointerOrReferenceType())
   STy = STy->getPointeeType();
 return STy->castAs()->getNumParams();
   }
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e2c9643151126..6212989e21737 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -152,7 +152,7 @@ bool CXXTypeidExpr::isMostDerived(ASTContext ) 
const {
   const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
   if (const auto *DRE = dyn_cast(E)) {
 QualType Ty = DRE->getDecl()->getType();
-if (!Ty->isPointerType() && !Ty->isReferenceType())
+if (!Ty->isPointerOrReferenceType())
   return true;
   }
 
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index b5e992c5a9ac1..fd66e6fe8dcbc 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -176,7 +176,7 @@ std::optional Context::classify(QualType T) const 
{
   T->isFunctionType())
 return PT_FnPtr;
 
-  if (T->isReferenceType() || T->isPointerType() ||
+  if (T->isPointerOrReferenceType() ||
   T->isObjCObjectPointerType())
 return PT_Ptr;
 
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d46d621d4c7d4..ead5da4e90f2f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -6484,7 +6484,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, 
const APValue ,
 
   case APValue::LValue: {
 // Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
-assert((T->isPointerType() || T->isReferenceType()) &&
+assert((T->isPointerOrReferenceType()) &&
"unexpected type for LValue template arg");
 
 if (V.isNullPointer()) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fdaab8e434593..0456b5f96b210 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -75,7 +75,7 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
 const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
   const Type* ty = getTypePtr();
   NamedDecl *ND = nullptr;
-  if (ty->isPointerType() || ty->isReferenceType())
+  if (ty->isPointerOrReferenceType())
 return ty->getPointeeType().getBaseTypeIdentifier();
   else if (ty->isRecordType())
 ND = ty->castAs()->getDecl();
diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp
index d01c7f688e8b5..63c5943242944 100644
--- a/clang/lib/Analysis/Consumed.cpp
+++ b/clang/lib/Analysis/Consumed.cpp
@@ -141,7 +141,7 @@ static bool isCallableInState(const 

[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-30 Thread Timm Baeder via cfe-commits


@@ -122,19 +124,18 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  for (auto [I, B] : llvm::enumerate(R->bases())) {

tbaederr wrote:

Does `auto &[I, B]` work here? What about `const auto &`?

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


[clang] [clang][NFC] Add Type::isPointerOrReferenceType() (PR #101206)

2024-07-30 Thread Timm Baeder via cfe-commits

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

>From 22debffc8fd3e0e5120f4a968ff788a040955448 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 30 Jul 2024 19:10:41 +0200
Subject: [PATCH] [clang][NFC] Add Type::isPointerOrReferenceType()

---
 clang/include/clang/AST/Type.h|  5 +
 clang/include/clang/Sema/Overload.h   |  2 +-
 clang/lib/AST/ExprCXX.cpp |  2 +-
 clang/lib/AST/Interp/Context.cpp  |  3 +--
 clang/lib/AST/ItaniumMangle.cpp   |  2 +-
 clang/lib/AST/Type.cpp|  2 +-
 clang/lib/Analysis/Consumed.cpp   | 10 +++---
 clang/lib/Analysis/ThreadSafetyCommon.cpp |  2 +-
 clang/lib/Sema/SemaDecl.cpp   | 12 ++--
 clang/lib/Sema/SemaDeclAttr.cpp   |  2 +-
 clang/lib/Sema/SemaExprCXX.cpp|  2 +-
 clang/lib/Sema/SemaTemplate.cpp   |  2 +-
 12 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 89a74ff1fb285..dec51e032158e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2509,6 +2509,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isPointerOrReferenceType() const;
   bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
@@ -7996,6 +7997,10 @@ inline bool Type::isPointerType() const {
   return isa(CanonicalType);
 }
 
+inline bool Type::isPointerOrReferenceType() const {
+  return isPointerType() || isReferenceType();
+}
+
 inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 26ffe057c74a2..d6a6cee62a752 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -984,7 +984,7 @@ class Sema;
 unsigned getNumParams() const {
   if (IsSurrogate) {
 QualType STy = Surrogate->getConversionType();
-while (STy->isPointerType() || STy->isReferenceType())
+while (STy->isPointerOrReferenceType())
   STy = STy->getPointeeType();
 return STy->castAs()->getNumParams();
   }
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e2c9643151126..6212989e21737 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -152,7 +152,7 @@ bool CXXTypeidExpr::isMostDerived(ASTContext ) 
const {
   const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
   if (const auto *DRE = dyn_cast(E)) {
 QualType Ty = DRE->getDecl()->getType();
-if (!Ty->isPointerType() && !Ty->isReferenceType())
+if (!Ty->isPointerOrReferenceType())
   return true;
   }
 
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index b5e992c5a9ac1..b1e06cd4d8a4c 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -176,8 +176,7 @@ std::optional Context::classify(QualType T) const 
{
   T->isFunctionType())
 return PT_FnPtr;
 
-  if (T->isReferenceType() || T->isPointerType() ||
-  T->isObjCObjectPointerType())
+  if (T->isPointerOrReferenceType() || T->isObjCObjectPointerType())
 return PT_Ptr;
 
   if (const auto *AT = T->getAs())
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d46d621d4c7d4..ead5da4e90f2f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -6484,7 +6484,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, 
const APValue ,
 
   case APValue::LValue: {
 // Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
-assert((T->isPointerType() || T->isReferenceType()) &&
+assert((T->isPointerOrReferenceType()) &&
"unexpected type for LValue template arg");
 
 if (V.isNullPointer()) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fdaab8e434593..0456b5f96b210 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -75,7 +75,7 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
 const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
   const Type* ty = getTypePtr();
   NamedDecl *ND = nullptr;
-  if (ty->isPointerType() || ty->isReferenceType())
+  if (ty->isPointerOrReferenceType())
 return ty->getPointeeType().getBaseTypeIdentifier();
   else if (ty->isRecordType())
 ND = ty->castAs()->getDecl();
diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp
index d01c7f688e8b5..63c5943242944 100644
--- a/clang/lib/Analysis/Consumed.cpp
+++ b/clang/lib/Analysis/Consumed.cpp
@@ -141,7 +141,7 @@ static bool 

[clang] [clang][NFC] Add Type::isPointerOrReferenceType() (PR #101206)

2024-07-30 Thread Timm Baeder via cfe-commits

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

Seems to be a common pattern.

>From be90760736b0b72e96d0aee5af521207811aebfc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 30 Jul 2024 19:10:41 +0200
Subject: [PATCH] [clang][NFC] Add Type::isPointerOrReferenceType()

---
 clang/include/clang/AST/Type.h|  5 +
 clang/include/clang/Sema/Overload.h   |  2 +-
 clang/lib/AST/ExprCXX.cpp |  2 +-
 clang/lib/AST/Interp/Context.cpp  |  3 +--
 clang/lib/AST/ItaniumMangle.cpp   |  2 +-
 clang/lib/AST/Type.cpp|  2 +-
 clang/lib/Analysis/Consumed.cpp   | 10 +++---
 clang/lib/Analysis/ThreadSafetyCommon.cpp |  2 +-
 clang/lib/Sema/SemaDecl.cpp   | 12 ++--
 clang/lib/Sema/SemaDeclAttr.cpp   |  2 +-
 clang/lib/Sema/SemaExprCXX.cpp|  2 +-
 clang/lib/Sema/SemaTemplate.cpp   |  2 +-
 12 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 89a74ff1fb285..dec51e032158e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2509,6 +2509,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isFunctionNoProtoType() const { return getAs(); }
   bool isFunctionProtoType() const { return getAs(); }
   bool isPointerType() const;
+  bool isPointerOrReferenceType() const;
   bool isSignableType() const;
   bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
   bool isCountAttributedType() const;
@@ -7996,6 +7997,10 @@ inline bool Type::isPointerType() const {
   return isa(CanonicalType);
 }
 
+inline bool Type::isPointerOrReferenceType() const {
+  return isPointerType() || isReferenceType();
+}
+
 inline bool Type::isAnyPointerType() const {
   return isPointerType() || isObjCObjectPointerType();
 }
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 26ffe057c74a2..d6a6cee62a752 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -984,7 +984,7 @@ class Sema;
 unsigned getNumParams() const {
   if (IsSurrogate) {
 QualType STy = Surrogate->getConversionType();
-while (STy->isPointerType() || STy->isReferenceType())
+while (STy->isPointerOrReferenceType())
   STy = STy->getPointeeType();
 return STy->castAs()->getNumParams();
   }
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index e2c9643151126..6212989e21737 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -152,7 +152,7 @@ bool CXXTypeidExpr::isMostDerived(ASTContext ) 
const {
   const Expr *E = getExprOperand()->IgnoreParenNoopCasts(Context);
   if (const auto *DRE = dyn_cast(E)) {
 QualType Ty = DRE->getDecl()->getType();
-if (!Ty->isPointerType() && !Ty->isReferenceType())
+if (!Ty->isPointerOrReferenceType())
   return true;
   }
 
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index b5e992c5a9ac1..b1e06cd4d8a4c 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -176,8 +176,7 @@ std::optional Context::classify(QualType T) const 
{
   T->isFunctionType())
 return PT_FnPtr;
 
-  if (T->isReferenceType() || T->isPointerType() ||
-  T->isObjCObjectPointerType())
+  if (T->isPointerOrReferenceType() || T->isObjCObjectPointerType())
 return PT_Ptr;
 
   if (const auto *AT = T->getAs())
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d46d621d4c7d4..ead5da4e90f2f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -6484,7 +6484,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, 
const APValue ,
 
   case APValue::LValue: {
 // Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
-assert((T->isPointerType() || T->isReferenceType()) &&
+assert((T->isPointerOrReferenceType()) &&
"unexpected type for LValue template arg");
 
 if (V.isNullPointer()) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index fdaab8e434593..0456b5f96b210 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -75,7 +75,7 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
 const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
   const Type* ty = getTypePtr();
   NamedDecl *ND = nullptr;
-  if (ty->isPointerType() || ty->isReferenceType())
+  if (ty->isPointerOrReferenceType())
 return ty->getPointeeType().getBaseTypeIdentifier();
   else if (ty->isRecordType())
 ND = ty->castAs()->getDecl();
diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp
index d01c7f688e8b5..63c5943242944 100644
--- a/clang/lib/Analysis/Consumed.cpp
+++ b/clang/lib/Analysis/Consumed.cpp
@@ -141,7 +141,7 @@ 

[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-30 Thread Timm Baeder via cfe-commits


@@ -122,19 +124,21 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  for (auto [I, B] : llvm::enumerate(R->bases())) {
 Pointer P = BasePtr.atField(B.Offset);
 if (!P.isInitialized()) {
   const Descriptor *Desc = BasePtr.getDeclDesc();
-  if (Desc->asDecl())
-S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
- diag::note_constexpr_uninitialized_base)
+  if (const auto *CD = dyn_cast_or_null(R->getDecl())) {

tbaederr wrote:

```suggestion
  if (const auto *CD = dyn_cast_if_present(R->getDecl())) {
```

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-30 Thread Timm Baeder via cfe-commits


@@ -122,19 +124,21 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  for (auto [I, B] : llvm::enumerate(R->bases())) {
 Pointer P = BasePtr.atField(B.Offset);
 if (!P.isInitialized()) {
   const Descriptor *Desc = BasePtr.getDeclDesc();
-  if (Desc->asDecl())
-S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
- diag::note_constexpr_uninitialized_base)
+  if (const auto *CD = dyn_cast_or_null(R->getDecl())) {
+const auto  = *std::next(CD->bases_begin(), I);
+S.FFDiag(BS.getBaseTypeLoc(), diag::note_constexpr_uninitialized_base)
+<< B.Desc->getType() << BS.getSourceRange();
+  } else {
+SourceLocation Loc =
+Desc->asDecl() ? BasePtr.getDeclDesc()->asDecl()->getLocation()
+   : BasePtr.getDeclDesc()->asExpr()->getExprLoc();
+S.FFDiag(Loc, diag::note_constexpr_uninitialized_base)

tbaederr wrote:

```suggestion
S.FFDiag(Desc->getLocation(), diag::note_constexpr_uninitialized_base)
```

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


[clang] [libclang/python] Export all enums (PR #100941)

2024-07-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> @tbaederr CI for this patch has failed due to unrelated failure that is 
> likely to be connected to your work:

That should be fixed already, I assume this is using an old version of the test.

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

CC @AaronBallman @Sirraide @shafik Since this adds new API to 
`CXXBaseSpecifier`.

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr commented:

![Screenshot from 2024-07-27 
07-04-02](https://github.com/user-attachments/assets/5a7c4b26-2c68-4bb1-8480-4b7ff9e4be87)

The three regressions all have similar stack traces:
```
 #5 0x0bba9f4c clang::Redeclarable::getFirstDecl() 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/Redeclarable.h:216:38
 #6 0x0bba9cd5 clang::Redeclarable::getMostRecentDecl() 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/Redeclarable.h:227:12
 #7 0x0bba9a69 clang::RecordDecl::getMostRecentDecl() 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/Decl.h:4168:59
 #8 0x0bba99b5 clang::CXXRecordDecl::getMostRecentDecl() 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:542:46
 #9 0x0bba9995 clang::CXXRecordDecl::getMostRecentDecl() const 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:546:5
#10 0x0bba9969 clang::CXXRecordDecl::dataPtr() const 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:458:5
#11 0x0bba9885 clang::CXXRecordDecl::data() const 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:463:11
#12 0x0bc92be5 clang::CXXRecordDecl::bases_begin() const 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:627:58
#13 0x0bc7a6a9 clang::CXXRecordDecl::bases() const 
/home/fedora/interp-tests/llvm-project/clang/include/clang/AST/DeclCXX.h:623:35
#14 0x127e9d9f 
clang::interp::CheckFieldsInitialized(clang::interp::InterpState&, 
clang::SourceLocation, clang::interp::Pointer const&, clang::interp::Record 
const*) 
/home/fedora/interp-tests/llvm-project/clang/lib/AST/Interp/EvaluationResult.cpp:127:41
```
So I think it's cases where the decl is no CXXRecordDecl. 
This patch also drops the handling where the pointer descriptor was created for 
an expression - this might be relevant for those tests or not.

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits


@@ -14,33 +14,29 @@ struct DelBase {
   constexpr DelBase() = delete; // expected-note {{'DelBase' has been 
explicitly marked deleted here}}

tbaederr wrote:

The second bullet point of the comment at the top of the file is obsolete now.

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits


@@ -122,22 +122,20 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  unsigned BaseIndex = 0;
+  const CXXRecordDecl *CD = dyn_cast(R->getDecl());

tbaederr wrote:

```suggestion
  const auto *CD = dyn_cast(R->getDecl());
```

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits


@@ -122,22 +122,20 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  unsigned BaseIndex = 0;
+  const CXXRecordDecl *CD = dyn_cast(R->getDecl());

tbaederr wrote:

This either needs to be a `cast<>` or a null check. And I think it should be a 
null check.

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits


@@ -122,22 +122,20 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  unsigned BaseIndex = 0;
+  const CXXRecordDecl *CD = dyn_cast(R->getDecl());
+  for (const CXXBaseSpecifier  : CD->bases()) {
+const Record::Base  = *R->getBase(BaseIndex);
 Pointer P = BasePtr.atField(B.Offset);
 if (!P.isInitialized()) {
-  const Descriptor *Desc = BasePtr.getDeclDesc();
-  if (Desc->asDecl())
-S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
- diag::note_constexpr_uninitialized_base)
-<< B.Desc->getType();
-  else
-S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(),
- diag::note_constexpr_uninitialized_base)
-<< B.Desc->getType();
-
+  SourceLocation TypeBeginLoc = BS.getBaseTypeLoc();
+  SourceRange Range(TypeBeginLoc, BS.getEndLoc());

tbaederr wrote:

Is this different than `BS.getSourceRange()`?

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits


@@ -122,22 +122,20 @@ static bool CheckFieldsInitialized(InterpState , 
SourceLocation Loc,
   }
 
   // Check Fields in all bases
-  for (const Record::Base  : R->bases()) {
+  unsigned BaseIndex = 0;
+  const CXXRecordDecl *CD = dyn_cast(R->getDecl());
+  for (const CXXBaseSpecifier  : CD->bases()) {
+const Record::Base  = *R->getBase(BaseIndex);
 Pointer P = BasePtr.atField(B.Offset);
 if (!P.isInitialized()) {
-  const Descriptor *Desc = BasePtr.getDeclDesc();
-  if (Desc->asDecl())
-S.FFDiag(BasePtr.getDeclDesc()->asDecl()->getLocation(),
- diag::note_constexpr_uninitialized_base)
-<< B.Desc->getType();
-  else
-S.FFDiag(BasePtr.getDeclDesc()->asExpr()->getExprLoc(),
- diag::note_constexpr_uninitialized_base)
-<< B.Desc->getType();
-
+  SourceLocation TypeBeginLoc = BS.getBaseTypeLoc();
+  SourceRange Range(TypeBeginLoc, BS.getEndLoc());
+  S.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
+  << B.Desc->getType() << Range;
   return false;
 }
 Result &= CheckFieldsInitialized(S, Loc, P, B.R);
+BaseIndex++;

tbaederr wrote:

```suggestion
++BaseIndex;
```

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


[clang] [Clang][Interp] Fix the location of uninitialized base warning (PR #100761)

2024-07-26 Thread Timm Baeder via cfe-commits

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


[clang] [NFC][Clang][Interp] Add more test for `__builtin_os_log_format_buffer_size` (PR #100566)

2024-07-25 Thread Timm Baeder via cfe-commits

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


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


[clang] [Clang][Interp] Create the variable that holds the value of evaluating the binding (PR #100565)

2024-07-25 Thread Timm Baeder via cfe-commits

tbaederr wrote:

https://godbolt.org/z/a8TW93h63

Because it isn't a constant expression - at the time of the evaluation of the 
`static_assert`, the parameter value `cf` is unknown and so initializing `scf` 
can't work. Rejecting this is correct.

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


[clang] [Clang][Interp] Visit `DecompositionDecl` and create a local variable (PR #100400)

2024-07-25 Thread Timm Baeder via cfe-commits


@@ -5234,6 +5240,9 @@ bool Compiler::visitDeclRef(const ValueDecl *D, 
const Expr *E) {
   return false;
 };
 
+if (isa(VD))

tbaederr wrote:

```suggestion
   // DecompositionDecls are just proxies for us.
if (isa(VD))
```

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


[clang] [Clang][Interp] Visit `DecompositionDecl` and create a local variable (PR #100400)

2024-07-25 Thread Timm Baeder via cfe-commits

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

LGTM with the suggested changes. This might not be perfect wrt. revisiting 
`DecompositionDecl`s, but we can handle problems when they arise.

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


[clang] [Clang][Interp] Visit `DecompositionDecl` and create a local variable (PR #100400)

2024-07-25 Thread Timm Baeder via cfe-commits


@@ -3593,8 +3593,14 @@ VarCreationState Compiler::visitDecl(const 
VarDecl *VD) {
   if (R.notCreated())
 return R;
 
-  if (R)
-return true;
+  if (R) {

tbaederr wrote:

Yes, remove it please.

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


[clang] [Clang][Interp] Visit `DecompositionDecl` and create a local variable (PR #100400)

2024-07-25 Thread Timm Baeder via cfe-commits

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


[clang] [clang][ExprConst] Allow non-literal types in C++23 (PR #100062)

2024-07-24 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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


[clang] [clang][ExprConst] Allow non-literal types in C++23 (PR #100062)

2024-07-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/100062

>From 695dff600a78e62ec65a964f80438661bd7a522c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 23 Jul 2024 07:02:23 +0200
Subject: [PATCH 1/2] [clang][ExprConst] Allow non-literal types in C++23

Instead of diagnosing non-literal types in C++23, allow them
and later diagnose them differently, e.g. because they have a
non-constexpr constructor, destructor, etc.
---
 clang/lib/AST/ExprConstant.cpp |  3 +++
 clang/test/CXX/drs/cwg18xx.cpp | 12 
 .../test/SemaCXX/constant-expression-cxx11.cpp | 18 +++---
 .../test/SemaCXX/constant-expression-cxx2b.cpp | 10 +-
 clang/test/SemaCXX/cxx23-invalid-constexpr.cpp | 13 ++---
 5 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fcb382474ea62..6d4c91f54fcbf 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2404,6 +2404,9 @@ static bool CheckLiteralType(EvalInfo , const Expr 
*E,
   if (!E->isPRValue() || E->getType()->isLiteralType(Info.Ctx))
 return true;
 
+  if (Info.getLangOpts().CPlusPlus23)
+return true;
+
   // C++1y: A constant initializer for an object o [...] may also invoke
   // constexpr constructors for o and its subobjects even if those objects
   // are of non-literal class types.
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 323e56f9c5278..adfdb738e81c9 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -3,8 +3,8 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14,cxx17 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14
 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14
 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 
 #if __cplusplus == 199711L
 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
@@ -480,8 +480,12 @@ namespace cwg1872 { // cwg1872: 9
   static_assert(y == 0);
 #endif
   constexpr int z = A().f();
-  // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a 
constant expression}}
-  //   since-cxx11-note@-2 {{non-literal type 'A' cannot be used in a 
constant expression}}
+  // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a 
constant expression}}a
+#if __cplusplus < 202302L
+  //   since-cxx11-note@-3 {{non-literal type 'A' cannot be used in a 
constant expression}}
+#else
+  //   since-cxx23-note@-5 {{cannot construct object of type 'A' 
with virtual base class in a constant expression}}
+#endif
 #endif
 }
 
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index efb391ba0922d..6df8a4740d6cc 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -std=c++23 -isystem %S/Inputs -fsyntax-only 
-verify=expected,cxx20_23,cxx23-triple x86_64-linux -Wno-string-plus-int 
-Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions 
-pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
-// RUN: %clang_cc1 -std=c++20 -isystem %S/Inputs -fsyntax-only 
-verify=expected,cxx11_20,cxx20_23 -triple x86_64-linux -Wno-string-plus-int 
-Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions 
-pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
-// RUN: %clang_cc1 -std=c++11 -isystem %S/Inputs -fsyntax-only 

[clang] [clang][ExprConst] Allow non-literal types in C++23 (PR #100062)

2024-07-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/100062

>From 18a4a08009ecd8e5a557d77028fc4efdbf5901ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 23 Jul 2024 07:02:23 +0200
Subject: [PATCH 1/2] [clang][ExprConst] Allow non-literal types in C++23

Instead of diagnosing non-literal types in C++23, allow them
and later diagnose them differently, e.g. because they have a
non-constexpr constructor, destructor, etc.
---
 clang/lib/AST/ExprConstant.cpp |  3 +++
 clang/test/CXX/drs/cwg18xx.cpp | 12 
 .../test/SemaCXX/constant-expression-cxx11.cpp | 18 +++---
 .../test/SemaCXX/constant-expression-cxx2b.cpp | 10 +-
 clang/test/SemaCXX/cxx23-invalid-constexpr.cpp | 13 ++---
 5 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5af712dd7257b..a402e6f204aaf 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2404,6 +2404,9 @@ static bool CheckLiteralType(EvalInfo , const Expr 
*E,
   if (!E->isPRValue() || E->getType()->isLiteralType(Info.Ctx))
 return true;
 
+  if (Info.getLangOpts().CPlusPlus23)
+return true;
+
   // C++1y: A constant initializer for an object o [...] may also invoke
   // constexpr constructors for o and its subobjects even if those objects
   // are of non-literal class types.
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 323e56f9c5278..adfdb738e81c9 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -3,8 +3,8 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14,cxx17 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 
-fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14
 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx23,since-cxx11,since-cxx14
 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
 
 #if __cplusplus == 199711L
 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
@@ -480,8 +480,12 @@ namespace cwg1872 { // cwg1872: 9
   static_assert(y == 0);
 #endif
   constexpr int z = A().f();
-  // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a 
constant expression}}
-  //   since-cxx11-note@-2 {{non-literal type 'A' cannot be used in a 
constant expression}}
+  // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a 
constant expression}}a
+#if __cplusplus < 202302L
+  //   since-cxx11-note@-3 {{non-literal type 'A' cannot be used in a 
constant expression}}
+#else
+  //   since-cxx23-note@-5 {{cannot construct object of type 'A' 
with virtual base class in a constant expression}}
+#endif
 #endif
 }
 
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index efb391ba0922d..6df8a4740d6cc 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -std=c++23 -isystem %S/Inputs -fsyntax-only 
-verify=expected,cxx20_23,cxx23-triple x86_64-linux -Wno-string-plus-int 
-Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions 
-pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
-// RUN: %clang_cc1 -std=c++20 -isystem %S/Inputs -fsyntax-only 
-verify=expected,cxx11_20,cxx20_23 -triple x86_64-linux -Wno-string-plus-int 
-Wno-pointer-arith -Wno-zero-length-array -Wno-c99-designator -fcxx-exceptions 
-pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
-// RUN: %clang_cc1 -std=c++11 -isystem %S/Inputs -fsyntax-only 

[clang] [Clang][Interp] Diagnose use sizeless vector type as the argument of `__builtin_vectorelements` (PR #99794)

2024-07-22 Thread Timm Baeder via cfe-commits

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

LGTM, thanks!

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


[clang] [Clang][Interp] Diagnose use sizeless vector type as the argument of `__builtin_vectorelements` (PR #99794)

2024-07-21 Thread Timm Baeder via cfe-commits


@@ -2735,6 +2736,13 @@ inline bool InvalidDeclRef(InterpState , CodePtr OpPC,
   return CheckDeclRef(S, OpPC, DR);
 }
 
+inline bool SizelessVectorElementSize(InterpState , CodePtr OpPC) {

tbaederr wrote:

If you look at what the current interpreter does: 1) This should use `CCEDiag` 
instead and 2) the diagnostic should only be emitted if we're in a constant 
context

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


[clang] [Clang][Interp] Diagnose use sizeless vector type as the argument of `__builtin_vectorelements` (PR #99794)

2024-07-21 Thread Timm Baeder via cfe-commits


@@ -1698,10 +1698,8 @@ bool Compiler::VisitUnaryExprOrTypeTraitExpr(
   if (Kind == UETT_VectorElements) {
 if (const auto *VT = E->getTypeOfArgument()->getAs())
   return this->emitConst(VT->getNumElements(), E);
-
-// FIXME: Apparently we need to catch the fact that a sizeless vector type
-// has been passed and diagnose that (at run time).
-assert(E->getTypeOfArgument()->isSizelessVectorType());
+if (E->getTypeOfArgument()->isSizelessVectorType())
+  return this->emitSizelessVectorElementSize(E);

tbaederr wrote:

```suggestion
assert(E->getTypeOfArgument()->isSizelessVectorType());
return this->emitSizelessVectorElementSize(E);
```

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


[clang] [Clang][Interp] Diagnose use sizeless vector type as the argument of `__builtin_vectorelements` (PR #99794)

2024-07-21 Thread Timm Baeder via cfe-commits


@@ -29,6 +29,7 @@
 #include "State.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
+#include "clang/Basic/DiagnosticSema.h"

tbaederr wrote:

What do we need this include for?

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-17 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Thanks for all the help with this issue. I think I figured it out - there was 
an unsigned wraparound some time before doing the actual allocation, which 
caused us to write over the bounds of the allocation. I've pushed 
https://github.com/llvm/llvm-project/commit/72b3d7bc87019ba7ef268ce322f90382f01b11af
 to ensure this doesn't happen and 
https://github.com/llvm/llvm-project/commit/e94e72a0c2293a02ea6c5335ac5fbc2d34de13f1
 to implement the dynamic allocation management.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-16 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> I know there is UB in there 
> (https://github.com/llvm/llvm-project/issues/94741) so this is not 
> unsurprising.

Ah, interesting. Didn't know about that issue

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-16 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> You can also try it under qemu - 
> https://linaro.atlassian.net/wiki/spaces/TCWGPUB/pages/29360783374/How+to+Reproduce+32+bit+Arm+Builds+Without+Hardware.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-14 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-14 Thread Timm Baeder via cfe-commits

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

>From 8825030bcb7f2249fbc37a9911b8b5a7afc56d15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/Compiler.cpp  | 103 +
 clang/lib/AST/Interp/Compiler.h|   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 118 +
 clang/lib/AST/Interp/DynamicAllocator.h|  96 
 clang/lib/AST/Interp/EvalEmitter.cpp   |  23 +
 clang/lib/AST/Interp/EvaluationResult.cpp  |  72 +++
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  52 +++
 clang/lib/AST/Interp/Interp.h  | 151 +++
 clang/lib/AST/Interp/InterpBlock.h |  11 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 488 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  24 +-
 19 files changed, 1196 insertions(+), 8 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index ceaad8d3c5a86..70aecb781c2ff 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/Compiler.cpp 
b/clang/lib/AST/Interp/Compiler.cpp
index 30dc7f5e4840b..1f43f46c399f1 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -2771,6 +2771,109 @@ bool Compiler::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:
+//
+//   new (std::align_val_t{N}) X(int)
+//
+// (which should presumably be valid only if N is a multiple of
+// alignof(int), and in any case can't be deallocated unless N is
+// alignof(X) and X has new-extended alignment).
+if (PlacementArgs != 1 || !E->getPlacementArg(0)->getType()->isNothrowT())
+  return this->emitInvalid(E);
+
+if (!this->discard(E->getPlacementArg(0)))
+  return false;
+IsNoThrow = true;
+  }
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
+return false;
+}
+
+if (Init && !this->visitInitializer(Init))
+  return false;
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  

[clang] [clang] [Diagnostic] Clarify -Winfinite-recursion message (PR #98763)

2024-07-13 Thread Timm Baeder via cfe-commits

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


[clang] [clang] Emit bad shift warnings (PR #70307)

2024-07-10 Thread Timm Baeder via cfe-commits

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


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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-10 Thread Timm Baeder via cfe-commits


@@ -2771,6 +2771,109 @@ bool Compiler::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:

tbaederr wrote:

Yep, I saw. I'll wait for @cor3ntin to come up with the test cases though :)

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-09 Thread Timm Baeder via cfe-commits

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

>From 0731875f41bff19e228b0c31700293ed3379 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/Compiler.cpp  | 103 +
 clang/lib/AST/Interp/Compiler.h|   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 118 +
 clang/lib/AST/Interp/DynamicAllocator.h|  96 
 clang/lib/AST/Interp/EvalEmitter.cpp   |  23 +
 clang/lib/AST/Interp/EvaluationResult.cpp  |  72 +++
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  52 +++
 clang/lib/AST/Interp/Interp.h  | 151 +++
 clang/lib/AST/Interp/InterpBlock.h |  11 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +-
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 488 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  24 +-
 19 files changed, 1195 insertions(+), 9 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index ceaad8d3c5a86..70aecb781c2ff 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/Compiler.cpp 
b/clang/lib/AST/Interp/Compiler.cpp
index 48e7519f8f89d..4ac0e01df5768 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -2771,6 +2771,109 @@ bool Compiler::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:
+//
+//   new (std::align_val_t{N}) X(int)
+//
+// (which should presumably be valid only if N is a multiple of
+// alignof(int), and in any case can't be deallocated unless N is
+// alignof(X) and X has new-extended alignment).
+if (PlacementArgs != 1 || !E->getPlacementArg(0)->getType()->isNothrowT())
+  return this->emitInvalid(E);
+
+if (!this->discard(E->getPlacementArg(0)))
+  return false;
+IsNoThrow = true;
+  }
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
+return false;
+}
+
+if (Init && !this->visitInitializer(Init))
+  return false;
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+ 

[clang] [clang-tools-extra] [compiler-rt] clang::Linkage #71049 (PR #80064)

2024-07-04 Thread Timm Baeder via cfe-commits

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


[clang] Refactor clang::Linkage (PR #80063)

2024-07-04 Thread Timm Baeder via cfe-commits

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


[clang] [Parser][ObjC] Add -Wobjc-prefix-length warning option. (PR #97597)

2024-07-04 Thread Timm Baeder via cfe-commits


@@ -204,6 +204,89 @@ void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
 Diag(Decl->getBeginLoc(), diag::note_objc_container_start) << (int)ock;
 }
 
+/// An Objective-C public name (a class name or protocol name) is
+/// expected to have a prefix as all names are in a single global
+/// namespace.
+///
+/// If the `-Wobjc-prefix=` option is active, it specifies a list
+/// of permitted prefixes; classes and protocols must start with a
+/// prefix from that list.  Note that in this case, we check that
+/// the name matches (?)?, so e.g.
+/// if you specify `-Wobjc-prefix=NS`, then `NSURL` would not be valid;
+/// you would want to specify `-Wobjc-prefix=NS,NSURL` in that case.
+///
+/// If the -Wobjc-prefix-length is set to N, the name must start
+/// with N+1 capital letters, which must be followed by a character
+/// that is not a capital letter.
+///
+/// For instance, for N set to 2, the following are valid:
+///
+///  NSString
+///  NSArray
+///
+///  but these are not:
+///
+///  MyString
+///  NSKString
+///  NSnotAString
+///
+/// We make a special exception for NSCF things when the prefix is set
+/// to length 2, because that's an unusual special case in the implementation
+/// of the Cocoa frameworks.
+///
+/// Names that start with underscores are exempt from this check, but
+/// are reserved for the system and should not be used by user code.
+bool Parser::isObjCPublicNamePrefixAllowed(StringRef name) {

tbaederr wrote:

Newly introduced  parameters and variables should start with an uppercase 
letter.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-07-04 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/70306

>From a2213c595637d63b48658d2532e00b08fd05427f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 4 Jul 2024 07:26:27 +0200
Subject: [PATCH 1/2] [clang][Interp] Fix init chain in local initializers

---
 clang/lib/AST/Interp/Compiler.cpp |  4 +++-
 clang/test/AST/Interp/records.cpp | 12 
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/Compiler.cpp 
b/clang/lib/AST/Interp/Compiler.cpp
index 775cabf7f8c59..2af4c38c5ac3d 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -3577,6 +3577,7 @@ VarCreationState Compiler::visitVarDecl(const 
VarDecl *VD, bool Topleve
 return !Init || (checkDecl() && initGlobal(*GlobalIndex));
   } else {
 VariableScope LocalScope(this, VD);
+InitLinkScope ILS(this, InitLink::Decl(VD));
 
 if (VarT) {
   unsigned Offset = this->allocateLocalPrimitive(
@@ -3911,7 +3912,8 @@ bool Compiler::VisitCXXDefaultInitExpr(const 
CXXDefaultInitExpr *E) {
   SourceLocScope SLS(this, E);
 
   bool Old = InitStackActive;
-  InitStackActive = !isa(E->getUsedContext());
+  InitStackActive =
+  !(E->getUsedContext()->getDeclKind() == Decl::CXXConstructor);
   bool Result = this->delegate(E->getExpr());
   InitStackActive = Old;
   return Result;
diff --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index 9f341f5bc6d1d..1554e54275598 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1482,3 +1482,15 @@ namespace FloatAPValue {
   ClassTemplateArgRefTemplate ClassTemplateArgRefObj;
 }
 #endif
+
+namespace LocalWithThisPtrInit {
+  struct S {
+int i;
+int *p = 
+  };
+  constexpr int foo() {
+S s{2};
+return *s.p;
+  }
+  static_assert(foo() == 2, "");
+}

>From 43f20bfd68556d7ba246f90599345077488c6a92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH 2/2] [clang][Interp] Implement dynamic memory allocation
 handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/Compiler.cpp  | 103 +
 clang/lib/AST/Interp/Compiler.h|   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 118 +
 clang/lib/AST/Interp/DynamicAllocator.h|  96 
 clang/lib/AST/Interp/EvalEmitter.cpp   |  23 +
 clang/lib/AST/Interp/EvaluationResult.cpp  |  72 +++
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  52 +++
 clang/lib/AST/Interp/Interp.h  | 151 +++
 clang/lib/AST/Interp/InterpBlock.h |  11 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +-
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 488 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  22 +-
 19 files changed, 1193 insertions(+), 9 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index ceaad8d3c5a86..70aecb781c2ff 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/Compiler.cpp 
b/clang/lib/AST/Interp/Compiler.cpp
index 2af4c38c5ac3d..7ffec61e01d1d 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -2756,6 +2756,109 @@ bool Compiler::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:
+//
+//   new (std::align_val_t{N}) X(int)
+//
+// (which should presumably be valid only if N is a multiple of
+// alignof(int), and 

[clang] [Clang][ExprConstant] fix constant expression did not evaluate to integer (PR #97146)

2024-06-29 Thread Timm Baeder via cfe-commits


@@ -15858,7 +15858,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, 
Expr::EvalResult ,
   }
 
   if (const auto *CE = dyn_cast(Exp)) {
-if (CE->hasAPValueResult()) {
+if (CE->hasAPValueResult() && !CE->getAPValueResult().isLValue()) {

tbaederr wrote:

It looks like `ConstantExpr::getAPValueResult()` will sometimes create a new 
APValue, so we should try ti call `getAPValueResult()` only once.

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


[clang] [clang] Implement function pointer type discrimination (PR #96992)

2024-06-28 Thread Timm Baeder via cfe-commits


@@ -2220,6 +2220,11 @@ llvm::Constant 
*ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) {
 
   // The assertions here are all checked by Sema.
   assert(Result.Val.isLValue());
+  const auto *Base = Result.Val.getLValueBase().get();
+  if (const auto *Decl = dyn_cast_or_null(Base)) {

tbaederr wrote:

```suggestion
  if (const auto *Decl = dyn_cast_if_present(Base)) {
```

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


[clang] [clang][Interp] Merge ByteCodeExprGen and ByteCodeStmtGen (PR #83683)

2024-06-27 Thread Timm Baeder via cfe-commits

tbaederr wrote:

That failure looks like it's just a case of 
https://github.com/llvm/llvm-project/issues/54972

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


[clang] [clang][Interp] Merge ByteCodeExprGen and ByteCodeStmtGen (PR #83683)

2024-06-27 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Merge ByteCodeExprGen and ByteCodeStmtGen (PR #83683)

2024-06-27 Thread Timm Baeder via cfe-commits

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

>From 74550f244eed465d4f0db1787eecb73a09d5881a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 2 Mar 2024 17:00:26 +0100
Subject: [PATCH] [clang][Interp] Merge ByteCode{Stmt,Expr}Gen

---
 clang/lib/AST/CMakeLists.txt  |3 +-
 clang/lib/AST/Interp/ByteCodeStmtGen.cpp  |  734 
 clang/lib/AST/Interp/ByteCodeStmtGen.h|   91 --
 .../{ByteCodeExprGen.cpp => Compiler.cpp} | 1002 ++---
 .../Interp/{ByteCodeExprGen.h => Compiler.h}  |   93 +-
 clang/lib/AST/Interp/Context.cpp  |   13 +-
 clang/lib/AST/Interp/EvalEmitter.h|1 +
 clang/lib/AST/Interp/Program.cpp  |1 -
 8 files changed, 911 insertions(+), 1027 deletions(-)
 delete mode 100644 clang/lib/AST/Interp/ByteCodeStmtGen.cpp
 delete mode 100644 clang/lib/AST/Interp/ByteCodeStmtGen.h
 rename clang/lib/AST/Interp/{ByteCodeExprGen.cpp => Compiler.cpp} (81%)
 rename clang/lib/AST/Interp/{ByteCodeExprGen.h => Compiler.h} (87%)

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 0328666d59b1f..ceaad8d3c5a86 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -65,8 +65,7 @@ add_clang_library(clangAST
   FormatString.cpp
   InheritViz.cpp
   Interp/ByteCodeEmitter.cpp
-  Interp/ByteCodeExprGen.cpp
-  Interp/ByteCodeStmtGen.cpp
+  Interp/Compiler.cpp
   Interp/Context.cpp
   Interp/Descriptor.cpp
   Interp/Disasm.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
deleted file mode 100644
index 0618ec1aa8f58..0
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ /dev/null
@@ -1,734 +0,0 @@
-//===--- ByteCodeStmtGen.cpp - Code generator for expressions ---*- 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
-//
-//===--===//
-
-#include "ByteCodeStmtGen.h"
-#include "ByteCodeEmitter.h"
-#include "Context.h"
-#include "Function.h"
-#include "PrimType.h"
-
-using namespace clang;
-using namespace clang::interp;
-
-namespace clang {
-namespace interp {
-
-/// Scope managing label targets.
-template  class LabelScope {
-public:
-  virtual ~LabelScope() {  }
-
-protected:
-  LabelScope(ByteCodeStmtGen *Ctx) : Ctx(Ctx) {}
-  /// ByteCodeStmtGen instance.
-  ByteCodeStmtGen *Ctx;
-};
-
-/// Sets the context for break/continue statements.
-template  class LoopScope final : public LabelScope {
-public:
-  using LabelTy = typename ByteCodeStmtGen::LabelTy;
-  using OptLabelTy = typename ByteCodeStmtGen::OptLabelTy;
-
-  LoopScope(ByteCodeStmtGen *Ctx, LabelTy BreakLabel,
-LabelTy ContinueLabel)
-  : LabelScope(Ctx), OldBreakLabel(Ctx->BreakLabel),
-OldContinueLabel(Ctx->ContinueLabel) {
-this->Ctx->BreakLabel = BreakLabel;
-this->Ctx->ContinueLabel = ContinueLabel;
-  }
-
-  ~LoopScope() {
-this->Ctx->BreakLabel = OldBreakLabel;
-this->Ctx->ContinueLabel = OldContinueLabel;
-  }
-
-private:
-  OptLabelTy OldBreakLabel;
-  OptLabelTy OldContinueLabel;
-};
-
-// Sets the context for a switch scope, mapping labels.
-template  class SwitchScope final : public LabelScope {
-public:
-  using LabelTy = typename ByteCodeStmtGen::LabelTy;
-  using OptLabelTy = typename ByteCodeStmtGen::OptLabelTy;
-  using CaseMap = typename ByteCodeStmtGen::CaseMap;
-
-  SwitchScope(ByteCodeStmtGen *Ctx, CaseMap &,
-  LabelTy BreakLabel, OptLabelTy DefaultLabel)
-  : LabelScope(Ctx), OldBreakLabel(Ctx->BreakLabel),
-OldDefaultLabel(this->Ctx->DefaultLabel),
-OldCaseLabels(std::move(this->Ctx->CaseLabels)) {
-this->Ctx->BreakLabel = BreakLabel;
-this->Ctx->DefaultLabel = DefaultLabel;
-this->Ctx->CaseLabels = std::move(CaseLabels);
-  }
-
-  ~SwitchScope() {
-this->Ctx->BreakLabel = OldBreakLabel;
-this->Ctx->DefaultLabel = OldDefaultLabel;
-this->Ctx->CaseLabels = std::move(OldCaseLabels);
-  }
-
-private:
-  OptLabelTy OldBreakLabel;
-  OptLabelTy OldDefaultLabel;
-  CaseMap OldCaseLabels;
-};
-
-} // namespace interp
-} // namespace clang
-
-template 
-bool ByteCodeStmtGen::emitLambdaStaticInvokerBody(
-const CXXMethodDecl *MD) {
-  assert(MD->isLambdaStaticInvoker());
-  assert(MD->hasBody());
-  assert(cast(MD->getBody())->body_empty());
-
-  const CXXRecordDecl *ClosureClass = MD->getParent();
-  const CXXMethodDecl *LambdaCallOp = ClosureClass->getLambdaCallOperator();
-  assert(ClosureClass->captures_begin() == ClosureClass->captures_end());
-  const Function *Func = this->getFunction(LambdaCallOp);
-  if (!Func)
-return false;
-  assert(Func->hasThisPointer());
-  assert(Func->getNumParams() == (MD->getNumParams() + 1 + 

[clang] Performance optimizations for function effects (nonblocking attribute etc.) (PR #96844)

2024-06-26 Thread Timm Baeder via cfe-commits

tbaederr wrote:

I guess you meant to link to 
https://llvm-compile-time-tracker.com/compare.php?from=f03cb005eb4ba3c6fb645aca2228e907db8cd452=038b39d3235c6c8151127c34d34f498dd298273c=instructions:u
 directly?

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


[clang] [clang][test] Enable a commented-out test (PR #96195)

2024-06-21 Thread Timm Baeder via cfe-commits

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


[clang] Clang: Support minimumnum and maximumnum intrinsics (PR #96281)

2024-06-21 Thread Timm Baeder via cfe-commits


@@ -215,6 +215,18 @@ def FminF16F128 : Builtin, F16F128MathTemplate {
   let Prototype = "T(T, T)";
 }
 
+def FmaximumNumF16F128 : Builtin, F16F128MathTemplate {
+  let Spellings = ["__builtin_fmaximum_num"];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
+  let Prototype = "T(T, T)";
+}
+
+def FminimumNumF16F128 : Builtin, F16F128MathTemplate {
+  let Spellings = ["__builtin_fminimum_num"];
+  let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];

tbaederr wrote:

Where's the constexpr implementation?

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


[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2024-06-21 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> I tried out this WIP on our codebase after we ran into a problem where an 
> annotation was added to a definition rather than a declaration, leading to a 
> (silently) missed capability check.
> 
> This addition seems to work fine, but it triggers warnings when annotations 
> are added to both the definition and declaration. This can be seen here: 
> [bitcoin/bitcoin#30316](https://github.com/bitcoin/bitcoin/pull/30316)
> 
> I went ahead and PR'd the removals because they're straightforward enough, 
> but it seems (to me) that those these are all false positives. If the same 
> annotation is listed in the declaration and definition, should it really warn?

No I don't think it should, at least that was not the intention of this patch. 
As it is right now, the code should warn for attributes listed in the 
definition, but _now_ in the declaration(s).

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


[clang] [clang-tools-extra] Reland [clang][Sema, Lex, Parse] Preprocessor embed in C and C++ (PR #95802)

2024-06-20 Thread Timm Baeder via cfe-commits

tbaederr wrote:

I just pushed 
https://github.com/llvm/llvm-project/commit/99f5fcb0d1e04125daa404ff14c9cd14b7a2c40b
 - I don't have time to run _all_ the tests though, so this is a bit of a long 
shot. If that doesn't  fix it, then disabling them for now sounds fine to me.

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


[clang] [clang-tools-extra] Reland [clang][Sema, Lex, Parse] Preprocessor embed in C and C++ (PR #95802)

2024-06-20 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Here's a quick patch with the cast inserted: 

```diff
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 731153a6ead9..e7fa1a62c277 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1346,13 +1346,30 @@ bool 
ByteCodeExprGen::visitInitList(ArrayRef Inits,
   }
 }

-auto Eval = [&](Expr *Init, unsigned ElemIndex) {
-  return visitArrayElemInit(ElemIndex, Init);
-};
-
+E->dump();
 unsigned ElementIndex = 0;
 for (const Expr *Init : Inits) {
-  if (auto *EmbedS = dyn_cast(Init->IgnoreParenImpCasts())) {
+  if (const auto *EmbedS = 
dyn_cast(Init->IgnoreParenImpCasts())) {
+QualType TargetType = Init->getType();
+PrimType TargetT = classifyPrim(Init->getType());
+TargetType->dump();
+
+
+auto Eval = [&](const Expr *Init, unsigned ElemIndex) {
+  PrimType InitT = classifyPrim(Init->getType());
+  if (!this->visit(Init))
+return false;
+  if (InitT != TargetT) {
+if (!this->emitCast(InitT, TargetT, E))
+  return false;
+  }
+return this->emitInitElem(TargetT, ElemIndex, Init);
+};
+
+
+
+
+
 if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
   return false;
   } else {
```

Can you check if that fixes the problem?

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


[clang] [clang-tools-extra] Reland [clang][Sema, Lex, Parse] Preprocessor embed in C and C++ (PR #95802)

2024-06-20 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Do you have a smaller reproducer? Are all the failing build bots big endian?

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


[clang] [clang][test] Enable a commented-out test (PR #96195)

2024-06-20 Thread Timm Baeder via cfe-commits

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


[clang] [clang][test] Enable a commented-out test (PR #96195)

2024-06-20 Thread Timm Baeder via cfe-commits

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

I can't reproduce the assertion failure locally, let's see that the precommit 
CI says about it.

>From 4aa4c6cb272852cbaa48267d8e21463d14d3309f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 20 Jun 2024 16:20:51 +0200
Subject: [PATCH] [clang][test] Enable a commented-out test

---
 clang/test/CodeGenCXX/temporaries.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/test/CodeGenCXX/temporaries.cpp 
b/clang/test/CodeGenCXX/temporaries.cpp
index 186f4934873fa..f992ce206c581 100644
--- a/clang/test/CodeGenCXX/temporaries.cpp
+++ b/clang/test/CodeGenCXX/temporaries.cpp
@@ -683,8 +683,7 @@ namespace Vector {
   // CHECK: store i32 {{.*}}, ptr @_ZGRN6Vector1sE_
   // CHECK: store ptr @_ZGRN6Vector1sE_, ptr @_ZN6Vector1sE,
   int & = S().w[1];
-  // FIXME PR16204: The following code leads to an assertion in Sema.
-  //int & = S().w.y;
+  int & = S().w.y;
 }
 
 namespace ImplicitTemporaryCleanup {

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits

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

>From 34b15ca688eef0fd0c23298957faaa6342d15cfd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp   | 103 +
 clang/lib/AST/Interp/ByteCodeExprGen.h |   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 118 +
 clang/lib/AST/Interp/DynamicAllocator.h|  95 
 clang/lib/AST/Interp/EvalEmitter.cpp   |  23 +
 clang/lib/AST/Interp/EvaluationResult.cpp  |  72 +++
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  52 +++
 clang/lib/AST/Interp/Interp.h  | 149 +++
 clang/lib/AST/Interp/InterpBlock.h |  21 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +-
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 488 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  22 +-
 19 files changed, 1196 insertions(+), 13 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 0328666d59b1f..df27f1239abe4 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -76,6 +76,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 06e54e4baaaf5..4eb258c12cafd 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2656,6 +2656,109 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:
+//
+//   new (std::align_val_t{N}) X(int)
+//
+// (which should presumably be valid only if N is a multiple of
+// alignof(int), and in any case can't be deallocated unless N is
+// alignof(X) and X has new-extended alignment).
+if (PlacementArgs != 1 || !E->getPlacementArg(0)->getType()->isNothrowT())
+  return this->emitInvalid(E);
+
+if (!this->discard(E->getPlacementArg(0)))
+  return false;
+IsNoThrow = true;
+  }
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
+return false;
+}
+
+if (Init && !this->visitInitializer(Init))
+  return false;
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if 

[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2024-06-19 Thread Timm Baeder via cfe-commits

tbaederr wrote:

I've resorted to do this in `ThreadSafety.cpp` now, since all other places 
where we merge function definition and declaration happen before we have the 
late-parsed attributes available.

>From a diagnostic POV, this seems quite complicated since we have N 
>declarations and need to report differences in M attributes (and each one of 
>them can have >=1 parameter...). For the POC implementation here, I've left if 
>with just reporting a mismatch in attributes. For example with 
>`test/SemaCXX/warn-thread-safety-analysis.cpp`:
```console
error: 'expected-warning' diagnostics seen but not expected:
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 2171: attribute mismatch between function definition and declaration of 
'foo2'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 2172: attribute mismatch between function definition and declaration of 
'foo3'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line : attribute mismatch between function definition and declaration of 
'fooF2'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 3182: attribute mismatch between function definition and declaration of 
'foo1'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 3183: attribute mismatch between function definition and declaration of 
'foo2'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 5220: attribute mismatch between function definition and declaration of 
'test'
  File 
/home/tbaeder/code/llvm-project/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
 Line 5221: attribute mismatch between function definition and declaration of 
'test2'

```

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


[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2024-06-19 Thread Timm Baeder via cfe-commits

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

>From 800ce47e967593ec149e0187abf6d2cb3ee1b1b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 20 Jun 2024 07:39:20 +0200
Subject: [PATCH] Warn on RequiresCapability attribute mismatch

---
 .../clang/Analysis/Analyses/ThreadSafety.h|  4 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++-
 clang/lib/Analysis/ThreadSafety.cpp   | 34 +++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  7 
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h 
b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
index 0866b09bab299..169eef811f579 100644
--- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -26,6 +26,7 @@ namespace clang {
 class AnalysisDeclContext;
 class FunctionDecl;
 class NamedDecl;
+class Attr;
 
 namespace threadSafety {
 
@@ -230,6 +231,9 @@ class ThreadSafetyHandler {
   /// Warn that there is a cycle in acquired_before/after dependencies.
   virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {}
 
+  virtual void handleAttributeMismatch(const FunctionDecl *FD1,
+   const FunctionDecl *FD2) {}
+
   /// Called by the analysis when starting analysis of a function.
   /// Used to issue suggestions for changes to annotations.
   virtual void enterFunction(const FunctionDecl *FD) {}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 14736784cff5f..4e8e6f66ebc8f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3978,7 +3978,9 @@ def warn_acquired_before : Warning<
 def warn_acquired_before_after_cycle : Warning<
   "cycle in acquired_before/after dependencies, starting with '%0'">,
   InGroup, DefaultIgnore;
-
+def warn_attribute_mismatch : Warning<
+  "attribute mismatch between function definition and declaration of %0">,
+  InGroup, DefaultIgnore;
 
 // Thread safety warnings negative capabilities
 def warn_acquire_requires_negative_cap : Warning<
diff --git a/clang/lib/Analysis/ThreadSafety.cpp 
b/clang/lib/Analysis/ThreadSafety.cpp
index e25b843c9bf83..6051a5e9d6bd9 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -2260,6 +2260,37 @@ static bool neverReturns(const CFGBlock *B) {
   return false;
 }
 
+template 
+static SmallVector collectAttrArgs(const FunctionDecl *FD) {
+  SmallVector Args;
+  for (const AttrT *A : FD->specific_attrs()) {
+for (const Expr *E : A->args())
+  Args.push_back(E);
+  }
+
+  return Args;
+}
+
+static void diagnoseMismatchedFunctionAttrs(const FunctionDecl *FD,
+ThreadSafetyHandler ) {
+  assert(FD);
+  FD = FD->getDefinition();
+  assert(FD);
+  auto FDArgs = collectAttrArgs(FD);
+
+  for (const FunctionDecl *D = FD->getPreviousDecl(); D;
+   D = D->getPreviousDecl()) {
+auto DArgs = collectAttrArgs(D);
+
+for (const Expr *E : FDArgs) {
+  if (!llvm::is_contained(DArgs, E)) {
+// FD requires E, but D doesn't.
+Handler.handleAttributeMismatch(FD, D);
+  }
+}
+  }
+}
+
 /// Check a function's CFG for thread-safety violations.
 ///
 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
@@ -2279,6 +2310,9 @@ void 
ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext ) {
   const NamedDecl *D = walker.getDecl();
   CurrentFunction = dyn_cast(D);
 
+  if (CurrentFunction)
+diagnoseMismatchedFunctionAttrs(CurrentFunction, Handler);
+
   if (D->hasAttr())
 return;
 
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 0f604c61fa3af..02d60a803d77a 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2073,6 +2073,13 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
+  void handleAttributeMismatch(const FunctionDecl *FD1,
+   const FunctionDecl *FD2) override {
+PartialDiagnosticAt Warning(FD2->getLocation(),
+S.PDiag(diag::warn_attribute_mismatch) << FD1);
+Warnings.emplace_back(std::move(Warning), getNotes());
+  }
+
   void enterFunction(const FunctionDecl* FD) override {
 CurrentFunction = FD;
   }

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits

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

>From c36e40f5454ebb50e8ec6b83d50ac988f8aa780c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp   | 103 +
 clang/lib/AST/Interp/ByteCodeExprGen.h |   2 +
 clang/lib/AST/Interp/Context.cpp   |   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 118 +
 clang/lib/AST/Interp/DynamicAllocator.h|  95 
 clang/lib/AST/Interp/EvalEmitter.cpp   |  23 +
 clang/lib/AST/Interp/EvaluationResult.cpp  |  72 +++
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  52 +++
 clang/lib/AST/Interp/Interp.h  | 149 +++
 clang/lib/AST/Interp/InterpBlock.h |  21 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +-
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 488 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  22 +-
 20 files changed, 1198 insertions(+), 13 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 0328666d59b1f..df27f1239abe4 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -76,6 +76,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 06e54e4baaaf5..4eb258c12cafd 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2656,6 +2656,109 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+  unsigned PlacementArgs = E->getNumPlacementArgs();
+  bool IsNoThrow = false;
+
+  // FIXME: Better diagnostic. diag::note_constexpr_new_placement
+  if (PlacementArgs != 0) {
+// The only new-placement list we support is of the form (std::nothrow).
+//
+// FIXME: There is no restriction on this, but it's not clear that any
+// other form makes any sense. We get here for cases such as:
+//
+//   new (std::align_val_t{N}) X(int)
+//
+// (which should presumably be valid only if N is a multiple of
+// alignof(int), and in any case can't be deallocated unless N is
+// alignof(X) and X has new-extended alignment).
+if (PlacementArgs != 1 || !E->getPlacementArg(0)->getType()->isNothrowT())
+  return this->emitInvalid(E);
+
+if (!this->discard(E->getPlacementArg(0)))
+  return false;
+IsNoThrow = true;
+  }
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, IsNoThrow, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, IsNoThrow, E))
+return false;
+}
+
+if (Init && !this->visitInitializer(Init))
+  return false;
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else 

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -2544,6 +2544,85 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);

tbaederr wrote:

Added support for the `std::nothrow` version of it + tests

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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

>From 02256cbbd7860d788d86864e83ec2ddcedb9f0ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 18 Jun 2024 16:45:15 +0200
Subject: [PATCH 1/4] Fixup! --

---
 .../clang/Analysis/Analyses/ThreadSafety.h|  2 +
 clang/lib/Analysis/ThreadSafety.cpp   | 42 +++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  5 +++
 3 files changed, 49 insertions(+)

diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h 
b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
index 0866b09bab299..79c6f5959afe4 100644
--- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -230,6 +230,8 @@ class ThreadSafetyHandler {
   /// Warn that there is a cycle in acquired_before/after dependencies.
   virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {}
 
+  virtual void handleAttributeMismatch() {}
+
   /// Called by the analysis when starting analysis of a function.
   /// Used to issue suggestions for changes to annotations.
   virtual void enterFunction(const FunctionDecl *FD) {}
diff --git a/clang/lib/Analysis/ThreadSafety.cpp 
b/clang/lib/Analysis/ThreadSafety.cpp
index e25b843c9bf83..a42c4ca98ea9b 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -2260,6 +2260,45 @@ static bool neverReturns(const CFGBlock *B) {
   return false;
 }
 
+template
+static SmallVector collectAttrArgs(const FunctionDecl *FD) {
+SmallVectorArgs;
+for (const AttrT *A : FD->specific_attrs()) {
+  for (const Expr *E : A->args())
+Args.push_back(E);
+}
+
+return Args;
+}
+
+static void diagnoseMismatchedFunctionAttrs(const FunctionDecl *FD, 
ThreadSafetyHandler ) {
+  llvm::errs() << __PRETTY_FUNCTION__ << "\n";
+  assert(FD);
+  FD = FD->getDefinition();
+  assert(FD);
+
+  FD->dump();
+
+  auto FDArgs = collectAttrArgs(FD);
+
+  for (const FunctionDecl *D = FD->getPreviousDecl(); D; D = 
D->getPreviousDecl()) {
+D->dump();
+auto DArgs = collectAttrArgs(D);
+
+llvm::errs() << "FD Args: " << FDArgs.size() << "\n";
+llvm::errs() << " D Args: " << DArgs.size() << "\n";
+
+for (const Expr *E : FDArgs) {
+  if (!llvm::is_contained(DArgs, E)) {
+// FD requires E, but D doesn't.
+llvm::errs() << "OMG\n";
+Handler.handleAttributeMismatch();
+  }
+}
+llvm::errs() << "---\n";
+  }
+}
+
 /// Check a function's CFG for thread-safety violations.
 ///
 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
@@ -2279,6 +2318,9 @@ void 
ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext ) {
   const NamedDecl *D = walker.getDecl();
   CurrentFunction = dyn_cast(D);
 
+  if (CurrentFunction)
+diagnoseMismatchedFunctionAttrs(CurrentFunction, Handler);
+
   if (D->hasAttr())
 return;
 
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 0f604c61fa3af..9eac80603ff88 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2073,6 +2073,11 @@ class ThreadSafetyReporter : public 
clang::threadSafety::ThreadSafetyHandler {
 Warnings.emplace_back(std::move(Warning), getNotes());
   }
 
+  void handleAttributeMismatch() override {
+llvm::errs() << __PRETTY_FUNCTION__ << "\n";
+
+  }
+
   void enterFunction(const FunctionDecl* FD) override {
 CurrentFunction = FD;
   }

>From 837ad17e1b1cc2465cd24bebbf5187e430310049 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 18 Jun 2024 20:42:18 +0200
Subject: [PATCH 2/4] [clang][Interp][NFC] Fix initializing union APValues

The InitElem op assumes an array.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d47f6f23c8bc1..61a7394854d40 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3507,7 +3507,7 @@ bool 
ByteCodeExprGen::visitAPValueInitializer(const APValue ,
 PrimType T = classifyPrim(RF->Decl->getType());
 if (!this->visitAPValue(F, T, E))
   return false;
-return this->emitInitElem(T, 0, E);
+return this->emitInitField(T, RF->Offset, E);
   }
   // TODO: Other types.
 

>From ff5713200186b909b55cdc55321f0e25464a1af0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 19 Jun 2024 10:09:06 +0200
Subject: [PATCH 3/4] [clang][Interp][NFC] Loosen an assertion

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits


@@ -2544,6 +2544,85 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)

tbaederr wrote:

That works, we're getting the size expr from the `CXXNewExpr`.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-19 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-18 Thread Timm Baeder via cfe-commits


@@ -0,0 +1,119 @@
+//== DynamicAllocator.cpp - Dynamic allocations --*- 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
+//
+//===--===//
+
+#include "DynamicAllocator.h"
+#include "InterpBlock.h"
+#include "InterpState.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+DynamicAllocator::~DynamicAllocator() { cleanup(); }
+
+void DynamicAllocator::cleanup() {
+  // Invoke destructors of all the blocks and as a last restort,
+  // reset all the pointers pointing to them to null pointees.
+  // This should never show up in diagnostics, but it's necessary
+  // for us to not cause use-after-free problems.
+  for (auto  : AllocationSites) {
+auto  = Iter.second;
+for (auto  : AllocSite.Allocations) {
+  Block *B = reinterpret_cast(Alloc.Memory.get());
+  B->invokeDtor();
+  if (B->hasPointers()) {
+while (B->Pointers) {
+  Pointer *Next = B->Pointers->Next;
+  B->Pointers->PointeeStorage.BS.Pointee = nullptr;
+  B->Pointers = Next;
+}
+B->Pointers = nullptr;
+  }
+}
+  }
+
+  AllocationSites.clear();
+}
+
+Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
+  /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, 
NumElements,
+  /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *D) {
+  assert(D->asExpr());
+
+  auto Memory =
+  std::make_unique(sizeof(Block) + D->getAllocSize());
+  auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
+  B->invokeCtor();
+
+  InlineDescriptor *ID = reinterpret_cast(B->rawData());
+  ID->Desc = D;
+  ID->IsActive = true;
+  ID->Offset = sizeof(InlineDescriptor);
+  ID->IsBase = false;
+  ID->IsFieldMutable = false;
+  ID->IsConst = false;
+  ID->IsInitialized = false;
+  assert(ID->Desc);
+
+  B->IsDynamic = true;
+
+  if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())
+It->second.Allocations.emplace_back(std::move(Memory));
+  else
+AllocationSites.insert(
+{D->asExpr(), AllocationSite(std::move(Memory), D->isArray())});
+  return B;
+}
+
+bool DynamicAllocator::deallocate(const Expr *Source,
+  const Block *BlockToDelete, InterpState ) {
+  auto It = AllocationSites.find(Source);
+  if (It == AllocationSites.end())
+return false;
+
+  auto  = It->second;
+  assert(Site.size() > 0);
+
+  // Find the Block to delete.
+  auto AllocIt = llvm::find_if(Site.Allocations, [&](const Allocation ) {
+const Block *B = reinterpret_cast(A.Memory.get());
+return BlockToDelete == B;
+  });
+
+  assert(AllocIt != Site.Allocations.end());
+
+  Block *B = reinterpret_cast(AllocIt->Memory.get());
+  B->invokeDtor();
+
+  S.deallocate(B);
+  Site.Allocations.erase(AllocIt);
+
+  if (Site.size() == 0)

tbaederr wrote:

`Size.size()` just returns `Size.Allocations.size()`, so this is affected by 
the `erase()` call above.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-18 Thread Timm Baeder via cfe-commits


@@ -2544,6 +2544,85 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+assert(ArraySizeExpr);
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+

tbaederr wrote:

Good catch

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


[clang] [clang] Remove update_options_td_flags.py (PR #95909)

2024-06-18 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Implement complex division (PR #94892)

2024-06-18 Thread Timm Baeder via cfe-commits

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


[clang] [clang] Remove update_options_td_flags.py (PR #95909)

2024-06-18 Thread Timm Baeder via cfe-commits

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

The comment says:

> This script will be removed after the next LLVM release.

but it's still there. Change that.

>From 0137a56765c1486b461c21c36d5977469fd6ffef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 18 Jun 2024 13:47:07 +0200
Subject: [PATCH] [clang] Remove update_options_td_flags.py

The comment says:

> This script will be removed after the next LLVM release.

but it's still there. Change that.
---
 clang/utils/update_options_td_flags.py | 182 -
 1 file changed, 182 deletions(-)
 delete mode 100755 clang/utils/update_options_td_flags.py

diff --git a/clang/utils/update_options_td_flags.py 
b/clang/utils/update_options_td_flags.py
deleted file mode 100755
index 9271b453c3fd6..0
--- a/clang/utils/update_options_td_flags.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/env python3
-"""Update Options.td for the flags changes in https://reviews.llvm.org/Dxyz
-
-This script translates Options.td from using Flags to control option visibility
-to using Vis instead. It is meant to be idempotent and usable to help update
-downstream forks if they have their own changes to Options.td.
-
-Usage:
-```sh
-% update_options_td_flags.py path/to/Options.td > Options.td.new
-% mv Options.td.new path/to/Options.td
-```
-
-This script will be removed after the next LLVM release.
-"""
-
-import argparse
-import re
-import shutil
-import sys
-import tempfile
-
-def rewrite_option_flags(input_file, output_file):
-for src_line in input_file:
-for dst_line in process_line(src_line):
-output_file.write(dst_line)
-
-def process_line(line):
-# We only deal with one thing per line. If multiple things can be
-# on the same line (like NegFlag and PosFlag), please preprocess
-# that first.
-m = re.search(r'((NegFlag|PosFlag)<[A-Za-z]+, |BothFlags<)'
-  r'\[([A-Za-z0-9, ]+)\](, \[ClangOption\]|(?=>))', line)
-if m:
-return process_boolflags(m.group(3), line[:m.end(1)], line[m.end():])
-m = re.search(r'\bFlags<\[([A-Za-z0-9, ]*)\]>', line)
-if m:
-return process_flags(m.group(1), line[:m.start()], line[m.end():])
-m = re.search(r'let Flags = \[([A-Za-z0-9, ]*)\]', line)
-if m:
-return process_letflags(m.group(1), line[:m.start(1)], line[m.end():])
-
-return [line]
-
-def process_boolflags(flag_group, prefix, suffix):
-flags = [f.strip() for f in flag_group.split(',')] if flag_group else []
-if not flags:
-return f'{prefix}[], [ClangOption]{suffix}'
-
-flags_to_keep, vis_mods = translate_flags(flags)
-flag_text = f'[{", ".join(flags_to_keep)}]'
-vis_text = f'[{", ".join(vis_mods)}]'
-new_text = ', '.join([flag_text, vis_text])
-
-if prefix.startswith('Both'):
-indent = ' ' * len(prefix)
-else:
-indent = ' ' * (len(prefix) - len(prefix.lstrip()) + len('XyzFlag<'))
-
-return get_edited_lines(prefix, new_text, suffix, indent=indent)
-
-def process_flags(flag_group, prefix, suffix):
-flags = [f.strip() for f in flag_group.split(',')]
-
-flags_to_keep, vis_mods = translate_flags(flags)
-
-flag_text = ''
-vis_text = ''
-if flags_to_keep:
-flag_text = f'Flags<[{", ".join(flags_to_keep)}]>'
-if vis_mods:
-flag_text += ', '
-if vis_mods:
-vis_text = f'Visibility<[{", ".join(vis_mods)}]>'
-
-return get_edited_lines(prefix, flag_text, vis_text, suffix)
-
-def process_letflags(flag_group, prefix, suffix):
-is_end_comment = prefix.startswith('} //')
-if not is_end_comment and not prefix.startswith('let'):
-raise AssertionError(f'Unusual let block: {prefix}')
-
-flags = [f.strip() for f in flag_group.split(',')]
-
-flags_to_keep, vis_mods = translate_flags(flags)
-
-lines = []
-if flags_to_keep:
-lines += [f'let Flags = [{", ".join(flags_to_keep)}]']
-if vis_mods:
-lines += [f'let Visibility = [{", ".join(vis_mods)}]']
-
-if is_end_comment:
-lines = list(reversed([f'}} // {l}\n' for l in lines]))
-else:
-lines = [f'{l} in {{\n' for l in lines]
-return lines
-
-def get_edited_lines(prefix, *fragments, indent='  '):
-out_lines = []
-current = prefix
-for fragment in fragments:
-if fragment and len(current) + len(fragment) > 80:
-# Make a minimal attempt at reasonable line lengths
-if fragment.startswith(',') or fragment.startswith(';'):
-# Avoid wrapping the , or ; to the new line
-current += fragment[0]
-fragment = fragment[1:].lstrip()
-out_lines += [current.rstrip() + '\n']
-current = max(' ' * (len(current) - len(current.lstrip())), indent)
-current += fragment
-
-if current.strip():
-out_lines += [current]
-return out_lines
-
-def translate_flags(flags):
- 

[clang] [clang][Interp] Implement complex division (PR #94892)

2024-06-18 Thread Timm Baeder via cfe-commits

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

>From 7a1c16f2fe0b23ffe49789275ffa66b2ac64c4d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 9 Jun 2024 09:25:24 +0200
Subject: [PATCH] [clang][Interp] Implement Complex division

---
 clang/lib/AST/ExprConstShared.h  |  3 +
 clang/lib/AST/ExprConstant.cpp   | 76 ++--
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 67 ++---
 clang/lib/AST/Interp/Interp.h| 72 ++
 clang/lib/AST/Interp/Opcodes.td  |  4 ++
 clang/test/AST/Interp/complex.cpp| 15 +
 clang/test/SemaCXX/complex-folding.cpp   |  1 +
 7 files changed, 196 insertions(+), 42 deletions(-)

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
index 9decd47e41767..2a7088e4e371a 100644
--- a/clang/lib/AST/ExprConstShared.h
+++ b/clang/lib/AST/ExprConstShared.h
@@ -62,5 +62,8 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
 void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
  llvm::APFloat D, llvm::APFloat ,
  llvm::APFloat );
+void HandleComplexComplexDiv(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
+ llvm::APFloat D, llvm::APFloat ,
+ llvm::APFloat );
 
 #endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3a6c8b4f82cca..9ac53438de8e4 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15189,6 +15189,48 @@ void HandleComplexComplexMul(APFloat A, APFloat B, 
APFloat C, APFloat D,
   }
 }
 
+void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D,
+ APFloat , APFloat ) {
+  // This is an implementation of complex division according to the
+  // constraints laid out in C11 Annex G. The implementation uses the
+  // following naming scheme:
+  //   (a + ib) / (c + id)
+
+  int DenomLogB = 0;
+  APFloat MaxCD = maxnum(abs(C), abs(D));
+  if (MaxCD.isFinite()) {
+DenomLogB = ilogb(MaxCD);
+C = scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
+D = scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
+  }
+  APFloat Denom = C * C + D * D;
+  ResR =
+  scalbn((A * C + B * D) / Denom, -DenomLogB, 
APFloat::rmNearestTiesToEven);
+  ResI =
+  scalbn((B * C - A * D) / Denom, -DenomLogB, 
APFloat::rmNearestTiesToEven);
+  if (ResR.isNaN() && ResI.isNaN()) {
+if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
+  ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
+  ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
+} else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
+   D.isFinite()) {
+  A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
+A);
+  B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
+B);
+  ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
+  ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
+} else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
+  C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
+C);
+  D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
+D);
+  ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
+  ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
+}
+  }
+}
+
 bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15326,39 +15368,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const 
BinaryOperator *E) {
   // No real optimizations we can do here, stub out with zero.
   B = APFloat::getZero(A.getSemantics());
 }
-int DenomLogB = 0;
-APFloat MaxCD = maxnum(abs(C), abs(D));
-if (MaxCD.isFinite()) {
-  DenomLogB = ilogb(MaxCD);
-  C = scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
-  D = scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
-}
-APFloat Denom = C * C + D * D;
-ResR = scalbn((A * C + B * D) / Denom, -DenomLogB,
-  APFloat::rmNearestTiesToEven);
-ResI = scalbn((B * C - A * D) / Denom, -DenomLogB,
-  APFloat::rmNearestTiesToEven);
-if (ResR.isNaN() && ResI.isNaN()) {
-  if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
-ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
-ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
-  } else if 

[clang] [Clang] [Sema] Ensure noexcept(typeid(E)) checks if E throws when needed (PR #95846)

2024-06-17 Thread Timm Baeder via cfe-commits


@@ -,13 +,18 @@ static CanThrowResult canDynamicCastThrow(const 
CXXDynamicCastExpr *DC) {
 }
 
 static CanThrowResult canTypeidThrow(Sema , const CXXTypeidExpr *DC) {
-  if (DC->isTypeOperand())
+  // Operand is not evaluated, cannot possibly throw
+  if (!DC->isPotentiallyEvaluated())
 return CT_Cannot;
 
   if (DC->isValueDependent())
 return CT_Dependent;
 
-  return DC->hasNullCheck() ? CT_Can : CT_Cannot;
+  // Can throw std::bad_typeid if a nullptr is dereferenced

tbaederr wrote:

```suggestion
  // Can throw std::bad_typeid if a nullptr is dereferenced.
```

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


[clang] [Clang] [Sema] Ensure noexcept(typeid(E)) checks if E throws when needed (PR #95846)

2024-06-17 Thread Timm Baeder via cfe-commits


@@ -,13 +,18 @@ static CanThrowResult canDynamicCastThrow(const 
CXXDynamicCastExpr *DC) {
 }
 
 static CanThrowResult canTypeidThrow(Sema , const CXXTypeidExpr *DC) {
-  if (DC->isTypeOperand())
+  // Operand is not evaluated, cannot possibly throw

tbaederr wrote:

```suggestion
  // Operand is not evaluated, cannot possibly throw.
```

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


[clang] [clang][Interp] Implement Complex-complex multiplication (PR #94891)

2024-06-17 Thread Timm Baeder via cfe-commits

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


[clang] [clang][Interp] Implement Complex-complex multiplication (PR #94891)

2024-06-17 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Implement complex division (PR #94892)

2024-06-17 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/94892
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-12 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)

2024-06-10 Thread Timm Baeder via cfe-commits


@@ -846,6 +846,7 @@ Bug Fixes to C++ Support
 - Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
 - Fixed several bugs in capturing variables within unevaluated contexts. 
(#GH63845), (#GH67260), (#GH69307),
   (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+- Fix a crash when SourceLocExpr instantiated in a dependent context. 
(GH80210).

tbaederr wrote:

```suggestion
- Fix a crash when SourceLocExpr instantiated in a dependent context. 
(#GH80210).
```

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


[clang] [Clang][C++23] update constexpr diagnostics for missing return statements per P2448 (PR #94123)

2024-06-10 Thread Timm Baeder via cfe-commits

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


[clang] [Clang][C++23] update constexpr diagnostics for missing return statements per P2448 (PR #94123)

2024-06-10 Thread Timm Baeder via cfe-commits

tbaederr wrote:

@a-tarasyuk Do you need someone else to merge this?

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


[clang] [clang][Interp] Implement complex division (PR #94892)

2024-06-09 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/94892

>From b89efd9e0e38a6e79130e0a1b9e8d0443654c6c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 9 Mar 2024 17:07:24 +0100
Subject: [PATCH 1/2] [clang][Interp] Implement Complex-complex multiplication

Share the implementation for floating-point complex-complex
multiplication with the current interpreter. This means we need a new
opcode for this, but there's no good way around that.
---
 clang/lib/AST/ExprConstShared.h  |   7 ++
 clang/lib/AST/ExprConstant.cpp   | 106 ---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  55 +---
 clang/lib/AST/Interp/Interp.h|  57 
 clang/lib/AST/Interp/Opcodes.td  |   4 +
 clang/test/AST/Interp/complex.cpp|  31 +++
 6 files changed, 201 insertions(+), 59 deletions(-)

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
index a97eac85abc69..9decd47e41767 100644
--- a/clang/lib/AST/ExprConstShared.h
+++ b/clang/lib/AST/ExprConstShared.h
@@ -14,6 +14,9 @@
 #ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 #define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 
+namespace llvm {
+class APFloat;
+}
 namespace clang {
 class QualType;
 class LangOptions;
@@ -56,4 +59,8 @@ enum class GCCTypeClass {
 GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
  const LangOptions );
 
+void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
+ llvm::APFloat D, llvm::APFloat ,
+ llvm::APFloat );
+
 #endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86fb396fabe2d..7c597a238f041 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15126,6 +15126,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const 
CastExpr *E) {
   llvm_unreachable("unknown cast resulting in complex value");
 }
 
+void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
+ APFloat , APFloat ) {
+  // This is an implementation of complex multiplication according to the
+  // constraints laid out in C11 Annex G. The implementation uses the
+  // following naming scheme:
+  //   (a + ib) * (c + id)
+
+  APFloat AC = A * C;
+  APFloat BD = B * D;
+  APFloat AD = A * D;
+  APFloat BC = B * C;
+  ResR = AC - BD;
+  ResI = AD + BC;
+  if (ResR.isNaN() && ResI.isNaN()) {
+bool Recalc = false;
+if (A.isInfinity() || B.isInfinity()) {
+  A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
+A);
+  B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
+B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (C.isInfinity() || D.isInfinity()) {
+  C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
+C);
+  D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
+D);
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  Recalc = true;
+}
+if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
+BC.isInfinity())) {
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (Recalc) {
+  ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
+  ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
+}
+  }
+}
+
 bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15225,55 +15281,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const 
BinaryOperator *E) {
 !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
   return false;
   } else {
-// In the fully general case, we need to handle NaNs and infinities
-// robustly.
-APFloat AC = A * C;
-APFloat BD = B * D;
-APFloat AD = A * D;
-APFloat BC = B * C;
-ResR = AC - BD;
-ResI = AD + BC;
-if (ResR.isNaN() && ResI.isNaN()) {
-  bool Recalc = false;
-  if (A.isInfinity() || B.isInfinity()) {
-  

[clang] [clang][Interp] Implement complex division (PR #94892)

2024-06-09 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID: 
In-Reply-To:


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

Depends on the multiplication PR.

>From b89efd9e0e38a6e79130e0a1b9e8d0443654c6c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 9 Mar 2024 17:07:24 +0100
Subject: [PATCH 1/2] [clang][Interp] Implement Complex-complex multiplication

Share the implementation for floating-point complex-complex
multiplication with the current interpreter. This means we need a new
opcode for this, but there's no good way around that.
---
 clang/lib/AST/ExprConstShared.h  |   7 ++
 clang/lib/AST/ExprConstant.cpp   | 106 ---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  55 +---
 clang/lib/AST/Interp/Interp.h|  57 
 clang/lib/AST/Interp/Opcodes.td  |   4 +
 clang/test/AST/Interp/complex.cpp|  31 +++
 6 files changed, 201 insertions(+), 59 deletions(-)

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
index a97eac85abc69..9decd47e41767 100644
--- a/clang/lib/AST/ExprConstShared.h
+++ b/clang/lib/AST/ExprConstShared.h
@@ -14,6 +14,9 @@
 #ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 #define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 
+namespace llvm {
+class APFloat;
+}
 namespace clang {
 class QualType;
 class LangOptions;
@@ -56,4 +59,8 @@ enum class GCCTypeClass {
 GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
  const LangOptions );
 
+void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
+ llvm::APFloat D, llvm::APFloat ,
+ llvm::APFloat );
+
 #endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86fb396fabe2d..7c597a238f041 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15126,6 +15126,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const 
CastExpr *E) {
   llvm_unreachable("unknown cast resulting in complex value");
 }
 
+void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
+ APFloat , APFloat ) {
+  // This is an implementation of complex multiplication according to the
+  // constraints laid out in C11 Annex G. The implementation uses the
+  // following naming scheme:
+  //   (a + ib) * (c + id)
+
+  APFloat AC = A * C;
+  APFloat BD = B * D;
+  APFloat AD = A * D;
+  APFloat BC = B * C;
+  ResR = AC - BD;
+  ResI = AD + BC;
+  if (ResR.isNaN() && ResI.isNaN()) {
+bool Recalc = false;
+if (A.isInfinity() || B.isInfinity()) {
+  A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
+A);
+  B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
+B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (C.isInfinity() || D.isInfinity()) {
+  C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
+C);
+  D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
+D);
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  Recalc = true;
+}
+if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
+BC.isInfinity())) {
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (Recalc) {
+  ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
+  ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
+}
+  }
+}
+
 bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15225,55 +15281,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const 
BinaryOperator *E) {
 !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
   return false;
   } else {
-// In the fully general case, we need to handle NaNs and infinities
-// robustly.
-APFloat AC = A * C;
-APFloat BD = B * D;
-APFloat AD = A * D;
-APFloat BC = B * C;
-ResR = AC - BD;
-ResI = AD + BC;
-if (ResR.isNaN() && ResI.isNaN()) {
-  bool Recalc = false;
-  if 

[clang] [clang][Interp] Implement Complex-complex multiplication (PR #94891)

2024-06-09 Thread Timm Baeder via cfe-commits

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

Share the implementation for floating-point complex-complex multiplication with 
the current interpreter. This means we need a new opcode for this, but there's 
no good way around that.

>From b89efd9e0e38a6e79130e0a1b9e8d0443654c6c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 9 Mar 2024 17:07:24 +0100
Subject: [PATCH] [clang][Interp] Implement Complex-complex multiplication

Share the implementation for floating-point complex-complex
multiplication with the current interpreter. This means we need a new
opcode for this, but there's no good way around that.
---
 clang/lib/AST/ExprConstShared.h  |   7 ++
 clang/lib/AST/ExprConstant.cpp   | 106 ---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  55 +---
 clang/lib/AST/Interp/Interp.h|  57 
 clang/lib/AST/Interp/Opcodes.td  |   4 +
 clang/test/AST/Interp/complex.cpp|  31 +++
 6 files changed, 201 insertions(+), 59 deletions(-)

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
index a97eac85abc69..9decd47e41767 100644
--- a/clang/lib/AST/ExprConstShared.h
+++ b/clang/lib/AST/ExprConstShared.h
@@ -14,6 +14,9 @@
 #ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 #define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
 
+namespace llvm {
+class APFloat;
+}
 namespace clang {
 class QualType;
 class LangOptions;
@@ -56,4 +59,8 @@ enum class GCCTypeClass {
 GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
  const LangOptions );
 
+void HandleComplexComplexMul(llvm::APFloat A, llvm::APFloat B, llvm::APFloat C,
+ llvm::APFloat D, llvm::APFloat ,
+ llvm::APFloat );
+
 #endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86fb396fabe2d..7c597a238f041 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15126,6 +15126,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const 
CastExpr *E) {
   llvm_unreachable("unknown cast resulting in complex value");
 }
 
+void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
+ APFloat , APFloat ) {
+  // This is an implementation of complex multiplication according to the
+  // constraints laid out in C11 Annex G. The implementation uses the
+  // following naming scheme:
+  //   (a + ib) * (c + id)
+
+  APFloat AC = A * C;
+  APFloat BD = B * D;
+  APFloat AD = A * D;
+  APFloat BC = B * C;
+  ResR = AC - BD;
+  ResI = AD + BC;
+  if (ResR.isNaN() && ResI.isNaN()) {
+bool Recalc = false;
+if (A.isInfinity() || B.isInfinity()) {
+  A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
+A);
+  B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
+B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (C.isInfinity() || D.isInfinity()) {
+  C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
+C);
+  D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
+D);
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  Recalc = true;
+}
+if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
+BC.isInfinity())) {
+  if (A.isNaN())
+A = APFloat::copySign(APFloat(A.getSemantics()), A);
+  if (B.isNaN())
+B = APFloat::copySign(APFloat(B.getSemantics()), B);
+  if (C.isNaN())
+C = APFloat::copySign(APFloat(C.getSemantics()), C);
+  if (D.isNaN())
+D = APFloat::copySign(APFloat(D.getSemantics()), D);
+  Recalc = true;
+}
+if (Recalc) {
+  ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
+  ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
+}
+  }
+}
+
 bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
   if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15225,55 +15281,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const 
BinaryOperator *E) {
 !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
   return false;
   } else {
-// In the fully general case, we need to handle NaNs and infinities
-// robustly.
-APFloat AC = A * C;
-APFloat BD = B * D;
-APFloat AD = A * D;
-APFloat BC = B * C;
-ResR = AC - BD;
-ResI = AD + 

[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)

2024-06-08 Thread Timm Baeder via cfe-commits

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


[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)

2024-06-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> Out of curiosity, why are they not using `__builtin_complex` as requested?

I started out replacing a lot of those expressions with `__builtin_complex` but 
ended up just creating a variable for it so the lines don't get too unwieldy. 
But then I naturally just used an initlist instead of  `__builtin_complex`.


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


[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2024-06-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

@AaronBallman Is the prototype of the implementation here at least sound? Or 
should this go somewhere completely different? Maybe in one of the TSA source 
files?

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


[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)

2024-06-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

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


[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-06 Thread Timm Baeder via cfe-commits

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


[clang] [Clang] CWG2749: relational operators involving pointers to void (PR #93046)

2024-06-06 Thread Timm Baeder via cfe-commits

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

LGTM.

I guess we should close https://github.com/llvm/llvm-project/pull/89449 after 
merging this.

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


[clang] [clang] NFCI: Make ASTContext optional in the AST text dumper again (PR #94522)

2024-06-06 Thread Timm Baeder via cfe-commits

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

Can't say much about this functionally, but it fixes my problems, so LGTM from 
that side.

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


[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-06 Thread Timm Baeder via cfe-commits

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

>From 0f047f686ac69549834bfbfdecaa6383c6ab5305 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 10 Apr 2024 16:42:36 +0200
Subject: [PATCH] Memberpointers

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  | 100 -
 clang/lib/AST/Interp/Context.cpp  |  15 +-
 clang/lib/AST/Interp/Context.h|   2 +
 clang/lib/AST/Interp/Descriptor.cpp   |   1 +
 clang/lib/AST/Interp/Disasm.cpp   |   3 +
 clang/lib/AST/Interp/Interp.cpp   |  30 ++-
 clang/lib/AST/Interp/Interp.h |  99 +
 clang/lib/AST/Interp/InterpFrame.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.h|   3 +
 clang/lib/AST/Interp/MemberPointer.cpp|  76 +++
 clang/lib/AST/Interp/MemberPointer.h  | 112 ++
 clang/lib/AST/Interp/Opcodes.td   |  18 +-
 clang/lib/AST/Interp/Pointer.cpp  |   1 +
 clang/lib/AST/Interp/Pointer.h|   1 +
 clang/lib/AST/Interp/PrimType.cpp |   1 +
 clang/lib/AST/Interp/PrimType.h   |   8 +-
 clang/test/AST/Interp/eval-order.cpp  |   4 +-
 clang/test/AST/Interp/literals.cpp|   7 +-
 clang/test/AST/Interp/memberpointers.cpp  | 197 ++
 .../CodeGenCXX/pointers-to-data-members.cpp   |   1 +
 clang/test/SemaCXX/attr-weak.cpp  |   1 +
 .../SemaCXX/nullptr_in_arithmetic_ops.cpp |   1 +
 clang/unittests/AST/Interp/toAPValue.cpp  |  46 
 25 files changed, 705 insertions(+), 25 deletions(-)
 create mode 100644 clang/lib/AST/Interp/MemberPointer.cpp
 create mode 100644 clang/lib/AST/Interp/MemberPointer.h
 create mode 100644 clang/test/AST/Interp/memberpointers.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599f..a5d3dacfc1a84 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -87,6 +87,7 @@ add_clang_library(clangAST
   Interp/Record.cpp
   Interp/Source.cpp
   Interp/State.cpp
+  Interp/MemberPointer.cpp
   Interp/InterpShared.cpp
   ItaniumCXXABI.cpp
   ItaniumMangle.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3671c41ae7039..b0f28c9cec414 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitMemcpy(CE);
   }
 
+  case CK_DerivedToBaseMemberPointer: {
+assert(classifyPrim(CE->getType()) == PT_MemberPtr);
+assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+   QualType(FromMP->getClass(), 
0));
+
+if (!this->visit(SubExpr))
+  return false;
+
+return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
+  }
+
+  case CK_BaseToDerivedMemberPointer: {
+assert(classifyPrim(CE) == PT_MemberPtr);
+assert(classifyPrim(SubExpr) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+   QualType(ToMP->getClass(), 0));
+
+if (!this->visit(SubExpr))
+  return false;
+return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
+  }
+
   case CK_UncheckedDerivedToBase:
   case CK_DerivedToBase: {
 if (!this->visit(SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
-  case CK_NullToPointer: {
+  case CK_NullToPointer:
+  case CK_NullToMemberPointer: {
 if (DiscardResult)
   return true;
 
@@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCast(*FromT, *ToT, CE);
   }
 
-  case CK_PointerToBoolean: {
+  case CK_PointerToBoolean:
+  case CK_MemberPointerToBoolean: {
 PrimType PtrT = classifyPrim(SubExpr->getType());
 
 // Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   BO->isComparisonOp())
 return this->emitComplexComparison(LHS, RHS, BO);
 
-  if (BO->isPtrMemOp())
-return this->visit(RHS);
+  if (BO->isPtrMemOp()) {
+if (!this->visit(LHS))
+  return false;
+
+if (!this->visit(RHS))
+  return false;
+
+if (!this->emitToMemberPtr(BO))
+  return false;
+
+if (classifyPrim(BO) == PT_MemberPtr)
+  return true;
+
+if (!this->emitCastMemberPtrPtr(BO))
+  

[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-05 Thread Timm Baeder via cfe-commits

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

>From 922a2239a69efe5136a9c8229ef223bfbaad2fe5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 10 Apr 2024 16:42:36 +0200
Subject: [PATCH] Memberpointers

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  | 100 -
 clang/lib/AST/Interp/Context.cpp  |  15 +-
 clang/lib/AST/Interp/Context.h|   2 +
 clang/lib/AST/Interp/Descriptor.cpp   |   1 +
 clang/lib/AST/Interp/Disasm.cpp   |   3 +
 clang/lib/AST/Interp/Interp.cpp   |  30 ++-
 clang/lib/AST/Interp/Interp.h |  99 +
 clang/lib/AST/Interp/InterpFrame.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.h|   3 +
 clang/lib/AST/Interp/MemberPointer.cpp|  76 +++
 clang/lib/AST/Interp/MemberPointer.h  | 112 ++
 clang/lib/AST/Interp/Opcodes.td   |  18 +-
 clang/lib/AST/Interp/Pointer.cpp  |   1 +
 clang/lib/AST/Interp/Pointer.h|   1 +
 clang/lib/AST/Interp/PrimType.cpp |   1 +
 clang/lib/AST/Interp/PrimType.h   |   8 +-
 clang/test/AST/Interp/eval-order.cpp  |   4 +-
 clang/test/AST/Interp/literals.cpp|   7 +-
 clang/test/AST/Interp/memberpointers.cpp  | 197 ++
 .../mangle-ms-templates-memptrs.cpp   |   2 +-
 .../CodeGenCXX/pointers-to-data-members.cpp   |   2 +-
 clang/test/SemaCXX/attr-weak.cpp  |   1 +
 .../SemaCXX/nullptr_in_arithmetic_ops.cpp |   2 +-
 clang/unittests/AST/Interp/toAPValue.cpp  |  46 
 26 files changed, 706 insertions(+), 28 deletions(-)
 create mode 100644 clang/lib/AST/Interp/MemberPointer.cpp
 create mode 100644 clang/lib/AST/Interp/MemberPointer.h
 create mode 100644 clang/test/AST/Interp/memberpointers.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599f..a5d3dacfc1a84 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -87,6 +87,7 @@ add_clang_library(clangAST
   Interp/Record.cpp
   Interp/Source.cpp
   Interp/State.cpp
+  Interp/MemberPointer.cpp
   Interp/InterpShared.cpp
   ItaniumCXXABI.cpp
   ItaniumMangle.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3671c41ae7039..b0f28c9cec414 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitMemcpy(CE);
   }
 
+  case CK_DerivedToBaseMemberPointer: {
+assert(classifyPrim(CE->getType()) == PT_MemberPtr);
+assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+   QualType(FromMP->getClass(), 
0));
+
+if (!this->visit(SubExpr))
+  return false;
+
+return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
+  }
+
+  case CK_BaseToDerivedMemberPointer: {
+assert(classifyPrim(CE) == PT_MemberPtr);
+assert(classifyPrim(SubExpr) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+   QualType(ToMP->getClass(), 0));
+
+if (!this->visit(SubExpr))
+  return false;
+return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
+  }
+
   case CK_UncheckedDerivedToBase:
   case CK_DerivedToBase: {
 if (!this->visit(SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
-  case CK_NullToPointer: {
+  case CK_NullToPointer:
+  case CK_NullToMemberPointer: {
 if (DiscardResult)
   return true;
 
@@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCast(*FromT, *ToT, CE);
   }
 
-  case CK_PointerToBoolean: {
+  case CK_PointerToBoolean:
+  case CK_MemberPointerToBoolean: {
 PrimType PtrT = classifyPrim(SubExpr->getType());
 
 // Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   BO->isComparisonOp())
 return this->emitComplexComparison(LHS, RHS, BO);
 
-  if (BO->isPtrMemOp())
-return this->visit(RHS);
+  if (BO->isPtrMemOp()) {
+if (!this->visit(LHS))
+  return false;
+
+if (!this->visit(RHS))
+  return false;
+
+if (!this->emitToMemberPtr(BO))
+  return false;
+
+if (classifyPrim(BO) == PT_MemberPtr)
+  return 

[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-05 Thread Timm Baeder via cfe-commits

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

>From 34a35dfa66835b8810e27899c9c7978de191f8e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 10 Apr 2024 16:42:36 +0200
Subject: [PATCH] Memberpointers

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  | 100 -
 clang/lib/AST/Interp/Context.cpp  |  15 +-
 clang/lib/AST/Interp/Context.h|   2 +
 clang/lib/AST/Interp/Descriptor.cpp   |   1 +
 clang/lib/AST/Interp/Disasm.cpp   |   3 +
 clang/lib/AST/Interp/Interp.cpp   |  30 ++-
 clang/lib/AST/Interp/Interp.h |  99 +
 clang/lib/AST/Interp/InterpFrame.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.h|   3 +
 clang/lib/AST/Interp/MemberPointer.cpp|  76 +++
 clang/lib/AST/Interp/MemberPointer.h  | 112 ++
 clang/lib/AST/Interp/Opcodes.td   |  18 +-
 clang/lib/AST/Interp/Pointer.cpp  |   1 +
 clang/lib/AST/Interp/Pointer.h|   1 +
 clang/lib/AST/Interp/PrimType.cpp |   1 +
 clang/lib/AST/Interp/PrimType.h   |   8 +-
 clang/test/AST/Interp/eval-order.cpp  |   4 +-
 clang/test/AST/Interp/literals.cpp|   7 +-
 clang/test/AST/Interp/memberpointers.cpp  | 197 ++
 .../mangle-ms-templates-memptrs.cpp   |   2 +-
 .../CodeGenCXX/pointers-to-data-members.cpp   |   2 +-
 clang/test/SemaCXX/attr-weak.cpp  |   1 +
 .../SemaCXX/nullptr_in_arithmetic_ops.cpp |   2 +-
 clang/unittests/AST/Interp/toAPValue.cpp  |  46 
 26 files changed, 706 insertions(+), 28 deletions(-)
 create mode 100644 clang/lib/AST/Interp/MemberPointer.cpp
 create mode 100644 clang/lib/AST/Interp/MemberPointer.h
 create mode 100644 clang/test/AST/Interp/memberpointers.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599f..a5d3dacfc1a84 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -87,6 +87,7 @@ add_clang_library(clangAST
   Interp/Record.cpp
   Interp/Source.cpp
   Interp/State.cpp
+  Interp/MemberPointer.cpp
   Interp/InterpShared.cpp
   ItaniumCXXABI.cpp
   ItaniumMangle.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3671c41ae7039..b0f28c9cec414 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitMemcpy(CE);
   }
 
+  case CK_DerivedToBaseMemberPointer: {
+assert(classifyPrim(CE->getType()) == PT_MemberPtr);
+assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+   QualType(FromMP->getClass(), 
0));
+
+if (!this->visit(SubExpr))
+  return false;
+
+return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
+  }
+
+  case CK_BaseToDerivedMemberPointer: {
+assert(classifyPrim(CE) == PT_MemberPtr);
+assert(classifyPrim(SubExpr) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+   QualType(ToMP->getClass(), 0));
+
+if (!this->visit(SubExpr))
+  return false;
+return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
+  }
+
   case CK_UncheckedDerivedToBase:
   case CK_DerivedToBase: {
 if (!this->visit(SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
-  case CK_NullToPointer: {
+  case CK_NullToPointer:
+  case CK_NullToMemberPointer: {
 if (DiscardResult)
   return true;
 
@@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCast(*FromT, *ToT, CE);
   }
 
-  case CK_PointerToBoolean: {
+  case CK_PointerToBoolean:
+  case CK_MemberPointerToBoolean: {
 PrimType PtrT = classifyPrim(SubExpr->getType());
 
 // Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   BO->isComparisonOp())
 return this->emitComplexComparison(LHS, RHS, BO);
 
-  if (BO->isPtrMemOp())
-return this->visit(RHS);
+  if (BO->isPtrMemOp()) {
+if (!this->visit(LHS))
+  return false;
+
+if (!this->visit(RHS))
+  return false;
+
+if (!this->emitToMemberPtr(BO))
+  return false;
+
+if (classifyPrim(BO) == PT_MemberPtr)
+  return 

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-05 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Rebased and updated with a lot more tests.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2024-06-05 Thread Timm Baeder via cfe-commits

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

>From 471d7a14b6475c4d06365b01ac35847276a464ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp   |  79 ++
 clang/lib/AST/Interp/ByteCodeExprGen.h |   2 +
 clang/lib/AST/Interp/DynamicAllocator.cpp  | 119 +
 clang/lib/AST/Interp/DynamicAllocator.h|  95 +++
 clang/lib/AST/Interp/EvalEmitter.cpp   |  26 ++
 clang/lib/AST/Interp/EvaluationResult.cpp  |  67 +
 clang/lib/AST/Interp/EvaluationResult.h|   6 +
 clang/lib/AST/Interp/Interp.cpp|  49 
 clang/lib/AST/Interp/Interp.h  | 128 ++
 clang/lib/AST/Interp/InterpBlock.h |  21 +-
 clang/lib/AST/Interp/InterpState.cpp   |  17 +-
 clang/lib/AST/Interp/InterpState.h |  11 +
 clang/lib/AST/Interp/Opcodes.td|  24 +-
 clang/lib/AST/Interp/Pointer.h |   1 +
 clang/test/AST/Interp/new-delete.cpp   | 274 +
 clang/test/Rewriter/rewrite-modern-catch.m |   2 +-
 clang/test/SemaCXX/delete.cpp  |   2 +-
 clang/test/SemaCXX/new-delete.cpp  |  22 +-
 19 files changed, 933 insertions(+), 13 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599f..4ab1064f2e0a3 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -76,6 +76,7 @@ add_clang_library(clangAST
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
   Interp/EvaluationResult.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3671c41ae7039..2e78bdfa09ece 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2471,6 +2471,85 @@ bool 
ByteCodeExprGen::VisitCXXInheritedCtorInitExpr(
   return this->emitCall(F, 0, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+std::optional ArraySizeExpr = E->getArraySize();
+if (!ArraySizeExpr)
+  return false;
+assert(ArraySizeExpr);
+PrimType SizeT = classifyPrim((*ArraySizeExpr)->getType());
+
+if (!this->visit(*ArraySizeExpr))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  }
+}
+  }
+
+  if (DiscardResult)
+return this->emitPopPtr(E);
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  const Expr *Arg = E->getArgument();
+
+  // Arg must be an lvalue.
+  if (!this->visit(Arg))
+return false;
+
+  return this->emitFree(E->isArrayForm(), E);
+}
+
 template 
 bool ByteCodeExprGen::VisitExpressionTraitExpr(
 const ExpressionTraitExpr *E) {
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 44c495240289f..2432beaa223a3 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,6 +128,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
   bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
   bool 

[clang] [Clang] `constexpr` builtin floating point classification / comparison functions (PR #94118)

2024-06-04 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr commented:

`Interp/` changes LGTM.

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


[clang] [clang] Move CWG2390 test into `cwg23xx.cpp` (PR #94206)

2024-06-04 Thread Timm Baeder via cfe-commits

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

Looks good, thanks

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


[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-01 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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

>From 30d86295dda9b7aaa06c23b67c54806475266e5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 10 Apr 2024 16:42:36 +0200
Subject: [PATCH 1/7] Memberpointers

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  | 103 +-
 clang/lib/AST/Interp/Context.cpp  |  15 +-
 clang/lib/AST/Interp/Context.h|   2 +
 clang/lib/AST/Interp/Descriptor.cpp   |   1 +
 clang/lib/AST/Interp/Disasm.cpp   |   3 +
 clang/lib/AST/Interp/Interp.cpp   |  30 ++-
 clang/lib/AST/Interp/Interp.h |  99 ++
 clang/lib/AST/Interp/InterpFrame.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.cpp  |   1 +
 clang/lib/AST/Interp/InterpStack.h|   3 +
 clang/lib/AST/Interp/MemberPointer.cpp|  73 +++
 clang/lib/AST/Interp/MemberPointer.h  | 112 +++
 clang/lib/AST/Interp/Opcodes.td   |  18 +-
 clang/lib/AST/Interp/Pointer.cpp  |   1 +
 clang/lib/AST/Interp/Pointer.h|   1 +
 clang/lib/AST/Interp/PrimType.cpp |   1 +
 clang/lib/AST/Interp/PrimType.h   |   8 +-
 clang/test/AST/Interp/eval-order.cpp  |   4 +-
 clang/test/AST/Interp/literals.cpp|   7 +-
 clang/test/AST/Interp/memberpointers.cpp  | 184 ++
 .../mangle-ms-templates-memptrs.cpp   |   2 +-
 .../CodeGenCXX/pointers-to-data-members.cpp   |   2 +-
 clang/test/SemaCXX/attr-weak.cpp  |   1 +
 .../SemaCXX/nullptr_in_arithmetic_ops.cpp |   2 +-
 clang/unittests/AST/Interp/toAPValue.cpp  |  46 +
 26 files changed, 692 insertions(+), 29 deletions(-)
 create mode 100644 clang/lib/AST/Interp/MemberPointer.cpp
 create mode 100644 clang/lib/AST/Interp/MemberPointer.h
 create mode 100644 clang/test/AST/Interp/memberpointers.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 3faefb54f599f..a5d3dacfc1a84 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -87,6 +87,7 @@ add_clang_library(clangAST
   Interp/Record.cpp
   Interp/Source.cpp
   Interp/State.cpp
+  Interp/MemberPointer.cpp
   Interp/InterpShared.cpp
   ItaniumCXXABI.cpp
   ItaniumMangle.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6607727b5246f..5f8b94c3a0f94 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitMemcpy(CE);
   }
 
+  case CK_DerivedToBaseMemberPointer: {
+assert(classifyPrim(CE->getType()) == PT_MemberPtr);
+assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+   QualType(FromMP->getClass(), 
0));
+
+if (!this->visit(SubExpr))
+  return false;
+
+return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
+  }
+
+  case CK_BaseToDerivedMemberPointer: {
+assert(classifyPrim(CE) == PT_MemberPtr);
+assert(classifyPrim(SubExpr) == PT_MemberPtr);
+const auto *FromMP = SubExpr->getType()->getAs();
+const auto *ToMP = CE->getType()->getAs();
+
+unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+   QualType(ToMP->getClass(), 0));
+
+if (!this->visit(SubExpr))
+  return false;
+return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
+  }
+
   case CK_UncheckedDerivedToBase:
   case CK_DerivedToBase: {
 if (!this->visit(SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
-  case CK_NullToPointer: {
+  case CK_NullToPointer:
+  case CK_NullToMemberPointer: {
 if (DiscardResult)
   return true;
 
@@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitCast(*FromT, *ToT, CE);
   }
 
-  case CK_PointerToBoolean: {
+  case CK_PointerToBoolean:
+  case CK_MemberPointerToBoolean: {
 PrimType PtrT = classifyPrim(SubExpr->getType());
 
 // Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   BO->isComparisonOp())
 return this->emitComplexComparison(LHS, RHS, BO);
 
-  if (BO->isPtrMemOp())
-return this->visit(RHS);
+  if (BO->isPtrMemOp()) {
+if (!this->visit(LHS))
+  

  1   2   3   4   5   6   7   8   9   10   >