[clang] [clang][NFC] Add CWG882 test (Defining `main` as deleted) (PR #101382)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/101382

>From 9dcbd0779bf379bbf62bf52247ef46de82cb4877 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Wed, 31 Jul 2024 19:18:09 +0100
Subject: [PATCH 1/2] [clang][Tests][NFC] Add CWG882 test (Defining `main` as
 deleted)

---
 clang/test/CXX/drs/cwg8xx.cpp | 7 ++-
 clang/www/cxx_dr_status.html  | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang/test/CXX/drs/cwg8xx.cpp b/clang/test/CXX/drs/cwg8xx.cpp
index c8cbdfcee3f4d..86ee1c0c86b0d 100644
--- a/clang/test/CXX/drs/cwg8xx.cpp
+++ b/clang/test/CXX/drs/cwg8xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -30,3 +30,8 @@ void g(int i) {
 }
 #endif
 } // namespace cwg873
+
+// cwg882: 3.5
+int main() = delete;
+// expected-error@-1 {{'main' is not allowed to be deleted}}
+// cxx98-error@-2 {{deleted function definitions are a C++11 extension}}
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..0b3477fbd217b 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -5161,7 +5161,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/882.html;>882
 CD2
 Defining main as deleted
-Unknown
+Clang 3.5
   
   
 https://cplusplus.github.io/CWG/issues/883.html;>883

>From 422b306ac043c236714161ef33e28a6c7456eac5 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Wed, 31 Jul 2024 20:27:32 +0100
Subject: [PATCH 2/2] Check for C++11

---
 clang/test/CXX/drs/cwg8xx.cpp | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/test/CXX/drs/cwg8xx.cpp b/clang/test/CXX/drs/cwg8xx.cpp
index 86ee1c0c86b0d..38bff3adf262a 100644
--- a/clang/test/CXX/drs/cwg8xx.cpp
+++ b/clang/test/CXX/drs/cwg8xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -32,6 +32,7 @@ void g(int i) {
 } // namespace cwg873
 
 // cwg882: 3.5
+#if __cplusplus >= 201103L
 int main() = delete;
-// expected-error@-1 {{'main' is not allowed to be deleted}}
-// cxx98-error@-2 {{deleted function definitions are a C++11 extension}}
+// since-cxx11-error@-1 {{'main' is not allowed to be deleted}}
+#endif

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


[clang] [Clang][SemaCXX] Fix bug where unexpanded lambda captures where assumed to have size 1 (PR #101385)

2024-07-31 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

Revived from https://reviews.llvm.org/D154716

This probably needs a fresh review, I've just rebased onto main.

The problem still exists on main: https://godbolt.org/z/vPTb4qEnd

CC @cor3ntin @shafik (as people who reviewed on the phabricator)

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


[clang] [Clang][SemaCXX] Fix bug where unexpanded lambda captures where assumed to have size 1 (PR #101385)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/101385

Fixes #63677

>From 555373715bc2eb025d6580129cead087f7f45ed1 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 7 Jul 2023 14:31:03 +0100
Subject: [PATCH] [Clang][SemaCXX] Fix bug where unexpanded lambda captures
 where assumed to have size 1

---
 clang/docs/ReleaseNotes.rst  |  1 +
 clang/lib/Sema/SemaTemplateInstantiate.cpp   |  3 ++-
 clang/lib/Sema/TreeTransform.h   |  6 ++---
 clang/test/SemaCXX/lambda-pack-expansion.cpp | 27 
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3c2e0282d1c72..2f4158ac36ac2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -170,6 +170,7 @@ Bug Fixes to C++ Support
 - Fixed a failed assertion when checking invalid delete operator declaration. 
(#GH96191)
 - Fix a crash when checking destructor reference with an invalid initializer. 
(#GH97230)
 - Clang now correctly parses potentially declarative nested-name-specifiers in 
pointer-to-member declarators.
+- Fix init-capture packs having a size of one before being instantiated. 
(#GH63677)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8995d461362d7..de470739ab78e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1447,7 +1447,8 @@ namespace {
 }
 
 void transformedLocalDecl(Decl *Old, ArrayRef NewDecls) {
-  if (Old->isParameterPack()) {
+  if (Old->isParameterPack() &&
+  (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {
 SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
 for (auto *New : NewDecls)
   SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8d3e1edf7a45d..540e1e0cb8df0 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14340,14 +14340,14 @@ 
TreeTransform::TransformLambdaExpr(LambdaExpr *E) {
   OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
   RetainExpansion, NumExpansions))
 return ExprError();
+  assert(!RetainExpansion && "Should not need to retain expansion after a "
+ "capture since it cannot be extended");
   if (Expand) {
 for (unsigned I = 0; I != *NumExpansions; ++I) {
   Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
   SubstInitCapture(SourceLocation(), std::nullopt);
 }
-  }
-  if (!Expand || RetainExpansion) {
-ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+  } else {
 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
   }
diff --git a/clang/test/SemaCXX/lambda-pack-expansion.cpp 
b/clang/test/SemaCXX/lambda-pack-expansion.cpp
index 221d1d01a06ae..77b2e244753a9 100644
--- a/clang/test/SemaCXX/lambda-pack-expansion.cpp
+++ b/clang/test/SemaCXX/lambda-pack-expansion.cpp
@@ -41,3 +41,30 @@ int h(Ts... ts) {
 }
 
 }
+
+namespace GH63677 {
+
+template
+void f() {
+  []() -> void {
+[...us = Ts{}]{
+  (Ts(us), ...);
+};
+  }.template operator()();
+}
+
+template void f();
+
+template 
+inline constexpr auto fun =
+  [](Ts... ts) {
+return [... us = (Ts&&) ts](Fun&& fn) mutable {
+  return static_cast(fn)(static_cast(us)...);
+};
+  };
+
+void f() {
+  [[maybe_unused]] auto s = fun(1, 2, 3, 4);
+}
+
+}

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


[clang] [clang][Tests][NFC] Add CWG882 test (Defining `main` as deleted) (PR #101382)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/101382

https://cplusplus.github.io/CWG/issues/882.html

This was implemented for Clang 3.5 by b63b6ee9a00ef0710d899df6cfda78a1b8bd762a

>From 9dcbd0779bf379bbf62bf52247ef46de82cb4877 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Wed, 31 Jul 2024 19:18:09 +0100
Subject: [PATCH] [clang][Tests][NFC] Add CWG882 test (Defining `main` as
 deleted)

---
 clang/test/CXX/drs/cwg8xx.cpp | 7 ++-
 clang/www/cxx_dr_status.html  | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang/test/CXX/drs/cwg8xx.cpp b/clang/test/CXX/drs/cwg8xx.cpp
index c8cbdfcee3f4d..86ee1c0c86b0d 100644
--- a/clang/test/CXX/drs/cwg8xx.cpp
+++ b/clang/test/CXX/drs/cwg8xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -30,3 +30,8 @@ void g(int i) {
 }
 #endif
 } // namespace cwg873
+
+// cwg882: 3.5
+int main() = delete;
+// expected-error@-1 {{'main' is not allowed to be deleted}}
+// cxx98-error@-2 {{deleted function definitions are a C++11 extension}}
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..0b3477fbd217b 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -5161,7 +5161,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/882.html;>882
 CD2
 Defining main as deleted
-Unknown
+Clang 3.5
   
   
 https://cplusplus.github.io/CWG/issues/883.html;>883

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


[clang] [llvm] [Clang] Fix definition of layout-compatible to ignore empty classes (PR #92103)

2024-07-31 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

I am also looking to cherry-pick this for Clang 19 so there won't be a 
difference between Clang 19 (when `__is_layout_compatible` was added) and Clang 
20

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


[clang] [llvm] [Clang] Fix definition of layout-compatible to ignore empty classes (PR #92103)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/92103

>From 5908130604728b9aa9b70eeb2523d368df08e68d Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Tue, 14 May 2024 08:28:19 +0100
Subject: [PATCH 1/5] [Clang] Fix definition of layout-compatible to ignore
 empty classes

Also changes the behaviour of __builtin_is_layout_compatible

None of the historic nor the current definition of layout-compatible classes 
mention anything about base classes (other than implicitly through being 
standard-layout) and are defined in terms of members, not direct members.
---
 clang/include/clang/AST/DeclCXX.h  |  7 
 clang/lib/AST/DeclCXX.cpp  | 36 +
 clang/lib/Sema/SemaChecking.cpp| 63 +-
 clang/test/SemaCXX/type-traits.cpp | 11 ++
 llvm/include/llvm/ADT/STLExtras.h  |  6 +++
 5 files changed, 79 insertions(+), 44 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index fb52ac804849d..60a5005c51a5e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1229,6 +1229,13 @@ class CXXRecordDecl : public RecordDecl {
   /// C++11 [class]p7, specifically using the C++11 rules without any DRs.
   bool isCXX11StandardLayout() const { return data().IsCXX11StandardLayout; }
 
+  /// If this is a standard-layout class or union, any and all data members 
will
+  /// be declared in the same type.
+  ///
+  /// This retrieves the type if this class has any data members,
+  /// or the current class if there is no class with fields.
+  const CXXRecordDecl *getStandardLayoutBaseWithFields() const;
+
   /// Determine whether this class, or any of its class subobjects,
   /// contains a mutable field.
   bool hasMutableFields() const { return data().HasMutableFields; }
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 75c441293d62e..ab032a4595d46 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -561,6 +561,42 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl 
*Subobj) {
 data().StructuralIfLiteral = false;
 }
 
+const CXXRecordDecl *CXXRecordDecl::getStandardLayoutBaseWithFields() const {
+#ifndef NDEBUG
+  {
+assert(
+isStandardLayout() &&
+"getStandardLayoutBaseWithFields called on a non-standard-layout 
type");
+unsigned NumberOfBasesWithFields = 0;
+if (!field_empty())
+  ++NumberOfBasesWithFields;
+std::set UniqueBases;
+forallBases([&](const CXXRecordDecl *Base) -> bool {
+  if (!Base->field_empty())
+++NumberOfBasesWithFields;
+  assert(
+  UniqueBases.insert(Base->getCanonicalDecl()).second &&
+  "Standard layout struct has multiple base classes of the same type");
+  return true;
+});
+assert(NumberOfBasesWithFields <= 1 &&
+   "Standard layout struct has fields declared in more than one 
class");
+  }
+#endif
+  if (!field_empty())
+return this;
+  const CXXRecordDecl *Result = this;
+  forallBases([&](const CXXRecordDecl *Base) -> bool {
+if (!Base->field_empty()) {
+  // This is the base where the fields are declared; return early
+  Result = Base;
+  return false;
+}
+return true;
+  });
+  return Result;
+}
+
 bool CXXRecordDecl::hasConstexprDestructor() const {
   auto *Dtor = getDestructor();
   return Dtor ? Dtor->isConstexpr() : defaultedDestructorIsConstexpr();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ecd1821651140..acd142c1932ad 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -19084,7 +19084,8 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const 
Expr *RHSExpr,
 static bool isLayoutCompatible(ASTContext , QualType T1, QualType T2);
 
 /// Check if two enumeration types are layout-compatible.
-static bool isLayoutCompatible(ASTContext , EnumDecl *ED1, EnumDecl *ED2) {
+static bool isLayoutCompatible(ASTContext , const EnumDecl *ED1,
+   const EnumDecl *ED2) {
   // C++11 [dcl.enum] p8:
   // Two enumeration types are layout-compatible if they have the same
   // underlying type.
@@ -19095,8 +19096,8 @@ static bool isLayoutCompatible(ASTContext , EnumDecl 
*ED1, EnumDecl *ED2) {
 /// Check if two fields are layout-compatible.
 /// Can be used on union members, which are exempt from alignment requirement
 /// of common initial sequence.
-static bool isLayoutCompatible(ASTContext , FieldDecl *Field1,
-   FieldDecl *Field2,
+static bool isLayoutCompatible(ASTContext , const FieldDecl *Field1,
+   const FieldDecl *Field2,
bool AreUnionMembers = false) {
   [[maybe_unused]] const Type *Field1Parent =
   Field1->getParent()->getTypeForDecl();
@@ -19139,52 +19140,26 @@ static bool isLayoutCompatible(ASTContext , 
FieldDecl *Field1,
 
 /// Check if two standard-layout 

[clang] [clang] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/78112

>From 92f8720e3d21521b589d5291f086a2f32b87bfe0 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 14 Jan 2024 19:52:31 +
Subject: [PATCH 01/13] [clang] [SemaCXX] Implement CWG2627 Bit-fields and
 narrowing conversions

---
 clang/docs/ReleaseNotes.rst   |   5 +
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Overload.h   |   7 +-
 clang/lib/Sema/SemaExpr.cpp   |  10 +-
 clang/lib/Sema/SemaInit.cpp   |  20 ++-
 clang/lib/Sema/SemaOverload.cpp   | 119 +--
 .../dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp |  24 
 clang/test/CXX/drs/dr26xx.cpp | 136 ++
 clang/www/cxx_dr_status.html  |   2 +-
 9 files changed, 278 insertions(+), 48 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92563262cc673..28202fc604e29 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -157,6 +157,11 @@ Resolutions to C++ Defect Reports
 - Clang now diagnoses declarative nested-name-specifiers with 
pack-index-specifiers.
   (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers 
`_).
 
+- Casts from a bit-field to an integral type is now not considered narrowing 
if the
+  width of the bit-field means that all potential values are in the range
+  of the target type, even if the type of the bit-field is larger.
+  (`CWG2627. Bit-fields and narrowing conversions  
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fdca82934cb4d..6cdb439be30ae 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6253,6 +6253,9 @@ def ext_init_list_variable_narrowing_const_reference : 
ExtWarn<
 def ext_init_list_constant_narrowing : ExtWarn<
   "constant expression evaluates to %0 which cannot be narrowed to type %1">,
   InGroup, DefaultError, SFINAEFailure;
+def ext_bit_field_narrowing : Extension<
+  "narrowing non-constant-expression from %0 bit-field of width %2 to %1 is a 
C++23 extension">,
+  InGroup, SFINAEFailure;
 def ext_init_list_constant_narrowing_const_reference : ExtWarn<
   ext_init_list_constant_narrowing.Summary>,
   InGroup, DefaultError, SFINAEFailure;
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 76311b00d2fc5..0d94045cc13f7 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -244,7 +244,11 @@ class Sema;
 /// Not a narrowing conversion.
 NK_Not_Narrowing,
 
-/// A narrowing conversion by virtue of the source and destination types.
+/// Not a narrowing conversion in C++23 because the source is a bit-field
+/// whose range can fit in the target type
+NK_BitField_Not_Narrowing,
+
+/// A narrowing conversion by virtue of the source and target types.
 NK_Type_Narrowing,
 
 /// A narrowing conversion, because a constant expression got narrowed.
@@ -387,6 +391,7 @@ class Sema;
 NarrowingKind
 getNarrowingKind(ASTContext , const Expr *Converted,
  APValue , QualType ,
+ unsigned ,
  bool IgnoreFloatToIntegralConversion = false) const;
 bool isPointerConversionToBool() const;
 bool isPointerConversionToVoidPointer(ASTContext& Context) const;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 50f92c496a539..4c16fcc60fc77 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12361,8 +12361,9 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
 
   APValue PreNarrowingValue;
   QualType PreNarrowingType;
+  unsigned BitFieldWidth;
   switch (SCS.getNarrowingKind(S.Context, E, PreNarrowingValue,
-   PreNarrowingType,
+   PreNarrowingType, BitFieldWidth,
/*IgnoreFloatToIntegralConversion*/ true)) {
   case NK_Dependent_Narrowing:
 // Implicit conversion to a narrower type, but the expression is
@@ -12370,6 +12371,13 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
   case NK_Not_Narrowing:
 return false;
 
+  case NK_BitField_Not_Narrowing:
+if (!S.getLangOpts().CPlusPlus23) {
+  return S.Diag(E->getBeginLoc(), diag::ext_bit_field_narrowing)
+ << FromType << ToType << BitFieldWidth;
+}
+return false;
+
   case NK_Constant_Narrowing:
 // Implicit conversion to a narrower type, and the value is not a constant
 // expression.
diff --git a/clang/lib/Sema/SemaInit.cpp 

[clang] [clang] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-31 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

@AaronBallman This shouldn't affect C at all since this is only about 
non-constant-expressions which come from a bit-field

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


[clang] [clang] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-31 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/78112

>From 92f8720e3d21521b589d5291f086a2f32b87bfe0 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 14 Jan 2024 19:52:31 +
Subject: [PATCH 01/11] [clang] [SemaCXX] Implement CWG2627 Bit-fields and
 narrowing conversions

---
 clang/docs/ReleaseNotes.rst   |   5 +
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Overload.h   |   7 +-
 clang/lib/Sema/SemaExpr.cpp   |  10 +-
 clang/lib/Sema/SemaInit.cpp   |  20 ++-
 clang/lib/Sema/SemaOverload.cpp   | 119 +--
 .../dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp |  24 
 clang/test/CXX/drs/dr26xx.cpp | 136 ++
 clang/www/cxx_dr_status.html  |   2 +-
 9 files changed, 278 insertions(+), 48 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92563262cc673..28202fc604e29 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -157,6 +157,11 @@ Resolutions to C++ Defect Reports
 - Clang now diagnoses declarative nested-name-specifiers with 
pack-index-specifiers.
   (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers 
`_).
 
+- Casts from a bit-field to an integral type is now not considered narrowing 
if the
+  width of the bit-field means that all potential values are in the range
+  of the target type, even if the type of the bit-field is larger.
+  (`CWG2627. Bit-fields and narrowing conversions  
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fdca82934cb4d..6cdb439be30ae 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6253,6 +6253,9 @@ def ext_init_list_variable_narrowing_const_reference : 
ExtWarn<
 def ext_init_list_constant_narrowing : ExtWarn<
   "constant expression evaluates to %0 which cannot be narrowed to type %1">,
   InGroup, DefaultError, SFINAEFailure;
+def ext_bit_field_narrowing : Extension<
+  "narrowing non-constant-expression from %0 bit-field of width %2 to %1 is a 
C++23 extension">,
+  InGroup, SFINAEFailure;
 def ext_init_list_constant_narrowing_const_reference : ExtWarn<
   ext_init_list_constant_narrowing.Summary>,
   InGroup, DefaultError, SFINAEFailure;
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 76311b00d2fc5..0d94045cc13f7 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -244,7 +244,11 @@ class Sema;
 /// Not a narrowing conversion.
 NK_Not_Narrowing,
 
-/// A narrowing conversion by virtue of the source and destination types.
+/// Not a narrowing conversion in C++23 because the source is a bit-field
+/// whose range can fit in the target type
+NK_BitField_Not_Narrowing,
+
+/// A narrowing conversion by virtue of the source and target types.
 NK_Type_Narrowing,
 
 /// A narrowing conversion, because a constant expression got narrowed.
@@ -387,6 +391,7 @@ class Sema;
 NarrowingKind
 getNarrowingKind(ASTContext , const Expr *Converted,
  APValue , QualType ,
+ unsigned ,
  bool IgnoreFloatToIntegralConversion = false) const;
 bool isPointerConversionToBool() const;
 bool isPointerConversionToVoidPointer(ASTContext& Context) const;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 50f92c496a539..4c16fcc60fc77 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12361,8 +12361,9 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
 
   APValue PreNarrowingValue;
   QualType PreNarrowingType;
+  unsigned BitFieldWidth;
   switch (SCS.getNarrowingKind(S.Context, E, PreNarrowingValue,
-   PreNarrowingType,
+   PreNarrowingType, BitFieldWidth,
/*IgnoreFloatToIntegralConversion*/ true)) {
   case NK_Dependent_Narrowing:
 // Implicit conversion to a narrower type, but the expression is
@@ -12370,6 +12371,13 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
   case NK_Not_Narrowing:
 return false;
 
+  case NK_BitField_Not_Narrowing:
+if (!S.getLangOpts().CPlusPlus23) {
+  return S.Diag(E->getBeginLoc(), diag::ext_bit_field_narrowing)
+ << FromType << ToType << BitFieldWidth;
+}
+return false;
+
   case NK_Constant_Narrowing:
 // Implicit conversion to a narrower type, and the value is not a constant
 // expression.
diff --git a/clang/lib/Sema/SemaInit.cpp 

[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100747

>From 1ba0cbc3f3fc1d7982c36172ffd0e72245593e6c Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 13:34:00 +0100
Subject: [PATCH 1/4] [clang][Tests][NFC] Add CWG713 test; add example from
 CWG1584 test

https://cplusplus.github.io/CWG/issues/713.html
https://cplusplus.github.io/CWG/issues/1584.html
---
 clang/test/CXX/drs/cwg15xx.cpp | 48 ++
 clang/test/CXX/drs/cwg7xx.cpp  | 18 -
 clang/www/cxx_dr_status.html   |  2 +-
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 21a392a5141e3..961c25000111a 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14,cxx14-17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -6,6 +6,11 @@
 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 
+#if __cplusplus == 199711L
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
+#endif
+
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
 if (p > 0) {}
@@ -556,24 +561,33 @@ auto CWG1579_lambda_invalid = []() -> 
GenericMoveOnly {
 } // end namespace cwg1579
 
 namespace cwg1584 { // cwg1584: 7 drafting 2015-05
-#if __cplusplus >= 201103L
-  // Deducing function types from cv-qualified types
-  template void f(const T *); // #cwg1584-f
-  template void g(T *, const T * = 0);
-  template void h(T *) { T::error; }
-  // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' 
because it has no members}}
-  //   since-cxx11-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
-  template void h(const T *);
-  void i() {
-f();
-// since-cxx11-error@-1 {{no matching function for call to 'f'}}
-//   since-cxx11-note@#cwg1584-f {{candidate template ignored: could not 
match 'const T *' against 'void (*)()'}}
-g();
-h(); // #cwg1584-h
-  }
-#endif
+// Deducing function types from cv-qualified types
+template void f(const T *); // #cwg1584-f
+template void g(T *, const T * = 0);
+template void h(T *) { T::error; }
+// expected-error@-1 {{type 'void ()' cannot be used prior to '::' because it 
has no members}}
+//   expected-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
+template void h(const T *);
+void i() {
+  f();
+  // expected-error@-1 {{no matching function for call to 'f'}}
+  //   expected-note@#cwg1584-f {{candidate template ignored: could not match 
'const T *' against 'void (*)()'}}
+  g();
+  h(); // #cwg1584-h
 }
 
+template struct tuple_size {
+  static const bool is_primary = true;
+};
+template struct tuple_size : tuple_size {
+  static const bool is_primary = false;
+};
+
+tuple_size t;
+static_assert(tuple_size::is_primary, "");
+static_assert(tuple_size::is_primary, "");
+} // namespace cwg1584
+
 namespace cwg1589 {   // cwg1589: 3.7 c++11
 #if __cplusplus >= 201103L
   // Ambiguous ranking of list-initialization sequences
diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp
index 6d93e2948dadb..1e5d3c0873d8b 100644
--- a/clang/test/CXX/drs/cwg7xx.cpp
+++ b/clang/test/CXX/drs/cwg7xx.cpp
@@ -1,9 +1,14 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s 
-verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s 
-verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // 

[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

> Based on https://godbolt.org/z/n6oPdMT91, I think `3.1` is the correct 
> availability here, but I can be persuaded for `3.0`.

The warnings are because of how the test is written, the tested behaviour 
("function types are never const or volatile") is still true in Clang 3.0

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


[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100747

>From 1ba0cbc3f3fc1d7982c36172ffd0e72245593e6c Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 13:34:00 +0100
Subject: [PATCH 1/3] [clang][Tests][NFC] Add CWG713 test; add example from
 CWG1584 test

https://cplusplus.github.io/CWG/issues/713.html
https://cplusplus.github.io/CWG/issues/1584.html
---
 clang/test/CXX/drs/cwg15xx.cpp | 48 ++
 clang/test/CXX/drs/cwg7xx.cpp  | 18 -
 clang/www/cxx_dr_status.html   |  2 +-
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 21a392a5141e3..961c25000111a 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14,cxx14-17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -6,6 +6,11 @@
 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 
+#if __cplusplus == 199711L
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
+#endif
+
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
 if (p > 0) {}
@@ -556,24 +561,33 @@ auto CWG1579_lambda_invalid = []() -> 
GenericMoveOnly {
 } // end namespace cwg1579
 
 namespace cwg1584 { // cwg1584: 7 drafting 2015-05
-#if __cplusplus >= 201103L
-  // Deducing function types from cv-qualified types
-  template void f(const T *); // #cwg1584-f
-  template void g(T *, const T * = 0);
-  template void h(T *) { T::error; }
-  // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' 
because it has no members}}
-  //   since-cxx11-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
-  template void h(const T *);
-  void i() {
-f();
-// since-cxx11-error@-1 {{no matching function for call to 'f'}}
-//   since-cxx11-note@#cwg1584-f {{candidate template ignored: could not 
match 'const T *' against 'void (*)()'}}
-g();
-h(); // #cwg1584-h
-  }
-#endif
+// Deducing function types from cv-qualified types
+template void f(const T *); // #cwg1584-f
+template void g(T *, const T * = 0);
+template void h(T *) { T::error; }
+// expected-error@-1 {{type 'void ()' cannot be used prior to '::' because it 
has no members}}
+//   expected-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
+template void h(const T *);
+void i() {
+  f();
+  // expected-error@-1 {{no matching function for call to 'f'}}
+  //   expected-note@#cwg1584-f {{candidate template ignored: could not match 
'const T *' against 'void (*)()'}}
+  g();
+  h(); // #cwg1584-h
 }
 
+template struct tuple_size {
+  static const bool is_primary = true;
+};
+template struct tuple_size : tuple_size {
+  static const bool is_primary = false;
+};
+
+tuple_size t;
+static_assert(tuple_size::is_primary, "");
+static_assert(tuple_size::is_primary, "");
+} // namespace cwg1584
+
 namespace cwg1589 {   // cwg1589: 3.7 c++11
 #if __cplusplus >= 201103L
   // Ambiguous ranking of list-initialization sequences
diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp
index 6d93e2948dadb..1e5d3c0873d8b 100644
--- a/clang/test/CXX/drs/cwg7xx.cpp
+++ b/clang/test/CXX/drs/cwg7xx.cpp
@@ -1,9 +1,14 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s 
-verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s 
-verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // 

[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100747

>From 1ba0cbc3f3fc1d7982c36172ffd0e72245593e6c Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 13:34:00 +0100
Subject: [PATCH 1/3] [clang][Tests][NFC] Add CWG713 test; add example from
 CWG1584 test

https://cplusplus.github.io/CWG/issues/713.html
https://cplusplus.github.io/CWG/issues/1584.html
---
 clang/test/CXX/drs/cwg15xx.cpp | 48 ++
 clang/test/CXX/drs/cwg7xx.cpp  | 18 -
 clang/www/cxx_dr_status.html   |  2 +-
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 21a392a5141e3..961c25000111a 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14,cxx14-17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -6,6 +6,11 @@
 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 
+#if __cplusplus == 199711L
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
+#endif
+
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
 if (p > 0) {}
@@ -556,24 +561,33 @@ auto CWG1579_lambda_invalid = []() -> 
GenericMoveOnly {
 } // end namespace cwg1579
 
 namespace cwg1584 { // cwg1584: 7 drafting 2015-05
-#if __cplusplus >= 201103L
-  // Deducing function types from cv-qualified types
-  template void f(const T *); // #cwg1584-f
-  template void g(T *, const T * = 0);
-  template void h(T *) { T::error; }
-  // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' 
because it has no members}}
-  //   since-cxx11-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
-  template void h(const T *);
-  void i() {
-f();
-// since-cxx11-error@-1 {{no matching function for call to 'f'}}
-//   since-cxx11-note@#cwg1584-f {{candidate template ignored: could not 
match 'const T *' against 'void (*)()'}}
-g();
-h(); // #cwg1584-h
-  }
-#endif
+// Deducing function types from cv-qualified types
+template void f(const T *); // #cwg1584-f
+template void g(T *, const T * = 0);
+template void h(T *) { T::error; }
+// expected-error@-1 {{type 'void ()' cannot be used prior to '::' because it 
has no members}}
+//   expected-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
+template void h(const T *);
+void i() {
+  f();
+  // expected-error@-1 {{no matching function for call to 'f'}}
+  //   expected-note@#cwg1584-f {{candidate template ignored: could not match 
'const T *' against 'void (*)()'}}
+  g();
+  h(); // #cwg1584-h
 }
 
+template struct tuple_size {
+  static const bool is_primary = true;
+};
+template struct tuple_size : tuple_size {
+  static const bool is_primary = false;
+};
+
+tuple_size t;
+static_assert(tuple_size::is_primary, "");
+static_assert(tuple_size::is_primary, "");
+} // namespace cwg1584
+
 namespace cwg1589 {   // cwg1589: 3.7 c++11
 #if __cplusplus >= 201103L
   // Ambiguous ranking of list-initialization sequences
diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp
index 6d93e2948dadb..1e5d3c0873d8b 100644
--- a/clang/test/CXX/drs/cwg7xx.cpp
+++ b/clang/test/CXX/drs/cwg7xx.cpp
@@ -1,9 +1,14 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s 
-verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s 
-verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // 

[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

New test compiles down to clang 3.0 (except warnings for 
https://cplusplus.github.io/CWG/issues/547.html) but do not compile before that 
because of the lack of `__is_const`/`__is_volatile` type traits.

Function types with cv- qualifiers were added for Clang 2.5 in 
22c40fa28551f0da487f399a2fe0d3d25edf3edc, where they already used a different 
field to hold the qualifiers (thus the function types were not considered 
`const`/`volatile`/`__restrict` themselves), so it should be okay to claim this 
was implemented in Clang 2.5?

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


[clang] [Clang] Qualified functions can't decay into pointers (PR #90353)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/90353

>From d983badd09dcc227f5945f4b4759214b7b6adbf5 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 08:44:19 +0100
Subject: [PATCH 1/5] [Clang] Qualified functions can't decay into pointers

---
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h|  4 +-
 clang/lib/AST/TypePrinter.cpp | 23 ++
 clang/lib/Sema/SemaDecl.cpp   |  7 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 16 +--
 clang/lib/Sema/SemaTemplate.cpp   | 10 +++-
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 14 +-
 clang/lib/Sema/SemaType.cpp   | 46 +++
 .../dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp|  5 +-
 .../CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp   |  5 +-
 clang/test/SemaCXX/function-type-qual.cpp | 36 ++-
 clang/test/SemaCXX/type-traits.cpp| 12 +
 12 files changed, 138 insertions(+), 43 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b165f6e65636d..f25f178bccf7f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -145,6 +145,9 @@ Bug Fixes in This Version
 - Fixed the definition of ``ATOMIC_FLAG_INIT`` in  so it can
   be used in C++.
 
+- cv- and ref- qualified function types no longer silently produce invalid 
pointer to
+  qualified function types when they implicitly decay in some places. Fixes 
(#GH27059).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 72723c7c56e07..fa5dac96b996d 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -5377,6 +5377,8 @@ class FunctionProtoType final
 return static_cast(FunctionTypeBits.RefQualifier);
   }
 
+  std::string getFunctionQualifiersAsString() const;
+
   using param_type_iterator = const QualType *;
 
   ArrayRef param_types() const {
@@ -7758,7 +7760,7 @@ inline bool QualType::isReferenceable() const {
   if (const auto *F = Self.getAs())
 return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None;
 
-  return false;
+  return Self.isFunctionType();
 }
 
 inline SplitQualType QualType::split() const {
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ffec3ef9d2269..499e049923e2f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2605,3 +2605,26 @@ raw_ostream ::operator<<(raw_ostream , QualType 
QT) {
   TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
   return OS;
 }
+
+std::string FunctionProtoType::getFunctionQualifiersAsString() const {
+  std::string Quals = getMethodQuals().getAsString();
+
+  switch (getRefQualifier()) {
+  case RQ_None:
+break;
+
+  case RQ_LValue:
+if (!Quals.empty())
+  Quals += ' ';
+Quals += '&';
+break;
+
+  case RQ_RValue:
+if (!Quals.empty())
+  Quals += ' ';
+Quals += "&&";
+break;
+  }
+
+  return Quals;
+}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 575bd292f27de..123dc46c7d884 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15071,6 +15071,13 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
SourceLocation StartLoc,
 T = Context.getLifetimeQualifiedType(T, lifetime);
   }
 
+  if (T->isFunctionType() && !T.isReferenceable()) {
+Diag(NameLoc, diag::err_compound_qualified_function_type)
+<< 1 << true << T
+<< T->castAs()->getFunctionQualifiersAsString();
+return nullptr;
+  }
+
   ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
  Context.getAdjustedParameterType(T),
  TSInfo, SC, nullptr);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1cca8ac9b9343..58b21a1d6f33e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11123,7 +11123,8 @@ void Sema::CheckConversionDeclarator(Declarator , 
QualType ,
 D.setInvalidType();
   } else if (ConvType->isFunctionType()) {
 Diag(D.getIdentifierLoc(), diag::err_conv_function_to_function);
-ConvType = Context.getPointerType(ConvType);
+if (ConvType.isReferenceable())
+  ConvType = Context.getPointerType(ConvType);
 D.setInvalidType();
   }
 
@@ -16719,8 +16720,17 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, 
TypeSourceInfo *TInfo,
   // Arrays and functions decay.
   if (ExDeclType->isArrayType())
 ExDeclType = Context.getArrayDecayedType(ExDeclType);
-  else if (ExDeclType->isFunctionType())
-ExDeclType = Context.getPointerType(ExDeclType);
+  else if (ExDeclType->isFunctionType()) {
+if (ExDeclType.isReferenceable())
+  ExDeclType = Context.getPointerType(ExDeclType);
+else 

[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

@Endilll The problem with the CWG713 test in Clang 18 was with parsing the type 
trait (#81298), they weren't actually considered `const`: 
https://godbolt.org/z/snde76brE

Also, I would think since the resolution is purely editorial (it just changes 
notes, nothing normative), it would be considered implemented in any clang 
version?

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


[clang] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584 test (PR #100747)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/100747

https://cplusplus.github.io/CWG/issues/713.html
https://cplusplus.github.io/CWG/issues/1584.html

>From 1ba0cbc3f3fc1d7982c36172ffd0e72245593e6c Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 13:34:00 +0100
Subject: [PATCH] [clang][Tests][NFC] Add CWG713 test; add example from CWG1584
 test

https://cplusplus.github.io/CWG/issues/713.html
https://cplusplus.github.io/CWG/issues/1584.html
---
 clang/test/CXX/drs/cwg15xx.cpp | 48 ++
 clang/test/CXX/drs/cwg7xx.cpp  | 18 -
 clang/www/cxx_dr_status.html   |  2 +-
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp
index 21a392a5141e3..961c25000111a 100644
--- a/clang/test/CXX/drs/cwg15xx.cpp
+++ b/clang/test/CXX/drs/cwg15xx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,cxx11-14,cxx14-17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s 
-verify=expected,cxx11-20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions 
-pedantic-errors
@@ -6,6 +6,11 @@
 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s 
-verify=expected,since-cxx23,since-cxx20,since-cxx11,since-cxx17 -fexceptions 
-fcxx-exceptions -pedantic-errors
 
+#if __cplusplus == 199711L
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
+#endif
+
 namespace cwg1512 { // cwg1512: 4
   void f(char *p) {
 if (p > 0) {}
@@ -556,24 +561,33 @@ auto CWG1579_lambda_invalid = []() -> 
GenericMoveOnly {
 } // end namespace cwg1579
 
 namespace cwg1584 { // cwg1584: 7 drafting 2015-05
-#if __cplusplus >= 201103L
-  // Deducing function types from cv-qualified types
-  template void f(const T *); // #cwg1584-f
-  template void g(T *, const T * = 0);
-  template void h(T *) { T::error; }
-  // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' 
because it has no members}}
-  //   since-cxx11-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
-  template void h(const T *);
-  void i() {
-f();
-// since-cxx11-error@-1 {{no matching function for call to 'f'}}
-//   since-cxx11-note@#cwg1584-f {{candidate template ignored: could not 
match 'const T *' against 'void (*)()'}}
-g();
-h(); // #cwg1584-h
-  }
-#endif
+// Deducing function types from cv-qualified types
+template void f(const T *); // #cwg1584-f
+template void g(T *, const T * = 0);
+template void h(T *) { T::error; }
+// expected-error@-1 {{type 'void ()' cannot be used prior to '::' because it 
has no members}}
+//   expected-note@#cwg1584-h {{in instantiation of function template 
specialization 'cwg1584::h' requested here}}
+template void h(const T *);
+void i() {
+  f();
+  // expected-error@-1 {{no matching function for call to 'f'}}
+  //   expected-note@#cwg1584-f {{candidate template ignored: could not match 
'const T *' against 'void (*)()'}}
+  g();
+  h(); // #cwg1584-h
 }
 
+template struct tuple_size {
+  static const bool is_primary = true;
+};
+template struct tuple_size : tuple_size {
+  static const bool is_primary = false;
+};
+
+tuple_size t;
+static_assert(tuple_size::is_primary, "");
+static_assert(tuple_size::is_primary, "");
+} // namespace cwg1584
+
 namespace cwg1589 {   // cwg1589: 3.7 c++11
 #if __cplusplus >= 201103L
   // Ambiguous ranking of list-initialization sequences
diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp
index 6d93e2948dadb..1e5d3c0873d8b 100644
--- a/clang/test/CXX/drs/cwg7xx.cpp
+++ b/clang/test/CXX/drs/cwg7xx.cpp
@@ -1,9 +1,14 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s 
-verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s 
-verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions 
-pedantic-errors
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s 

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 01/13] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-26 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

I've just found out "accepted" is a resolved DR, not open: 
https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#Issue%20Status

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


[clang] [Clang] Qualified functions can't decay into pointers (PR #90353)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/90353

>From d983badd09dcc227f5945f4b4759214b7b6adbf5 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 26 Jul 2024 08:44:19 +0100
Subject: [PATCH 1/4] [Clang] Qualified functions can't decay into pointers

---
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/include/clang/AST/Type.h|  4 +-
 clang/lib/AST/TypePrinter.cpp | 23 ++
 clang/lib/Sema/SemaDecl.cpp   |  7 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 16 +--
 clang/lib/Sema/SemaTemplate.cpp   | 10 +++-
 clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 14 +-
 clang/lib/Sema/SemaType.cpp   | 46 +++
 .../dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp|  5 +-
 .../CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp   |  5 +-
 clang/test/SemaCXX/function-type-qual.cpp | 36 ++-
 clang/test/SemaCXX/type-traits.cpp| 12 +
 12 files changed, 138 insertions(+), 43 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b165f6e65636d..f25f178bccf7f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -145,6 +145,9 @@ Bug Fixes in This Version
 - Fixed the definition of ``ATOMIC_FLAG_INIT`` in  so it can
   be used in C++.
 
+- cv- and ref- qualified function types no longer silently produce invalid 
pointer to
+  qualified function types when they implicitly decay in some places. Fixes 
(#GH27059).
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 72723c7c56e07..fa5dac96b996d 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -5377,6 +5377,8 @@ class FunctionProtoType final
 return static_cast(FunctionTypeBits.RefQualifier);
   }
 
+  std::string getFunctionQualifiersAsString() const;
+
   using param_type_iterator = const QualType *;
 
   ArrayRef param_types() const {
@@ -7758,7 +7760,7 @@ inline bool QualType::isReferenceable() const {
   if (const auto *F = Self.getAs())
 return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None;
 
-  return false;
+  return Self.isFunctionType();
 }
 
 inline SplitQualType QualType::split() const {
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index ffec3ef9d2269..499e049923e2f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2605,3 +2605,26 @@ raw_ostream ::operator<<(raw_ostream , QualType 
QT) {
   TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
   return OS;
 }
+
+std::string FunctionProtoType::getFunctionQualifiersAsString() const {
+  std::string Quals = getMethodQuals().getAsString();
+
+  switch (getRefQualifier()) {
+  case RQ_None:
+break;
+
+  case RQ_LValue:
+if (!Quals.empty())
+  Quals += ' ';
+Quals += '&';
+break;
+
+  case RQ_RValue:
+if (!Quals.empty())
+  Quals += ' ';
+Quals += "&&";
+break;
+  }
+
+  return Quals;
+}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 575bd292f27de..123dc46c7d884 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15071,6 +15071,13 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
SourceLocation StartLoc,
 T = Context.getLifetimeQualifiedType(T, lifetime);
   }
 
+  if (T->isFunctionType() && !T.isReferenceable()) {
+Diag(NameLoc, diag::err_compound_qualified_function_type)
+<< 1 << true << T
+<< T->castAs()->getFunctionQualifiersAsString();
+return nullptr;
+  }
+
   ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
  Context.getAdjustedParameterType(T),
  TSInfo, SC, nullptr);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1cca8ac9b9343..58b21a1d6f33e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11123,7 +11123,8 @@ void Sema::CheckConversionDeclarator(Declarator , 
QualType ,
 D.setInvalidType();
   } else if (ConvType->isFunctionType()) {
 Diag(D.getIdentifierLoc(), diag::err_conv_function_to_function);
-ConvType = Context.getPointerType(ConvType);
+if (ConvType.isReferenceable())
+  ConvType = Context.getPointerType(ConvType);
 D.setInvalidType();
   }
 
@@ -16719,8 +16720,17 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, 
TypeSourceInfo *TInfo,
   // Arrays and functions decay.
   if (ExDeclType->isArrayType())
 ExDeclType = Context.getArrayDecayedType(ExDeclType);
-  else if (ExDeclType->isFunctionType())
-ExDeclType = Context.getPointerType(ExDeclType);
+  else if (ExDeclType->isFunctionType()) {
+if (ExDeclType.isReferenceable())
+  ExDeclType = Context.getPointerType(ExDeclType);
+else 

[clang] [Clang] Qualified functions can't decay into pointers (PR #90353)

2024-07-26 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

> https://cplusplus.github.io/CWG/issues/713.html

This one is entirely editorial: it adds a note and edits another note. I've 
added a test for what the note says

> https://cplusplus.github.io/CWG/issues/1417.html

I'm not sure that this DR actually changes anything. It seems 
pointers/references to function pointers were ill-formed before and remain 
ill-formed afterwards.

> https://cplusplus.github.io/CWG/issues/1584.html

Clang 7 implemented the 2015 resolution of this: 
413f3c55955537552b556a556d678d5756a9f16b

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


[clang] [Clang] Add __builtin_is_within_lifetime to implement P2641R4's std::is_within_lifetime (PR #91895)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/91895

>From 56aed689dc5825fc5bacc6dfdff58ee0eaf71f82 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 12 May 2024 19:48:24 +0100
Subject: [PATCH 1/9] [Clang] Add attribute for consteval builtins; Declare
 constexpr builtins as constexpr in C++

Also support redeclaring now-constexpr builtins without constexpr
---
 clang/include/clang/Basic/Builtins.h  |  5 +
 clang/include/clang/Basic/BuiltinsBase.td |  2 ++
 clang/lib/Sema/SemaDecl.cpp   | 15 +++
 clang/lib/Sema/SemaDeclCXX.cpp| 18 +-
 clang/lib/Sema/SemaExpr.cpp   |  8 ++--
 clang/test/Sema/builtin-redecl.cpp| 15 ++-
 6 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/Builtins.h 
b/clang/include/clang/Basic/Builtins.h
index f955d21169556..e85ec5b2dca14 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -280,6 +280,11 @@ class Context {
 return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
+  /// Returns true if this is an immediate (consteval) function
+  bool isImmediate(unsigned ID) const {
+return strchr(getRecord(ID).Attributes, 'G') != nullptr;
+  }
+
 private:
   const Info (unsigned ID) const;
 
diff --git a/clang/include/clang/Basic/BuiltinsBase.td 
b/clang/include/clang/Basic/BuiltinsBase.td
index 724747ec76d73..1196b9e15c10d 100644
--- a/clang/include/clang/Basic/BuiltinsBase.td
+++ b/clang/include/clang/Basic/BuiltinsBase.td
@@ -70,6 +70,8 @@ class VScanfFormat : IndexedAttribute<"S", I>;
 
 // Builtin can be constant evaluated
 def Constexpr : Attribute<"E">;
+// Builtin is immediate and must be constant evaluated. Implies Constexpr.
+def Consteval : Attribute<"EG">;
 
 // Builtin kinds
 // =
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index fb913034bd836..6b0a04585928a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2409,10 +2409,17 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, 
QualType Type,
 Parent = CLinkageDecl;
   }
 
-  FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type,
-   /*TInfo=*/nullptr, SC_Extern,
-   
getCurFPFeatures().isFPConstrained(),
-   false, Type->isFunctionProtoType());
+  ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified;
+  if (getLangOpts().CPlusPlus && Context.BuiltinInfo.isConstantEvaluated(ID)) {
+ConstexprKind = ConstexprSpecKind::Constexpr;
+if (Context.BuiltinInfo.isImmediate(ID))
+  ConstexprKind = ConstexprSpecKind::Consteval;
+  }
+
+  FunctionDecl *New = FunctionDecl::Create(
+  Context, Parent, Loc, Loc, II, Type, /*TInfo=*/nullptr, SC_Extern,
+  getCurFPFeatures().isFPConstrained(), /*isInlineSpecified=*/false,
+  Type->isFunctionProtoType(), ConstexprKind);
   New->setImplicit();
   New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));
 
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 53238d355ea09..1b558d70f9b48 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -676,11 +676,19 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, 
FunctionDecl *Old,
   // template has a constexpr specifier then all its declarations shall
   // contain the constexpr specifier.
   if (New->getConstexprKind() != Old->getConstexprKind()) {
-Diag(New->getLocation(), diag::err_constexpr_redecl_mismatch)
-<< New << static_cast(New->getConstexprKind())
-<< static_cast(Old->getConstexprKind());
-Diag(Old->getLocation(), diag::note_previous_declaration);
-Invalid = true;
+if (Old->getBuiltinID() &&
+Old->getConstexprKind() == ConstexprSpecKind::Constexpr &&
+New->getConstexprKind() == ConstexprSpecKind::Unspecified) {
+  // Except allow redeclaring a builtin as non-constexpr to match C
+  // redeclarations which will not be constexpr
+  New->setConstexprKind(ConstexprSpecKind::Constexpr);
+} else {
+  Diag(New->getLocation(), diag::err_constexpr_redecl_mismatch)
+  << New << static_cast(New->getConstexprKind())
+  << static_cast(Old->getConstexprKind());
+  Diag(Old->getLocation(), diag::note_previous_declaration);
+  Invalid = true;
+}
   } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() &&
  Old->isDefined(Def) &&
  // If a friend function is inlined but does not have 'inline'
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bb4b116fd73ca..39aa32526d2b1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7095,8 +7095,12 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, 
NamedDecl *NDecl,
   }
 
   // Bail out 

[clang] [clang] Implement CWG2851: floating-point conversions in converted constant expressions (PR #90387)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/90387

>From 77cb28e6faf95f5beb3fadc225cb5f0525b3dfe6 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 28 Apr 2024 09:48:47 +0100
Subject: [PATCH 1/3] [clang] Implement CWG2851: floating-point conversions in
 converted constant expressions

---
 clang/docs/ReleaseNotes.rst   |  3 +
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/lib/Sema/SemaOverload.cpp   | 38 ++-
 clang/test/CXX/drs/dr28xx.cpp | 64 +++
 clang/www/cxx_dr_status.html  |  2 +-
 5 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 604782ca43dd5..6fb0b2d1030be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -166,6 +166,9 @@ Resolutions to C++ Defect Reports
 - Clang now diagnoses declarative nested-name-specifiers with 
pack-index-specifiers.
   (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers 
`_).
 
+- Allow floating-point promotions and conversions in converted constant 
expressions.
+  (`CWG2851 Allow floating-point conversions in converted constant expressions 
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fdca82934cb4d..cb248f2ea6374 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -85,6 +85,10 @@ def err_expr_not_cce : Error<
   "%select{case value|enumerator value|non-type template argument|"
   "array size|explicit specifier argument|noexcept specifier argument|"
   "call to 'size()'|call to 'data()'}0 is not a constant expression">;
+def err_float_conv_cant_represent : Error<
+  "non-type template argument evaluates to %0 which cannot be "
+  "exactly represented in type %1"
+>;
 def ext_cce_narrowing : ExtWarn<
   "%select{case value|enumerator value|non-type template argument|"
   "array size|explicit specifier argument|noexcept specifier argument|"
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 04cd9e78739d2..40d65638e3afc 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6072,6 +6072,10 @@ static bool CheckConvertedConstantConversions(Sema ,
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere.
   case ICK_Zero_Queue_Conversion:
+  // Per CWG2851, floating-point promotions and conversions are allowed.
+  // The value of a conversion is checked afterwards.
+  case ICK_Floating_Promotion:
+  case ICK_Floating_Conversion:
 return true;
 
   case ICK_Boolean_Conversion:
@@ -6091,9 +6095,7 @@ static bool CheckConvertedConstantConversions(Sema ,
 // only permitted if the source type is std::nullptr_t.
 return SCS.getFromType()->isNullPtrType();
 
-  case ICK_Floating_Promotion:
   case ICK_Complex_Promotion:
-  case ICK_Floating_Conversion:
   case ICK_Complex_Conversion:
   case ICK_Floating_Integral:
   case ICK_Compatible_Conversion:
@@ -6229,7 +6231,37 @@ static ExprResult BuildConvertedConstantExpression(Sema 
, Expr *From,
   if (Result.isInvalid())
 return Result;
 
-  // Check for a narrowing implicit conversion.
+  if (SCS->Second == ICK_Floating_Conversion) {
+// Unlike with narrowing conversions, the value must fit
+// exactly even if it is in range
+assert(CCE == Sema::CCEKind::CCEK_TemplateArg &&
+   "Only non-type template args should use floating-point 
conversions");
+
+// Initializer is From, except it is a full-expression
+const Expr *Initializer =
+IgnoreNarrowingConversion(S.Context, Result.get());
+
+// If it's value-dependent, we can't tell whether it will fit
+if (Initializer->isValueDependent())
+  return Result;
+
+// Not-constant diagnosed afterwards
+if (!Initializer->isCXX11ConstantExpr(S.Context, ))
+  return Result;
+
+llvm::APFloat PostNarrowingValue = PreNarrowingValue.getFloat();
+bool LosesInfo = true;
+PostNarrowingValue.convert(S.Context.getFloatTypeSemantics(T),
+   llvm::APFloat::rmNearestTiesToEven, );
+
+if (LosesInfo)
+  S.Diag(From->getBeginLoc(), diag::err_float_conv_cant_represent)
+  << PreNarrowingValue.getAsString(S.Context, From->getType()) << T;
+
+return Result;
+  }
+
+  // Check for a narrowing integer conversion.
   bool ReturnPreNarrowingValue = false;
   QualType PreNarrowingType;
   switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue,
diff --git a/clang/test/CXX/drs/dr28xx.cpp b/clang/test/CXX/drs/dr28xx.cpp
index be35d366bdd61..9076598da1418 100644
--- a/clang/test/CXX/drs/dr28xx.cpp
+++ 

[clang] [clang] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-26 Thread Mital Ashok via cfe-commits

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


[clang] [clang] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-26 Thread Mital Ashok via cfe-commits

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


[clang] [clang] [SemaCXX] Implement CWG2627 Bit-fields and narrowing conversions (PR #78112)

2024-07-26 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/78112

>From 92f8720e3d21521b589d5291f086a2f32b87bfe0 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 14 Jan 2024 19:52:31 +
Subject: [PATCH 01/10] [clang] [SemaCXX] Implement CWG2627 Bit-fields and
 narrowing conversions

---
 clang/docs/ReleaseNotes.rst   |   5 +
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Overload.h   |   7 +-
 clang/lib/Sema/SemaExpr.cpp   |  10 +-
 clang/lib/Sema/SemaInit.cpp   |  20 ++-
 clang/lib/Sema/SemaOverload.cpp   | 119 +--
 .../dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp |  24 
 clang/test/CXX/drs/dr26xx.cpp | 136 ++
 clang/www/cxx_dr_status.html  |   2 +-
 9 files changed, 278 insertions(+), 48 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92563262cc673..28202fc604e29 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -157,6 +157,11 @@ Resolutions to C++ Defect Reports
 - Clang now diagnoses declarative nested-name-specifiers with 
pack-index-specifiers.
   (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers 
`_).
 
+- Casts from a bit-field to an integral type is now not considered narrowing 
if the
+  width of the bit-field means that all potential values are in the range
+  of the target type, even if the type of the bit-field is larger.
+  (`CWG2627. Bit-fields and narrowing conversions  
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fdca82934cb4d..6cdb439be30ae 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6253,6 +6253,9 @@ def ext_init_list_variable_narrowing_const_reference : 
ExtWarn<
 def ext_init_list_constant_narrowing : ExtWarn<
   "constant expression evaluates to %0 which cannot be narrowed to type %1">,
   InGroup, DefaultError, SFINAEFailure;
+def ext_bit_field_narrowing : Extension<
+  "narrowing non-constant-expression from %0 bit-field of width %2 to %1 is a 
C++23 extension">,
+  InGroup, SFINAEFailure;
 def ext_init_list_constant_narrowing_const_reference : ExtWarn<
   ext_init_list_constant_narrowing.Summary>,
   InGroup, DefaultError, SFINAEFailure;
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 76311b00d2fc5..0d94045cc13f7 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -244,7 +244,11 @@ class Sema;
 /// Not a narrowing conversion.
 NK_Not_Narrowing,
 
-/// A narrowing conversion by virtue of the source and destination types.
+/// Not a narrowing conversion in C++23 because the source is a bit-field
+/// whose range can fit in the target type
+NK_BitField_Not_Narrowing,
+
+/// A narrowing conversion by virtue of the source and target types.
 NK_Type_Narrowing,
 
 /// A narrowing conversion, because a constant expression got narrowed.
@@ -387,6 +391,7 @@ class Sema;
 NarrowingKind
 getNarrowingKind(ASTContext , const Expr *Converted,
  APValue , QualType ,
+ unsigned ,
  bool IgnoreFloatToIntegralConversion = false) const;
 bool isPointerConversionToBool() const;
 bool isPointerConversionToVoidPointer(ASTContext& Context) const;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 50f92c496a539..4c16fcc60fc77 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -12361,8 +12361,9 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
 
   APValue PreNarrowingValue;
   QualType PreNarrowingType;
+  unsigned BitFieldWidth;
   switch (SCS.getNarrowingKind(S.Context, E, PreNarrowingValue,
-   PreNarrowingType,
+   PreNarrowingType, BitFieldWidth,
/*IgnoreFloatToIntegralConversion*/ true)) {
   case NK_Dependent_Narrowing:
 // Implicit conversion to a narrower type, but the expression is
@@ -12370,6 +12371,13 @@ static bool checkThreeWayNarrowingConversion(Sema , 
QualType ToType, Expr *E,
   case NK_Not_Narrowing:
 return false;
 
+  case NK_BitField_Not_Narrowing:
+if (!S.getLangOpts().CPlusPlus23) {
+  return S.Diag(E->getBeginLoc(), diag::ext_bit_field_narrowing)
+ << FromType << ToType << BitFieldWidth;
+}
+return false;
+
   case NK_Constant_Narrowing:
 // Implicit conversion to a narrower type, and the value is not a constant
 // expression.
diff --git a/clang/lib/Sema/SemaInit.cpp 

[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits

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


[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits


@@ -14578,21 +14578,51 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation 
OpLoc,
 BinaryOperatorKind Opc,
 Expr *LHSExpr, Expr *RHSExpr) {
   if (getLangOpts().CPlusPlus11 && isa(RHSExpr)) {
-// The syntax only allows initializer lists on the RHS of assignment,
-// so we don't need to worry about accepting invalid code for
-// non-assignment operators.
-// C++11 5.17p9:
-//   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-//   of x = {} is x = T().
-InitializationKind Kind = InitializationKind::CreateDirectList(
-RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
+// C++11 [expr.ass]p9, per CWG2768:
+//   A braced-init-list B may appear on the right-hand side of
+//- an assignment to a scalar of type T, in which case B shall have at
+//  most a single element. The meaning of x = B is x = t, where t is an
+//  invented temporary variable declared and initialized as T t = B.
+if (Opc != BO_Assign) {

MitalAshok wrote:

Here's the test: 
https://github.com/llvm/llvm-project/pull/100548/files#diff-b618bc278c2279c9a4b407c5d4863f53c258e1f8bf6629c4daff11bc38c6e452R28

Previously this was accepted. This line in the standard only applies to "scalar 
= B", not "scalar op= B".

Actually this might be a bit ambiguous. The following example in the standard 
() does not use a compound 
assignment with scalars. But "E1 op= E2" seems to only be defined as "E1 = E1 
op E2" (), which shouldn't be 
accepted if E2 is a braced-init-list

Also GCC rejects this (`int i; i += {0};`)

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


[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100548

>From 2c1d87c025a8caa818dd275560f31d0d4f8d64b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Thu, 25 Jul 2024 10:56:16 +0100
Subject: [PATCH 1/2] [Clang] Initializer list on RHS of assignment

---
 clang/docs/ReleaseNotes.rst |  4 ++
 clang/lib/Sema/SemaExpr.cpp | 65 +++--
 clang/test/CXX/drs/cwg27xx.cpp  | 26 +++---
 clang/test/SemaCXX/assign-init-list.cpp | 20 
 clang/www/cxx_dr_status.html|  2 +-
 5 files changed, 95 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/SemaCXX/assign-init-list.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b79e952b48af..bc048e8bfacba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,9 @@ C++2c Feature Support
 Resolutions to C++ Defect Reports
 ^
 
+- Reject assigning to enums with an initailizer list containing an integer.
+  (`CWG2768: Assignment to enumeration variable with a braced-init-list 
`_).
+
 C Language Changes
 --
 
@@ -150,6 +153,7 @@ Bug Fixes to C++ Support
 
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
+- Reject compound assignment operators with a braced-init-list.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 74c0e01705905..08ee28c108952 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14578,21 +14578,56 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation 
OpLoc,
 BinaryOperatorKind Opc,
 Expr *LHSExpr, Expr *RHSExpr) {
   if (getLangOpts().CPlusPlus11 && isa(RHSExpr)) {
-// The syntax only allows initializer lists on the RHS of assignment,
-// so we don't need to worry about accepting invalid code for
-// non-assignment operators.
-// C++11 5.17p9:
-//   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-//   of x = {} is x = T().
-InitializationKind Kind = InitializationKind::CreateDirectList(
-RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
-InitializedEntity Entity =
-InitializedEntity::InitializeTemporary(LHSExpr->getType());
-InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
-ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
-if (Init.isInvalid())
-  return Init;
-RHSExpr = Init.get();
+// C++11 [expr.ass]p9, per CWG2768:
+//   A braced-init-list B may appear on the right-hand side of
+//- an assignment to a scalar of type T, in which case the initializer
+//  list shall have at most a single element. The meaning of x = B is
+//  x = t, where t is an invented temporary variable declared and
+//  initialized as T t = B.
+switch (Opc) {
+case BO_Assign: {
+  QualType LHSTy = LHSExpr->getType();
+  assert(!LHSTy->isDependentType() &&
+ "Should not have tried to create a builtin binary operator");
+  if (LHSTy->isScalarType()) {
+InitializationKind Kind =
+InitializationKind::CreateCopy(RHSExpr->getBeginLoc(), OpLoc);
+InitializedEntity Entity =
+InitializedEntity::InitializeTemporary(LHSExpr->getType());
+InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
+ExprResult InventedTemporary =
+InitSeq.Perform(*this, Entity, Kind, RHSExpr);
+if (InventedTemporary.isInvalid())
+  return InventedTemporary;
+assert(cast(RHSExpr)->getNumInits() <= 1 &&
+   "The initialization should have failed");
+RHSExpr = InventedTemporary.get();
+  }
+  break;
+}
+case BO_MulAssign:
+case BO_DivAssign:
+case BO_RemAssign:
+case BO_AddAssign:
+case BO_SubAssign:
+case BO_ShlAssign:
+case BO_ShrAssign:
+case BO_AndAssign:
+case BO_XorAssign:
+case BO_OrAssign: {
+  // A compound assignment like `i += {0}` is equivalent to `i = i + {0}`,
+  // which is a parsing error
+  StringRef Op = BinaryOperator::getOpcodeStr(Opc);
+  [[maybe_unused]] bool AssignmentStripped = Op.consume_back("=");
+  assert(AssignmentStripped);
+  Diag(OpLoc, diag::err_init_list_bin_op)
+  << 1 << Op << getExprRange(RHSExpr);
+  return ExprError();
+}
+default:
+  llvm_unreachable("Non-assignment binary operator with braced-init-list "
+   "should not be parsed");
+}
   }
 
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 

[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100548

>From 2c1d87c025a8caa818dd275560f31d0d4f8d64b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Thu, 25 Jul 2024 10:56:16 +0100
Subject: [PATCH 1/2] [Clang] Initializer list on RHS of assignment

---
 clang/docs/ReleaseNotes.rst |  4 ++
 clang/lib/Sema/SemaExpr.cpp | 65 +++--
 clang/test/CXX/drs/cwg27xx.cpp  | 26 +++---
 clang/test/SemaCXX/assign-init-list.cpp | 20 
 clang/www/cxx_dr_status.html|  2 +-
 5 files changed, 95 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/SemaCXX/assign-init-list.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b79e952b48af..bc048e8bfacba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,9 @@ C++2c Feature Support
 Resolutions to C++ Defect Reports
 ^
 
+- Reject assigning to enums with an initailizer list containing an integer.
+  (`CWG2768: Assignment to enumeration variable with a braced-init-list 
`_).
+
 C Language Changes
 --
 
@@ -150,6 +153,7 @@ Bug Fixes to C++ Support
 
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
+- Reject compound assignment operators with a braced-init-list.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 74c0e01705905..08ee28c108952 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14578,21 +14578,56 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation 
OpLoc,
 BinaryOperatorKind Opc,
 Expr *LHSExpr, Expr *RHSExpr) {
   if (getLangOpts().CPlusPlus11 && isa(RHSExpr)) {
-// The syntax only allows initializer lists on the RHS of assignment,
-// so we don't need to worry about accepting invalid code for
-// non-assignment operators.
-// C++11 5.17p9:
-//   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-//   of x = {} is x = T().
-InitializationKind Kind = InitializationKind::CreateDirectList(
-RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
-InitializedEntity Entity =
-InitializedEntity::InitializeTemporary(LHSExpr->getType());
-InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
-ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
-if (Init.isInvalid())
-  return Init;
-RHSExpr = Init.get();
+// C++11 [expr.ass]p9, per CWG2768:
+//   A braced-init-list B may appear on the right-hand side of
+//- an assignment to a scalar of type T, in which case the initializer
+//  list shall have at most a single element. The meaning of x = B is
+//  x = t, where t is an invented temporary variable declared and
+//  initialized as T t = B.
+switch (Opc) {
+case BO_Assign: {
+  QualType LHSTy = LHSExpr->getType();
+  assert(!LHSTy->isDependentType() &&
+ "Should not have tried to create a builtin binary operator");
+  if (LHSTy->isScalarType()) {
+InitializationKind Kind =
+InitializationKind::CreateCopy(RHSExpr->getBeginLoc(), OpLoc);
+InitializedEntity Entity =
+InitializedEntity::InitializeTemporary(LHSExpr->getType());
+InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
+ExprResult InventedTemporary =
+InitSeq.Perform(*this, Entity, Kind, RHSExpr);
+if (InventedTemporary.isInvalid())
+  return InventedTemporary;
+assert(cast(RHSExpr)->getNumInits() <= 1 &&
+   "The initialization should have failed");
+RHSExpr = InventedTemporary.get();
+  }
+  break;
+}
+case BO_MulAssign:
+case BO_DivAssign:
+case BO_RemAssign:
+case BO_AddAssign:
+case BO_SubAssign:
+case BO_ShlAssign:
+case BO_ShrAssign:
+case BO_AndAssign:
+case BO_XorAssign:
+case BO_OrAssign: {
+  // A compound assignment like `i += {0}` is equivalent to `i = i + {0}`,
+  // which is a parsing error
+  StringRef Op = BinaryOperator::getOpcodeStr(Opc);
+  [[maybe_unused]] bool AssignmentStripped = Op.consume_back("=");
+  assert(AssignmentStripped);
+  Diag(OpLoc, diag::err_init_list_bin_op)
+  << 1 << Op << getExprRange(RHSExpr);
+  return ExprError();
+}
+default:
+  llvm_unreachable("Non-assignment binary operator with braced-init-list "
+   "should not be parsed");
+}
   }
 
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 

[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100548

>From 2c1d87c025a8caa818dd275560f31d0d4f8d64b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Thu, 25 Jul 2024 10:56:16 +0100
Subject: [PATCH] [Clang] Initializer list on RHS of assignment

---
 clang/docs/ReleaseNotes.rst |  4 ++
 clang/lib/Sema/SemaExpr.cpp | 65 +++--
 clang/test/CXX/drs/cwg27xx.cpp  | 26 +++---
 clang/test/SemaCXX/assign-init-list.cpp | 20 
 clang/www/cxx_dr_status.html|  2 +-
 5 files changed, 95 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/SemaCXX/assign-init-list.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b79e952b48af..bc048e8bfacba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,9 @@ C++2c Feature Support
 Resolutions to C++ Defect Reports
 ^
 
+- Reject assigning to enums with an initailizer list containing an integer.
+  (`CWG2768: Assignment to enumeration variable with a braced-init-list 
`_).
+
 C Language Changes
 --
 
@@ -150,6 +153,7 @@ Bug Fixes to C++ Support
 
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
+- Reject compound assignment operators with a braced-init-list.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 74c0e01705905..08ee28c108952 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14578,21 +14578,56 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation 
OpLoc,
 BinaryOperatorKind Opc,
 Expr *LHSExpr, Expr *RHSExpr) {
   if (getLangOpts().CPlusPlus11 && isa(RHSExpr)) {
-// The syntax only allows initializer lists on the RHS of assignment,
-// so we don't need to worry about accepting invalid code for
-// non-assignment operators.
-// C++11 5.17p9:
-//   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-//   of x = {} is x = T().
-InitializationKind Kind = InitializationKind::CreateDirectList(
-RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
-InitializedEntity Entity =
-InitializedEntity::InitializeTemporary(LHSExpr->getType());
-InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
-ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
-if (Init.isInvalid())
-  return Init;
-RHSExpr = Init.get();
+// C++11 [expr.ass]p9, per CWG2768:
+//   A braced-init-list B may appear on the right-hand side of
+//- an assignment to a scalar of type T, in which case the initializer
+//  list shall have at most a single element. The meaning of x = B is
+//  x = t, where t is an invented temporary variable declared and
+//  initialized as T t = B.
+switch (Opc) {
+case BO_Assign: {
+  QualType LHSTy = LHSExpr->getType();
+  assert(!LHSTy->isDependentType() &&
+ "Should not have tried to create a builtin binary operator");
+  if (LHSTy->isScalarType()) {
+InitializationKind Kind =
+InitializationKind::CreateCopy(RHSExpr->getBeginLoc(), OpLoc);
+InitializedEntity Entity =
+InitializedEntity::InitializeTemporary(LHSExpr->getType());
+InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
+ExprResult InventedTemporary =
+InitSeq.Perform(*this, Entity, Kind, RHSExpr);
+if (InventedTemporary.isInvalid())
+  return InventedTemporary;
+assert(cast(RHSExpr)->getNumInits() <= 1 &&
+   "The initialization should have failed");
+RHSExpr = InventedTemporary.get();
+  }
+  break;
+}
+case BO_MulAssign:
+case BO_DivAssign:
+case BO_RemAssign:
+case BO_AddAssign:
+case BO_SubAssign:
+case BO_ShlAssign:
+case BO_ShrAssign:
+case BO_AndAssign:
+case BO_XorAssign:
+case BO_OrAssign: {
+  // A compound assignment like `i += {0}` is equivalent to `i = i + {0}`,
+  // which is a parsing error
+  StringRef Op = BinaryOperator::getOpcodeStr(Opc);
+  [[maybe_unused]] bool AssignmentStripped = Op.consume_back("=");
+  assert(AssignmentStripped);
+  Diag(OpLoc, diag::err_init_list_bin_op)
+  << 1 << Op << getExprRange(RHSExpr);
+  return ExprError();
+}
+default:
+  llvm_unreachable("Non-assignment binary operator with braced-init-list "
+   "should not be parsed");
+}
   }
 
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 

[clang] [Clang] Initializer list on RHS of assignment (PR #100548)

2024-07-25 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/100548

This implements [CWG2768](https://cplusplus.github.io/CWG/issues/2768.html).

Also fixes a bug where `x op= {v}` was treated as `x op= v` for compound 
assignments, which shouldn't have happened.

Fixes #100527

>From 3de1983173a0281811d9d53cd4f553438fe2b054 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Thu, 25 Jul 2024 10:56:16 +0100
Subject: [PATCH] [Clang] Initializer list on RHS of assignment

---
 clang/docs/ReleaseNotes.rst |  4 ++
 clang/lib/Sema/SemaExpr.cpp | 65 +++--
 clang/test/CXX/drs/cwg27xx.cpp  | 26 +++---
 clang/test/SemaCXX/assign-init-list.cpp | 20 
 clang/www/cxx_dr_status.html|  2 +-
 5 files changed, 95 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/SemaCXX/assign-init-list.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b79e952b48af..bc048e8bfacba 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,9 @@ C++2c Feature Support
 Resolutions to C++ Defect Reports
 ^
 
+- Reject assigning to enums with an initailizer list containing an integer.
+  (`CWG2768: Assignment to enumeration variable with a braced-init-list 
`_).
+
 C Language Changes
 --
 
@@ -150,6 +153,7 @@ Bug Fixes to C++ Support
 
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
+- Reject compound assignment operators with a braced-init-list.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 74c0e01705905..7b9301cf9c560 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14578,21 +14578,56 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation 
OpLoc,
 BinaryOperatorKind Opc,
 Expr *LHSExpr, Expr *RHSExpr) {
   if (getLangOpts().CPlusPlus11 && isa(RHSExpr)) {
-// The syntax only allows initializer lists on the RHS of assignment,
-// so we don't need to worry about accepting invalid code for
-// non-assignment operators.
-// C++11 5.17p9:
-//   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
-//   of x = {} is x = T().
-InitializationKind Kind = InitializationKind::CreateDirectList(
-RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
-InitializedEntity Entity =
-InitializedEntity::InitializeTemporary(LHSExpr->getType());
-InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
-ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
-if (Init.isInvalid())
-  return Init;
-RHSExpr = Init.get();
+// C++11 [expr.ass]p9, per CWG2768:
+//   A braced-init-list B may appear on the right-hand side of
+//- an assignment to a scalar of type T, in which case the initializer
+//list shall have at most a single element. The meaning of x=B is x = 
t,
+//where t is an invented temporary variable declared and initialized as
+//T t = B
+switch (Opc) {
+case BO_Assign: {
+  QualType LHSTy = LHSExpr->getType();
+  assert(!LHSTy->isDependentType() &&
+ "Should not have tried to create a builtin binary operator");
+  if (LHSTy->isScalarType()) {
+InitializationKind Kind =
+InitializationKind::CreateCopy(RHSExpr->getBeginLoc(), OpLoc);
+InitializedEntity Entity =
+InitializedEntity::InitializeTemporary(LHSExpr->getType());
+InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
+ExprResult InventedTemporary =
+InitSeq.Perform(*this, Entity, Kind, RHSExpr);
+if (InventedTemporary.isInvalid())
+  return InventedTemporary;
+assert(cast(RHSExpr)->getNumInits() <= 1 &&
+   "The initialization should have failed");
+RHSExpr = InventedTemporary.get();
+  }
+  break;
+}
+case BO_MulAssign:
+case BO_DivAssign:
+case BO_RemAssign:
+case BO_AddAssign:
+case BO_SubAssign:
+case BO_ShlAssign:
+case BO_ShrAssign:
+case BO_AndAssign:
+case BO_XorAssign:
+case BO_OrAssign: {
+  // A compound assignment like `i += {0}` is equivalent to `i = i + {0}`,
+  // which is a parsing error
+  StringRef Op = BinaryOperator::getOpcodeStr(Opc);
+  [[maybe_unused]] bool AssignmentStripped = Op.consume_back("=");
+  assert(AssignmentStripped);
+  Diag(OpLoc, diag::err_init_list_bin_op)
+  << 1 << Op << getExprRange(RHSExpr);
+  return ExprError();
+}
+default:
+  llvm_unreachable("Non-assignment binary operator with braced-init-list "
+   

[clang] [Clang] Check explicit object parameter for defaulted operators properly (PR #100419)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/100419

>From 5d2b3fa876c00869a3964081a57ae23563d18175 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Wed, 24 Jul 2024 16:58:56 +0100
Subject: [PATCH 1/4] [Clang] Check explicit object param for defaulted
 relational operator has correct type

---
 clang/docs/ReleaseNotes.rst   |  3 +
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/Sema/SemaDeclCXX.cpp| 49 +
 .../class.compare.default/p1.cpp  |  2 +
 clang/test/CXX/drs/cwg25xx.cpp| 55 +++
 clang/test/SemaCXX/cxx2b-deducing-this.cpp| 12 +++-
 clang/www/cxx_dr_status.html  |  4 +-
 7 files changed, 100 insertions(+), 27 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 65de90f69e198..550414ae82fdd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -149,6 +149,9 @@ Bug Fixes to C++ Support
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
 
+- Properly reject defaulted relational operators with invalid types for 
explicit object parameters,
+  e.g., ``bool operator==(this int, const Foo&)`` (#GH100329), and rvalue 
reference parameters.
+
 Bug Fixes to AST Handling
 ^
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 810abe4f23e31..d147992bca18d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9741,7 +9741,7 @@ def err_defaulted_special_member_quals : Error<
   "have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
 def err_defaulted_special_member_explicit_object_mismatch : Error<
   "the type of the explicit object parameter of an explicitly-defaulted "
-  "%select{copy|move}0 assignment operator should match the type of the class 
%1">;
+  "%select{copy|move}0 assignment operator should be reference to %1">;
 def err_defaulted_special_member_volatile_param : Error<
   "the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 
"
   "may not be volatile">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 04b8d88cae217..273e83748d1fe 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7617,9 +7617,13 @@ bool 
Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
 // parameter is of (possibly different) type “reference to C”,
 // in which case the type of F1 would differ from the type of F2
 // in that the type of F1 has an additional parameter;
-if (!Context.hasSameType(
-ThisType.getNonReferenceType().getUnqualifiedType(),
-Context.getRecordType(RD))) {
+QualType ExplicitObjectParameter = MD->isExplicitObjectMemberFunction()
+   ? MD->getParamDecl(0)->getType()
+   : QualType();
+if (!ExplicitObjectParameter.isNull() &&
+(!ExplicitObjectParameter->isReferenceType() ||
+ !Context.hasSameType(ExplicitObjectParameter.getNonReferenceType(),
+  Context.getRecordType(RD {
   if (DeleteOnTypeMismatch)
 ShouldDeleteForTypeMismatch = true;
   else {
@@ -8704,7 +8708,8 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, 
FunctionDecl *FD,
 if (!RD)
   RD = MD->getParent();
 QualType T = MD->getFunctionObjectParameterType();
-if (!T.isConstQualified()) {
+if (!T.getNonReferenceType().isConstQualified() &&
+(MD->isImplicitObjectMemberFunction() || T->isLValueReferenceType())) {
   SourceLocation Loc, InsertLoc;
   if (MD->isExplicitObjectMemberFunction()) {
 Loc = MD->getParamDecl(0)->getBeginLoc();
@@ -8723,11 +8728,17 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, 
FunctionDecl *FD,
   }
 
   // Add the 'const' to the type to recover.
-  const auto *FPT = MD->getType()->castAs();
-  FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-  EPI.TypeQuals.addConst();
-  MD->setType(Context.getFunctionType(FPT->getReturnType(),
-  FPT->getParamTypes(), EPI));
+  if (MD->isExplicitObjectMemberFunction()) {
+assert(T->isLValueReferenceType());
+MD->getParamDecl(0)->setType(Context.getLValueReferenceType(
+T.getNonReferenceType().withConst()));
+  } else {
+const auto *FPT = MD->getType()->castAs();
+FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+EPI.TypeQuals.addConst();
+MD->setType(Context.getFunctionType(FPT->getReturnType(),
+FPT->getParamTypes(), EPI));
+  }
 }
 
 if 

[clang] [Clang] Check explicit object parameter for defaulted operators properly (PR #100419)

2024-07-24 Thread Mital Ashok via cfe-commits


@@ -7617,9 +7617,13 @@ bool 
Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
 // parameter is of (possibly different) type “reference to C”,
 // in which case the type of F1 would differ from the type of F2
 // in that the type of F1 has an additional parameter;
-if (!Context.hasSameType(
-ThisType.getNonReferenceType().getUnqualifiedType(),
-Context.getRecordType(RD))) {

MitalAshok wrote:

That's checked somewhere later, this was operating on `ThisType`.

For an implicit object member function, 
`ThisType.getNonReferenceType().getUnqualifiedType()` is *always* 
`Context.getRecordType(RD)` (and this shouldn't fail anyways because the 
diagnostic emitted here is 
`err_defaulted_special_member_explicit_object_mismatch`)

The only difference is with explicit object member functions. The old code 
rejected `S& S::operator=(this int, const S&) = default;`, but accepted `S& 
S::operator=(this S, const S&)` since it didn't check that it was a reference.

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


[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/95112

>From e53dfbc9b2c6b7f30c1378731d7de284fa99d568 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Tue, 11 Jun 2024 14:26:38 +0100
Subject: [PATCH 1/9] [Clang] Implement CWG2813

---
 clang/docs/ReleaseNotes.rst   |  5 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/lib/Sema/SemaExprMember.cpp | 64 +++---
 clang/lib/Sema/SemaOverload.cpp   | 11 +--
 clang/lib/Sema/SemaStmt.cpp   | 14 ++-
 .../test/AST/ast-dump-for-range-lifetime.cpp  | 12 +--
 .../dcl.attr/dcl.attr.nodiscard/p2.cpp| 86 ++-
 clang/test/CXX/drs/cwg28xx.cpp| 17 
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp |  1 -
 clang/www/cxx_dr_status.html  |  2 +-
 10 files changed, 164 insertions(+), 51 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..36bf1fdea3602 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -260,6 +260,11 @@ Resolutions to C++ Defect Reports
 - Clang now requires a template argument list after a template keyword.
   (`CWG96: Syntactic disambiguation using the template keyword 
`_).
 
+- Clang now allows calling explicit object member functions directly with 
prvalues
+  instead of always materializing a temporary, meaning by-value explicit 
object parameters
+  do not need to move from a temporary.
+  (`CWG2813: Class member access with prvalues 
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 193eae3bc41d6..008bf5fa0ccfc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9182,6 +9182,9 @@ def warn_unused_constructor : Warning<
 def warn_unused_constructor_msg : Warning<
   "ignoring temporary created by a constructor declared with %0 attribute: 
%1">,
   InGroup;
+def warn_discarded_class_member_access : Warning<
+  "left operand of dot in this class member access is discarded and has no 
effect">,
+  InGroup;
 def warn_side_effects_unevaluated_context : Warning<
   "expression with side effects has no effect in an unevaluated context">,
   InGroup;
diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 3ae1af26d0096..4679fe529ac91 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1015,15 +1015,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   : !isDependentScopeSpecifier(SS) || computeDeclContext(SS)) &&
  "dependent lookup context that isn't the current instantiation?");
 
-  // C++1z [expr.ref]p2:
-  //   For the first option (dot) the first expression shall be a glvalue [...]
-  if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) {
-ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
-if (Converted.isInvalid())
-  return ExprError();
-BaseExpr = Converted.get();
-  }
-
   const DeclarationNameInfo  = R.getLookupNameInfo();
   DeclarationName MemberName = MemberNameInfo.getName();
   SourceLocation MemberLoc = MemberNameInfo.getLoc();
@@ -1140,26 +1131,68 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
   }
 
+  // C++17 [expr.ref]p2, per CWG2813:
+  //   For the first option (dot), if the id-expression names a static member 
or
+  //   an enumerator, the first expression is a discarded-value expression; if
+  //   the id-expression names a non-static data member, the first expression
+  //   shall be a glvalue.
+  auto MakeDiscardedValue = [, IsArrow, this] {
+assert(getLangOpts().CPlusPlus &&
+   "Static member / member enumerator outside of C++");
+if (IsArrow)
+  return false;
+ExprResult Converted = IgnoredValueConversions(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+DiagnoseUnusedExprResult(BaseExpr,
+ diag::warn_discarded_class_member_access);
+return false;
+  };
+  auto MakeGLValue = [, IsArrow, this] {
+if (IsArrow || !BaseExpr->isPRValue())
+  return false;
+ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+return false;
+  };
+
   // Check the use of this member.
   if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
 return ExprError();
 
-  if (FieldDecl *FD = dyn_cast(MemberDecl))
+  if (FieldDecl *FD = dyn_cast(MemberDecl)) {
+if (MakeGLValue())
+  return ExprError();
 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, 

[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/95112

>From e53dfbc9b2c6b7f30c1378731d7de284fa99d568 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Tue, 11 Jun 2024 14:26:38 +0100
Subject: [PATCH 01/11] [Clang] Implement CWG2813

---
 clang/docs/ReleaseNotes.rst   |  5 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/lib/Sema/SemaExprMember.cpp | 64 +++---
 clang/lib/Sema/SemaOverload.cpp   | 11 +--
 clang/lib/Sema/SemaStmt.cpp   | 14 ++-
 .../test/AST/ast-dump-for-range-lifetime.cpp  | 12 +--
 .../dcl.attr/dcl.attr.nodiscard/p2.cpp| 86 ++-
 clang/test/CXX/drs/cwg28xx.cpp| 17 
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp |  1 -
 clang/www/cxx_dr_status.html  |  2 +-
 10 files changed, 164 insertions(+), 51 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..36bf1fdea3602 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -260,6 +260,11 @@ Resolutions to C++ Defect Reports
 - Clang now requires a template argument list after a template keyword.
   (`CWG96: Syntactic disambiguation using the template keyword 
`_).
 
+- Clang now allows calling explicit object member functions directly with 
prvalues
+  instead of always materializing a temporary, meaning by-value explicit 
object parameters
+  do not need to move from a temporary.
+  (`CWG2813: Class member access with prvalues 
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 193eae3bc41d6..008bf5fa0ccfc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9182,6 +9182,9 @@ def warn_unused_constructor : Warning<
 def warn_unused_constructor_msg : Warning<
   "ignoring temporary created by a constructor declared with %0 attribute: 
%1">,
   InGroup;
+def warn_discarded_class_member_access : Warning<
+  "left operand of dot in this class member access is discarded and has no 
effect">,
+  InGroup;
 def warn_side_effects_unevaluated_context : Warning<
   "expression with side effects has no effect in an unevaluated context">,
   InGroup;
diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 3ae1af26d0096..4679fe529ac91 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1015,15 +1015,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   : !isDependentScopeSpecifier(SS) || computeDeclContext(SS)) &&
  "dependent lookup context that isn't the current instantiation?");
 
-  // C++1z [expr.ref]p2:
-  //   For the first option (dot) the first expression shall be a glvalue [...]
-  if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) {
-ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
-if (Converted.isInvalid())
-  return ExprError();
-BaseExpr = Converted.get();
-  }
-
   const DeclarationNameInfo  = R.getLookupNameInfo();
   DeclarationName MemberName = MemberNameInfo.getName();
   SourceLocation MemberLoc = MemberNameInfo.getLoc();
@@ -1140,26 +1131,68 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
   }
 
+  // C++17 [expr.ref]p2, per CWG2813:
+  //   For the first option (dot), if the id-expression names a static member 
or
+  //   an enumerator, the first expression is a discarded-value expression; if
+  //   the id-expression names a non-static data member, the first expression
+  //   shall be a glvalue.
+  auto MakeDiscardedValue = [, IsArrow, this] {
+assert(getLangOpts().CPlusPlus &&
+   "Static member / member enumerator outside of C++");
+if (IsArrow)
+  return false;
+ExprResult Converted = IgnoredValueConversions(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+DiagnoseUnusedExprResult(BaseExpr,
+ diag::warn_discarded_class_member_access);
+return false;
+  };
+  auto MakeGLValue = [, IsArrow, this] {
+if (IsArrow || !BaseExpr->isPRValue())
+  return false;
+ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+return false;
+  };
+
   // Check the use of this member.
   if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
 return ExprError();
 
-  if (FieldDecl *FD = dyn_cast(MemberDecl))
+  if (FieldDecl *FD = dyn_cast(MemberDecl)) {
+if (MakeGLValue())
+  return ExprError();
 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, 

[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)

2024-07-24 Thread Mital Ashok via cfe-commits

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


[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/95112

>From e53dfbc9b2c6b7f30c1378731d7de284fa99d568 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Tue, 11 Jun 2024 14:26:38 +0100
Subject: [PATCH 01/10] [Clang] Implement CWG2813

---
 clang/docs/ReleaseNotes.rst   |  5 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/lib/Sema/SemaExprMember.cpp | 64 +++---
 clang/lib/Sema/SemaOverload.cpp   | 11 +--
 clang/lib/Sema/SemaStmt.cpp   | 14 ++-
 .../test/AST/ast-dump-for-range-lifetime.cpp  | 12 +--
 .../dcl.attr/dcl.attr.nodiscard/p2.cpp| 86 ++-
 clang/test/CXX/drs/cwg28xx.cpp| 17 
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp |  1 -
 clang/www/cxx_dr_status.html  |  2 +-
 10 files changed, 164 insertions(+), 51 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..36bf1fdea3602 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -260,6 +260,11 @@ Resolutions to C++ Defect Reports
 - Clang now requires a template argument list after a template keyword.
   (`CWG96: Syntactic disambiguation using the template keyword 
`_).
 
+- Clang now allows calling explicit object member functions directly with 
prvalues
+  instead of always materializing a temporary, meaning by-value explicit 
object parameters
+  do not need to move from a temporary.
+  (`CWG2813: Class member access with prvalues 
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 193eae3bc41d6..008bf5fa0ccfc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9182,6 +9182,9 @@ def warn_unused_constructor : Warning<
 def warn_unused_constructor_msg : Warning<
   "ignoring temporary created by a constructor declared with %0 attribute: 
%1">,
   InGroup;
+def warn_discarded_class_member_access : Warning<
+  "left operand of dot in this class member access is discarded and has no 
effect">,
+  InGroup;
 def warn_side_effects_unevaluated_context : Warning<
   "expression with side effects has no effect in an unevaluated context">,
   InGroup;
diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 3ae1af26d0096..4679fe529ac91 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1015,15 +1015,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   : !isDependentScopeSpecifier(SS) || computeDeclContext(SS)) &&
  "dependent lookup context that isn't the current instantiation?");
 
-  // C++1z [expr.ref]p2:
-  //   For the first option (dot) the first expression shall be a glvalue [...]
-  if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) {
-ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
-if (Converted.isInvalid())
-  return ExprError();
-BaseExpr = Converted.get();
-  }
-
   const DeclarationNameInfo  = R.getLookupNameInfo();
   DeclarationName MemberName = MemberNameInfo.getName();
   SourceLocation MemberLoc = MemberNameInfo.getLoc();
@@ -1140,26 +1131,68 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
   }
 
+  // C++17 [expr.ref]p2, per CWG2813:
+  //   For the first option (dot), if the id-expression names a static member 
or
+  //   an enumerator, the first expression is a discarded-value expression; if
+  //   the id-expression names a non-static data member, the first expression
+  //   shall be a glvalue.
+  auto MakeDiscardedValue = [, IsArrow, this] {
+assert(getLangOpts().CPlusPlus &&
+   "Static member / member enumerator outside of C++");
+if (IsArrow)
+  return false;
+ExprResult Converted = IgnoredValueConversions(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+DiagnoseUnusedExprResult(BaseExpr,
+ diag::warn_discarded_class_member_access);
+return false;
+  };
+  auto MakeGLValue = [, IsArrow, this] {
+if (IsArrow || !BaseExpr->isPRValue())
+  return false;
+ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+return false;
+  };
+
   // Check the use of this member.
   if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
 return ExprError();
 
-  if (FieldDecl *FD = dyn_cast(MemberDecl))
+  if (FieldDecl *FD = dyn_cast(MemberDecl)) {
+if (MakeGLValue())
+  return ExprError();
 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, 

[clang] [Clang] Check explicit object parameter for defaulted operators properly (PR #100419)

2024-07-24 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

CC @cor3ntin 

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


[clang] [Clang] Check explicit object parameter for defaulted operators properly (PR #100419)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/100419

Previously, the type of explicit object parameters was not checked at all for 
relational operators. This was defined by CWG2586, 
. This fix also means CWG2547 
 is now fully implemented. 
Fixes #100329

Now start rejecting invalid rvalue reference parameters, which weren't checked 
for, and start accepting non-reference explicit object parameters (like `bool 
operator==(this C, C) = default;`) which were previously rejected for the 
object param not being a reference.

Also start rejecting non-reference explicit object parameters for defaulted 
copy/move assign operators (`A& operator=(this A, const A&) = default;` is 
invalid but was previously accepted)


>From 5d2b3fa876c00869a3964081a57ae23563d18175 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Wed, 24 Jul 2024 16:58:56 +0100
Subject: [PATCH] [Clang] Check explicit object param for defaulted relational
 operator has correct type

---
 clang/docs/ReleaseNotes.rst   |  3 +
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +-
 clang/lib/Sema/SemaDeclCXX.cpp| 49 +
 .../class.compare.default/p1.cpp  |  2 +
 clang/test/CXX/drs/cwg25xx.cpp| 55 +++
 clang/test/SemaCXX/cxx2b-deducing-this.cpp| 12 +++-
 clang/www/cxx_dr_status.html  |  4 +-
 7 files changed, 100 insertions(+), 27 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 65de90f69e198..550414ae82fdd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -149,6 +149,9 @@ Bug Fixes to C++ Support
 
 - Fixed a crash when an expression with a dependent ``__typeof__`` type is 
used as the operand of a unary operator. (#GH97646)
 
+- Properly reject defaulted relational operators with invalid types for 
explicit object parameters,
+  e.g., ``bool operator==(this int, const Foo&)`` (#GH100329), and rvalue 
reference parameters.
+
 Bug Fixes to AST Handling
 ^
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 810abe4f23e31..d147992bca18d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9741,7 +9741,7 @@ def err_defaulted_special_member_quals : Error<
   "have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
 def err_defaulted_special_member_explicit_object_mismatch : Error<
   "the type of the explicit object parameter of an explicitly-defaulted "
-  "%select{copy|move}0 assignment operator should match the type of the class 
%1">;
+  "%select{copy|move}0 assignment operator should be reference to %1">;
 def err_defaulted_special_member_volatile_param : Error<
   "the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 
"
   "may not be volatile">;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 04b8d88cae217..273e83748d1fe 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7617,9 +7617,13 @@ bool 
Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
 // parameter is of (possibly different) type “reference to C”,
 // in which case the type of F1 would differ from the type of F2
 // in that the type of F1 has an additional parameter;
-if (!Context.hasSameType(
-ThisType.getNonReferenceType().getUnqualifiedType(),
-Context.getRecordType(RD))) {
+QualType ExplicitObjectParameter = MD->isExplicitObjectMemberFunction()
+   ? MD->getParamDecl(0)->getType()
+   : QualType();
+if (!ExplicitObjectParameter.isNull() &&
+(!ExplicitObjectParameter->isReferenceType() ||
+ !Context.hasSameType(ExplicitObjectParameter.getNonReferenceType(),
+  Context.getRecordType(RD {
   if (DeleteOnTypeMismatch)
 ShouldDeleteForTypeMismatch = true;
   else {
@@ -8704,7 +8708,8 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, 
FunctionDecl *FD,
 if (!RD)
   RD = MD->getParent();
 QualType T = MD->getFunctionObjectParameterType();
-if (!T.isConstQualified()) {
+if (!T.getNonReferenceType().isConstQualified() &&
+(MD->isImplicitObjectMemberFunction() || T->isLValueReferenceType())) {
   SourceLocation Loc, InsertLoc;
   if (MD->isExplicitObjectMemberFunction()) {
 Loc = MD->getParamDecl(0)->getBeginLoc();
@@ -8723,11 +8728,17 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, 
FunctionDecl *FD,
   }
 
   // Add the 'const' to the type to recover.
-  const auto *FPT = MD->getType()->castAs();
-  FunctionProtoType::ExtProtoInfo EPI = 

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-24 Thread Mital Ashok via cfe-commits


@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-06-25

MitalAshok wrote:

It looks like the github pages hasn't been updated for a month: 
https://github.com/cplusplus/CWG/deployments/github-pages but 
make_cxx_dr_status pulls from raw.githubusercontent.com which is always the 
latest. I may have been reading some stale info if that is the case

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


[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-24 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 01/12] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-24 Thread Mital Ashok via cfe-commits


@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-06-25

MitalAshok wrote:

That makes sense, thanks for explaining. For cwg2561/cwg2883 it shouldn't need 
a date now because they are in the standard draft: 
https://eel.is/c++draft/expr.prim.lambda.closure#9.sentence-1 
https://eel.is/c++draft/basic.def.odr#10.2.3

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


[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)

2024-07-23 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/95112

>From e53dfbc9b2c6b7f30c1378731d7de284fa99d568 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Tue, 11 Jun 2024 14:26:38 +0100
Subject: [PATCH 1/7] [Clang] Implement CWG2813

---
 clang/docs/ReleaseNotes.rst   |  5 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  3 +
 clang/lib/Sema/SemaExprMember.cpp | 64 +++---
 clang/lib/Sema/SemaOverload.cpp   | 11 +--
 clang/lib/Sema/SemaStmt.cpp   | 14 ++-
 .../test/AST/ast-dump-for-range-lifetime.cpp  | 12 +--
 .../dcl.attr/dcl.attr.nodiscard/p2.cpp| 86 ++-
 clang/test/CXX/drs/cwg28xx.cpp| 17 
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp |  1 -
 clang/www/cxx_dr_status.html  |  2 +-
 10 files changed, 164 insertions(+), 51 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cf1ba02cbc4b2..36bf1fdea3602 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -260,6 +260,11 @@ Resolutions to C++ Defect Reports
 - Clang now requires a template argument list after a template keyword.
   (`CWG96: Syntactic disambiguation using the template keyword 
`_).
 
+- Clang now allows calling explicit object member functions directly with 
prvalues
+  instead of always materializing a temporary, meaning by-value explicit 
object parameters
+  do not need to move from a temporary.
+  (`CWG2813: Class member access with prvalues 
`_).
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 193eae3bc41d6..008bf5fa0ccfc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9182,6 +9182,9 @@ def warn_unused_constructor : Warning<
 def warn_unused_constructor_msg : Warning<
   "ignoring temporary created by a constructor declared with %0 attribute: 
%1">,
   InGroup;
+def warn_discarded_class_member_access : Warning<
+  "left operand of dot in this class member access is discarded and has no 
effect">,
+  InGroup;
 def warn_side_effects_unevaluated_context : Warning<
   "expression with side effects has no effect in an unevaluated context">,
   InGroup;
diff --git a/clang/lib/Sema/SemaExprMember.cpp 
b/clang/lib/Sema/SemaExprMember.cpp
index 3ae1af26d0096..4679fe529ac91 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1015,15 +1015,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
   : !isDependentScopeSpecifier(SS) || computeDeclContext(SS)) &&
  "dependent lookup context that isn't the current instantiation?");
 
-  // C++1z [expr.ref]p2:
-  //   For the first option (dot) the first expression shall be a glvalue [...]
-  if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) {
-ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
-if (Converted.isInvalid())
-  return ExprError();
-BaseExpr = Converted.get();
-  }
-
   const DeclarationNameInfo  = R.getLookupNameInfo();
   DeclarationName MemberName = MemberNameInfo.getName();
   SourceLocation MemberLoc = MemberNameInfo.getLoc();
@@ -1140,26 +1131,68 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType 
BaseExprType,
 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
   }
 
+  // C++17 [expr.ref]p2, per CWG2813:
+  //   For the first option (dot), if the id-expression names a static member 
or
+  //   an enumerator, the first expression is a discarded-value expression; if
+  //   the id-expression names a non-static data member, the first expression
+  //   shall be a glvalue.
+  auto MakeDiscardedValue = [, IsArrow, this] {
+assert(getLangOpts().CPlusPlus &&
+   "Static member / member enumerator outside of C++");
+if (IsArrow)
+  return false;
+ExprResult Converted = IgnoredValueConversions(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+DiagnoseUnusedExprResult(BaseExpr,
+ diag::warn_discarded_class_member_access);
+return false;
+  };
+  auto MakeGLValue = [, IsArrow, this] {
+if (IsArrow || !BaseExpr->isPRValue())
+  return false;
+ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+if (Converted.isInvalid())
+  return true;
+BaseExpr = Converted.get();
+return false;
+  };
+
   // Check the use of this member.
   if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
 return ExprError();
 
-  if (FieldDecl *FD = dyn_cast(MemberDecl))
+  if (FieldDecl *FD = dyn_cast(MemberDecl)) {
+if (MakeGLValue())
+  return ExprError();
 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, 

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-23 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 01/12] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-23 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 01/11] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-23 Thread Mital Ashok via cfe-commits


@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-06-25

MitalAshok wrote:

It doesn't really make sense to put a date for something Clang doesn't 
implement yet right? So I just removed the date. This one is now status=DR on 
https://raw.githubusercontent.com/cplusplus/CWG/gh-pages/issues/cwg_index.html 
so there isn't supposed to be a date anyway

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


[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-18 Thread Mital Ashok via cfe-commits


@@ -215,6 +215,14 @@ struct NewUnspecified;
 SingleTemplate tmpl_single;
 UnspecTemplate tmpl_unspec;
 
+// Member pointers used in base specifiers force an unspecified inheritance 
model
+struct MemPtrInBase : UnspecTemplate {};

MitalAshok wrote:

It's not for simply naming the type for the template argument but 
`UnspecTemplate`'s definition does complete it by taking its `sizeof`, forcing 
the inheritance model to be assigned

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


[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-18 Thread Mital Ashok via cfe-commits


@@ -13,3 +15,18 @@ template 
 struct S3 {
   int T::*foo;
 };
+
+template struct Base {};
+struct
+S5 // #S5
+:
+Base
+// expected-error@-1 {{member pointer has incomplete base type 'S5'}}

MitalAshok wrote:

It's an error for `-fcomplete-member-pointers` which is supposed to tell you 
when you use a member pointer in a way that the MS ABI would have it be 
unspecified, regardless of if you are compiling with MS member pointers or 
Itanium member pointers

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


[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-17 Thread Mital Ashok via cfe-commits


@@ -9015,11 +9015,20 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, 
QualType T,
 
   if (const MemberPointerType *MPTy = T->getAs()) {
 if (!MPTy->getClass()->isDependentType()) {
-  if (getLangOpts().CompleteMemberPointers &&
-  !MPTy->getClass()->getAsCXXRecordDecl()->isBeingDefined() &&
-  RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), Kind,
-  diag::err_memptr_incomplete))
-return true;
+  if (getLangOpts().CompleteMemberPointers) {
+const CXXRecordDecl *RD = MPTy->getClass()->getAsCXXRecordDecl();
+if (RD->isBeingDefined()) {
+  if (RD->isParsingBaseSpecifiers()) {

MitalAshok wrote:

I really only want to call `RequireCompleteType`in the else branch  when 
`!RD->isBeingDefined()` (when called while `RD->isParsingBaseSpecifiers()`, 
there's an extra note 'definition of "[class name]" is incomplete until the 
closing "}"', which is misleading since for CompleteMemberPointers purposes 
it's complete after the bases are parsed)



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


[clang] [Clang] Reuse tail-padding for more types that are not POD for the purpose of layout (PR #90462)

2024-07-17 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

I have reached out to Fuschia on their discord and am still waiting for a 
response.  
I was unable to find a place to ask someone related to IBM XL what is supposed 
to happen (and I couldn't get the xl++ compiler to check what it does). Would 
be grateful if someone more knowledgeable about this could help.

This patch currently changes nothing for Fuschia and XL. It could be merged as 
is and the Fuschia/XL behaviour could be changed for -fclang-abi-compat=20 if 
they need to be changed. Or this could be pushed back entirely for Clang 20

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


[clang] [Clang] [C23] Fix typeof_unqual for qualified array types (PR #92767)

2024-07-12 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

@AaronBallman was there anything else that needed to be done? Just did a merge 
because ReleaseNotes was edited but this should be fine

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


[clang] [Clang] [C23] Fix typeof_unqual for qualified array types (PR #92767)

2024-07-12 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/92767

>From f87cb4c754a477515746e2ac2f8906b93ccd1fe3 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 20 May 2024 15:58:58 +0100
Subject: [PATCH 1/5] [Clang] [C23] Fix typeof_unqual for qualified array types

Properly remove qualifiers for both the element type and the array type

Fixes #92667
---
 clang/include/clang/AST/ASTContext.h |  6 -
 clang/include/clang/AST/Type.h   | 37 +--
 clang/lib/AST/ASTContext.cpp | 14 +-
 clang/lib/AST/Type.cpp   | 38 ++--
 clang/test/Sema/c2x-typeof.c | 25 ++
 5 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index e03b112194786..ff7bdb7e7e1a6 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2611,7 +2611,11 @@ class ASTContext : public RefCountedBase {
   ///
   /// \returns if this is an array type, the completely unqualified array type
   /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
-  QualType getUnqualifiedArrayType(QualType T, Qualifiers );
+  QualType getUnqualifiedArrayType(QualType T, Qualifiers ) const;
+  QualType getUnqualifiedArrayType(QualType T) const {
+Qualifiers Quals;
+return getUnqualifiedArrayType(T, Quals);
+  }
 
   /// Determine whether the given types are equivalent after
   /// cvr-qualifiers have been removed.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index da3834f19ca04..df7f396bae095 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1605,6 +1605,10 @@ class QualType {
   QualType stripObjCKindOfType(const ASTContext ) const;
 
   /// Remove all qualifiers including _Atomic.
+  ///
+  /// Like getUnqualifiedType(), the type may still be qualified if it is a
+  /// sugared array type.  To strip qualifiers even from within a sugared array
+  /// type, use ASTContext::getUnqualifiedArrayType.
   QualType getAtomicUnqualifiedType() const;
 
 private:
@@ -2092,8 +2096,8 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
 
 LLVM_PREFERRED_TYPE(TypeBitfields)
 unsigned : NumTypeBits;
-LLVM_PREFERRED_TYPE(bool)
-unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof
+LLVM_PREFERRED_TYPE(TypeOfKind)
+unsigned Kind : 1;
   };
 
   class UsingBitfields {
@@ -5273,19 +5277,20 @@ class MacroQualifiedType : public Type {
 /// extension) or a `typeof_unqual` expression (a C23 feature).
 class TypeOfExprType : public Type {
   Expr *TOExpr;
+  const ASTContext 
 
 protected:
   friend class ASTContext; // ASTContext creates these.
 
-  TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType());
+  TypeOfExprType(const ASTContext , Expr *E, TypeOfKind Kind,
+ QualType Can = QualType());
 
 public:
   Expr *getUnderlyingExpr() const { return TOExpr; }
 
   /// Returns the kind of 'typeof' type this is.
   TypeOfKind getKind() const {
-return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
-   : TypeOfKind::Qualified;
+return static_cast(TypeOfBits.Kind);
   }
 
   /// Remove a single level of sugar.
@@ -5306,7 +5311,8 @@ class TypeOfExprType : public Type {
 class DependentTypeOfExprType : public TypeOfExprType,
 public llvm::FoldingSetNode {
 public:
-  DependentTypeOfExprType(Expr *E, TypeOfKind Kind) : TypeOfExprType(E, Kind) 
{}
+  DependentTypeOfExprType(const ASTContext , Expr *E, TypeOfKind Kind)
+  : TypeOfExprType(Context, E, Kind) {}
 
   void Profile(llvm::FoldingSetNodeID , const ASTContext ) {
 Profile(ID, Context, getUnderlyingExpr(),
@@ -5323,32 +5329,23 @@ class TypeOfType : public Type {
   friend class ASTContext; // ASTContext creates these.
 
   QualType TOType;
+  const ASTContext 
 
-  TypeOfType(QualType T, QualType Can, TypeOfKind Kind)
-  : Type(TypeOf,
- Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType()
- : Can,
- T->getDependence()),
-TOType(T) {
-TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
-  }
+  TypeOfType(const ASTContext , QualType T, QualType Can,
+ TypeOfKind Kind);
 
 public:
   QualType getUnmodifiedType() const { return TOType; }
 
   /// Remove a single level of sugar.
-  QualType desugar() const {
-QualType QT = getUnmodifiedType();
-return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT;
-  }
+  QualType desugar() const;
 
   /// Returns whether this type directly provides sugar.
   bool isSugared() const { return true; }
 
   /// Returns the kind of 'typeof' type this is.
   TypeOfKind getKind() const {
-return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
-   : 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-11 Thread Mital Ashok via cfe-commits


@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline

MitalAshok wrote:

https://github.com/llvm/llvm-project/blob/e46468407a7bb7f8b2fe13675a5a1c32b85f8cad/clang/lib/Lex/Lexer.cpp#L1288

https://github.com/llvm/llvm-project/blob/e46468407a7bb7f8b2fe13675a5a1c32b85f8cad/clang/lib/Lex/Lexer.cpp#L2775

And with the current clang:

```c++
int main() { // this line ends with \n\r\
  return 1;
}
```

(That is, the file is generated with `python3 -c 'open("test.cpp", 
"wb").write(b"int main() { // this line ends with \\n\\r\\\n\r  return 
1;\n}\n")'`)

Exits 0. It seems like Clang has always done this, gcc exits with code 1 here.

The reason given is efficiency:

https://github.com/llvm/llvm-project/blob/e46468407a7bb7f8b2fe13675a5a1c32b85f8cad/clang/lib/Lex/Lexer.cpp#L2711-L2715

Maybe those other places are a mistake since it does affect "correctness", and 
it should treat \n\r as a Unix style newline followed by an old Mac style 
newline, but it is currently treated as a single newline so thats what this 
patch treats it as.

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-09 Thread Mital Ashok via cfe-commits


@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -verify=c23 -std=c23 %s
+// RUN: %clang_cc1 -verify=c17 -std=c17 %s

MitalAshok wrote:

I think I ran the wrong tests then misread some `-E` output... Should be fixed 
now (`__STDC_VERSION__ > 202311L` -> `__STDC_VERSION__ >= 202311L`)

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-09 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/9] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-09 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/8] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-09 Thread Mital Ashok via cfe-commits


@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -verify=c23 -std=c23 %s
+// RUN: %clang_cc1 -verify=c17 -std=c17 %s

MitalAshok wrote:

That still seems to fail on the CI:

```
 TEST 'Clang :: C/C23/n2653.c' FAILED 
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/build/bin/clang
 -cc1 -internal-isystem 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/build/lib/clang/19/include
 -nostdsysteminc -ffreestanding -verify=c23 -std=c23 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/clang/test/C/C23/n2653.c
+ 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/build/bin/clang
 -cc1 -internal-isystem 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/build/lib/clang/19/include
 -nostdsysteminc -ffreestanding -verify=c23 -std=c23 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/clang/test/C/C23/n2653.c
error: 'c23-error' diagnostics seen but not expected: 
  File 
/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-vhr99-1/llvm-project/github-pull-requests/clang/test/C/C23/n2653.c
 Line 11: missing
1 error generated.

--


```

So I've just removed the test for  (`-nostdinc` seems to disable 
the clang header too)

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-09 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/7] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [llvm] [Clang] Fix definition of layout-compatible to ignore empty classes (PR #92103)

2024-07-08 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

Ping

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


[clang] [clang-tools-extra] [Clang] Make -fcomplete-member-pointers the same as using the Microsoft C++ ABI (PR #98010)

2024-07-08 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/98010

>From 5163153a122f705c6ed25a372bec6868aa42d0b5 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 8 Jul 2024 10:36:35 +0100
Subject: [PATCH] [Clang] Make -fcomplete-member-pointers the same as using the
 Microsoft C++ ABI

---
 clang-tools-extra/clangd/IncludeFixer.cpp |   3 +-
 clang/docs/ControlFlowIntegrity.rst   |   6 +-
 clang/include/clang/Basic/DiagnosticGroups.td |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/include/clang/Basic/TargetCXXABI.h  |   5 +
 clang/include/clang/Sema/Sema.h   |  17 +++
 clang/lib/AST/Type.cpp|   2 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   8 +-
 clang/lib/Frontend/CompilerInvocation.cpp |   9 +-
 clang/lib/Sema/SemaCast.cpp   |  14 +--
 clang/lib/Sema/SemaExpr.cpp   |  10 +-
 clang/lib/Sema/SemaExprCXX.cpp|   6 +-
 clang/lib/Sema/SemaOverload.cpp   |   3 +-
 clang/lib/Sema/SemaType.cpp   | 108 +++---
 clang/test/Misc/warning-wall.c|   1 +
 .../test/SemaCXX/complete-member-pointers.cpp |  39 ++-
 16 files changed, 164 insertions(+), 81 deletions(-)

diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp 
b/clang-tools-extra/clangd/IncludeFixer.cpp
index fadd1105691fc..ec2a744b9800b 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -122,7 +122,8 @@ std::vector IncludeFixer::fix(DiagnosticsEngine::Level 
DiagLevel,
   case diag::err_lambda_incomplete_result:
   //case diag::err_matrix_incomplete_index:
   //case diag::err_matrix_separate_incomplete_index:
-  case diag::err_memptr_incomplete:
+  case diag::warn_memptr_incomplete:
+  case diag::warn_memptr_incomplete_ms:
   case diag::err_new_incomplete_or_sizeless_type:
   case diag::err_objc_incomplete_boxed_expression_type:
   case diag::err_objc_index_incomplete_class_type:
diff --git a/clang/docs/ControlFlowIntegrity.rst 
b/clang/docs/ControlFlowIntegrity.rst
index 7de805e2154db..9b1086f4bbb8d 100644
--- a/clang/docs/ControlFlowIntegrity.rst
+++ b/clang/docs/ControlFlowIntegrity.rst
@@ -351,9 +351,9 @@ The compiler will only emit a full CFI check if the member 
function pointer's
 base type is complete. This is because the complete definition of the base
 type contains information that is necessary to correctly compile the CFI
 check. To ensure that the compiler always emits a full CFI check, it is
-recommended to also pass the flag ``-fcomplete-member-pointers``, which
-enables a non-conforming language extension that requires member pointer
-base types to be complete if they may be used for a call.
+recommended to enable the ``-Wincomplete-member-pointer`` warning, which
+warns if a member pointer does not have a complete base types when the
+member pointer type is specified.
 
 For this scheme to work, all translation units containing the definition
 of a virtual member function (whether inline or not), other than members
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 2241f8481484e..16ede9e2a59ac 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1040,6 +1040,8 @@ def VoidPointerDeref : DiagGroup<"void-ptr-dereference">;
 
 def FUseLdPath : DiagGroup<"fuse-ld-path">;
 
+def MicrosoftIncompleteMemberPointer : 
DiagGroup<"microsoft-incomplete-member-pointer">;
+
 def Move : DiagGroup<"move", [
 PessimizingMove,
 RedundantMove,
@@ -1102,7 +1104,8 @@ def Most : DiagGroup<"most", [
 PrivateExtern,
 SelTypeCast,
 ExternCCompat,
-UserDefinedWarnings
+UserDefinedWarnings,
+MicrosoftIncompleteMemberPointer
  ]>;
 
 // Thread Safety warnings
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 44fd51ec9abc9..79dc6b15fb704 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8082,8 +8082,13 @@ def err_bad_memptr_rhs : Error<
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
-def err_memptr_incomplete : Error<
-  "member pointer has incomplete base type %0">;
+def warn_memptr_incomplete : Warning<
+  "member pointer has incomplete base type %0">, 
InGroup>, DefaultIgnore;
+def warn_memptr_incomplete_ms : Warning<
+  "this usage of a member pointer with an incomplete base type %0 may cause 
ODR violations">, InGroup, DefaultIgnore;
+def note_memptr_incomplete_specify_inheritance : Note<"consider specifying the 
inheritance model">;
+def note_memptr_incomplete_until_bases : Note<
+  "this will affect the ABI of the member pointer until the bases have been 
specified">;
 def 

[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-08 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

> Will that include fixing clang incorrectly warning when an inheritance model 
> is explicitly specified?

Yes, I have a WIP of it here #98010 where that doesn't get a warning 
(https://github.com/llvm/llvm-project/pull/98010/files#diff-bec1ae40e5793adbd61e7a9dc41a4715a06e27888a384c0752bb6b4b09a1075fR20-R21)

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


[clang] [Clang] Make -fcomplete-member-pointers the same as using the Microsoft C++ ABI (PR #98010)

2024-07-08 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/98010

>From 7cc8f4c8c4e39db82ff8f7cb7164a94abf6b2029 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 8 Jul 2024 10:36:35 +0100
Subject: [PATCH] [Clang] Make -fcomplete-member-pointers the same as using the
 Microsoft C++ ABI

---
 clang/docs/ControlFlowIntegrity.rst   |   6 +-
 clang/include/clang/Basic/DiagnosticGroups.td |   5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|   9 +-
 clang/include/clang/Basic/TargetCXXABI.h  |   5 +
 clang/include/clang/Sema/Sema.h   |  17 +++
 clang/lib/AST/Type.cpp|   2 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   8 +-
 clang/lib/Frontend/CompilerInvocation.cpp |   9 +-
 clang/lib/Sema/SemaCast.cpp   |  14 +--
 clang/lib/Sema/SemaExpr.cpp   |  10 +-
 clang/lib/Sema/SemaExprCXX.cpp|   6 +-
 clang/lib/Sema/SemaOverload.cpp   |   3 +-
 clang/lib/Sema/SemaType.cpp   | 108 +++---
 clang/test/Misc/warning-wall.c|   1 +
 .../test/SemaCXX/complete-member-pointers.cpp |  39 ++-
 15 files changed, 162 insertions(+), 80 deletions(-)

diff --git a/clang/docs/ControlFlowIntegrity.rst 
b/clang/docs/ControlFlowIntegrity.rst
index 7de805e2154db..9b1086f4bbb8d 100644
--- a/clang/docs/ControlFlowIntegrity.rst
+++ b/clang/docs/ControlFlowIntegrity.rst
@@ -351,9 +351,9 @@ The compiler will only emit a full CFI check if the member 
function pointer's
 base type is complete. This is because the complete definition of the base
 type contains information that is necessary to correctly compile the CFI
 check. To ensure that the compiler always emits a full CFI check, it is
-recommended to also pass the flag ``-fcomplete-member-pointers``, which
-enables a non-conforming language extension that requires member pointer
-base types to be complete if they may be used for a call.
+recommended to enable the ``-Wincomplete-member-pointer`` warning, which
+warns if a member pointer does not have a complete base types when the
+member pointer type is specified.
 
 For this scheme to work, all translation units containing the definition
 of a virtual member function (whether inline or not), other than members
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 2241f8481484e..16ede9e2a59ac 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1040,6 +1040,8 @@ def VoidPointerDeref : DiagGroup<"void-ptr-dereference">;
 
 def FUseLdPath : DiagGroup<"fuse-ld-path">;
 
+def MicrosoftIncompleteMemberPointer : 
DiagGroup<"microsoft-incomplete-member-pointer">;
+
 def Move : DiagGroup<"move", [
 PessimizingMove,
 RedundantMove,
@@ -1102,7 +1104,8 @@ def Most : DiagGroup<"most", [
 PrivateExtern,
 SelTypeCast,
 ExternCCompat,
-UserDefinedWarnings
+UserDefinedWarnings,
+MicrosoftIncompleteMemberPointer
  ]>;
 
 // Thread Safety warnings
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 44fd51ec9abc9..79dc6b15fb704 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8082,8 +8082,13 @@ def err_bad_memptr_rhs : Error<
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
-def err_memptr_incomplete : Error<
-  "member pointer has incomplete base type %0">;
+def warn_memptr_incomplete : Warning<
+  "member pointer has incomplete base type %0">, 
InGroup>, DefaultIgnore;
+def warn_memptr_incomplete_ms : Warning<
+  "this usage of a member pointer with an incomplete base type %0 may cause 
ODR violations">, InGroup, DefaultIgnore;
+def note_memptr_incomplete_specify_inheritance : Note<"consider specifying the 
inheritance model">;
+def note_memptr_incomplete_until_bases : Note<
+  "this will affect the ABI of the member pointer until the bases have been 
specified">;
 def warn_exception_caught_by_earlier_handler : Warning<
   "exception of type %0 will be caught by earlier handler">,
   InGroup;
diff --git a/clang/include/clang/Basic/TargetCXXABI.h 
b/clang/include/clang/Basic/TargetCXXABI.h
index d204452afbf4b..d88846839b20c 100644
--- a/clang/include/clang/Basic/TargetCXXABI.h
+++ b/clang/include/clang/Basic/TargetCXXABI.h
@@ -68,6 +68,11 @@ class TargetCXXABI {
 return T.isOSFuchsia();
   }
 
+  // Return true if this target uses the Microsoft C++ ABI by default.
+  static bool defaultABIIsMicrosoft(const llvm::Triple ) {
+return T.isKnownWindowsMSVCEnvironment();
+  }
+
   /// A bogus initialization of the platform ABI.
   TargetCXXABI() : TheKind(GenericItanium) {}
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 

[clang] [Clang] Make -fcomplete-member-pointers the same as using the Microsoft C++ ABI (PR #98010)

2024-07-08 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

TODO:

 - Tests for `-Wincomplete-member-pointer`
 - Possibly do something else about `-fsanitize=cfi-mfcall`. 
`-Wincomplete-member-pointer` is too broad, for the sanitizer we only care 
about a call to a pointer to member function. The warning could also be emitted 
here: 
https://github.com/llvm/llvm-project/blob/1b8ab2f08998d3220e5d95003d47bb3d7cac966b/clang/lib/CodeGen/ItaniumCXXABI.cpp#L800
 - It's weird that `-fcomplete-member-pointers` enables an error. Possibly 
deprecate `-fcomplete-member-pointers` and have it be an alias for 
`-fmicrosoft-complete-member-pointers 
-Werror=microsoft-incomplete-member-pointer` (where 
`-fmicrosoft-complete-member-pointers` is a new option).
 - Release note
 - Maybe reword the warning with `-fcomplete-member-pointers` is used with a 
non-Microsoft ABI. It's not actually an ODR violation then, and the 
`__single_inheritance` etc. keywords might not be available.

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


[clang] [Clang] Make -fcomplete-member-pointers the same as using the Microsoft C++ ABI (PR #98010)

2024-07-08 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/98010

This essentially adds a new language mode `CompleteMemberPointers`. With the 
Microsoft C++ ABI, this will always be true. Otherwise, it can be enabled with 
`-fcomplete-member-pointers`, and will work the same as if the Microsoft C++ 
ABI was being used for member pointers (only during sema, not codegen).

Previously `-fcomplete-member-pointers` was also being used for 
`-fsanitize=cfi-mfcall`. It can still be used for this, but the new 
`-Wincomplete-member-pointer` will warn in a similar way without enabling a 
non-standard language mode.

Before, an MSVC triple with `-fc++-abi=itanium` would still complete base types 
of member pointers even though it wasn't needed for codegen. It can still be 
completed with `-fc++-abi=itanium -fcomplete-member-pointers`.

Also adds a new warning `-Wmicrosoft-incomplete-member-pointers`, which will 
warn if a member pointer's base type is given an unspecified inheritance. This 
only warns with `CompleteMemberPointers`. It is enabled by `-Wmost`/`-Wall`. A 
similar warning 
[C5243](https://learn.microsoft.com/en-gb/cpp/error-messages/compiler-warnings/c5243?view=msvc-170)
 exists in MSVC.


>From 0de7bd39af61eb47ee33ff991e6de18f83e005dd Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 8 Jul 2024 10:36:35 +0100
Subject: [PATCH] [Clang] Make -fcomplete-member-pointers the same as using the
 Microsoft C++ ABI

---
 clang/docs/ControlFlowIntegrity.rst   |  6 +-
 clang/include/clang/Basic/DiagnosticGroups.td |  5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  9 +-
 clang/include/clang/Basic/TargetCXXABI.h  |  5 +
 clang/include/clang/Sema/Sema.h   | 14 +++
 clang/lib/AST/Type.cpp|  2 +-
 clang/lib/Driver/ToolChains/Clang.cpp |  7 +-
 clang/lib/Frontend/CompilerInvocation.cpp |  9 +-
 clang/lib/Sema/SemaCast.cpp   | 14 +--
 clang/lib/Sema/SemaExpr.cpp   | 10 +-
 clang/lib/Sema/SemaExprCXX.cpp|  6 +-
 clang/lib/Sema/SemaOverload.cpp   |  3 +-
 clang/lib/Sema/SemaType.cpp   | 99 ++-
 clang/test/Misc/warning-wall.c|  1 +
 .../test/SemaCXX/complete-member-pointers.cpp | 39 +++-
 15 files changed, 149 insertions(+), 80 deletions(-)

diff --git a/clang/docs/ControlFlowIntegrity.rst 
b/clang/docs/ControlFlowIntegrity.rst
index 7de805e2154db..9b1086f4bbb8d 100644
--- a/clang/docs/ControlFlowIntegrity.rst
+++ b/clang/docs/ControlFlowIntegrity.rst
@@ -351,9 +351,9 @@ The compiler will only emit a full CFI check if the member 
function pointer's
 base type is complete. This is because the complete definition of the base
 type contains information that is necessary to correctly compile the CFI
 check. To ensure that the compiler always emits a full CFI check, it is
-recommended to also pass the flag ``-fcomplete-member-pointers``, which
-enables a non-conforming language extension that requires member pointer
-base types to be complete if they may be used for a call.
+recommended to enable the ``-Wincomplete-member-pointer`` warning, which
+warns if a member pointer does not have a complete base types when the
+member pointer type is specified.
 
 For this scheme to work, all translation units containing the definition
 of a virtual member function (whether inline or not), other than members
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 2241f8481484e..16ede9e2a59ac 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1040,6 +1040,8 @@ def VoidPointerDeref : DiagGroup<"void-ptr-dereference">;
 
 def FUseLdPath : DiagGroup<"fuse-ld-path">;
 
+def MicrosoftIncompleteMemberPointer : 
DiagGroup<"microsoft-incomplete-member-pointer">;
+
 def Move : DiagGroup<"move", [
 PessimizingMove,
 RedundantMove,
@@ -1102,7 +1104,8 @@ def Most : DiagGroup<"most", [
 PrivateExtern,
 SelTypeCast,
 ExternCCompat,
-UserDefinedWarnings
+UserDefinedWarnings,
+MicrosoftIncompleteMemberPointer
  ]>;
 
 // Thread Safety warnings
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 44fd51ec9abc9..79dc6b15fb704 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8082,8 +8082,13 @@ def err_bad_memptr_rhs : Error<
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
-def err_memptr_incomplete : Error<
-  "member pointer has incomplete base type %0">;
+def warn_memptr_incomplete : Warning<
+  "member pointer has incomplete base type %0">, 
InGroup>, DefaultIgnore;
+def warn_memptr_incomplete_ms : Warning<
+  "this usage of a member pointer with an 

[clang] [libcxx] [Clang] Implement CWG2137 (list-initialization from objects of the same type) (PR #94355)

2024-07-07 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/94355

>From ac803f979f2779da35a006988d2d42cdabbad252 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sat, 22 Jul 2023 20:07:00 +0100
Subject: [PATCH 1/6] [SemaCXX] Implement CWG2137 (list-initialization from
 objects of the same type)

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

---

This is a cherry-pick from 
https://github.com/llvm/llvm-project/pull/77768/commits/644ec10fc357f70ca8af94ae6544e9631021eb5e
---
 clang/docs/ReleaseNotes.rst   |  3 ++
 clang/lib/Sema/SemaInit.cpp   | 14 +++---
 clang/lib/Sema/SemaOverload.cpp   | 38 +++-
 clang/test/CXX/drs/cwg14xx.cpp| 10 -
 clang/test/CXX/drs/cwg21xx.cpp| 45 +++
 clang/www/cxx_dr_status.html  |  2 +-
 .../pairs.pair/ctor.pair_U_V_move.pass.cpp| 21 -
 7 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 99580c0d28a4fd..818fa160ef9848 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -254,6 +254,9 @@ Resolutions to C++ Defect Reports
 - Clang now requires a template argument list after a template keyword.
   (`CWG96: Syntactic disambiguation using the template keyword 
`_).
 
+- Implemented `CWG2137 `_ which allows
+  list-initialization from objects of the same type.
+
 C Language Changes
 --
 
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 79bdc8e9f87838..6aa0ebeeaa11fc 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4231,7 +4231,7 @@ static OverloadingResult ResolveConstructorOverload(
 /// \param IsListInit Is this list-initialization?
 /// \param IsInitListCopy Is this non-list-initialization resulting from a
 ///   list-initialization from {x} where x is the same
-///   type as the entity?
+///   aggregate type as the entity?
 static void TryConstructorInitialization(Sema ,
  const InitializedEntity ,
  const InitializationKind ,
@@ -4271,8 +4271,8 @@ static void TryConstructorInitialization(Sema ,
   // ObjC++: Lambda captured by the block in the lambda to block conversion
   // should avoid copy elision.
   if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor &&
-  UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
-  S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) 
{
+  Args.size() == 1 && Args[0]->isPRValue() &&
+  S.Context.hasSameUnqualifiedType(Args[0]->getType(), DestType)) {
 // Convert qualifications if necessary.
 Sequence.AddQualificationConversionStep(DestType, VK_PRValue);
 if (ILE)
@@ -4603,9 +4603,9 @@ static void TryListInitialization(Sema ,
 return;
   }
 
-  // C++11 [dcl.init.list]p3, per DR1467:
-  // - If T is a class type and the initializer list has a single element of
-  //   type cv U, where U is T or a class derived from T, the object is
+  // C++11 [dcl.init.list]p3, per DR1467 and DR2137:
+  // - If T is an aggregate class and the initializer list has a single element
+  //   of type cv U, where U is T or a class derived from T, the object is
   //   initialized from that element (by copy-initialization for
   //   copy-list-initialization, or by direct-initialization for
   //   direct-list-initialization).
@@ -4616,7 +4616,7 @@ static void TryListInitialization(Sema ,
   // - Otherwise, if T is an aggregate, [...] (continue below).
   if (S.getLangOpts().CPlusPlus11 && InitList->getNumInits() == 1 &&
   !IsDesignatedInit) {
-if (DestType->isRecordType()) {
+if (DestType->isRecordType() && DestType->isAggregateType()) {
   QualType InitType = InitList->getInit(0)->getType();
   if (S.Context.hasSameUnqualifiedType(InitType, DestType) ||
   S.IsDerivedFrom(InitList->getBeginLoc(), InitType, DestType)) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6c4ce1022ae274..b6d6d9d1ef3af3 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1628,19 +1628,37 @@ TryUserDefinedConversion(Sema , Expr *From, QualType 
ToType,
 //   called for those cases.
 if (CXXConstructorDecl *Constructor
   = dyn_cast(ICS.UserDefined.ConversionFunction)) {
-  QualType FromCanon
-= S.Context.getCanonicalType(From->getType().getUnqualifiedType());
+  QualType FromType;
+  SourceLocation FromLoc;
+  // C++11 [over.ics.list]p6, per DR2137:
+  // C++17 [over.ics.list]p6:
+  //   If C is not an initializer-list constructor and the initializer list
+  //   has a single element of type cv U, where U is X or a 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-06 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/6] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-06 Thread Mital Ashok via cfe-commits

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


[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-06 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/91990

>From 5dc9193af0d98335a87e93ad70d945dbc0ffce79 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 13 May 2024 16:59:06 +0100
Subject: [PATCH 1/5] [Clang] Fix Microsoft ABI inheritance model when member
 pointer is used in a base specifier

Fix CXXRecordDecl::isParsingBaseSpecifiers so that it is true while parsing 
base specifiers instead of directly after they have been parsed.

-fcomplete-member-pointers now issues a diagnostic when a member pointer is 
used in a base specifier.

-fcomplete-member-pointers has also been relaxed to not issue a diagnostic for 
incomplete classes with an explicit __{single|multiple|virtual}_inheritance 
attribute, whose completeness would not affect the representation of 
pointer-to-member objects.
---
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang/AST/DeclCXX.h |  7 +++--
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/DeclCXX.cpp |  6 +
 clang/lib/Parse/ParseDeclCXX.cpp  | 24 +
 clang/lib/Sema/SemaDeclCXX.cpp|  3 ---
 clang/lib/Sema/SemaType.cpp   | 27 ---
 .../test/SemaCXX/complete-member-pointers.cpp | 24 -
 clang/test/SemaCXX/member-pointer-ms.cpp  |  8 ++
 9 files changed, 85 insertions(+), 20 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4702b8c10cdbb..054332c2cee4e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -79,6 +79,10 @@ ABI Changes in This Version
 - Fixed Microsoft calling convention when returning classes that have a deleted
   copy assignment operator. Such a class should be returned indirectly.
 
+- Fixed Microsoft layout of pointer-to-members of classes when the layout is 
needed
+  directly or indirectly by the base classes of a class. These should use the 
most
+  general unspecified inheritance layout. Also affects 
-fcomplete-member-pointers.
+
 AST Dumping Potentially Breaking Changes
 
 
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index fb52ac804849d..81669b1f606b3 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -297,7 +297,8 @@ class CXXRecordDecl : public RecordDecl {
 LLVM_PREFERRED_TYPE(bool)
 unsigned IsLambda : 1;
 
-/// Whether we are currently parsing base specifiers.
+/// Whether we are currently parsing base specifiers; the
+/// colon has been consumed but the beginning left brace hasn't.
 LLVM_PREFERRED_TYPE(bool)
 unsigned IsParsingBaseSpecifiers : 1;
 
@@ -598,7 +599,9 @@ class CXXRecordDecl : public RecordDecl {
 return !hasDefinition() || !isDynamicClass() || hasAnyDependentBases();
   }
 
-  void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+  void setIsParsingBaseSpecifiers(bool to = true) {
+data().IsParsingBaseSpecifiers = to;
+  }
 
   bool isParsingBaseSpecifiers() const {
 return data().IsParsingBaseSpecifiers;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9e82130c93609..a9f9f02651cff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8003,6 +8003,8 @@ def err_bad_memptr_rhs : Error<
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
+def note_memptr_incomplete_until_bases : Note<
+  "this will affect the ABI of the member pointer until the bases have been 
specified">;
 def err_memptr_incomplete : Error<
   "member pointer has incomplete base type %0">;
 def warn_exception_caught_by_earlier_handler : Warning<
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 75c441293d62e..7f20a47e6a054 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -474,10 +474,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
   if (data().IsStandardLayout && NumBases > 1 && hasRepeatedBaseClass(this))
 data().IsStandardLayout = false;
 
-  if (VBases.empty()) {
-data().IsParsingBaseSpecifiers = false;
+  if (VBases.empty())
 return;
-  }
 
   // Create base specifier for any direct or indirect virtual bases.
   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -488,8 +486,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
   addedClassSubobject(Type->getAsCXXRecordDecl());
 data().getVBases()[I] = *VBases[I];
   }
-
-  data().IsParsingBaseSpecifiers = false;
 }
 
 unsigned CXXRecordDecl::getODRHash() const {
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 65ddebca49bc6..a28503b5b4de4 100644
--- 

[clang] [Clang] Fix Microsoft ABI inheritance model when member pointer is used in a base specifier (PR #91990)

2024-07-06 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/91990

>From 5dc9193af0d98335a87e93ad70d945dbc0ffce79 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 13 May 2024 16:59:06 +0100
Subject: [PATCH 1/4] [Clang] Fix Microsoft ABI inheritance model when member
 pointer is used in a base specifier

Fix CXXRecordDecl::isParsingBaseSpecifiers so that it is true while parsing 
base specifiers instead of directly after they have been parsed.

-fcomplete-member-pointers now issues a diagnostic when a member pointer is 
used in a base specifier.

-fcomplete-member-pointers has also been relaxed to not issue a diagnostic for 
incomplete classes with an explicit __{single|multiple|virtual}_inheritance 
attribute, whose completeness would not affect the representation of 
pointer-to-member objects.
---
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang/AST/DeclCXX.h |  7 +++--
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/DeclCXX.cpp |  6 +
 clang/lib/Parse/ParseDeclCXX.cpp  | 24 +
 clang/lib/Sema/SemaDeclCXX.cpp|  3 ---
 clang/lib/Sema/SemaType.cpp   | 27 ---
 .../test/SemaCXX/complete-member-pointers.cpp | 24 -
 clang/test/SemaCXX/member-pointer-ms.cpp  |  8 ++
 9 files changed, 85 insertions(+), 20 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4702b8c10cdbb..054332c2cee4e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -79,6 +79,10 @@ ABI Changes in This Version
 - Fixed Microsoft calling convention when returning classes that have a deleted
   copy assignment operator. Such a class should be returned indirectly.
 
+- Fixed Microsoft layout of pointer-to-members of classes when the layout is 
needed
+  directly or indirectly by the base classes of a class. These should use the 
most
+  general unspecified inheritance layout. Also affects 
-fcomplete-member-pointers.
+
 AST Dumping Potentially Breaking Changes
 
 
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index fb52ac804849d..81669b1f606b3 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -297,7 +297,8 @@ class CXXRecordDecl : public RecordDecl {
 LLVM_PREFERRED_TYPE(bool)
 unsigned IsLambda : 1;
 
-/// Whether we are currently parsing base specifiers.
+/// Whether we are currently parsing base specifiers; the
+/// colon has been consumed but the beginning left brace hasn't.
 LLVM_PREFERRED_TYPE(bool)
 unsigned IsParsingBaseSpecifiers : 1;
 
@@ -598,7 +599,9 @@ class CXXRecordDecl : public RecordDecl {
 return !hasDefinition() || !isDynamicClass() || hasAnyDependentBases();
   }
 
-  void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+  void setIsParsingBaseSpecifiers(bool to = true) {
+data().IsParsingBaseSpecifiers = to;
+  }
 
   bool isParsingBaseSpecifiers() const {
 return data().IsParsingBaseSpecifiers;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9e82130c93609..a9f9f02651cff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8003,6 +8003,8 @@ def err_bad_memptr_rhs : Error<
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
+def note_memptr_incomplete_until_bases : Note<
+  "this will affect the ABI of the member pointer until the bases have been 
specified">;
 def err_memptr_incomplete : Error<
   "member pointer has incomplete base type %0">;
 def warn_exception_caught_by_earlier_handler : Warning<
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 75c441293d62e..7f20a47e6a054 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -474,10 +474,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
   if (data().IsStandardLayout && NumBases > 1 && hasRepeatedBaseClass(this))
 data().IsStandardLayout = false;
 
-  if (VBases.empty()) {
-data().IsParsingBaseSpecifiers = false;
+  if (VBases.empty())
 return;
-  }
 
   // Create base specifier for any direct or indirect virtual bases.
   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -488,8 +486,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const 
*Bases,
   addedClassSubobject(Type->getAsCXXRecordDecl());
 data().getVBases()[I] = *VBases[I];
   }
-
-  data().IsParsingBaseSpecifiers = false;
 }
 
 unsigned CXXRecordDecl::getODRHash() const {
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 65ddebca49bc6..a28503b5b4de4 100644
--- 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/9] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2c..dca941fa30624 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// to 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits


@@ -3183,8 +3193,35 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  StringRef WithoutLastNewline =
+  StringRef(BufferStart, LastNewline.data() - BufferStart);
+  while (!WithoutLastNewline.empty()) {
+if (isHorizontalWhitespace(WithoutLastNewline.back())) {
+  WithoutLastNewline = WithoutLastNewline.drop_back();
+} else {
+  break;
+}
+  }
+
+  if (WithoutLastNewline.ends_with('\\') ||
+  (LangOpts.Trigraphs && WithoutLastNewline.ends_with("??"
+  "/"))) {

MitalAshok wrote:

Clang-format doesn't mind `"??/"`, but it's the compiler that complains.

I had no idea `\?` was a valid escape sequence, but apparently it is: 
https://eel.is/c++draft/lex.ccon#note-1

I'll be using that thanks!

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


[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/8] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2c..dca941fa30624 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// to 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits


@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash. #GH41571.

MitalAshok wrote:

Is the space before the full stop intentional?

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


[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits


@@ -3183,8 +3193,35 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  StringRef WithoutLastNewline =
+  StringRef(BufferStart, LastNewline.data() - BufferStart);
+  while (!WithoutLastNewline.empty()) {
+if (isHorizontalWhitespace(WithoutLastNewline.back())) {
+  WithoutLastNewline = WithoutLastNewline.drop_back();
+} else {
+  break;
+}
+  }
+
+  if (WithoutLastNewline.ends_with('\\') ||
+  (LangOpts.Trigraphs && WithoutLastNewline.ends_with("??"
+  "/"))) {

MitalAshok wrote:

That gives a "warning: trigraph ignored [-Wtrigraphs]" warning when compiling 
this

clang-format refuses to put concatenated string literals on the same line.

I've changed this and added a comment, but let me know if this could be done in 
a cleaner way

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


[clang] [Clang] [C23] Fix typeof_unqual for qualified array types (PR #92767)

2024-07-05 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/92767

>From f87cb4c754a477515746e2ac2f8906b93ccd1fe3 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Mon, 20 May 2024 15:58:58 +0100
Subject: [PATCH 1/5] [Clang] [C23] Fix typeof_unqual for qualified array types

Properly remove qualifiers for both the element type and the array type

Fixes #92667
---
 clang/include/clang/AST/ASTContext.h |  6 -
 clang/include/clang/AST/Type.h   | 37 +--
 clang/lib/AST/ASTContext.cpp | 14 +-
 clang/lib/AST/Type.cpp   | 38 ++--
 clang/test/Sema/c2x-typeof.c | 25 ++
 5 files changed, 84 insertions(+), 36 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index e03b112194786..ff7bdb7e7e1a6 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2611,7 +2611,11 @@ class ASTContext : public RefCountedBase {
   ///
   /// \returns if this is an array type, the completely unqualified array type
   /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
-  QualType getUnqualifiedArrayType(QualType T, Qualifiers );
+  QualType getUnqualifiedArrayType(QualType T, Qualifiers ) const;
+  QualType getUnqualifiedArrayType(QualType T) const {
+Qualifiers Quals;
+return getUnqualifiedArrayType(T, Quals);
+  }
 
   /// Determine whether the given types are equivalent after
   /// cvr-qualifiers have been removed.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index da3834f19ca04..df7f396bae095 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1605,6 +1605,10 @@ class QualType {
   QualType stripObjCKindOfType(const ASTContext ) const;
 
   /// Remove all qualifiers including _Atomic.
+  ///
+  /// Like getUnqualifiedType(), the type may still be qualified if it is a
+  /// sugared array type.  To strip qualifiers even from within a sugared array
+  /// type, use ASTContext::getUnqualifiedArrayType.
   QualType getAtomicUnqualifiedType() const;
 
 private:
@@ -2092,8 +2096,8 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
 
 LLVM_PREFERRED_TYPE(TypeBitfields)
 unsigned : NumTypeBits;
-LLVM_PREFERRED_TYPE(bool)
-unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof
+LLVM_PREFERRED_TYPE(TypeOfKind)
+unsigned Kind : 1;
   };
 
   class UsingBitfields {
@@ -5273,19 +5277,20 @@ class MacroQualifiedType : public Type {
 /// extension) or a `typeof_unqual` expression (a C23 feature).
 class TypeOfExprType : public Type {
   Expr *TOExpr;
+  const ASTContext 
 
 protected:
   friend class ASTContext; // ASTContext creates these.
 
-  TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType());
+  TypeOfExprType(const ASTContext , Expr *E, TypeOfKind Kind,
+ QualType Can = QualType());
 
 public:
   Expr *getUnderlyingExpr() const { return TOExpr; }
 
   /// Returns the kind of 'typeof' type this is.
   TypeOfKind getKind() const {
-return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
-   : TypeOfKind::Qualified;
+return static_cast(TypeOfBits.Kind);
   }
 
   /// Remove a single level of sugar.
@@ -5306,7 +5311,8 @@ class TypeOfExprType : public Type {
 class DependentTypeOfExprType : public TypeOfExprType,
 public llvm::FoldingSetNode {
 public:
-  DependentTypeOfExprType(Expr *E, TypeOfKind Kind) : TypeOfExprType(E, Kind) 
{}
+  DependentTypeOfExprType(const ASTContext , Expr *E, TypeOfKind Kind)
+  : TypeOfExprType(Context, E, Kind) {}
 
   void Profile(llvm::FoldingSetNodeID , const ASTContext ) {
 Profile(ID, Context, getUnderlyingExpr(),
@@ -5323,32 +5329,23 @@ class TypeOfType : public Type {
   friend class ASTContext; // ASTContext creates these.
 
   QualType TOType;
+  const ASTContext 
 
-  TypeOfType(QualType T, QualType Can, TypeOfKind Kind)
-  : Type(TypeOf,
- Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType()
- : Can,
- T->getDependence()),
-TOType(T) {
-TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
-  }
+  TypeOfType(const ASTContext , QualType T, QualType Can,
+ TypeOfKind Kind);
 
 public:
   QualType getUnmodifiedType() const { return TOType; }
 
   /// Remove a single level of sugar.
-  QualType desugar() const {
-QualType QT = getUnmodifiedType();
-return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT;
-  }
+  QualType desugar() const;
 
   /// Returns whether this type directly provides sugar.
   bool isSugared() const { return true; }
 
   /// Returns the kind of 'typeof' type this is.
   TypeOfKind getKind() const {
-return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
-   : 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits


@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++11 -pedantic-errors -verify=expected %s -E | 
FileCheck %s --strict-whitespace --allow-empty

MitalAshok wrote:

Fixed now, thanks

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


[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-05 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/6] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb0..7c0ac3a504f982 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee9..e6b2c1385944c7 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b38623..0e540834b473ba 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2cc..dca941fa30624f 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-04 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/5] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2c..dca941fa30624 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// to 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-04 Thread Mital Ashok via cfe-commits

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


[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-04 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/4] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb0..7c0ac3a504f982 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee9..e6b2c1385944c7 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b38623..0e540834b473ba 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2cc..dca941fa30624f 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-04 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/3] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2c..dca941fa30624 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// to 

[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-04 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97585

>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH 1/2] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, *LastSpliceLocation == '\\' ? 1 : 3));
+  }
+}
   }
 
   BufferPtr = CurPtr;
diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp
index cf6b45ceabf2c..dca941fa30624 100644
--- a/clang/test/CXX/drs/cwg16xx.cpp
+++ b/clang/test/CXX/drs/cwg16xx.cpp
@@ -536,3 +536,12 @@ namespace cwg1696 { // cwg1696: 7
   };
 #endif
 }
+
+// cwg1698: yes
+// This file intentionally does not end in a newline
+// to 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-03 Thread Mital Ashok via cfe-commits


@@ -1165,6 +1165,8 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
+  if (LangOpts.Char8 || LangOpts.C23)
+DefineType("__CHAR8_TYPE__", TI.UnsignedChar, Builder);

MitalAshok wrote:

According to https://gcc.gnu.org/legacy-ml/gcc-patches/2018-11/msg00295.html 
`__CHAR8_TYPE__` is "the underlying type of `char8_t`" in C++. `char8_t` in C++ 
was added in GCC9 which explains the difference between GCC8 and 9

And this made me realise `-std=c++11 -fchar8_t` sets `LangOpts.Char8` in C++11, 
which I think this patch handles fine (See also: #97601).
Also `-std=c23 -fchar8_t` is a mode that exists. It makes `typeof(u8'x')` 
`char8_t` and `typeof(u8"")` `char8_t[1]`, even with this patch, which I guess 
is fine. Pending #55373 if `-std=c23 -fchar8_t` even makes sense.

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


[clang] [Clang] Warn on backslash-newline-EOF (PR #97585)

2024-07-03 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/97585

C99 §5.1.1.2p2, C23 §5.1.1.2p2

> A source file that is not empty shall end in a new-line character, which 
> shall not be immediately preceded by a backslash character before any such 
> splicing takes place.

Also adds tests for C++ DRs 
[CWG1698](https://cplusplus.github.io/CWG/issues/1698.html) and 
[CWG2747](https://cplusplus.github.io/CWG/issues/2747.html) related to line 
splices near the end of a source file.


>From 8af656659b79d76c971b01f1f4c14dc7315565b8 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Fri, 21 Jun 2024 18:55:38 +0100
Subject: [PATCH] [Clang] Warn on backslash-newline-EOF

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../include/clang/Basic/DiagnosticLexKinds.td |  1 +
 clang/lib/Lex/Lexer.cpp   | 39 +--
 clang/test/CXX/drs/cwg16xx.cpp|  9 +
 clang/test/CXX/drs/cwg2747.cpp| 11 ++
 clang/test/CXX/drs/cwg27xx.cpp|  2 +
 .../test/Preprocessor/backslash_newline_eof.c | 12 ++
 .../Preprocessor/backslash_without_newline.c  |  8 
 .../Preprocessor/backslash_without_newline.h  |  4 ++
 clang/www/cxx_dr_status.html  |  4 +-
 10 files changed, 87 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/CXX/drs/cwg2747.cpp
 create mode 100644 clang/test/Preprocessor/backslash_newline_eof.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.c
 create mode 100644 clang/test/Preprocessor/backslash_without_newline.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f40fd1cd145bb..7c0ac3a504f98 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -647,6 +647,8 @@ Improvements to Clang's diagnostics
 
 - Clang now shows implicit deduction guides when diagnosing overload 
resolution failure. #GH92393.
 
+- Clang now emits ``-Wnewline-eof`` when the last newline is deleted by a 
preceding backslash.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..e6b2c1385944c 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -56,6 +56,7 @@ def ext_no_newline_eof : Extension<"no newline at end of 
file">,
   InGroup;
 def warn_no_newline_eof : Warning<"no newline at end of file">,
   InGroup, DefaultIgnore;
+def note_backslash_newline_eof : Note<"last newline deleted by splice here">;
 
 def warn_cxx98_compat_no_newline_eof : Warning<
   "C++98 requires newline at end of file">,
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..0e540834b473b 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3165,7 +3165,17 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
 
   // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue
   // a pedwarn.
-  if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
+  if (CurPtr != BufferStart) {
+StringRef LastNewline;
+if (CurPtr[-1] == '\r' || CurPtr[-1] == '\n') {
+  LastNewline = StringRef(CurPtr - 1, 1);
+  if (CurPtr - 1 != BufferStart && CurPtr[-2] != CurPtr[-1] &&
+  (CurPtr[-2] == '\r' || CurPtr[-2] == '\n')) {
+// \r\n or \n\r is one newline
+LastNewline = StringRef(CurPtr - 2, 2);
+  }
+}
+
 DiagnosticsEngine  = PP->getDiagnostics();
 SourceLocation EndLoc = getSourceLocation(BufferEnd);
 unsigned DiagID;
@@ -3183,8 +3193,31 @@ bool Lexer::LexEndOfFile(Token , const char 
*CurPtr) {
   DiagID = diag::ext_no_newline_eof;
 }
 
-Diag(BufferEnd, DiagID)
-  << FixItHint::CreateInsertion(EndLoc, "\n");
+if (LastNewline.empty()) {
+  Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
+} else {
+  // While the file physically ends in a newline, the previous
+  // line might have ended in a splice, so it would be deleted
+  const char *LastSpliceLocation = LastNewline.data();
+  while (LastSpliceLocation != BufferStart &&
+ isHorizontalWhitespace(*--LastSpliceLocation))
+;
+
+  bool LastIsSplice = *LastSpliceLocation == '\\';
+  if (*LastSpliceLocation == '/' && LangOpts.Trigraphs)
+// Check for "??/" trigraph for "\"
+LastIsSplice =
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?' 
&&
+LastSpliceLocation != BufferStart && *--LastSpliceLocation == '?';
+
+  if (LastIsSplice) {
+PP->Diag(getSourceLocation(LastNewline.data(), LastNewline.size()),
+ DiagID);
+Diag(LastSpliceLocation, diag::note_backslash_newline_eof)
+<< FixItHint::CreateRemoval(getSourceLocation(
+   LastSpliceLocation, 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-03 Thread Mital Ashok via cfe-commits


@@ -1165,6 +1165,8 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
+  if (LangOpts.Char8 || LangOpts.C23)
+DefineType("__CHAR8_TYPE__", TI.UnsignedChar, Builder);

MitalAshok wrote:

This matches GCC behaviour: https://godbolt.org/z/6Eax3eqrd

But I'm not sure why it's defined in C++ at all

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-03 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/5] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-03 Thread Mital Ashok via cfe-commits


@@ -104,6 +107,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;

MitalAshok wrote:

It seems like this header doesn't properly implement 
[P0943R6](https://wg21.link/P0943R6) in C++23 (Where `#define _Atomic(T) 
std::atomic` and all these typedefs should just be `using std::atomic_*`.

So `::atomic_char8_t` should be `std::atomic`, not 
`std::atomic` (nor `unsigned char _Atomic`), but that is outside 
the scope of this PR. I'll just make this match the surrounding typedefs for 
now.

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


[clang] [Clang] Implement CWG2351 `void{}` (PR #78060)

2024-07-02 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

Is there anything else that needs to be done for this? Also, thanks for all the 
reviews and help on this!

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


[clang] [libcxx] [Clang] Implement CWG2137 (list-initialization from objects of the same type) (PR #94355)

2024-07-02 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

I'm waiting to rebase on #97403 to remove the libc++ component of this now

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


[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-07-01 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 01/10] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-01 Thread Mital Ashok via cfe-commits


@@ -104,6 +107,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;

MitalAshok wrote:

Should the definition of `atomic_char8_t` also be gated behind C23/C++20?

Also in C++20, this should be `_Atomic(char8_t)`, but the next two are also 
wrong in C++11 (`_Atomic(char16_t)`/`_Atomic(char32_t)`)

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-01 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97208

>From ef0072d1fc9b14f7ee657fa95f44a686b78b525a Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:07:54 +0100
Subject: [PATCH 1/3] [Clang] [C23] Implement N2653: u8 strings are char8_t[]

---
 clang/docs/ReleaseNotes.rst   |  6 
 .../clang/Basic/DiagnosticSemaKinds.td|  5 +++-
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++--
 clang/lib/Headers/stdatomic.h |  5 
 clang/lib/Sema/SemaExpr.cpp   | 23 ++-
 clang/test/C/C2x/n2653.c  | 29 +++
 clang/www/c_status.html   |  2 +-
 7 files changed, 65 insertions(+), 11 deletions(-)
 create mode 100644 clang/test/C/C2x/n2653.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..e51be81d8b11a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -337,6 +337,12 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Compiler support for `N2653 char8_t: A type for UTF-8 characters and strings`
+  `_: ``u8`` string
+  literals are now of type ``char8_t[N]`` in C23 and expose
+  ``__CLANG_ATOMIC_CHAR8_T_LOCK_FREE``/``__GCC_ATOMIC_CHAR8_T_LOCK_FREE`` to
+  implement the corresponding macro in .
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..6a00b92df1c36 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7252,7 +7252,10 @@ def err_array_init_utf8_string_into_char : Error<
 def warn_cxx20_compat_utf8_string : Warning<
   "type of UTF-8 string literal will change from array of const char to "
   "array of const char8_t in C++20">, InGroup, DefaultIgnore;
-def note_cxx20_compat_utf8_string_remove_u8 : Note<
+def warn_c23_compat_utf8_string : Warning<
+  "type of UTF-8 string literal will change from array of char to "
+  "array of char8_t in C23">, InGroup, DefaultIgnore;
+def note_cxx20_c23_compat_utf8_string_remove_u8 : Note<
   "remove 'u8' prefix to avoid a change of behavior; "
   "Clang encodes unprefixed narrow string literals as UTF-8">;
 def err_array_init_different_type : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..6270c37342bcf 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)
+  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char);
 DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
 DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
 DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h
index 9c103d98af8c5..c33cd8083525c 100644
--- a/clang/lib/Headers/stdatomic.h
+++ b/clang/lib/Headers/stdatomic.h
@@ -35,6 +35,10 @@ extern "C" {
 
 #define ATOMIC_BOOL_LOCK_FREE   __CLANG_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE   __CLANG_ATOMIC_CHAR_LOCK_FREE
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||  
\
+defined(__cplusplus)
+#define ATOMIC_CHAR8_T_LOCK_FREE__CLANG_ATOMIC_CHAR8_T_LOCK_FREE
+#endif
 #define ATOMIC_CHAR16_T_LOCK_FREE   __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
 #define ATOMIC_CHAR32_T_LOCK_FREE   __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
 #define ATOMIC_WCHAR_T_LOCK_FREE__CLANG_ATOMIC_WCHAR_T_LOCK_FREE
@@ -104,6 +108,7 @@ typedef _Atomic(long)   atomic_long;
 typedef _Atomic(unsigned long)  atomic_ulong;
 typedef _Atomic(long long)  atomic_llong;
 typedef _Atomic(unsigned long long) atomic_ullong;
+typedef _Atomic(unsigned char)  atomic_char8_t;
 typedef _Atomic(uint_least16_t) atomic_char16_t;
 typedef _Atomic(uint_least32_t) atomic_char32_t;
 typedef _Atomic(wchar_t)atomic_wchar_t;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..a1b060f7f1510 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2082,6 +2082,8 @@ Sema::ActOnStringLiteral(ArrayRef StringToks, 
Scope *UDLScope) {
   } else if (Literal.isUTF8()) {
 if 

[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-07-01 Thread Mital Ashok via cfe-commits


@@ -1342,8 +1342,10 @@ static void InitializePredefinedMacros(const TargetInfo 
,
   getLockFreeValue(TI.get##Type##Width(), TI));
 DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
 DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-if (LangOpts.Char8)
-  DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
+// char8_t has the same representation / width as unsigned
+// char in C++ and is a typedef for unsigned char in C23
+if (LangOpts.Char8 || LangOpts.C23)

MitalAshok wrote:

Looks like that also controls if `char8_t` is a keyword/builtin type, which it 
isn't in C23. (`LangOpts.Char8` is also false in C++20 with `-fno-char8_t`)

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


[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-06-30 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 1/9] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-06-30 Thread Mital Ashok via cfe-commits

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


[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-06-30 Thread Mital Ashok via cfe-commits


@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05

MitalAshok wrote:

The date of the proposed resolution did not change for this one: 
https://cplusplus.github.io/CWG/issues/2858.html

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


[clang] [NFC] [Clang] Some core issues have changed status from tentatively ready -> ready / review (PR #97200)

2024-06-30 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok updated 
https://github.com/llvm/llvm-project/pull/97200

>From 0dea95701ca4dfca9b7d0bd889003fc35aa3017e Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 10:39:15 +0100
Subject: [PATCH 1/8] [NFC] [Clang] Some core issues have changed status from
 tentatively ready -> ready / review

---
 clang/test/CXX/drs/cwg25xx.cpp |   2 +-
 clang/test/CXX/drs/cwg28xx.cpp |  16 ++--
 clang/www/cxx_dr_status.html   | 130 +++--
 clang/www/make_cxx_dr_status   |   6 +-
 4 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp
index 0934f0cc19c6a..5f8a058f8157a 100644
--- a/clang/test/CXX/drs/cwg25xx.cpp
+++ b/clang/test/CXX/drs/cwg25xx.cpp
@@ -139,7 +139,7 @@ struct D3 : B {
 #endif
 
 #if __cplusplus >= 202302L
-namespace cwg2561 { // cwg2561: no tentatively ready 2024-03-18
+namespace cwg2561 { // cwg2561: no ready 2024-03-18
 struct C {
 constexpr C(auto) { }
 };
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index c77bd433d8e21..524e67b52de51 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -30,7 +30,7 @@ using U2 = decltype();
 #endif
 } // namespace cwg2811
 
-namespace cwg2819 { // cwg2819: 19 tentatively ready 2023-12-01
+namespace cwg2819 { // cwg2819: 19 ready 2023-12-01
 #if __cpp_constexpr >= 202306L
   constexpr void* p = nullptr;
   constexpr int* q = static_cast(p);
@@ -111,7 +111,7 @@ struct D : N::B {
 #endif
 } // namespace cwg2857
 
-namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
+namespace cwg2858 { // cwg2858: 19 ready 2024-04-05
 
 #if __cplusplus > 202302L
 
@@ -134,7 +134,7 @@ struct A {
 
 } // namespace cwg2858
 
-namespace cwg2877 { // cwg2877: 19 tentatively ready 2024-05-31
+namespace cwg2877 { // cwg2877: 19 ready 2024-05-31
 #if __cplusplus >= 202002L
 enum E { x };
 void f() {
@@ -150,7 +150,7 @@ void g() {
 #endif
 } // namespace cwg2877
 
-namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19
+namespace cwg2881 { // cwg2881: 19 ready 2024-04-19
 
 #if __cplusplus >= 202302L
 
@@ -220,7 +220,7 @@ void f() {
 
 } // namespace cwg2881
 
-namespace cwg2882 { // cwg2882: 2.7 tentatively ready 2024-05-31
+namespace cwg2882 { // cwg2882: 2.7 ready 2024-05-31
 struct C {
   operator void() = delete;
   // expected-warning@-1 {{conversion function converting 'cwg2882::C' to 
'void' will never be used}}
@@ -232,7 +232,7 @@ void f(C c) {
 }
 } // namespace cwg2882
 
-namespace cwg2883 { // cwg2883: no tentatively ready 2024-05-31
+namespace cwg2883 { // cwg2883: no ready 2024-05-31
 #if __cplusplus >= 201103L
 void f() {
   int x;
@@ -257,7 +257,7 @@ void g() {
 #endif
 } // namespace cwg2883
 
-namespace cwg2885 { // cwg2885: 16 tentatively ready 2024-05-31
+namespace cwg2885 { // cwg2885: 16 review 2024-05-31
 #if __cplusplus >= 202002L
 template 
 struct A {
@@ -271,7 +271,7 @@ static_assert(!__is_trivially_constructible(B));
 #endif
 } // namespace cwg2885
 
-namespace cwg2886 { // cwg2886: 9 tentatively ready 2024-05-31
+namespace cwg2886 { // cwg2886: 9 ready 2024-05-31
 #if __cplusplus >= 201103L
 struct C {
   C() = default;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 937f67981e296..64b361976a5a5 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -1442,7 +1442,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/233.html;>233
-tentatively ready
+ready
 References vs pointers in UDC overload resolution
 Not resolved
   
@@ -7329,11 +7329,11 @@ C++ defect report implementation 
status
 Overloading member function templates based on dependent return 
type
 Unknown
   
-  
+  
 https://cplusplus.github.io/CWG/issues/1253.html;>1253
-open
+C++17
 Generic non-template members
-Not resolved
+Unknown
   
   
 https://cplusplus.github.io/CWG/issues/1254.html;>1254
@@ -12677,7 +12677,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2144.html;>2144
-tentatively ready
+ready
 Function/variable declaration ambiguity
 Not resolved
   
@@ -15179,7 +15179,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2561.html;>2561
-tentatively ready
+ready
 Conversion to function pointer for lambda with explicit object 
parameter
 Not Resolved*
   
@@ -15341,7 +15341,7 @@ C++ defect report implementation 
status
   
   
 https://cplusplus.github.io/CWG/issues/2588.html;>2588
-tentatively ready
+ready
 friend declarations and module linkage
 Not resolved
   
@@ -15541,7 +15541,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/2621.html;>2621
 C++23
 Kind of lookup for using enum declarations
-Superseded by 2877
+

[clang] [Clang] Warn with -Wpre-c23-compat instead of -Wpre-c++17-compat for u8 character literals in C23 (PR #97210)

2024-06-30 Thread Mital Ashok via cfe-commits

https://github.com/MitalAshok created 
https://github.com/llvm/llvm-project/pull/97210

None

>From c6ee783243e1888074778e2cb6de05df41cc8333 Mon Sep 17 00:00:00 2001
From: Mital Ashok 
Date: Sun, 30 Jun 2024 12:55:04 +0100
Subject: [PATCH] [Clang] Warn with -Wpre-c23-compat instead of
 -Wpre-c++17-compat for u8 character literals in C23

---
 clang/docs/ReleaseNotes.rst | 2 ++
 clang/include/clang/Basic/DiagnosticLexKinds.td | 3 +++
 clang/lib/Lex/Lexer.cpp | 4 +++-
 clang/test/Sema/pre-c2x-compat.c| 1 +
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c720e47dbe35b..d2939ef7a875c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -627,6 +627,8 @@ Improvements to Clang's diagnostics
   used rather than when they are needed for constant evaluation or when code 
is generated for them.
   The check is now stricter to prevent crashes for some unsupported 
declarations (Fixes #GH95495).
 
+- Clang now warns for u8 character literals used in C23 with 
``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 12d7b8c0205ee..fc14bb6aa2165 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -283,6 +283,9 @@ def warn_cxx98_compat_unicode_literal : Warning<
 def warn_cxx14_compat_u8_character_literal : Warning<
   "unicode literals are incompatible with C++ standards before C++17">,
   InGroup, DefaultIgnore;
+def warn_c17_compat_u8_character_literal : Warning<
+  "unicode literals are incompatible with C standards before C23">,
+  InGroup, DefaultIgnore;
 def warn_cxx11_compat_user_defined_literal : Warning<
   "identifier after literal will be treated as a user-defined literal suffix "
   "in C++11">, InGroup, DefaultIgnore;
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..c61d81e93d990 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2428,7 +2428,9 @@ bool Lexer::LexCharConstant(Token , const char 
*CurPtr,
   ? diag::warn_cxx98_compat_unicode_literal
   : diag::warn_c99_compat_unicode_literal);
 else if (Kind == tok::utf8_char_constant)
-  Diag(BufferPtr, diag::warn_cxx14_compat_u8_character_literal);
+  Diag(BufferPtr, LangOpts.CPlusPlus
+  ? diag::warn_cxx14_compat_u8_character_literal
+  : diag::warn_c17_compat_u8_character_literal);
   }
 
   char C = getAndAdvanceChar(CurPtr, Result);
diff --git a/clang/test/Sema/pre-c2x-compat.c b/clang/test/Sema/pre-c2x-compat.c
index fad472f1f72d5..15bb9b58349fa 100644
--- a/clang/test/Sema/pre-c2x-compat.c
+++ b/clang/test/Sema/pre-c2x-compat.c
@@ -1,3 +1,4 @@
 // RUN: %clang_cc1 %s -std=c2x -Wpre-c2x-compat -pedantic -fsyntax-only -verify
 
 int digit_seps = 123'456; // expected-warning {{digit separators are 
incompatible with C standards before C23}}
+unsigned char u8_char = u8'x'; // expected-warning {{unicode literals are 
incompatible with C standards before C23}}

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


[clang] [Clang] [C23] Implement N2653: u8 strings are char8_t[] (PR #97208)

2024-06-30 Thread Mital Ashok via cfe-commits

MitalAshok wrote:

CC @AaronBallman

Also the clang-format issues are intentional to fit the style of the 
surrounding lines

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


  1   2   3   4   >