[clang] Don't pass sanitizers' rtlibs to linker with `-r` (PR #147905)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Dmitry Chestnykh (chestnykh)


Changes

If clang is invoked with `-r` (relocatable linking) then we shouldn't construct 
sanitizer arguments and then pass sanitizer runtime libs to the linker
GCC simply ignores `-fsanitize=...` if `-r` is also here

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


2 Files Affected:

- (modified) clang/lib/Driver/SanitizerArgs.cpp (+4) 
- (modified) clang/test/Driver/sanitizer-ld.c (+16) 


``diff
diff --git a/clang/lib/Driver/SanitizerArgs.cpp 
b/clang/lib/Driver/SanitizerArgs.cpp
index 4bd61c2f8deef..037d98e4cfc3d 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -406,6 +406,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
   SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
 // Used to deduplicate diagnostics.
   SanitizerMask Kinds;
+
+  if (Args.hasArg(options::OPT_r))
+return;
+
   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
 
   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index d2e4877e89d78..5144dbc2007d3 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -1369,3 +1369,19 @@
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lresolv"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--dynamic-list"
+
+// RUN: %clang -fsanitize=address,undefined -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB-NOT: "{{.*}}(asan|ubsan){{.*}}"
+
+// RUN: %clang -fsanitize=thread -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-TSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-TSAN-RTLIB-NOT: "{{.*}}tsan{{.*}}"

``




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


[clang] Don't pass sanitizers' rtlibs to linker with `-r` (PR #147905)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Dmitry Chestnykh (chestnykh)


Changes

If clang is invoked with `-r` (relocatable linking) then we shouldn't construct 
sanitizer arguments and then pass sanitizer runtime libs to the linker
GCC simply ignores `-fsanitize=...` if `-r` is also here

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


2 Files Affected:

- (modified) clang/lib/Driver/SanitizerArgs.cpp (+4) 
- (modified) clang/test/Driver/sanitizer-ld.c (+16) 


``diff
diff --git a/clang/lib/Driver/SanitizerArgs.cpp 
b/clang/lib/Driver/SanitizerArgs.cpp
index 4bd61c2f8deef..037d98e4cfc3d 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -406,6 +406,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
   SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
 // Used to deduplicate diagnostics.
   SanitizerMask Kinds;
+
+  if (Args.hasArg(options::OPT_r))
+return;
+
   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
 
   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index d2e4877e89d78..5144dbc2007d3 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -1369,3 +1369,19 @@
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lresolv"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--dynamic-list"
+
+// RUN: %clang -fsanitize=address,undefined -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB-NOT: "{{.*}}(asan|ubsan){{.*}}"
+
+// RUN: %clang -fsanitize=thread -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-TSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-TSAN-RTLIB-NOT: "{{.*}}tsan{{.*}}"

``




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


[clang] Don't pass sanitizers' rtlibs to linker with `-r` (PR #147905)

2025-07-10 Thread Dmitry Chestnykh via cfe-commits

https://github.com/chestnykh created 
https://github.com/llvm/llvm-project/pull/147905

If clang is invoked with `-r` (relocatable linking) then we shouldn't construct 
sanitizer arguments and then pass sanitizer runtime libs to the linker
GCC simply ignores `-fsanitize=...` if `-r` is also here

>From 8d1f86a9030fcc1184603309c6528190735a6fbc Mon Sep 17 00:00:00 2001
From: Dmitry Chestnykh 
Date: Thu, 10 Jul 2025 10:19:31 +0300
Subject: [PATCH] Don't pass sanitizers' rtlibs to linker with `-r`

If clang is invoked with `-r` (relocatable linking)
then we shouldn't construct sanitizer arguments and
then pass sanitizer runtime libs to the linker
GCC simply ignores `-fsanitize=...` if `-r` is also here
---
 clang/lib/Driver/SanitizerArgs.cpp |  4 
 clang/test/Driver/sanitizer-ld.c   | 16 
 2 files changed, 20 insertions(+)

diff --git a/clang/lib/Driver/SanitizerArgs.cpp 
b/clang/lib/Driver/SanitizerArgs.cpp
index 4bd61c2f8deef..037d98e4cfc3d 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -406,6 +406,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
   SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
 // Used to deduplicate diagnostics.
   SanitizerMask Kinds;
+
+  if (Args.hasArg(options::OPT_r))
+return;
+
   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
 
   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index d2e4877e89d78..5144dbc2007d3 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -1369,3 +1369,19 @@
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lresolv"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic"
 // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--dynamic-list"
+
+// RUN: %clang -fsanitize=address,undefined -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-ASAN-UBSAN-RTLIB-NOT: "{{.*}}(asan|ubsan){{.*}}"
+
+// RUN: %clang -fsanitize=thread -r -### %s 2>&1 \
+// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | %{filecheck} --check-prefix=CHECK-RELOCATABLE-LINK-TSAN-RTLIB
+//
+// CHECK-RELOCATABLE-LINK-TSAN-RTLIB-NOT: "{{.*}}tsan{{.*}}"

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


[clang] [clang][bytecode] Allocate Record Fields and bases via Program (PR #147909)

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

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

>From b23c75ff781875da10baa9e6f033ed5358c0cf02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 10 Jul 2025 09:21:57 +0200
Subject: [PATCH] [clang][bytecode] Allocate Record Fields and bases via
 Program

Records have Program-lifetime, but we used to allocate their fields,
bases and virtual bases using llvm::SmallVector. However, after creating
a Record, it doesn't change and we know all the number of elements
beforehand.

So, allocate the lists via the BumpPtrAllocator we already have in
Program. This results in slight compile-time improvements:

https://llvm-compile-time-tracker.com/compare.php?from=3a3d55705b0f69f3ef5bed0b0211e7c884001842&to=e0fede973116c4d43e9883586c737c3d0bb99c3e&stat=instructions:u

Unfortunately, we still have the three DenseMaps in Record, so they
still heap-allocate memory on their own.
---
 clang/lib/AST/ByteCode/Program.cpp | 33 +++--
 clang/lib/AST/ByteCode/Record.cpp  | 21 --
 clang/lib/AST/ByteCode/Record.h| 46 ++
 3 files changed, 58 insertions(+), 42 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 5ac0f59f32d4e..de9008f0512e6 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -315,9 +315,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   };
 
   // Reserve space for base classes.
-  Record::BaseList Bases;
-  Record::VirtualBaseList VirtBases;
+  Record::Base *Bases = nullptr;
+  Record::Base *VBases = nullptr;
+  unsigned NumRecordBases = 0;
+  unsigned NumRecordVBases = 0;
   if (const auto *CD = dyn_cast(RD)) {
+unsigned NumBases = CD->getNumBases();
+unsigned NumVBases = CD->getNumVBases();
+
+Bases = new (*this) Record::Base[NumBases];
+VBases = new (*this) Record::Base[NumVBases];
+
 for (const CXXBaseSpecifier &Spec : CD->bases()) {
   if (Spec.isVirtual())
 continue;
@@ -334,9 +342,11 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   BaseSize += align(sizeof(InlineDescriptor));
-  Bases.push_back({BD, BaseSize, Desc, BR});
+  new (&Bases[NumRecordBases]) Record::Base{BD, BaseSize, Desc, BR};
   BaseSize += align(BR->getSize());
+  ++NumRecordBases;
 }
+assert(NumRecordBases <= NumBases);
 
 for (const CXXBaseSpecifier &Spec : CD->vbases()) {
   const auto *RT = Spec.getType()->getAs();
@@ -351,13 +361,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   VirtSize += align(sizeof(InlineDescriptor));
-  VirtBases.push_back({BD, VirtSize, Desc, BR});
+  new (&VBases[NumRecordVBases]) Record::Base{BD, VirtSize, Desc, BR};
   VirtSize += align(BR->getSize());
+  ++NumRecordVBases;
 }
+assert(NumRecordVBases <= NumVBases);
   }
 
   // Reserve space for fields.
-  Record::FieldList Fields;
+  unsigned NumFields = std::distance(RD->field_begin(), RD->field_end());
+  unsigned NumRecordFields = 0;
+  Record::Field *Fields = new (*this) Record::Field[NumFields];
   for (const FieldDecl *FD : RD->fields()) {
 FD = FD->getFirstDecl();
 // Note that we DO create fields and descriptors
@@ -382,12 +396,15 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 }
 if (!Desc)
   return nullptr;
-Fields.push_back({FD, BaseSize, Desc});
+
+new (&Fields[NumRecordFields]) Record::Field{FD, BaseSize, Desc};
 BaseSize += align(Desc->getAllocSize());
+++NumRecordFields;
   }
 
-  Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
- std::move(VirtBases), VirtSize, BaseSize);
+  Record *R =
+  new (Allocator) Record(RD, Bases, NumRecordBases, Fields, 
NumRecordFields,
+ VBases, NumRecordVBases, VirtSize, BaseSize);
   Records[RD] = R;
   return R;
 }
diff --git a/clang/lib/AST/ByteCode/Record.cpp 
b/clang/lib/AST/ByteCode/Record.cpp
index 1d4ac7103cb76..e40fb63914b61 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -12,20 +12,23 @@
 using namespace clang;
 using namespace clang::interp;
 
-Record::Record(const RecordDecl *Decl, BaseList &&SrcBases,
-   FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases,
-   unsigned VirtualSize, unsigned BaseSize)
-: Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)),
+Record::Record(const RecordDecl *Decl, const Base *SrcBases, unsigned NumBases,
+   const Field *Fields, unsigned NumFields, Base *VBases,
+   unsigned NumVBases, unsigned VirtualSize, unsigned BaseSize)
+: Decl(Decl), Bases(SrcBases), NumBases(NumBases), Fields(Fields),
+  NumFields(NumFields), VBases(VBases), NumVBases(NumVBases),
   BaseSize(BaseSize), VirtualSize(Virtual

[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balázs Kéri via cfe-commits

https://github.com/balazske updated 
https://github.com/llvm/llvm-project/pull/147766

From f8dc303029c68762cdbd19b217730192d26f6fca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= 
Date: Wed, 9 Jul 2025 16:55:07 +0200
Subject: [PATCH 1/2] [clang][analyzer] Add C standard streams to the internal
 memory space

If variables `stdin`, `stdout`, `stderr` are added to the system memory
space, they are invalidated at any call to system (or C library) functions.
These variables are not expected to be changed by system functions,
therefore should not belong to the system memory space.
This change moves these to the "internal memory space" which is not
invalidated at system calls (but is at non-system calls). This
eliminates some false positives coming from StreamChecker.
---
 clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 20 +++--
 clang/test/Analysis/stream.c| 45 +++--
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp 
b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 63ad567ab7151..4e946f39c1cef 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1054,10 +1054,24 @@ const VarRegion *MemRegionManager::getVarRegion(const 
VarDecl *D,
 assert(!Ty.isNull());
 if (Ty.isConstQualified()) {
   sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-} else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
-  sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
 } else {
-  sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  StringRef N = D->getNameAsString();
+  QualType FILETy = D->getASTContext().getFILEType();
+  if (!FILETy.isNull())
+FILETy = FILETy.getCanonicalType();
+  Ty = Ty.getCanonicalType();
+  bool IsStdStreamVar = Ty->isPointerType() &&
+Ty->getPointeeType() == FILETy &&
+(N == "stdin" || N == "stdout" || N == "stderr");
+  // Pointer value of C standard streams is usually not modified by system
+  // calls. This means they should not get invalidated at system calls and
+  // can not belong to the system memory space.
+  if (Ctx.getSourceManager().isInSystemHeader(D->getLocation()) &&
+  !IsStdStreamVar) {
+sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
+  } else {
+sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  }
 }
 
   // Finally handle static locals.
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index 758b40cca4931..781c023ea248a 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -519,14 +519,53 @@ void reopen_std_stream(void) {
   if (!fp) return;
 
   stdout = fp; // Let's make them alias.
-  clang_analyzer_eval(fp == oldStdout); // expected-warning {{UNKNOWN}}
-  clang_analyzer_eval(fp == stdout);// expected-warning {{TRUE}} 
no-FALSE
-  clang_analyzer_eval(oldStdout == stdout); // expected-warning {{UNKNOWN}}
+  clang_analyzer_eval(fp == oldStdout); // expected-warning {{FALSE}}
+  clang_analyzer_eval(fp == stdout);// expected-warning {{TRUE}}
+  clang_analyzer_eval(oldStdout == stdout); // expected-warning {{FALSE}}
 }
 
 void only_success_path_does_not_alias_with_stdout(void) {
   if (stdout) return;
   FILE *f = fopen("/tmp/foof", "r"); // no-crash
+  clang_analyzer_eval(f == 0);// expected-warning {{TRUE}} expected-warning 
{{FALSE}}
   if (!f) return;
   fclose(f);
 }
+
+extern void do_something();
+
+void test_no_invalidate_at_system_call(int use_std) {
+  FILE *fd;
+  char *buf;
+
+  if (use_std) {
+fd = stdin;
+  } else {
+if ((fd = fopen("x/y/z", "r")) == NULL)
+  return;
+
+clang_analyzer_eval(fd == stdin); // expected-warning{{FALSE}}
+buf = (char *)malloc(100);
+clang_analyzer_eval(fd == stdin); // expected-warning{{FALSE}}
+  }
+
+  if (fd != stdin)
+fclose(fd);
+}
+
+void test_invalidate_at_non_system_call(int use_std) {
+  FILE *fd;
+
+  if (use_std) {
+fd = stdin;
+  } else {
+if ((fd = fopen("x/y/z", "r")) == NULL)
+  return;
+  }
+
+  do_something();
+  clang_analyzer_eval(fd == stdin); // expected-warning{{UNKNOWN}}
+
+  if (fd != stdin)
+fclose(fd);
+} // expected-warning{{Opened stream never closed. Potential resource leak}}

From 3117a648fe537b11a51fcb1e6b4ba19f49f1c4bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= 
Date: Thu, 10 Jul 2025 10:04:29 +0200
Subject: [PATCH 2/2] updated code comment

---
 clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp 
b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 4e946f39c1cef..53f421640c555 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/

[libclc] [libclc] Add generic implementation of some atomic functions in OpenCL spec section 6.15.12.7 (PR #146814)

2025-07-10 Thread Fraser Cormack via cfe-commits


@@ -0,0 +1,24 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef __CLC_OPENCL_ATOMIC_ATOMIC_COMPARE_EXCHANGE_STRONG_H__
+#define __CLC_OPENCL_ATOMIC_ATOMIC_COMPARE_EXCHANGE_STRONG_H__
+
+#define FUNCTION atomic_compare_exchange_strong

frasercrmck wrote:

We should probably be only declaring/defining these OpenCL builtins according 
to the appropriate language features. For instance, for 
`atomic_compare_exchange_strong` we have:

``` c
// Requires OpenCL C 3.0 or newer and both the __opencl_c_atomic_order_seq_cst
// and __opencl_c_atomic_scope_device features.
```

The CLC functions are probably fine and we can unconditionally include them, 
for simplicity. But I feel we should be adhering to the spec for OpenCL 
builtins.

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


[clang] [clang][ObjC][PAC] Add ptrauth protections to objective-c (PR #147899)

2025-07-10 Thread Oliver Hunt via cfe-commits

https://github.com/ojhunt updated 
https://github.com/llvm/llvm-project/pull/147899

>From 3b0a91c3d4a4ae8ec7980d2201d94f59746fb769 Mon Sep 17 00:00:00 2001
From: Oliver Hunt 
Date: Wed, 9 Jul 2025 17:30:48 -0700
Subject: [PATCH] [clang][ObjC][PAC] Add ptrauth protections to objective-c

This PR introduces the use of pointer authentication to objective-c[++].

This includes:

* __ptrauth qualifier support for ivars
* protection of isa and super fields
* protection of SEL typed ivars
* protection of class_ro_t data
* protection of methodlist pointers and content
---
 clang/include/clang/AST/ASTContext.h  |   2 +
 clang/include/clang/Basic/Features.def|   6 +
 clang/include/clang/Basic/LangOptions.def |   5 +
 .../include/clang/Basic/PointerAuthOptions.h  |  35 +
 clang/include/clang/Driver/Options.td |   3 +
 clang/lib/AST/ASTContext.cpp  |  11 ++
 clang/lib/CodeGen/CGBlocks.cpp|  21 ++-
 clang/lib/CodeGen/CGObjC.cpp  |  52 ++-
 clang/lib/CodeGen/CGObjCMac.cpp   |  94 +
 clang/lib/CodeGen/CodeGenModule.cpp   |   4 +-
 clang/lib/CodeGen/ConstantInitBuilder.cpp |   2 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   7 +
 clang/lib/Frontend/CompilerInvocation.cpp |  34 +
 clang/lib/Headers/ptrauth.h   |  57 
 clang/lib/Sema/SemaDeclObjC.cpp   |   8 ++
 clang/lib/Sema/SemaObjCProperty.cpp   |   9 ++
 clang/test/CodeGenObjC/arc.m  |   8 +-
 .../test/CodeGenObjC/matrix-type-operators.m  |  10 +-
 .../test/CodeGenObjC/ptrauth-attr-exception.m |  17 +++
 clang/test/CodeGenObjC/ptrauth-block-isa.m|  40 ++
 clang/test/CodeGenObjC/ptrauth-class-ro.m |  24 
 clang/test/CodeGenObjC/ptrauth-class.m| 103 ++
 .../ptrauth-objc-interface-selector.m | 130 ++
 .../test/CodeGenObjC/ptrauth-objc-isa-super.m |  57 
 .../ptrauth-objc-method-list-pointer.m|  17 +++
 .../CodeGenObjC/ptrauth-property-backing.m|  80 +++
 .../ptrauth-objc-interface-selector.mm|  90 
 clang/test/SemaObjC/ptrauth-pointers.m|  46 +++
 clang/test/SemaObjC/ptrauth-qualifier.m   |  39 +-
 29 files changed, 969 insertions(+), 42 deletions(-)
 create mode 100644 clang/test/CodeGenObjC/ptrauth-attr-exception.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-block-isa.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-class-ro.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-class.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-objc-interface-selector.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-objc-isa-super.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-objc-method-list-pointer.m
 create mode 100644 clang/test/CodeGenObjC/ptrauth-property-backing.m
 create mode 100644 clang/test/CodeGenObjCXX/ptrauth-objc-interface-selector.mm
 create mode 100644 clang/test/SemaObjC/ptrauth-pointers.m

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 2b9cd035623cc..8c27728c404dd 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2300,6 +2300,8 @@ class ASTContext : public RefCountedBase {
 return getTypeDeclType(getObjCSelDecl());
   }
 
+  PointerAuthQualifier getObjCMemberSelTypePtrAuth();
+
   /// Retrieve the typedef declaration corresponding to the predefined
   /// Objective-C 'Class' type.
   TypedefDecl *getObjCClassDecl() const;
diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index 14bff8a68846d..c2e677e31e5a0 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -119,6 +119,12 @@ FEATURE(ptrauth_indirect_gotos, 
LangOpts.PointerAuthIndirectGotos)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
 FEATURE(ptrauth_init_fini_address_discrimination, 
LangOpts.PointerAuthInitFiniAddressDiscrimination)
 FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT)
+
+FEATURE(ptrauth_objc_isa, LangOpts.PointerAuthObjcIsa)
+FEATURE(ptrauth_objc_interface_sel, LangOpts.PointerAuthObjcInterfaceSel)
+FEATURE(ptrauth_objc_signable_class, true)
+FEATURE(ptrauth_objc_method_list_pointer, LangOpts.PointerAuthCalls)
+
 EXTENSION(swiftcc,
   PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
   clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 72321c204ce96..852188de18654 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -133,6 +133,11 @@ LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0, 
NotCompatible,
 LANGOPT(PointerAuthELFGOT, 1, 0, NotCompatible, "authenticate pointers from 
GOT")
 LANGOPT(AArch64JumpTableHardening, 1, 0, NotCompatible, "use hardened lowering 
for jump-table dispatch")
 
+LANGOPT(Pointer

[clang] [Clang][AArch64] Relax SVE bf16 requirement for opaque builtins. (PR #147795)

2025-07-10 Thread Paul Walker via cfe-commits


@@ -1,87 +0,0 @@
-// REQUIRES: aarch64-registered-target
-
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -verify 
-verify-ignore-unexpected=error,note -emit-llvm -o - %s
-
-#include 
-
-void test_bfloat(svbool_t pg, uint64_t u64, int64_t i64, const bfloat16_t 
*const_bf16_ptr, bfloat16_t *bf16_ptr, svbfloat16_t bf16, svbfloat16x2_t 
bf16x2, svbfloat16x3_t bf16x3, svbfloat16x4_t bf16x4)
-{
-  // expected-error@+1 {{'svcreate2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svcreate2_bf16(bf16, bf16);
-  // expected-error@+1 {{'svcreate3_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svcreate3_bf16(bf16, bf16, bf16);
-  // expected-error@+1 {{'svcreate4_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svcreate4_bf16(bf16, bf16, bf16, bf16);
-  // expected-error@+1 {{'svget2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svget2_bf16(bf16x2, 1);
-  // expected-error@+1 {{'svget3_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svget3_bf16(bf16x3, 1);
-  // expected-error@+1 {{'svget4_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svget4_bf16(bf16x4, 1);
-  // expected-error@+1 {{'svld1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svld1_bf16(pg, const_bf16_ptr);
-  // expected-error@+1 {{'svld1_vnum_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svld1_vnum_bf16(pg, const_bf16_ptr, i64);
-  // expected-error@+1 {{'svld1rq_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svld1rq_bf16(pg, const_bf16_ptr);
-  // expected-error@+1 {{'svldff1_bf16' needs target feature sve,bf16}}
-  svldff1_bf16(pg, const_bf16_ptr);
-  // expected-error@+1 {{'svldff1_vnum_bf16' needs target feature sve,bf16}}
-  svldff1_vnum_bf16(pg, const_bf16_ptr, i64);
-  // expected-error@+1 {{'svldnf1_bf16' needs target feature sve,bf16}}
-  svldnf1_bf16(pg, const_bf16_ptr);
-  // expected-error@+1 {{'svldnf1_vnum_bf16' needs target feature sve,bf16}}
-  svldnf1_vnum_bf16(pg, const_bf16_ptr, i64);
-  // expected-error@+1 {{'svldnt1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svldnt1_bf16(pg, const_bf16_ptr);
-  // expected-error@+1 {{'svldnt1_vnum_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svldnt1_vnum_bf16(pg, const_bf16_ptr, i64);
-  // expected-error@+1 {{'svrev_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svrev_bf16(bf16);
-  // expected-error@+1 {{'svset2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svset2_bf16(bf16x2, 1, bf16);
-  // expected-error@+1 {{'svset3_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svset3_bf16(bf16x3, 1, bf16);
-  // expected-error@+1 {{'svset4_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svset4_bf16(bf16x4, 1, bf16);
-  // expected-error@+1 {{'svst1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svst1_bf16(pg, bf16_ptr, bf16);
-  // expected-error@+1 {{'svst1_vnum_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svst1_vnum_bf16(pg, bf16_ptr, i64, bf16);
-  // expected-error@+1 {{'svstnt1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svstnt1_bf16(pg, bf16_ptr, bf16);
-  // expected-error@+1 {{'svstnt1_vnum_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svstnt1_vnum_bf16(pg, bf16_ptr, i64, bf16);
-  // expected-error@+1 {{'svtrn1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svtrn1_bf16(bf16, bf16);
-  // expected-error@+1 {{'svtrn1q_bf16' needs target feature sve,bf16}}
-  svtrn1q_bf16(bf16, bf16);
-  // expected-error@+1 {{'svtrn2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svtrn2_bf16(bf16, bf16);
-  // expected-error@+1 {{'svtrn2q_bf16' needs target feature sve,bf16}}
-  svtrn2q_bf16(bf16, bf16);
-  // expected-error@+1 {{'svundef_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svundef_bf16();
-  // expected-error@+1 {{'svundef2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svundef2_bf16();
-  // expected-error@+1 {{'svundef3_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svundef3_bf16();
-  // expected-error@+1 {{'svundef4_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svundef4_bf16();
-  // expected-error@+1 {{'svuzp1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svuzp1_bf16(bf16, bf16);
-  // expected-error@+1 {{'svuzp1q_bf16' needs target feature sve,bf16}}
-  svuzp1q_bf16(bf16, bf16);
-  // expected-error@+1 {{'svuzp2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svuzp2_bf16(bf16, bf16);
-  // expected-error@+1 {{'svuzp2q_bf16' needs target feature sve,bf16}}
-  svuzp2q_bf16(bf16, bf16);
-  // expected-error@+1 {{'svzip1_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svzip1_bf16(bf16, bf16);
-  // expected-error@+1 {{'svzip1q_bf16' needs target feature sve,bf16}}
-  svzip1q_bf16(bf16, bf16);
-  // expected-error@+1 {{'svzip2_bf16' needs target feature 
(sve,bf16)|(sme,bf16)}}
-  svzip2_bf16(bf16, bf16);
-  // expected-error@+1 {{'svzip2q_bf16' needs target feature sve,bf16}}
-  svzip2q_bf16(bf16, bf16);
-}

paulwal

[clang] [libcxx] [Clang] Diagnose forming references to nullptr (PR #143667)

2025-07-10 Thread Corentin Jabot via cfe-commits


@@ -59,7 +59,7 @@ constexpr bool test() {
 
   {
 //  bidi
-int buffer[2] = {1, 2};
+int buffer[3] = {1, 2, 3};

cor3ntin wrote:

It was doing an out-of-bounds read, which was not previously diagnosed 

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


[clang] [libcxx] [Clang] Diagnose forming references to nullptr (PR #143667)

2025-07-10 Thread Corentin Jabot via cfe-commits


@@ -265,7 +265,7 @@ namespace const_modify {
 
 namespace null {
   constexpr int test(int *p) {
-return *p = 123; // expected-note {{assignment to dereferenced null 
pointer}}
+return *p = 123; // expected-note {{read of dereferenced null pointer}}

cor3ntin wrote:

I think we can either
  - say something like "access to dereferenced null pointer"
  - introduce a different diagnostic for this case, so we can just say 
"dereferencing null pointer"

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


[clang] [clang][bytecode][NFC] Move Pointer::StorageKind above the union (PR #147942)

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

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

This is easier to read in debuggers and more common.

>From c2f5d0eb65d0f6b291ccfa41603f9800fda6a756 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 10 Jul 2025 13:52:10 +0200
Subject: [PATCH] [clang][bytecode][NFC] Move Pointer::StorageKind above the
 union

This is easier to read in debuggers and more common.
---
 clang/lib/AST/ByteCode/Pointer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index d525f84fd6605..e6a64e6658f06 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -809,13 +809,13 @@ class Pointer {
   /// Next link in the pointer chain.
   Pointer *Next = nullptr;
 
+  Storage StorageKind = Storage::Int;
   union {
 BlockPointer BS;
 IntPointer Int;
 FunctionPointer Fn;
 TypeidPointer Typeid;
   } PointeeStorage;
-  Storage StorageKind = Storage::Int;
 };
 
 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Pointer &P) {

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


[clang] [clang][bytecode][NFC] Move Pointer::StorageKind above the union (PR #147942)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

This is easier to read in debuggers and more common.

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


1 Files Affected:

- (modified) clang/lib/AST/ByteCode/Pointer.h (+1-1) 


``diff
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index d525f84fd6605..e6a64e6658f06 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -809,13 +809,13 @@ class Pointer {
   /// Next link in the pointer chain.
   Pointer *Next = nullptr;
 
+  Storage StorageKind = Storage::Int;
   union {
 BlockPointer BS;
 IntPointer Int;
 FunctionPointer Fn;
 TypeidPointer Typeid;
   } PointeeStorage;
-  Storage StorageKind = Storage::Int;
 };
 
 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Pointer &P) {

``




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


[clang] [Clang][AArch64] Relax SVE bf16 requirement for opaque builtins. (PR #147795)

2025-07-10 Thread Paul Walker via cfe-commits


@@ -1,12 +1,12 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s 
| opt -S -passes=mem2reg,tailcallelim | FileCheck %s
-// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x 
c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s 
-check-prefix=CPP-CHECK
-// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple 
aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror 
-Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
-// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple 
aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror 
-Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | 
FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S 
-passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S 
-passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple 
aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - 
%s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -triple 
aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - 
-x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s 
-check-prefix=CPP-CHECK
 
-// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
-// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sme -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sve -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature 
+sme -S -disable-O0-optnone -Werror -Wall -o /dev/null %s

paulwalker-arm wrote:

That's the plan.  A bit like the redundant structs I figure this was best done 
as a separate NFC PR? There's quite a few of them and the tests are pretty slow 
so it should speed up lit testing as well.

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


[clang] [clang] Use SmallString in CommentBriefParser to reduce heap allocs (PR #147853)

2025-07-10 Thread Bogdan Vetrenko via cfe-commits

b0gdnv wrote:

Thanks for your review. Yes, I ran micro-benchmarks to check performance 
implications.

### Benchmark results (mean)

| Benchmark | Metric   | New| Baseline   | Δ (%)   |
|--|--|||-|
| BM_Parse_Tiny | CPU Time | 494.7 ns   | 504.8 ns   | +2.0% (better) |
|  | Throughput   | 196.1 MB/s | 192.2 MB/s | -2.0% (better) |
| BM_Parse_Overflow | CPU Time | 650.5 ns   | 688.0 ns   | -5.5% (better) |
|  | Throughput   | 213.8 MB/s | 202.0 MB/s | +5.8% (better) |
| BM_Parse_1K   | CPU Time | 2194.5 ns  | 2289.0 ns  | -4.1% (better) |
|  | Throughput   | 470.3 MB/s | 450.9 MB/s | +4.3% (better) |
| BM_Parse_4K   | CPU Time | 7146.3 ns  | 7321.4 ns  | -2.4% (better) |
|  | Throughput   | 573.8 MB/s | 560.0 MB/s | +2.5% (better) |
| BM_Parse_8K   | CPU Time | 13592.7 ns | 13994.3 ns | -2.9% (better) |
|  | Throughput   | 605.5 MB/s | 588.2 MB/s | +2.9% (better) |
| BM_Parse_32K  | CPU Time | 53524.0 ns | 53229.9 ns | -0.6% (worse) |
|  | Throughput   | 612.6 MB/s | 615.7 MB/s | +0.5% (worse) |

You can find the benchmark source code here (not intended for commit):  
https://gist.github.com/b0gdnv/fb6b33eb2129747cb0030abdfba3b2b3

Raw JSON results:  
[brief_new.json](https://github.com/user-attachments/files/21163591/brief_new.json)
  
[brief_cur.json](https://github.com/user-attachments/files/21163593/brief_cur.json)

Let me know if you'd prefer this benchmark included somewhere more formal.

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


[clang-tools-extra] Add clang tidy check performance constexpr non static in scope (PR #147809)

2025-07-10 Thread Carlos Galvez via cfe-commits

carlosgalvezp wrote:

@PiotrZSL Here's some examples discussing the performance implications

https://youtu.be/IDQ0ng8RIqs?si=fDUuTFK9GiGCB-Po

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


[clang-tools-extra] Add clang tidy check performance constexpr non static in scope (PR #147809)

2025-07-10 Thread Carlos Galvez via cfe-commits

carlosgalvezp wrote:

> bellow specific size

Like I mentioned in the other patch I think this is brittle and leads to poor 
UX, because you add 1 field to a struct in a header file and suddenly you have 
to change all clients. 

I'd be preferred to have the user specify which types to warn on. Maybe arrays 
could have an option of it's own.

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


[clang] [llvm] [OpenMP][clang] 6.0: parsing/sema for message/severity for parallel (PR #146093)

2025-07-10 Thread Alexey Bataev via cfe-commits

https://github.com/alexey-bataev approved this pull request.


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


[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits

erichkeane wrote:

> > > avior due to the silent stripping. Given that an atomic type is not the 
> > > same as its underlying type (in terms of ABI or semantics) I think we 
> > > should diagnose the behavior with at least a warning. I could even be 
> > > convinced it should be a warning which defaults to an error because this 
> > > is just weird.
> > 
> > 
> > Yeah, I 100% agree with that. Warn-as-error is reasonable here IMO (as are 
> > ANY qualifiers?, but more so for atomic)
> 
> Would you like me to diagnose any qualifier? And turn it into 
> warning-as-error?

I thought about this more... I think a warning for 'qualifier ignored' for 
'normal' qualifier is sensible, but not as error.

I can make a pretty strong case (as you did above) for the _Atomic who-what-zit 
to be a default warning-as- error.

As far as what I want... feel free to land as-is, or if you feel motivated, do 
the rest.

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -76,6 +80,43 @@ class VoidType : public Type {
   static bool classof(const Type *T) { return T->getKind() == TypeKind::Void; }
 };
 
+class ComplexType : public Type {
+public:
+  ComplexType(const Type *ElementType, uint64_t SizeInBits, Align Alignment)
+  : Type(TypeKind::Complex, TypeSize::getFixed(SizeInBits), Alignment),
+ElementType(ElementType) {}
+
+  const Type *getElementType() const { return ElementType; }
+
+  static bool classof(const Type *T) {
+return T->getKind() == TypeKind::Complex;
+  }
+
+private:
+  const Type *ElementType;
+};
+
+class MemberPointerType : public Type {
+public:
+  MemberPointerType(bool IsFunctionPointer, bool Has64BitPointers,

nikic wrote:

Actually, it looks like you also have this property on the x86 ABIInfo already 
:)

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -76,6 +80,43 @@ class VoidType : public Type {
   static bool classof(const Type *T) { return T->getKind() == TypeKind::Void; }
 };
 
+class ComplexType : public Type {
+public:
+  ComplexType(const Type *ElementType, uint64_t SizeInBits, Align Alignment)
+  : Type(TypeKind::Complex, TypeSize::getFixed(SizeInBits), Alignment),
+ElementType(ElementType) {}
+
+  const Type *getElementType() const { return ElementType; }
+
+  static bool classof(const Type *T) {
+return T->getKind() == TypeKind::Complex;
+  }
+
+private:
+  const Type *ElementType;
+};
+
+class MemberPointerType : public Type {
+public:
+  MemberPointerType(bool IsFunctionPointer, bool Has64BitPointers,

nikic wrote:

I feel like Has64BitPointers doesn't belong on MemberPointerType, it's a 
property of the target / ABIInfo.

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -229,6 +231,7 @@ QualTypeMapper::convertCXXRecordType(const CXXRecordDecl 
*RD) {
 8;
 
 Fields.emplace_back(BaseType, BaseOffset);
+BaseClasses.emplace_back(BaseType, BaseOffset);

nikic wrote:

Looks like this adds base types *both* to BaseClasses/VirtualBaseClasses *and* 
Fields. Is that really what we want?

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo

nikic wrote:

It looks like the implementation actually already queries ABICompatInfo instead 
of these methods. (Though the clang implementation is a combination of the 
clang ABI version *and* these checks.)

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);

nikic wrote:

```suggestion
ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
/*IsNamedArg=*/true);
```

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [Multilib] Extend the Multilib system to support an IncludepPath field. (PR #146651)

2025-07-10 Thread Simi Pallipurath via cfe-commits

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


[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();
+}
+return false;
+  }
+
+  void computeInfo(ABIFunctionInfo &FI) const override;
+
+  bool has64BitPointers() const { return Has64BitPointers; }
+};
+
+void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo,
+  Class &Hi) const {
+  // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
+  //
+  // (a) If one of the classes is Memory, the whole argument is passed in
+  // memory.
+  //
+  // (b) If X87UP is not preceded by X87, the whole argument is passed in
+  // memory.
+  //
+  // (c) If the size of the aggregate exceeds two eightbytes and the first
+  // eightbyte isn't SSE or any other eightbyte isn't SSEUP, t

[clang] [llvm] [WIP] ABI Lowering Library (PR #140112)

2025-07-10 Thread Nikita Popov via cfe-commits


@@ -0,0 +1,523 @@
+//===- X86.cpp 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "llvm/ABI/ABIFunctionInfo.h"
+#include "llvm/ABI/ABIInfo.h"
+#include "llvm/ABI/TargetCodegenInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include 
+
+namespace llvm {
+namespace abi {
+
+enum class AVXABILevel { None, AVX, AVX512 };
+
+static unsigned getNativeVectorSizeForAVXABI(AVXABILevel AVXLevel) {
+  switch (AVXLevel) {
+  case AVXABILevel::AVX512:
+return 512;
+  case AVXABILevel::AVX:
+return 256;
+  case AVXABILevel::None:
+return 128;
+  }
+  llvm_unreachable("Unknown AVXLevel");
+}
+
+class X86_64ABIInfo : public ABIInfo {
+public:
+  enum Class {
+Integer = 0,
+SSE,
+SSEUp,
+X87,
+X87UP,
+Complex_X87,
+NoClass,
+Memory
+  };
+
+private:
+  AVXABILevel AVXLevel;
+  bool Has64BitPointers;
+  const llvm::Triple &TargetTriple;
+
+  static Class merge(Class Accum, Class Field);
+
+  void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const;
+
+  void classify(const Type *T, uint64_t OffsetBase, Class &Lo, Class &Hi,
+bool IsNamedArg, bool IsRegCall = false) const;
+
+  llvm::Type *getByteVectorType(const Type *Ty) const;
+  llvm::Type *getSseTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  llvm::Type *getIntegerTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
+ const Type *SourceTy,
+ unsigned SourceOffset) const;
+
+  ABIArgInfo getIndirectReturnResult(const Type *Ty) const;
+
+  ABIArgInfo getIndirectResult(const Type *Ty, unsigned FreeIntRegs) const;
+
+  ABIArgInfo classifyReturnType(const Type *RetTy) const override;
+
+  ABIArgInfo classifyArgumentType(const Type *Ty, unsigned FreeIntRegs,
+  unsigned &NeededInt, unsigned &NeededSse,
+  bool IsNamedArg,
+  bool IsRegCall = false) const;
+
+  ABIArgInfo classifyRegCallStructType(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  ABIArgInfo classifyRegCallStructTypeImpl(const Type *Ty, unsigned &NeededInt,
+   unsigned &NeededSSE,
+   unsigned &MaxVectorWidth) const;
+
+  bool isIllegalVectorType(const Type *Ty) const;
+
+  // The Functionality of these methods will be moved to
+  // llvm::abi::ABICompatInfo
+
+  bool honorsRevision98() const { return !TargetTriple.isOSDarwin(); }
+
+  bool classifyIntegerMMXAsSSE() const {
+if (TargetTriple.isOSDarwin() || TargetTriple.isPS() ||
+TargetTriple.isOSFreeBSD())
+  return false;
+return true;
+  }
+
+  bool passInt128VectorsInMem() const {
+// TODO: accept ABICompat info from the frontends
+return TargetTriple.isOSLinux() || TargetTriple.isOSNetBSD();
+  }
+
+  bool returnCXXRecordGreaterThan128InMem() const {
+// TODO: accept ABICompat info from the frontends
+return true;
+  }
+
+public:
+  X86_64ABIInfo(const Triple &Triple, AVXABILevel AVXABILevel,
+bool Has64BitPtrs, const ABICompatInfo &Compat)
+  : ABIInfo(Compat), AVXLevel(AVXABILevel), Has64BitPointers(Has64BitPtrs),
+TargetTriple(Triple) {}
+
+  bool isPassedUsingAVXType(const Type *Type) const {
+unsigned NeededInt, NeededSse;
+ABIArgInfo Info = classifyArgumentType(Type, 0, NeededInt, NeededSse, 
true);
+
+if (Info.isDirect()) {
+  auto *Ty = Info.getCoerceToType();
+  if (auto *VectorTy = dyn_cast_or_null(Ty))
+return VectorTy->getSizeInBits().getFixedValue();

nikic wrote:

```suggestion
return VectorTy->getSizeInBits().getFixedValue() > 128;
```

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


[clang] [LifetimeSafety] Introduce intra-procedural analysis in Clang (PR #142313)

2025-07-10 Thread Gábor Horváth via cfe-commits


@@ -0,0 +1,510 @@
+//===- LifetimeSafety.cpp - C++ Lifetime Safety Analysis -*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+#include "clang/Analysis/Analyses/LifetimeSafety.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/TimeProfiler.h"
+#include 
+
+namespace clang {
+namespace {
+
+/// Represents the storage location being borrowed, e.g., a specific stack
+/// variable.
+/// TODO: Model access paths of other types, e.g., s.field, heap and globals.
+struct AccessPath {
+  const clang::ValueDecl *D;
+
+  AccessPath(const clang::ValueDecl *D) : D(D) {}
+};
+
+/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
+/// Used for giving ID to loans and origins.
+template  struct ID {
+  uint32_t Value = 0;
+
+  bool operator==(const ID &Other) const { return Value == Other.Value; }
+  bool operator!=(const ID &Other) const { return !(*this == Other); }
+  bool operator<(const ID &Other) const { return Value < Other.Value; }
+  ID operator++(int) {
+ID Tmp = *this;
+++Value;
+return Tmp;
+  }
+  void Profile(llvm::FoldingSetNodeID &IDBuilder) const {
+IDBuilder.AddInteger(Value);
+  }
+};
+
+template 
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ID ID) {
+  return OS << ID.Value;
+}
+
+using LoanID = ID;
+using OriginID = ID;
+
+/// Information about a single borrow, or "Loan". A loan is created when a
+/// reference or pointer is created.
+struct Loan {
+  /// TODO: Represent opaque loans.
+  /// TODO: Represent nullptr: loans to no path. Accessing it UB! Currently it
+  /// is represented as empty LoanSet
+  LoanID ID;
+  AccessPath Path;
+  SourceLocation IssueLoc;
+
+  Loan(LoanID id, AccessPath path, SourceLocation loc)
+  : ID(id), Path(path), IssueLoc(loc) {}
+};
+
+/// An Origin is a symbolic identifier that represents the set of possible
+/// loans a pointer-like object could hold at any given time.
+/// TODO: Enhance the origin model to handle complex types, pointer
+/// indirection and reborrowing. The plan is to move from a single origin per
+/// variable/expression to a "list of origins" governed by the Type.
+/// For example, the type 'int**' would have two origins.
+/// See discussion:
+/// 
https://github.com/llvm/llvm-project/pull/142313/commits/0cd187b01e61b200d92ca0b640789c1586075142#r2137644238
+struct Origin {
+  OriginID ID;
+  /// A pointer to the AST node that this origin represents. This union
+  /// distinguishes between origins from lvalues (named variables or parameter)

Xazax-hun wrote:

I think this might not be entirely correct. The value category might be 
independent of whether we have variables or expressions. Consider:

```
int* &f();

f() = nullptr; 
```

Here, the expression `f()` is an lvalue but we do not have a declaration. 

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


[clang] 54ec521 - [CIR] Upstream __builtin_cimag for ComplexType (#147808)

2025-07-10 Thread via cfe-commits

Author: Amr Hesham
Date: 2025-07-10T18:19:24+02:00
New Revision: 54ec5217a07ed7389c5ee3c744cc1aa2534c

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

LOG: [CIR] Upstream __builtin_cimag for ComplexType (#147808)

Upstream __builtin_cimag support for ComplexType

https://github.com/llvm/llvm-project/issues/141365

Added: 


Modified: 
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
clang/test/CIR/CodeGen/complex-builtins.cpp

Removed: 




diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 1e56ea4d9bd8e..c65873209c31d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -128,6 +128,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 return RValue::get(real);
   }
 
+  case Builtin::BI__builtin_cimag:
+  case Builtin::BI__builtin_cimagf:
+  case Builtin::BI__builtin_cimagl:
+  case Builtin::BIcimag:
+  case Builtin::BIcimagf:
+  case Builtin::BIcimagl: {
+mlir::Value complex = emitComplexExpr(e->getArg(0));
+mlir::Value imag = builder.createComplexImag(loc, complex);
+return RValue::get(imag);
+  }
+
   case Builtin::BI__builtin_clrsb:
   case Builtin::BI__builtin_clrsbl:
   case Builtin::BI__builtin_clrsbll:

diff  --git a/clang/test/CIR/CodeGen/complex-builtins.cpp 
b/clang/test/CIR/CodeGen/complex-builtins.cpp
index fdda5eb707fb7..f0d12d0ef6663 100644
--- a/clang/test/CIR/CodeGen/complex-builtins.cpp
+++ b/clang/test/CIR/CodeGen/complex-builtins.cpp
@@ -58,3 +58,28 @@ void foo2() {
 // OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[COMPLEX]], i32 0, i32 1
 // OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
 // OGCG: store double %[[A_REAL]], ptr %[[INIT]], align 8
+
+void foo3() {
+  double _Complex a;
+  double imag = __builtin_cimag(a);
+}
+
+// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex, 
!cir.ptr>, ["a"]
+// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr, ["imag", 
init]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : 
!cir.ptr>, !cir.complex
+// CIR: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex 
-> !cir.double
+// CIR: cir.store{{.*}} %[[IMAG]], %[[INIT]] : !cir.double, 
!cir.ptr
+
+// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
+// LLVM: %[[TMP:.*]] = load { double, double }, ptr %[[COMPLEX]], align 8
+// LLVM: %[[IMAG:.*]] = extractvalue { double, double } %[[TMP]], 1
+// LLVM: store double %[[IMAG]], ptr %[[INIT]], align 8
+
+// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
+// OGCG: %[[INIT:.*]] = alloca double, align 8
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[COMPLEX]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[COMPLEX]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
+// OGCG: store double %[[A_IMAG]], ptr %[[INIT]], align 8



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


[clang-tools-extra] [clang-tidy][NFC] add '.clang-tidy' config for clang-tidy project (PR #147793)

2025-07-10 Thread Baranov Victor via cfe-commits

vbvictor wrote:

Based on [carlosgalvezp](https://github.com/carlosgalvezp)'s comment in 
https://github.com/llvm/llvm-project/pull/147902#pullrequestreview-3005674950 
changed `Checks: []` to `Checks: >` to comply with older version of 
`clang-tidy`.

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


[clang-tools-extra] [clang-tidy][readability-named-parameter] Add an option to print names without comment (PR #147953)

2025-07-10 Thread Dmitry Polukhin via cfe-commits

https://github.com/dmpolukhin updated 
https://github.com/llvm/llvm-project/pull/147953

>From 0f6d49539df0269daed67af2c7c054f3501fcc0b Mon Sep 17 00:00:00 2001
From: Dmitry Polukhin 
Date: Thu, 10 Jul 2025 05:26:11 -0700
Subject: [PATCH 1/3] [clang-tidy][readability-named-parameter] Add an option
 to print names without comment

Add InsertPlainNamesInForwardDecls option to readability-named-parameter check
to insert parameter names without comments for forward declarations only.

When enabled, forward declarations get plain parameter names (e.g., `int param`)
while function definitions continue to use commented names (e.g., `int 
/*param*/`).
Named parameters in forward decls don't cause compiler warnings and some 
developers
prefer to have names without comments but in sync between declarations
and the definition.

Default behavior remains unchanged (InsertPlainNamesInForwardDecls=false).

Example with InsertPlainNamesInForwardDecls=true:
```cpp
// Forward declaration - gets plain name
void func(int param);
void func(int param) { ... = param; }
```
---
 .../readability/NamedParameterCheck.cpp   | 34 +++---
 .../readability/NamedParameterCheck.h |  7 ++--
 clang-tools-extra/docs/ReleaseNotes.rst   |  7 +++-
 .../checks/readability/named-parameter.rst|  9 +
 .../checkers/readability/named-parameter.cpp  | 35 +++
 5 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp
index ea6597dbdd617..b2bc3d0a4d1ec 100644
--- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp
@@ -15,6 +15,17 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::readability {
 
+NamedParameterCheck::NamedParameterCheck(StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  InsertPlainNamesInForwardDecls(
+  Options.get("InsertPlainNamesInForwardDecls", false)) {}
+
+void NamedParameterCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "InsertPlainNamesInForwardDecls",
+InsertPlainNamesInForwardDecls);
+}
+
 void NamedParameterCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
   Finder->addMatcher(functionDecl().bind("decl"), this);
 }
@@ -84,7 +95,8 @@ void NamedParameterCheck::check(const 
MatchFinder::MatchResult &Result) {
 
 for (auto P : UnnamedParams) {
   // Fallback to an unused marker.
-  StringRef NewName = "unused";
+  constexpr StringRef FallbackName = "unused";
+  StringRef NewName = FallbackName;
 
   // If the method is overridden, try to copy the name from the base method
   // into the overrider.
@@ -105,12 +117,26 @@ void NamedParameterCheck::check(const 
MatchFinder::MatchResult &Result) {
   NewName = Name;
   }
 
-  // Now insert the comment. Note that getLocation() points to the place
+  // Now insert the fix. Note that getLocation() points to the place
   // where the name would be, this allows us to also get complex cases like
   // function pointers right.
   const ParmVarDecl *Parm = P.first->getParamDecl(P.second);
-  D << FixItHint::CreateInsertion(Parm->getLocation(),
-  " /*" + NewName.str() + "*/");
+
+  // The fix depends on the InsertPlainNamesInForwardDecls option,
+  // whether this is a forward declaration and whether the parameter has
+  // a real name.
+  bool IsForwardDeclaration = (!Definition || Function != Definition);
+  if (InsertPlainNamesInForwardDecls && IsForwardDeclaration &&
+  NewName != FallbackName) {
+// For forward declarations with InsertPlainNamesInForwardDecls 
enabled,
+// insert the parameter name without comments
+D << FixItHint::CreateInsertion(Parm->getLocation(),
+" " + NewName.str());
+  } else {
+// Default behavior: insert the parameter name as a comment
+D << FixItHint::CreateInsertion(Parm->getLocation(),
+" /*" + NewName.str() + "*/");
+  }
 }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h 
b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h
index 812d90ef7319c..f14a74d75eb49 100644
--- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.h
@@ -26,13 +26,16 @@ namespace clang::tidy::readability {
 /// Corresponding cpplint.py check name: 'readability/function'.
 class NamedParameterCheck : public ClangTidyCheck {
 public:
-  NamedParameterCheck(StringRef Name, ClangTidyContext *Context)
-  : ClangTidyCheck(Name, Context) {}
+  NamedParameterCheck(StringRef Na

[clang-tools-extra] [clang-tidy][NFC] add '.clang-tidy' config for clang-tidy project (PR #147793)

2025-07-10 Thread Baranov Victor via cfe-commits

https://github.com/vbvictor updated 
https://github.com/llvm/llvm-project/pull/147793

>From c4466d677619e6eb8ca65ed943bfb103207527c9 Mon Sep 17 00:00:00 2001
From: Victor Baranov 
Date: Wed, 9 Jul 2025 21:00:30 +0300
Subject: [PATCH 1/4] [clang-tidy][NFC] add '.clang-tidy' config for clang-tidy
 project

---
 clang-tools-extra/clang-tidy/.clang-tidy  | 11 +++
 .../bugprone/CrtpConstructorAccessibilityCheck.cpp|  7 ++-
 .../clang-tidy/bugprone/SizeofExpressionCheck.cpp | 10 +-
 3 files changed, 18 insertions(+), 10 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/.clang-tidy

diff --git a/clang-tools-extra/clang-tidy/.clang-tidy 
b/clang-tools-extra/clang-tidy/.clang-tidy
new file mode 100644
index 0..65af940909efe
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/.clang-tidy
@@ -0,0 +1,11 @@
+InheritParentConfig: true
+Checks: [
+  bugprone-*,
+  -bugprone-assignment-in-if-condition,
+  -bugprone-branch-clone,
+  -bugprone-easily-swappable-parameters,
+  -bugprone-narrowing-conversions,
+  -bugprone-suspicious-stringview-data-usage,
+  -bugprone-unchecked-optional-access,
+  -bugprone-unused-return-value
+]
diff --git 
a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..6565fa3f7c85b 100644
--- 
a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ 
b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -129,13 +129,10 @@ void CrtpConstructorAccessibilityCheck::check(
 << HintFriend;
   }
 
-  auto WithFriendHintIfNeeded =
-  [&](const DiagnosticBuilder &Diag,
-  bool NeedsFriend) -> const DiagnosticBuilder & {
+  auto WithFriendHintIfNeeded = [&](const DiagnosticBuilder &Diag,
+bool NeedsFriend) {
 if (NeedsFriend)
   Diag << HintFriend;
-
-return Diag;
   };
 
   if (!CRTPDeclaration->hasUserDeclaredConstructor()) {
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..88e048e65d4e8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -370,16 +370,16 @@ void SizeofExpressionCheck::check(const 
MatchFinder::MatchResult &Result) {
 << E->getSourceRange();
   } else if (Result.Nodes.getNodeAs("loop-expr")) {
 auto *SizeofArgTy = Result.Nodes.getNodeAs("sizeof-arg-type");
-if (const auto member = dyn_cast(SizeofArgTy))
-  SizeofArgTy = member->getPointeeType().getTypePtr();
+if (const auto *Member = dyn_cast(SizeofArgTy))
+  SizeofArgTy = Member->getPointeeType().getTypePtr();
 
 const auto *SzOfExpr = Result.Nodes.getNodeAs("sizeof-expr");
 
-if (const auto type = dyn_cast(SizeofArgTy)) {
+if (const auto *Type = dyn_cast(SizeofArgTy)) {
   // check if the array element size is larger than one. If true,
   // the size of the array is higher than the number of elements
-  CharUnits sSize = Ctx.getTypeSizeInChars(type->getElementType());
-  if (!sSize.isOne()) {
+  CharUnits SSize = Ctx.getTypeSizeInChars(Type->getElementType());
+  if (!SSize.isOne()) {
 diag(SzOfExpr->getBeginLoc(),
  "suspicious usage of 'sizeof' in the loop")
 << SzOfExpr->getSourceRange();

>From 4b061f9ad53bb7ca3ad3580743876f2457bbb713 Mon Sep 17 00:00:00 2001
From: Victor Baranov 
Date: Wed, 9 Jul 2025 22:42:47 +0300
Subject: [PATCH 2/4] [clang-tidy][NFC] enabled 'modernize', 'readability',
 'performance' categories in .clang-tidy

---
 clang-tools-extra/clang-tidy/.clang-tidy  | 33 ++-
 .../clang-tidy/boost/UseRangesCheck.h |  2 +-
 .../bugprone/ArgumentCommentCheck.cpp |  2 +-
 .../clang-tidy/bugprone/InfiniteLoopCheck.cpp |  6 ++--
 .../MacroRepeatedSideEffectsCheck.cpp |  3 +-
 .../bugprone/UnsafeFunctionsCheck.cpp |  2 +-
 .../MissingStdForwardCheck.cpp|  2 +-
 .../misc/RedundantExpressionCheck.cpp | 10 +++---
 .../modernize/UseConstraintsCheck.cpp |  4 +--
 .../clang-tidy/modernize/UseRangesCheck.h |  2 +-
 .../modernize/UseScopedLockCheck.cpp  |  7 ++--
 .../modernize/UseStdFormatCheck.cpp   |  2 +-
 .../objc/PropertyDeclarationCheck.cpp |  2 +-
 .../ConvertMemberFunctionsToStatic.cpp|  2 +-
 .../MakeMemberFunctionConstCheck.cpp  |  2 +-
 .../SuspiciousCallArgumentCheck.cpp   |  4 +--
 .../utils/DesignatedInitializers.cpp  |  2 +-
 .../clang-tidy/utils/HeaderGuard.cpp  |  4 ++-
 .../utils/RenamerClangTidyCheck.cpp   |  4 +--
 .../clang-tidy/utils/UseRangesCheck.cpp   |  4 +--
 .../clang-tidy/utils/UseRangesCheck.h |  2 +-
 21 files changed, 66 insertions(

[clang] [CIR] Upstream __builtin_cimag for ComplexType (PR #147808)

2025-07-10 Thread Amr Hesham via cfe-commits

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


[clang] [clang][deps] Stop lexing if hit a failure while loading a PCH/module in a submodule. (PR #146976)

2025-07-10 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

> Seems like this should have a release note?

What is the bar for a change to be release noted? This change is pretty much 
"make clang-scan-deps less likely to crash" and personally I don't think it 
deserves a release note.

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


[clang] [CIR] Implement AddOp for ComplexType (PR #147578)

2025-07-10 Thread Amr Hesham via cfe-commits

https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/147578

>From d91ac481a20e71275b441a9b9a7712aa9dfd270b Mon Sep 17 00:00:00 2001
From: AmrDeveloper 
Date: Tue, 8 Jul 2025 20:00:08 +0200
Subject: [PATCH 1/4] [CIR] Implement AddOp for ComplexType

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  26 +
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp   | 106 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  49 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   |  10 ++
 clang/test/CIR/CodeGen/complex-arithmetic.cpp |  92 +++
 6 files changed, 285 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/complex-arithmetic.cpp

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..802cda0a1a2e3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2521,6 +2521,32 @@ def ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
   let hasFolder = 1;
 }
 
+//===--===//
+// ComplexAddOp
+//===--===//
+
+def ComplexAddOp : CIR_Op<"complex.add", [Pure, SameOperandsAndResultType]> {
+  let summary = "Complex addition";
+  let description = [{
+The `cir.complex.add` operation takes two complex numbers and returns
+their sum.
+
+Example:
+
+```mlir
+%2 = cir.complex.add %0, %1 -> !cir.complex
+```
+  }];
+
+  let arguments = (ins CIR_ComplexType:$lhs, CIR_ComplexType:$rhs);
+
+  let results = (outs CIR_ComplexType:$result);
+
+  let assemblyFormat = [{
+$lhs `,` $rhs `->` qualified(type($result)) attr-dict
+  }];
+}
+
 
//===--===//
 // Bit Manipulation Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 84fad959ebf49..6001b0a51121d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -57,6 +57,55 @@ class ComplexExprEmitter : public 
StmtVisitor {
   mlir::Value
   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
   mlir::Value VisitUnaryDeref(const Expr *e);
+
+  struct BinOpInfo {
+mlir::Location loc;
+mlir::Value lhs{};
+mlir::Value rhs{};
+QualType ty{}; // Computation Type.
+FPOptions fpFeatures{};
+  };
+
+  BinOpInfo emitBinOps(const BinaryOperator *e,
+   QualType promotionTy = QualType());
+
+  mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
+
+  mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
+
+  mlir::Value emitBinAdd(const BinOpInfo &op);
+
+  QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
+if (auto *complexTy = ty->getAs()) {
+  QualType elementTy = complexTy->getElementType();
+  if (isDivOpCode && elementTy->isFloatingType() &&
+  cgf.getLangOpts().getComplexRange() ==
+  LangOptions::ComplexRangeKind::CX_Promoted) {
+cgf.cgm.errorNYI("HigherPrecisionTypeForComplexArithmetic");
+return QualType();
+  }
+
+  if (elementTy.UseExcessPrecision(cgf.getContext()))
+return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
+}
+
+if (ty.UseExcessPrecision(cgf.getContext()))
+  return cgf.getContext().FloatTy;
+return QualType();
+  }
+
+#define HANDLEBINOP(OP)
\
+  mlir::Value VisitBin##OP(const BinaryOperator *e) {  
\
+QualType promotionTy = getPromotionType(   
\
+e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div);   
\
+mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy));  
\
+if (!promotionTy.isNull()) 
\
+  cgf.cgm.errorNYI("Binop emitUnPromotedValue");   
\
+return result; 
\
+  }
+
+  HANDLEBINOP(Add)
+#undef HANDLEBINOP
 };
 } // namespace
 
@@ -291,6 +340,58 @@ mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr 
*e) {
   return emitLoadOfLValue(e);
 }
 
+mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
+ QualType promotionTy) {
+  e = e->IgnoreParens();
+  if (const auto *bo = dyn_cast(e)) {
+switch (bo->getOpcode()) {
+#define HANDLE_BINOP(OP)   
\
+  case BO_##OP:
\
+return emitBin##OP(emitBinOps(bo, promotionTy));
+  H

[clang] Add necessary linker flags when -static-pie is enabled in BareMetal Toolchain (PR #147589)

2025-07-10 Thread Sam Elliott via cfe-commits


@@ -599,11 +599,18 @@ void baremetal::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   const Driver &D = getToolChain().getDriver();
   const llvm::Triple::ArchType Arch = TC.getArch();
   const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+  const bool IsStaticPIE = getStaticPIE(Args, TC);
 
   if (!D.SysRoot.empty())
 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
   CmdArgs.push_back("-Bstatic");
+  if (IsStaticPIE) {
+CmdArgs.push_back("-pie");
+CmdArgs.push_back("--no-dynamic-linker");

lenary wrote:

I think @petrhosek was asking specifically about the "--no-dynamic-linker" 
flag. 

I think for gnu ld it is necessary as it's possible to mix -static and -shared 
according to the manpage. I presume this ensures that you get an error in that 
case rather than a statically linked shared library. 

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


[clang] [Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (PR #147996)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Corentin Jabot (cor3ntin)


Changes

When an overload is invalid, we try to initialize each conversion sequence for 
the purpose of diagmostics, but we failed to initialize explicit objects, 
leading to a crash

Fixes #147121

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+3-3) 
- (modified) clang/test/SemaCXX/cxx2b-deducing-this.cpp (+57) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ca00a80d10eca..3f1587d8113db 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -930,6 +930,7 @@ Bug Fixes to C++ Support
 - Fix a bug where private access specifier of overloaded function not 
respected. (#GH107629)
 - Correctly handles calling an explicit object member function template 
overload set
   through its address (``(&Foo::bar)()``).
+- Fix a crash when forming an invalid call to an operator with an explicit 
object member. (#GH147121)
 - Correctly handle allocations in the condition of a ``if 
constexpr``.(#GH120197) (#GH134820)
 - Fixed a crash when handling invalid member using-declaration in C++20+ mode. 
(#GH63254)
 - Fixed parsing of lambda expressions that appear after ``*`` or ``&`` in 
contexts where a declaration can appear. (#GH63880)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7af3acacb5ba6..1b54628c5e564 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -13131,7 +13131,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate 
*Cand,
 ParamTypes =
 
Cand->Function->getType()->castAs()->getParamTypes();
 if (isa(Cand->Function) &&
-!isa(Cand->Function) && !Reversed) {
+!isa(Cand->Function) && !Reversed &&
+!Cand->Function->hasCXXExplicitFunctionObjectParameter()) {
   // Conversion 0 is 'this', which doesn't have a corresponding parameter.
   ConvIdx = 1;
   if (CSK == OverloadCandidateSet::CSK_Operator &&
@@ -13149,9 +13150,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate 
*Cand,
 
   // Fill in the rest of the conversions.
   for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0;
-   ConvIdx != ConvCount;
+   ConvIdx != ConvCount && ArgIdx < Args.size();
++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) {
-assert(ArgIdx < Args.size() && "no argument for this arg conversion");
 if (Cand->Conversions[ConvIdx].isInitialized()) {
   // We've already checked this conversion.
 } else if (ParamIdx < ParamTypes.size()) {
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 3a3dc8855d827..6987d0c020457 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -1290,3 +1290,60 @@ void f() {
 
 
 }
+
+namespace GH147121 {
+struct X {};
+struct S1 {
+bool operator==(this auto &&, const X &); // #S1-cand
+};
+struct S2 {
+bool operator==(this X, const auto &&); // #S2-cand
+};
+
+struct S3 {
+S3& operator++(this X); // #S3-inc-cand
+S3& operator++(this int); // #S3-inc-cand
+int operator[](this X); // #S3-sub-cand
+int operator[](this int); // #S3-sub-cand2
+void f(this X); // #S3-f-cand
+void f(this int); // #S3-f-cand2
+};
+
+int main() {
+S1{} == S1{};
+// expected-error@-1 {{invalid operands to binary expression ('S1' and 
'S1')}}
+// expected-note@#S1-cand {{candidate function template not viable}}
+// expected-note@#S1-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S1{} != S1{};
+// expected-error@-1 {{invalid operands to binary expression ('S1' and 
'S1')}}
+// expected-note@#S1-cand {{candidate function template not viable}}
+// expected-note@#S1-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S2{} == S2{};
+// expected-error@-1 {{invalid operands to binary expression ('S2' and 
'S2')}}
+// expected-note@#S2-cand {{candidate function template not viable}}
+// expected-note@#S2-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S2{} != S2{};
+// expected-error@-1 {{invalid operands to binary expression ('S2' and 
'S2')}}
+// expected-note@#S2-cand {{candidate function template not viable}}
+// expected-note@#S2-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+S3 s3;
+++s3;
+// expected-error@-1{{cannot increment value of type 'S3'}}
+s3[];
+// expected-error@-1{{no viable overloaded operator[] for type 'S3'}}
+// expected-note@#S3-sub-cand {{candidate function not viable: no known 
conversion from 'S3' to 'X' for object argument}}
+// expected-note@#S3-sub-cand2 {{candidate function not viable

[clang] [Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (PR #147996)

2025-07-10 Thread Corentin Jabot via cfe-commits

https://github.com/cor3ntin created 
https://github.com/llvm/llvm-project/pull/147996

When an overload is invalid, we try to initialize each conversion sequence for 
the purpose of recovery, but we failed to initialize explicit objects, leading 
to a crash

Fixes #147121

>From 6d3df177b7061cb71bfb2943dabc1c211e2043ff Mon Sep 17 00:00:00 2001
From: Corentin Jabot 
Date: Thu, 10 Jul 2025 18:05:42 +0200
Subject: [PATCH] [Clang] Fix a crash when diagnosing wrong conversion to
 explicit object parameter

When an overload is invalid, we try to initialize each conversion sequence
for the purpose of recovery, but we failed to initialized explicit objects,
leading to a crash

Fixes #147121
---
 clang/docs/ReleaseNotes.rst|  1 +
 clang/lib/Sema/SemaOverload.cpp|  6 +--
 clang/test/SemaCXX/cxx2b-deducing-this.cpp | 57 ++
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ca00a80d10eca..3f1587d8113db 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -930,6 +930,7 @@ Bug Fixes to C++ Support
 - Fix a bug where private access specifier of overloaded function not 
respected. (#GH107629)
 - Correctly handles calling an explicit object member function template 
overload set
   through its address (``(&Foo::bar)()``).
+- Fix a crash when forming an invalid call to an operator with an explicit 
object member. (#GH147121)
 - Correctly handle allocations in the condition of a ``if 
constexpr``.(#GH120197) (#GH134820)
 - Fixed a crash when handling invalid member using-declaration in C++20+ mode. 
(#GH63254)
 - Fixed parsing of lambda expressions that appear after ``*`` or ``&`` in 
contexts where a declaration can appear. (#GH63880)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7af3acacb5ba6..1b54628c5e564 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -13131,7 +13131,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate 
*Cand,
 ParamTypes =
 
Cand->Function->getType()->castAs()->getParamTypes();
 if (isa(Cand->Function) &&
-!isa(Cand->Function) && !Reversed) {
+!isa(Cand->Function) && !Reversed &&
+!Cand->Function->hasCXXExplicitFunctionObjectParameter()) {
   // Conversion 0 is 'this', which doesn't have a corresponding parameter.
   ConvIdx = 1;
   if (CSK == OverloadCandidateSet::CSK_Operator &&
@@ -13149,9 +13150,8 @@ CompleteNonViableCandidate(Sema &S, OverloadCandidate 
*Cand,
 
   // Fill in the rest of the conversions.
   for (unsigned ParamIdx = Reversed ? ParamTypes.size() - 1 : 0;
-   ConvIdx != ConvCount;
+   ConvIdx != ConvCount && ArgIdx < Args.size();
++ConvIdx, ++ArgIdx, ParamIdx += (Reversed ? -1 : 1)) {
-assert(ArgIdx < Args.size() && "no argument for this arg conversion");
 if (Cand->Conversions[ConvIdx].isInitialized()) {
   // We've already checked this conversion.
 } else if (ParamIdx < ParamTypes.size()) {
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 3a3dc8855d827..6987d0c020457 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -1290,3 +1290,60 @@ void f() {
 
 
 }
+
+namespace GH147121 {
+struct X {};
+struct S1 {
+bool operator==(this auto &&, const X &); // #S1-cand
+};
+struct S2 {
+bool operator==(this X, const auto &&); // #S2-cand
+};
+
+struct S3 {
+S3& operator++(this X); // #S3-inc-cand
+S3& operator++(this int); // #S3-inc-cand
+int operator[](this X); // #S3-sub-cand
+int operator[](this int); // #S3-sub-cand2
+void f(this X); // #S3-f-cand
+void f(this int); // #S3-f-cand2
+};
+
+int main() {
+S1{} == S1{};
+// expected-error@-1 {{invalid operands to binary expression ('S1' and 
'S1')}}
+// expected-note@#S1-cand {{candidate function template not viable}}
+// expected-note@#S1-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S1{} != S1{};
+// expected-error@-1 {{invalid operands to binary expression ('S1' and 
'S1')}}
+// expected-note@#S1-cand {{candidate function template not viable}}
+// expected-note@#S1-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S2{} == S2{};
+// expected-error@-1 {{invalid operands to binary expression ('S2' and 
'S2')}}
+// expected-note@#S2-cand {{candidate function template not viable}}
+// expected-note@#S2-cand {{candidate function (with reversed parameter 
order) template not viable}}
+
+
+S2{} != S2{};
+// expected-error@-1 {{invalid operands to binary expression ('S2' and 
'S2')}}
+// expected-note@#S2-cand {{candidate function template not viable}}
+// expected-note@#S2-cand {{candidate function (with reversed parameter 
order) template not viable}}

[clang] [Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (PR #147996)

2025-07-10 Thread Corentin Jabot via cfe-commits

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


[clang] [CIR] Upstream ComplexRealPtrOp for ComplexType (PR #144235)

2025-07-10 Thread Amr Hesham via cfe-commits

https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/144235

>From acab11ee6a8e8041dab689c5518229e358d4f5a1 Mon Sep 17 00:00:00 2001
From: AmrDeveloper 
Date: Mon, 7 Jul 2025 20:52:33 +0200
Subject: [PATCH 1/2] [CIR] Upstream ComplexRealPtrOp for ComplexType

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 30 +++
 .../CIR/Dialect/IR/CIRTypeConstraints.td  | 24 +++
 clang/lib/CIR/CodeGen/CIRGenBuilder.h | 14 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  | 25 ++--
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp   | 18 +++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 +++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 10 +++
 clang/test/CIR/CodeGen/complex.cpp| 16 +-
 clang/test/CIR/IR/invalid-complex.cir | 12 
 9 files changed, 164 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..3c7b8b120af3b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2521,6 +2521,36 @@ def ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
   let hasFolder = 1;
 }
 
+//===--===//
+// ComplexRealPtrOp
+//===--===//
+
+def ComplexRealPtrOp : CIR_Op<"complex.real_ptr", [Pure]> {
+  let summary = "Derive a pointer to the real part of a complex value";
+  let description = [{
+`cir.complex.real_ptr` operation takes a pointer operand that points to a
+complex value of type `!cir.complex` and yields a pointer to the real part
+of the operand.
+
+Example:
+
+```mlir
+%1 = cir.complex.real_ptr %0 : !cir.ptr>
+  -> !cir.ptr
+```
+  }];
+
+  let results = (outs CIR_PtrToIntOrFloatType:$result);
+  let arguments = (ins CIR_PtrToComplexType:$operand);
+
+  let assemblyFormat = [{
+$operand `:`
+qualified(type($operand)) `->` qualified(type($result)) attr-dict
+  }];
+
+  let hasVerifier = 1;
+}
+
 
//===--===//
 // Bit Manipulation Operations
 
//===--===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index bcd516e27cc76..2bf77583465a6 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -159,6 +159,12 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, 
CIR_AnyIntType],
 let cppFunctionName = "isAnyIntegerOrFloatingPointType";
 }
 
+//===--===//
+// Complex Type predicates
+//===--===//
+
+def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">;
+
 
//===--===//
 // Pointer Type predicates
 
//===--===//
@@ -180,6 +186,17 @@ class CIR_PtrToPtrTo
 : CIR_ConfinedType],
 "pointer to pointer to " # summary>;
 
+// Pointee type constraint bases
+class CIR_PointeePred : SubstLeaves<"$_self",
+  "::mlir::cast<::cir::PointerType>($_self).getPointee()", pred>;
+
+class CIR_PtrToAnyOf types, string summary = "">
+: CIR_ConfinedType)>],
+  !if(!empty(summary),
+  "pointer to " # CIR_TypeSummaries.value,
+  summary)>;
+
 // Void pointer type constraints
 def CIR_VoidPtrType
 : CIR_PtrTo<"::cir::VoidType", "void type">,
@@ -192,6 +209,13 @@ def CIR_PtrToVoidPtrType
 "$_builder.getType<" # cppType # ">("
 "cir::VoidType::get($_builder.getContext(">;
 
+class CIR_PtrToType : CIR_PtrToAnyOf<[type]>;
+
+// Pointer to type constraints
+def CIR_PtrToIntOrFloatType : CIR_PtrToType;
+
+def CIR_PtrToComplexType : CIR_PtrToType;
+
 
//===--===//
 // Vector Type predicates
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 0b33f6c7d03b7..b09f1baf1d016 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -364,6 +364,20 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
 return create(loc, operandTy.getElementType(), 
operand);
   }
 
+  /// Create a cir.complex.real_ptr operation that derives a pointer to the 
real
+  /// part of the complex value pointed to by the specified pointer value.
+  mlir::Value createComplexRealPtr(mlir::Location loc, mlir::Value value) {
+auto srcPt

[clang] [Clang][Driver] Emit warning when -fsanitize-trap=undefined is passed without -fsanitize=undefined (PR #147997)

2025-07-10 Thread Anthony Tran via cfe-commits

https://github.com/anthonyhatran created 
https://github.com/llvm/llvm-project/pull/147997

Part of a GSoC 2025 Project


>From eadf3e52072fbae01e8de8f7f59883aec1b2c9bc Mon Sep 17 00:00:00 2001
From: Anthony Tran 
Date: Thu, 10 Jul 2025 09:18:50 -0700
Subject: [PATCH] Added warning and warning group for sanitizer argument
 mismatch

---
 clang/include/clang/Basic/DiagnosticDriverKinds.td | 5 +
 clang/include/clang/Basic/DiagnosticGroups.td  | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 34b6c0d7a8acd..49a8bdf06bda4 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -874,4 +874,9 @@ def warn_drv_openacc_without_cir
 : Warning<"OpenACC directives will result in no runtime behavior; use "
   "-fclangir to enable runtime effect">,
   InGroup;
+
+def warn_drv_sanitize_trap_mismatch : Warning<
+  "-fsanitize-trap=%0 has no effect because the matching sanitizer is not 
enabled; "
+  "did you mean to pass \"-fsanitize=%0\" as well?">,
+  InGroup;
 }
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index f54a830b0103e..a79562cd9c2e0 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1752,3 +1752,6 @@ def ExplicitSpecializationStorageClass : 
DiagGroup<"explicit-specialization-stor
 
 // A warning for options that enable a feature that is not yet complete
 def ExperimentalOption : DiagGroup<"experimental-option">;
+
+// Warnings for sanitizer arguments
+def SanitizeTrapMismatch : DiagGroup<"sanitize-trap-mismatch">;

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


[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/147797

From fc638a1d7d56becbe7e8350b46b75ade51718f71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Tue, 20 May 2025 15:51:48 +0200
Subject: [PATCH 1/6] [analyzer] Prettify checker registration and unittest
 code

This commit tweaks the interface of `CheckerRegistry::addChecker` to
make it more practical for plugins and tests:
- The most general overload (where `DocsUri` appears in the parameter
  list) is turned into a private method which is only used for loading
  the checkers described in `Checkers.td`. Note that currently _nothing_
  queries the documentation URI from the checker registry (it's only
  used by the logic that generates the clang-tidy documentation, but
  that loads it directly from `Checkers.td` without involving the
  `CheckerRegistry`), so there is no reason to require anyone to provide
  this value. (In fact, it may be a good idea to remove it completely
  from the `CheckerRegistry`.)
- A new public overload is introduced which differs from the most
  general one by omitting the `DocsUri` argument and making the
  `IsHidden` parameter optional (by setting it to `false` by default).
  This will cover the needs of plugins that want maximal customization.
- The templated overload (which takes the checker type as a
  template paarameter + the checker name and description as parameters)
  also loses the `DocsUri` parameter.
- A new method `addMockChecker` is added for use in unit tests.

In addition to propagating these changes (e.g. using `addMockChecker` in
unittests), this commit clarifies, corrects and extends lots of comments
and performs various minor code quality improvements in the code of
unittests and example plugins.

I originally wrote the bulk of this commit when I was planning to add an
extra parameter to `addChecker` in order to implement some technical
details of the CheckerFamily framework. At the end I decided against
adding that extra parameter, so this cleanup was left out of the PR
https://github.com/llvm/llvm-project/pull/139256 and I'm merging it now
as a separate commit (after minor tweaks).

This commit is mostly NFC: the only functional change is that the public
checker registration functions no longer require (or accept) `DocsUri`
as an argument, and the `IsHidden` argument is optional for both public
overloads of `addChecker` (and not just the "basic" templated one).
---
 .../StaticAnalyzer/Frontend/CheckerRegistry.h | 67 +++
 .../CheckerDependencyHandling.cpp | 12 ++--
 .../CheckerOptionHandling.cpp | 13 ++--
 .../SampleAnalyzer/MainCallChecker.cpp| 18 ++---
 .../BlockEntranceCallbackTest.cpp |  6 +-
 .../BugReportInterestingnessTest.cpp  |  4 +-
 .../StaticAnalyzer/CallDescriptionTest.cpp|  3 +-
 .../StaticAnalyzer/CallEventTest.cpp  |  3 +-
 .../ConflictingEvalCallsTest.cpp  |  6 +-
 .../StaticAnalyzer/ExprEngineVisitTest.cpp| 11 ++-
 .../FalsePositiveRefutationBRVisitorTest.cpp  |  4 +-
 .../MemRegionDescriptiveNameTest.cpp  |  3 +-
 .../NoStateChangeFuncVisitorTest.cpp  | 11 +--
 .../StaticAnalyzer/ObjcBug-124477.cpp |  4 +-
 .../RegisterCustomCheckersTest.cpp| 23 +++
 .../StaticAnalyzer/SValSimplifyerTest.cpp |  3 +-
 clang/unittests/StaticAnalyzer/SValTest.cpp   |  5 +-
 .../TestReturnValueUnderConstruction.cpp  |  6 +-
 18 files changed, 102 insertions(+), 100 deletions(-)

diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h 
b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index 43dbfb1585151..91871c13c9c83 100644
--- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -38,29 +38,29 @@
 // function clang_registerCheckers. For example:
 //
 //extern "C"
-//void clang_registerCheckers (CheckerRegistry ®istry) {
-//  registry.addChecker("example.MainCallChecker",
-//"Disallows calls to functions called main");
+//void clang_registerCheckers(CheckerRegistry &Registry) {
+//  Registry.addChecker(
+//"example.MainCallChecker",
+//"Disallows calls to functions called main");
 //}
 //
-// The first method argument is the full name of the checker, including its
-// enclosing package. By convention, the registered name of a checker is the
-// name of the associated class (the template argument).
-// The second method argument is a short human-readable description of the
-// checker.
+// The first argument of this templated method is the full name of the checker
+// (including its package), while the second argument is a short description
+// that is printed by `-analyzer-checker-help`.
 //
-// The clang_registerCheckers function may add any number of checkers to the
-// registry. If any checkers require additional initializati

[clang] [Clang][Driver] Emit warning when -fsanitize-trap=undefined is passed without -fsanitize=undefined (PR #147997)

2025-07-10 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [Clang][Driver] Emit warning when -fsanitize-trap=undefined is passed without -fsanitize=undefined (PR #147997)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Anthony Tran (anthonyhatran)


Changes

Part of a GSoC 2025 Project


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


2 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+5) 
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+3) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 34b6c0d7a8acd..49a8bdf06bda4 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -874,4 +874,9 @@ def warn_drv_openacc_without_cir
 : Warning<"OpenACC directives will result in no runtime behavior; use "
   "-fclangir to enable runtime effect">,
   InGroup;
+
+def warn_drv_sanitize_trap_mismatch : Warning<
+  "-fsanitize-trap=%0 has no effect because the matching sanitizer is not 
enabled; "
+  "did you mean to pass \"-fsanitize=%0\" as well?">,
+  InGroup;
 }
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index f54a830b0103e..a79562cd9c2e0 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1752,3 +1752,6 @@ def ExplicitSpecializationStorageClass : 
DiagGroup<"explicit-specialization-stor
 
 // A warning for options that enable a feature that is not yet complete
 def ExperimentalOption : DiagGroup<"experimental-option">;
+
+// Warnings for sanitizer arguments
+def SanitizeTrapMismatch : DiagGroup<"sanitize-trap-mismatch">;

``




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


[clang] [Clang] Fix a crash when diagnosing wrong conversion to explicit object parameter (PR #147996)

2025-07-10 Thread Erich Keane via cfe-commits

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


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


[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/147797

From fc638a1d7d56becbe7e8350b46b75ade51718f71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Tue, 20 May 2025 15:51:48 +0200
Subject: [PATCH 1/7] [analyzer] Prettify checker registration and unittest
 code

This commit tweaks the interface of `CheckerRegistry::addChecker` to
make it more practical for plugins and tests:
- The most general overload (where `DocsUri` appears in the parameter
  list) is turned into a private method which is only used for loading
  the checkers described in `Checkers.td`. Note that currently _nothing_
  queries the documentation URI from the checker registry (it's only
  used by the logic that generates the clang-tidy documentation, but
  that loads it directly from `Checkers.td` without involving the
  `CheckerRegistry`), so there is no reason to require anyone to provide
  this value. (In fact, it may be a good idea to remove it completely
  from the `CheckerRegistry`.)
- A new public overload is introduced which differs from the most
  general one by omitting the `DocsUri` argument and making the
  `IsHidden` parameter optional (by setting it to `false` by default).
  This will cover the needs of plugins that want maximal customization.
- The templated overload (which takes the checker type as a
  template paarameter + the checker name and description as parameters)
  also loses the `DocsUri` parameter.
- A new method `addMockChecker` is added for use in unit tests.

In addition to propagating these changes (e.g. using `addMockChecker` in
unittests), this commit clarifies, corrects and extends lots of comments
and performs various minor code quality improvements in the code of
unittests and example plugins.

I originally wrote the bulk of this commit when I was planning to add an
extra parameter to `addChecker` in order to implement some technical
details of the CheckerFamily framework. At the end I decided against
adding that extra parameter, so this cleanup was left out of the PR
https://github.com/llvm/llvm-project/pull/139256 and I'm merging it now
as a separate commit (after minor tweaks).

This commit is mostly NFC: the only functional change is that the public
checker registration functions no longer require (or accept) `DocsUri`
as an argument, and the `IsHidden` argument is optional for both public
overloads of `addChecker` (and not just the "basic" templated one).
---
 .../StaticAnalyzer/Frontend/CheckerRegistry.h | 67 +++
 .../CheckerDependencyHandling.cpp | 12 ++--
 .../CheckerOptionHandling.cpp | 13 ++--
 .../SampleAnalyzer/MainCallChecker.cpp| 18 ++---
 .../BlockEntranceCallbackTest.cpp |  6 +-
 .../BugReportInterestingnessTest.cpp  |  4 +-
 .../StaticAnalyzer/CallDescriptionTest.cpp|  3 +-
 .../StaticAnalyzer/CallEventTest.cpp  |  3 +-
 .../ConflictingEvalCallsTest.cpp  |  6 +-
 .../StaticAnalyzer/ExprEngineVisitTest.cpp| 11 ++-
 .../FalsePositiveRefutationBRVisitorTest.cpp  |  4 +-
 .../MemRegionDescriptiveNameTest.cpp  |  3 +-
 .../NoStateChangeFuncVisitorTest.cpp  | 11 +--
 .../StaticAnalyzer/ObjcBug-124477.cpp |  4 +-
 .../RegisterCustomCheckersTest.cpp| 23 +++
 .../StaticAnalyzer/SValSimplifyerTest.cpp |  3 +-
 clang/unittests/StaticAnalyzer/SValTest.cpp   |  5 +-
 .../TestReturnValueUnderConstruction.cpp  |  6 +-
 18 files changed, 102 insertions(+), 100 deletions(-)

diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h 
b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index 43dbfb1585151..91871c13c9c83 100644
--- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -38,29 +38,29 @@
 // function clang_registerCheckers. For example:
 //
 //extern "C"
-//void clang_registerCheckers (CheckerRegistry ®istry) {
-//  registry.addChecker("example.MainCallChecker",
-//"Disallows calls to functions called main");
+//void clang_registerCheckers(CheckerRegistry &Registry) {
+//  Registry.addChecker(
+//"example.MainCallChecker",
+//"Disallows calls to functions called main");
 //}
 //
-// The first method argument is the full name of the checker, including its
-// enclosing package. By convention, the registered name of a checker is the
-// name of the associated class (the template argument).
-// The second method argument is a short human-readable description of the
-// checker.
+// The first argument of this templated method is the full name of the checker
+// (including its package), while the second argument is a short description
+// that is printed by `-analyzer-checker-help`.
 //
-// The clang_registerCheckers function may add any number of checkers to the
-// registry. If any checkers require additional initializati

[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman updated 
https://github.com/llvm/llvm-project/pull/147802

>From e65fa6bdd251ceef52e11ff8ee856058e8e3c47a Mon Sep 17 00:00:00 2001
From: Aaron Ballman 
Date: Wed, 9 Jul 2025 14:40:00 -0400
Subject: [PATCH 1/7] [C23] Accept an _Atomic underlying type

The underlying type of an enumeration is the non-atomic, unqualified
version of the specified type. Clang was rejecting such enumerations,
but now accepts them.

Because we expose _Atomic in C++, the same behavior is carried over.

Fixes #147736
---
 clang/docs/ReleaseNotes.rst   |  3 +++
 clang/lib/Sema/SemaDecl.cpp   | 20 +++
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 10 --
 clang/test/C/C23/n3030_1.c| 13 
 clang/test/SemaCXX/enum-scoped.cpp| 13 
 5 files changed, 57 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/C/C23/n3030_1.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 57a94242c9e61..4fc74f430e768 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -310,6 +310,9 @@ C23 Feature Support
   `WG14 N2975 `_
 - Fixed a bug with handling the type operand form of ``typeof`` when it is used
   to specify a fixed underlying type for an enumeration. #GH146351
+- Fixed a rejects-valid bug where Clang would reject an enumeration with an
+  ``_Atomic`` underlying type. The underlying type is the non-atomic,
+  unqualified version of the specified type. (#GH147736)
 
 C11 Feature Support
 ^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 11cbda412667f..e2c99e1bb0cb2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -17152,6 +17152,13 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) 
{
   SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();
   QualType T = TI->getType();
 
+  // C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an
+  // integral type; any cv-qualification is ignored.
+  // C23 6.7.3.3p5: The underlying type of the enumeration is the unqualified,
+  // non-atomic version of the type specified by the type specifiers in the
+  // specifier qualifier list.
+  T = T.getAtomicUnqualifiedType();
+
   if (T->isDependentType())
 return false;
 
@@ -17551,6 +17558,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
 } else if (UnderlyingType.get()) {
   // C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an
   // integral type; any cv-qualification is ignored.
+  // C23 6.7.3.3p5: The underlying type of the enumeration is the
+  // unqualified, non-atomic version of the type specified by the type
+  // specifiers in the specifier qualifier list.
   TypeSourceInfo *TI = nullptr;
   GetTypeFromParser(UnderlyingType.get(), &TI);
   EnumUnderlying = TI;
@@ -17563,6 +17573,16 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
   UPPC_FixedUnderlyingType))
 EnumUnderlying = Context.IntTy.getTypePtr();
 
+  // If the underlying type is atomic, we need to adjust the type before
+  // continuing. This only happens in the case we stored a TypeSourceInfo
+  // into EnumUnderlying because the other cases are error recovery up to
+  // this point. But because it's not possible to gin up a TypeSourceInfo
+  // for a non-atomic type from an atomic one, we'll store into the Type
+  // field instead.
+  if (TypeSourceInfo *TI = dyn_cast(EnumUnderlying);
+  TI && TI->getType()->isAtomicType())
+EnumUnderlying = TI->getType().getAtomicUnqualifiedType().getTypePtr();
+
 } else if (Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment()) 
{
   // For MSVC ABI compatibility, unfixed enums must use an underlying type
   // of 'int'. However, if this is an unfixed forward declaration, don't 
set
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 70a4c159f9805..1608232f4553e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2022,8 +2022,14 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl 
*D) {
 DeclarationName());
   if (!NewTI || SemaRef.CheckEnumUnderlyingType(NewTI))
 Enum->setIntegerType(SemaRef.Context.IntTy);
-  else
-Enum->setIntegerTypeSourceInfo(NewTI);
+  else {
+// If the underlying type is atomic, we need to adjust the type before
+// continuing. See C23 6.7.3.3p5 and Sema::ActOnTag().
+if (NewTI->getType()->isAtomicType())
+  Enum->setIntegerType(NewTI->getType().getAtomicUnqualifiedType());
+else
+  Enum

[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- 
clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h 
clang/lib/Analysis/plugins/CheckerDependencyHandling/CheckerDependencyHandling.cpp
 clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp 
clang/lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp 
clang/unittests/StaticAnalyzer/BlockEntranceCallbackTest.cpp 
clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp 
clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp 
clang/unittests/StaticAnalyzer/CallEventTest.cpp 
clang/unittests/StaticAnalyzer/ConflictingEvalCallsTest.cpp 
clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp 
clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp 
clang/unittests/StaticAnalyzer/MemRegionDescriptiveNameTest.cpp 
clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp 
clang/unittests/StaticAnalyzer/ObjcBug-124477.cpp 
clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp 
clang/unittests/StaticAnalyzer/SValSimplifyerTest.cpp 
clang/unittests/StaticAnalyzer/SValTest.cpp 
clang/unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h 
b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index eedb813b0..35f63e734 100644
--- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -108,9 +108,7 @@ private:
 mgr.template registerChecker();
   }
 
-  static bool returnTrue(const CheckerManager &) {
-return true;
-  }
+  static bool returnTrue(const CheckerManager &) { return true; }
 
   /// Adds a checker to the registry.
   /// This private, most general variant is intended for loading the checker

``




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


[clang-tools-extra] [clang-tidy][NFC] add '.clang-tidy' config for clang-tidy project (PR #147793)

2025-07-10 Thread Baranov Victor via cfe-commits

vbvictor wrote:

> One last thing I'm missing: can you update the clang-tidy contributors guide, 
> to explain that we expect people to run clang-tidy as well (and what command 
> to run)? Since it's not currently enforced in CI.

I will add it in a separate PR. Don't feel right to make kind-of unrelated 
changes after most of the people gave their consent.

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


[clang] [llvm] [NFC][PowerPC] Add test case for lockdown of vector compare greater than support for Zero vector comparisons (PR #147246)

2025-07-10 Thread Tony Varghese via cfe-commits

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


[clang] [NFC][C++][Modules] Refine test/CXX/basic.link/p3.cpp with split-file (PR #147945)

2025-07-10 Thread via cfe-commits


@@ -51,4 +39,71 @@ template module module_var_template;
 
 // This is a variable named 'import' that shadows the type 'import' above.
 struct X {} import;
-#endif
+
+//--- ImportError1.cppm
+module;
+
+struct import { struct inner {}; };
+struct module { struct inner {}; };
+
+constexpr int n = 123;
+
+export module m; // #1
+
+import x = {}; // expected-error {{expected ';' after module name}}
+   // expected-error@-1 {{module 'x' not found}}
+
+//--- ImportError2.cppm
+module;
+
+struct module { struct inner {}; };
+
+constexpr int n = 123;
+
+export module m; // #1
+
+struct X;
+template struct import;
+template<> struct import {
+  static X y;
+};
+
+// This is not valid because the 'import ' is a pp-import, even though it
+// grammatically can't possibly be an import declaration.
+struct X {} import::y; // expected-error {{'n' file not found}}
+
+//--- A.cppm
+export module A;
+const double delta=0.01;
+export {
+  template
+  double derivative(F &&f,double x) {
+return (f(x+delta)-f(x))/delta;
+  }
+}
+
+//--- std.cppm
+export module std;
+export using size_t = decltype(sizeof(void *));
+
+export namespace std {
+  template 
+  struct array {};
+}
+
+//--- A-B.cppm
+module A:B;
+const int dimensions=3;
+
+//--- A_impl.cppm

yronglin wrote:

Fixed

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


[clang] [LifetimeSafety] Introduce intra-procedural analysis in Clang (PR #142313)

2025-07-10 Thread via cfe-commits

dyung wrote:

> I am part of a toolchain team at Google and we are seeing clang test failures 
> in our toolchain builders from this PR.
> 
> ```
> Exit Code: 1
> 
> Command Output (stderr):
> --
> /b/s/w/ir/x/w/llvm_build/bin/clang -cc1 -internal-isystem 
> /b/s/w/ir/x/w/llvm_build/lib/clang/21/include -nostdsysteminc -mllvm 
> -debug-only=LifetimeFacts -Wexperimental-lifetime-safety 
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
>  2>&1 | /b/s/w/ir/x/w/llvm_build/bin/FileCheck 
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
>  # RUN: at line 1
> + /b/s/w/ir/x/w/llvm_build/bin/clang -cc1 -internal-isystem 
> /b/s/w/ir/x/w/llvm_build/lib/clang/21/include -nostdsysteminc -mllvm 
> -debug-only=LifetimeFacts -Wexperimental-lifetime-safety 
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
> + /b/s/w/ir/x/w/llvm_build/bin/FileCheck 
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp:9:17:
>  error: CHECK-LABEL: expected string not found in input
> // CHECK-LABEL: Function: return_local_addr
> ^
> :1:1: note: scanning from here
> clang (LLVM option parsing): Unknown command line argument 
> '-debug-only=LifetimeFacts'. Try: 'clang (LLVM option parsing) --help'
> ^
> :1:105: note: possible intended match here
> clang (LLVM option parsing): Unknown command line argument 
> '-debug-only=LifetimeFacts'. Try: 'clang (LLVM option parsing) --help'
>   
>   ^
> 
> Input file: 
> Check file: 
> /b/s/w/ir/x/w/llvm-llvm-project/clang/test/Sema/warn-lifetime-safety-dataflow.cpp
> 
> -dump-input=help explains the following input dump.
> 
> Input was:
> <<
>1: clang (LLVM option parsing): Unknown command line argument 
> '-debug-only=LifetimeFacts'. Try: 'clang (LLVM option parsing) --help' 
> label:9'0 
> X~
>  error: no match found
> label:9'1 
> ?  possible 
> intended match
>2: clang (LLVM option parsing): Did you mean 
> '--debug-pass=LifetimeFacts'? 
> label:9'0 
> 
> >>
> 
> --
> ```
> 
> I am taking a closer look. Here are the logs: 
> https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8709695680348159649/+/u/clang/tests/stdout

The test just needs asserts to run, I am preparing a patch to fix it and will 
submit it shortly.

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


[clang] [clang] Fix a crash when dynamic_cast-ing to a `final` class (PR #148088)

2025-07-10 Thread Corentin Jabot via cfe-commits

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


[clang] [clang] Fix isConstantInitializer handling of transparent init lists. (PR #148030)

2025-07-10 Thread Corentin Jabot via cfe-commits

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

Can you add a release note?
LGTM otherwise

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


[clang] [Clang] Ignore invalid base classes (PR #147213)

2025-07-10 Thread Corentin Jabot via cfe-commits


@@ -2252,7 +2252,7 @@ void Parser::ParseBaseClause(Decl *ClassDecl) {
   while (true) {
 // Parse a base-specifier.
 BaseResult Result = ParseBaseSpecifier(ClassDecl);
-if (Result.isInvalid()) {
+if (!Result.isUsable()) {

cor3ntin wrote:

Result can either be invalid, null, or valid - this changes what we do in the 
null case, ie we don't want null base classes - does that make sense? 

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


[clang] [clang][bytecode] Keep a list of initializing blocks in InterpState (PR #148120)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

So we can know what blocks we're currently running constructors or destructors 
for.

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


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.cpp (+21-22) 
- (modified) clang/lib/AST/ByteCode/InterpState.h (+4) 


``diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index be77657acabcc..18b84fa48fb1d 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -576,23 +576,14 @@ bool CheckConst(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
   if (!Ptr.isConst() || Ptr.isMutable())
 return true;
 
-  // The This pointer is writable in constructors and destructors,
-  // even if isConst() returns true.
-  // TODO(perf): We could be hitting this code path quite a lot in complex
-  // constructors. Is there a better way to do this?
-  if (S.Current->getFunction()) {
-for (const InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) {
-  if (const Function *Func = Frame->getFunction();
-  Func && (Func->isConstructor() || Func->isDestructor()) &&
-  Ptr.block() == Frame->getThis().block()) {
-return true;
-  }
-}
-  }
-
   if (!Ptr.isBlockPointer())
 return false;
 
+  // The This pointer is writable in constructors and destructors,
+  // even if isConst() returns true.
+  if (llvm::find(S.InitializingBlocks, Ptr.block()))
+return true;
+
   const QualType Ty = Ptr.getType();
   const SourceInfo &Loc = S.Current->getSource(OpPC);
   S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty;
@@ -1524,6 +1515,9 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
   return false;
 if (Func->isDestructor() && !CheckDestructor(S, OpPC, ThisPtr))
   return false;
+
+if (Func->isConstructor() || Func->isDestructor())
+  S.InitializingBlocks.push_back(ThisPtr.block());
   }
 
   if (!Func->isFullyCompiled())
@@ -1550,16 +1544,21 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
   // Note that we cannot assert(CallResult.hasValue()) here since
   // Ret() above only sets the APValue if the curent frame doesn't
   // have a caller set.
-  if (Interpret(S)) {
-NewFrame.release(); // Frame was delete'd already.
-assert(S.Current == FrameBefore);
-return true;
+  bool Success = Interpret(S);
+  // Remove initializing  block again.
+  if (Func->isConstructor() || Func->isDestructor())
+S.InitializingBlocks.pop_back();
+
+  if (!Success) {
+// Interpreting the function failed somehow. Reset to
+// previous state.
+S.Current = FrameBefore;
+return false;
   }
 
-  // Interpreting the function failed somehow. Reset to
-  // previous state.
-  S.Current = FrameBefore;
-  return false;
+  NewFrame.release(); // Frame was delete'd already.
+  assert(S.Current == FrameBefore);
+  return true;
 }
 
 bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
diff --git a/clang/lib/AST/ByteCode/InterpState.h 
b/clang/lib/AST/ByteCode/InterpState.h
index 08765561985e2..861e4c38049ab 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -190,6 +190,10 @@ class InterpState final : public State, public 
SourceMapper {
   std::pair>
   SeenGlobalTemporaries;
 
+  /// List of blocks we're currently running either constructors or destructors
+  /// for.
+  llvm::SmallVector InitializingBlocks;
+
   mutable llvm::BumpPtrAllocator Allocator;
 };
 

``




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


[clang] [clang] Build argument string for clang::warn_unused_result (PR #148090)

2025-07-10 Thread via cfe-commits

https://github.com/zebullax updated 
https://github.com/llvm/llvm-project/pull/148090

>From 11909560ed6cb4e56192fbbfe4d8b1cdf58e1cb1 Mon Sep 17 00:00:00 2001
From: zebullax 
Date: Fri, 11 Jul 2025 09:12:44 +0900
Subject: [PATCH 1/2] Build argument string for clang::warn_unused_result

Preserve the argument-clause for `warn-unused-result` when under clang:: scope.
We are not touching gnu:: scope for now as it's an error for GCC to have that 
string. Personally I think it would be ok to relax it here too as we are not 
introducing breakage to currently passing code, but feedback is to go slowly 
about it.
---
 clang/lib/Sema/SemaDeclAttr.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7ebb53318702c..221197b3849e0 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2902,7 +2902,8 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, 
const ParsedAttr &AL) {
 }
 
   StringRef Str;
-  if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
+  if (AL.isStandardAttributeSyntax()
+  && (!AL.getScopeName() || AL.isClangScope())) {
 // The standard attribute cannot be applied to variable declarations such
 // as a function pointer.
 if (isa(D))

>From 75e585703826f50f704be099f550346a06223cb5 Mon Sep 17 00:00:00 2001
From: zebullax 
Date: Fri, 11 Jul 2025 15:51:22 +0900
Subject: [PATCH 2/2] Add unit test to check reason string on clang scope

Signed-off-by: zebullax 
---
 clang/test/SemaCXX/warn-unused-result.cpp | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/clang/test/SemaCXX/warn-unused-result.cpp 
b/clang/test/SemaCXX/warn-unused-result.cpp
index fa7540c116e67..1b9370765b377 100644
--- a/clang/test/SemaCXX/warn-unused-result.cpp
+++ b/clang/test/SemaCXX/warn-unused-result.cpp
@@ -364,3 +364,21 @@ void id_print_name() {
 ((int(*)())f)();
 }
 } // namespace GH117975
+
+namespace BuildStringOnClangScope {
+
+[[clang::warn_unused_result("Discarded result")]]
+bool makeClangTrue() { return true; }
+
+[[gnu::warn_unused_result("Discarded result")]]
+bool makeGccTrue() { return true; }
+
+void doClangThings() {
+  makeClangTrue(); // expected-warning {{ignoring return value of function 
declared with 'warn_unused_result' attribute: Discarded result}}
+}
+
+void doGccThings() {
+  makeGccTrue(); // expected-warning {{ignoring return value of function 
declared with 'warn_unused_result' attribute}}
+}
+
+}
\ No newline at end of file

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


[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Cristian Assaiante via cfe-commits

https://github.com/cristianassaiante updated 
https://github.com/llvm/llvm-project/pull/145059

>From ab6063493744ef5a1ee92fd249bf8d86b7299fad Mon Sep 17 00:00:00 2001
From: Cristian Assaiante 
Date: Fri, 20 Jun 2025 16:56:23 +0200
Subject: [PATCH 01/10] Adding -opt-disable and a test for it

---
 clang/test/CodeGen/opt-disable.c | 13 +++
 llvm/include/llvm/IR/OptBisect.h | 39 
 llvm/lib/IR/OptBisect.cpp| 63 ++--
 3 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/opt-disable.c

diff --git a/clang/test/CodeGen/opt-disable.c b/clang/test/CodeGen/opt-disable.c
new file mode 100644
index 0..ee90fc5620d65
--- /dev/null
+++ b/clang/test/CodeGen/opt-disable.c
@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+
+// Make sure opt-bisect works through both pass managers
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -mllvm 
-opt-disable="inlinerpass,SROAPass,machine code sinking" -mllvm 
-opt-disable-verbose -emit-obj -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: DISABLE: running pass InlinerPass
+// CHECK-NOT: DISABLE: running pass SROAPass
+// CHECK-NOT: DISABLE: running pass Machine code sinking
+// Make sure that legacy pass manager is running
+// CHECK: Instruction Selection
+
+int func(int a) { return a; }
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index be6aef3298b23..51c3a8040da9b 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
 #include 
+#include 
 
 namespace llvm {
 
@@ -82,6 +83,44 @@ class LLVM_ABI OptBisect : public OptPassGate {
   int LastBisectNum = 0;
 };
 
+/// This class implements a mechanism to disable passes and individual
+/// optimizations at compile time based on a command line option
+/// (-opt-disable) in order to study how single transformations, or
+/// combinations thereof, affect the IR.
+class LLVM_ABI OptDisable : public OptPassGate {
+public:
+  /// Default constructor. Initializes the state to empty set. The disabling
+  /// will be enabled by the cl::opt call-back when the command line option
+  /// is processed.
+  /// Clients should not instantiate this class directly.  All access should go
+  /// through LLVMContext.
+  OptDisable() = default;
+
+  virtual ~OptDisable() = default;
+
+  /// Checks the pass name to determine if the specified pass should run.
+  ///
+  /// The method prints the name of the pass, and whether or not the pass
+  /// will be executed. It returns true if the pass should run, i.e. if
+  /// its name is was not provided via command line.
+  ///
+  /// Most passes should not call this routine directly. Instead, it is called
+  /// through helper routines provided by the base classes of the pass. For
+  /// instance, function passes should call FunctionPass::skipFunction().
+  bool shouldRunPass(const StringRef PassName,
+ StringRef IRDescription) override;
+
+  /// Parses the command line argument to extract the names of the passes
+  /// to be disabled. Multiple pass names can be provided with comma 
separation.
+  void setDisabled(StringRef Passes);
+
+  /// isEnabled() should return true before calling shouldRunPass().
+  bool isEnabled() const override { return !DisabledPasses.empty(); }
+
+private:
+  std::set DisabledPasses = {};
+};
+
 /// Singleton instance of the OptBisect class, so multiple pass managers don't
 /// need to coordinate their uses of OptBisect.
 LLVM_ABI OptPassGate &getGlobalPassGate();
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 559b199445366..aa1dbdfdbebd4 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
+#include 
 
 using namespace llvm;
 
@@ -37,8 +38,8 @@ static cl::opt OptBisectVerbose(
 cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
 cl::init(true), cl::Optional);
 
-static void printPassMessage(const StringRef &Name, int PassNum,
- StringRef TargetDesc, bool Running) {
+static void printBisectPassMessage(const StringRef &Name, int PassNum,
+   StringRef TargetDesc, bool Running) {
   StringRef Status = Running ? "" : "NOT ";
   errs() << "BISECT: " << Status << "running pass "
  << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
@@ -51,10 +52,64 @@ bool OptBisect::shouldRunPass(const StringRef PassName,
   int CurBisectNum = ++LastBisectNum;
   bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit);
   if (OptBisectVerbose)
-printPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
+printBisectPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
   return ShouldRun;
 }
 
 const int OptBisect::Disabled;

[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Cristian Assaiante via cfe-commits


@@ -37,6 +42,18 @@ static cl::opt OptBisectVerbose(
 cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
 cl::init(true), cl::Optional);
 
+static cl::list OptDisablePasses(
+"opt-disable", cl::Hidden, cl::CommaSeparated, cl::Optional,
+cl::cb([](std::string Pass) {
+  getOptDisabler().setDisabled(Pass);
+}),
+cl::desc("Optimization pass(es) to disable (comma-separated list)"));

cristianassaiante wrote:

Not needed anymore, since now it is working with shorter names!

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


[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Nikita Popov via cfe-commits

https://github.com/nikic commented:

Can you please undo the unrelated formatting changes? It's hard to see what 
actually changed, especially inside StandardInstrumentations.cpp.

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


[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Cristian Assaiante via cfe-commits

https://github.com/cristianassaiante updated 
https://github.com/llvm/llvm-project/pull/145059

>From ab6063493744ef5a1ee92fd249bf8d86b7299fad Mon Sep 17 00:00:00 2001
From: Cristian Assaiante 
Date: Fri, 20 Jun 2025 16:56:23 +0200
Subject: [PATCH 01/11] Adding -opt-disable and a test for it

---
 clang/test/CodeGen/opt-disable.c | 13 +++
 llvm/include/llvm/IR/OptBisect.h | 39 
 llvm/lib/IR/OptBisect.cpp| 63 ++--
 3 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/opt-disable.c

diff --git a/clang/test/CodeGen/opt-disable.c b/clang/test/CodeGen/opt-disable.c
new file mode 100644
index 0..ee90fc5620d65
--- /dev/null
+++ b/clang/test/CodeGen/opt-disable.c
@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+
+// Make sure opt-bisect works through both pass managers
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -mllvm 
-opt-disable="inlinerpass,SROAPass,machine code sinking" -mllvm 
-opt-disable-verbose -emit-obj -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: DISABLE: running pass InlinerPass
+// CHECK-NOT: DISABLE: running pass SROAPass
+// CHECK-NOT: DISABLE: running pass Machine code sinking
+// Make sure that legacy pass manager is running
+// CHECK: Instruction Selection
+
+int func(int a) { return a; }
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index be6aef3298b23..51c3a8040da9b 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
 #include 
+#include 
 
 namespace llvm {
 
@@ -82,6 +83,44 @@ class LLVM_ABI OptBisect : public OptPassGate {
   int LastBisectNum = 0;
 };
 
+/// This class implements a mechanism to disable passes and individual
+/// optimizations at compile time based on a command line option
+/// (-opt-disable) in order to study how single transformations, or
+/// combinations thereof, affect the IR.
+class LLVM_ABI OptDisable : public OptPassGate {
+public:
+  /// Default constructor. Initializes the state to empty set. The disabling
+  /// will be enabled by the cl::opt call-back when the command line option
+  /// is processed.
+  /// Clients should not instantiate this class directly.  All access should go
+  /// through LLVMContext.
+  OptDisable() = default;
+
+  virtual ~OptDisable() = default;
+
+  /// Checks the pass name to determine if the specified pass should run.
+  ///
+  /// The method prints the name of the pass, and whether or not the pass
+  /// will be executed. It returns true if the pass should run, i.e. if
+  /// its name is was not provided via command line.
+  ///
+  /// Most passes should not call this routine directly. Instead, it is called
+  /// through helper routines provided by the base classes of the pass. For
+  /// instance, function passes should call FunctionPass::skipFunction().
+  bool shouldRunPass(const StringRef PassName,
+ StringRef IRDescription) override;
+
+  /// Parses the command line argument to extract the names of the passes
+  /// to be disabled. Multiple pass names can be provided with comma 
separation.
+  void setDisabled(StringRef Passes);
+
+  /// isEnabled() should return true before calling shouldRunPass().
+  bool isEnabled() const override { return !DisabledPasses.empty(); }
+
+private:
+  std::set DisabledPasses = {};
+};
+
 /// Singleton instance of the OptBisect class, so multiple pass managers don't
 /// need to coordinate their uses of OptBisect.
 LLVM_ABI OptPassGate &getGlobalPassGate();
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 559b199445366..aa1dbdfdbebd4 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
+#include 
 
 using namespace llvm;
 
@@ -37,8 +38,8 @@ static cl::opt OptBisectVerbose(
 cl::desc("Show verbose output when opt-bisect-limit is set"), cl::Hidden,
 cl::init(true), cl::Optional);
 
-static void printPassMessage(const StringRef &Name, int PassNum,
- StringRef TargetDesc, bool Running) {
+static void printBisectPassMessage(const StringRef &Name, int PassNum,
+   StringRef TargetDesc, bool Running) {
   StringRef Status = Running ? "" : "NOT ";
   errs() << "BISECT: " << Status << "running pass "
  << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
@@ -51,10 +52,64 @@ bool OptBisect::shouldRunPass(const StringRef PassName,
   int CurBisectNum = ++LastBisectNum;
   bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit);
   if (OptBisectVerbose)
-printPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
+printBisectPassMessage(PassName, CurBisectNum, IRDescription, ShouldRun);
   return ShouldRun;
 }
 
 const int OptBisect::Disabled;

[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Cristian Assaiante via cfe-commits


@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+
+// Make sure opt-bisect works through both pass managers
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -mllvm 
-opt-disable="inlinerpass,SROAPass,machine code sinking" -mllvm 
-opt-disable-verbose -emit-obj -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: DISABLE: running pass InlinerPass
+// CHECK-NOT: DISABLE: running pass SROAPass
+// CHECK-NOT: DISABLE: running pass Machine code sinking

cristianassaiante wrote:

@nikic Thank you for the suggestion! This works perfectly now and is definitely 
an improvement.

One side effect of this change is that it also alters the output of 
-opt-bisect-limit, since it relies on the same instrumentation. As a result, 
one test from check-llvm was failing. I've updated the test to account for the 
new pass name output, and it now passes correctly.

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


[clang] [llvm] [OptBisect][IR] Adding a new OptPassGate for disabling passes via name (PR #145059)

2025-07-10 Thread Cristian Assaiante via cfe-commits

cristianassaiante wrote:

> Can you please undo the unrelated formatting changes? It's hard to see what 
> actually changed, especially inside StandardInstrumentations.cpp.

Sure, sorry about that.

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


[clang] [clang] Don't pass sanitizers' rtlibs to linker with `-r` (PR #147905)

2025-07-10 Thread Dmitry Chestnykh via cfe-commits

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


[clang] [clang][bytecode] Allocate Record Fields and bases via Program (PR #147909)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

Records have Program-lifetime, but we used to allocate their fields, bases and 
virtual bases using llvm::SmallVector. However, after creating a Record, it 
doesn't change and we know all the number of elements beforehand.

So, allocate the lists via the BumpPtrAllocator we already have in Program. 
This results in slight compile-time improvements:

https://llvm-compile-time-tracker.com/compare.php?from=3a3d55705b0f69f3ef5bed0b0211e7c884001842&to=e0fede973116c4d43e9883586c737c3d0bb99c3e&stat=instructions:u

Unfortunately, we still have the three DenseMaps in Record, so they still 
heap-allocate memory on their own.

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


3 Files Affected:

- (modified) clang/lib/AST/ByteCode/Program.cpp (+25-8) 
- (modified) clang/lib/AST/ByteCode/Record.cpp (+12-9) 
- (modified) clang/lib/AST/ByteCode/Record.h (+20-24) 


``diff
diff --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 5ac0f59f32d4e..de9008f0512e6 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -315,9 +315,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   };
 
   // Reserve space for base classes.
-  Record::BaseList Bases;
-  Record::VirtualBaseList VirtBases;
+  Record::Base *Bases = nullptr;
+  Record::Base *VBases = nullptr;
+  unsigned NumRecordBases = 0;
+  unsigned NumRecordVBases = 0;
   if (const auto *CD = dyn_cast(RD)) {
+unsigned NumBases = CD->getNumBases();
+unsigned NumVBases = CD->getNumVBases();
+
+Bases = new (*this) Record::Base[NumBases];
+VBases = new (*this) Record::Base[NumVBases];
+
 for (const CXXBaseSpecifier &Spec : CD->bases()) {
   if (Spec.isVirtual())
 continue;
@@ -334,9 +342,11 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   BaseSize += align(sizeof(InlineDescriptor));
-  Bases.push_back({BD, BaseSize, Desc, BR});
+  new (&Bases[NumRecordBases]) Record::Base{BD, BaseSize, Desc, BR};
   BaseSize += align(BR->getSize());
+  ++NumRecordBases;
 }
+assert(NumRecordBases <= NumBases);
 
 for (const CXXBaseSpecifier &Spec : CD->vbases()) {
   const auto *RT = Spec.getType()->getAs();
@@ -351,13 +361,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   VirtSize += align(sizeof(InlineDescriptor));
-  VirtBases.push_back({BD, VirtSize, Desc, BR});
+  new (&VBases[NumRecordVBases]) Record::Base{BD, VirtSize, Desc, BR};
   VirtSize += align(BR->getSize());
+  ++NumRecordVBases;
 }
+assert(NumRecordVBases <= NumVBases);
   }
 
   // Reserve space for fields.
-  Record::FieldList Fields;
+  unsigned NumFields = std::distance(RD->field_begin(), RD->field_end());
+  unsigned NumRecordFields = 0;
+  Record::Field *Fields = new (*this) Record::Field[NumFields];
   for (const FieldDecl *FD : RD->fields()) {
 FD = FD->getFirstDecl();
 // Note that we DO create fields and descriptors
@@ -382,12 +396,15 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 }
 if (!Desc)
   return nullptr;
-Fields.push_back({FD, BaseSize, Desc});
+
+new (&Fields[NumRecordFields]) Record::Field{FD, BaseSize, Desc};
 BaseSize += align(Desc->getAllocSize());
+++NumRecordFields;
   }
 
-  Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
- std::move(VirtBases), VirtSize, BaseSize);
+  Record *R =
+  new (Allocator) Record(RD, Bases, NumRecordBases, Fields, 
NumRecordFields,
+ VBases, NumRecordVBases, VirtSize, BaseSize);
   Records[RD] = R;
   return R;
 }
diff --git a/clang/lib/AST/ByteCode/Record.cpp 
b/clang/lib/AST/ByteCode/Record.cpp
index 1d4ac7103cb76..e40fb63914b61 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -12,20 +12,23 @@
 using namespace clang;
 using namespace clang::interp;
 
-Record::Record(const RecordDecl *Decl, BaseList &&SrcBases,
-   FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases,
-   unsigned VirtualSize, unsigned BaseSize)
-: Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)),
+Record::Record(const RecordDecl *Decl, const Base *SrcBases, unsigned NumBases,
+   const Field *Fields, unsigned NumFields, Base *VBases,
+   unsigned NumVBases, unsigned VirtualSize, unsigned BaseSize)
+: Decl(Decl), Bases(SrcBases), NumBases(NumBases), Fields(Fields),
+  NumFields(NumFields), VBases(VBases), NumVBases(NumVBases),
   BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()),
   IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()) {
-  for (Base &V : SrcVirtualBases)
-VirtualBases.push_back({V.Decl, V.Offset + BaseSize

[clang] [clang][bytecode] Allocate Record Fields and bases via Program (PR #147909)

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

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

Records have Program-lifetime, but we used to allocate their fields, bases and 
virtual bases using llvm::SmallVector. However, after creating a Record, it 
doesn't change and we know all the number of elements beforehand.

So, allocate the lists via the BumpPtrAllocator we already have in Program. 
This results in slight compile-time improvements:

https://llvm-compile-time-tracker.com/compare.php?from=3a3d55705b0f69f3ef5bed0b0211e7c884001842&to=e0fede973116c4d43e9883586c737c3d0bb99c3e&stat=instructions:u

Unfortunately, we still have the three DenseMaps in Record, so they still 
heap-allocate memory on their own.

>From c61678045c15ebf3ac86f602aaf857ff371c3b45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 10 Jul 2025 09:21:57 +0200
Subject: [PATCH] [clang][bytecode] Allocate Record Fields and bases via
 Program

Records have Program-lifetime, but we used to allocate their fields,
bases and virtual bases using llvm::SmallVector. However, after creating
a Record, it doesn't change and we know all the number of elements
beforehand.

So, allocate the lists via the BumpPtrAllocator we already have in
Program. This results in slight compile-time improvements:

https://llvm-compile-time-tracker.com/compare.php?from=3a3d55705b0f69f3ef5bed0b0211e7c884001842&to=e0fede973116c4d43e9883586c737c3d0bb99c3e&stat=instructions:u

Unfortunately, we still have the three DenseMaps in Record, so they
still heap-allocate memory on their own.
---
 clang/lib/AST/ByteCode/Program.cpp | 33 --
 clang/lib/AST/ByteCode/Record.cpp  | 21 --
 clang/lib/AST/ByteCode/Record.h| 44 ++
 3 files changed, 57 insertions(+), 41 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 5ac0f59f32d4e..de9008f0512e6 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -315,9 +315,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
   };
 
   // Reserve space for base classes.
-  Record::BaseList Bases;
-  Record::VirtualBaseList VirtBases;
+  Record::Base *Bases = nullptr;
+  Record::Base *VBases = nullptr;
+  unsigned NumRecordBases = 0;
+  unsigned NumRecordVBases = 0;
   if (const auto *CD = dyn_cast(RD)) {
+unsigned NumBases = CD->getNumBases();
+unsigned NumVBases = CD->getNumVBases();
+
+Bases = new (*this) Record::Base[NumBases];
+VBases = new (*this) Record::Base[NumVBases];
+
 for (const CXXBaseSpecifier &Spec : CD->bases()) {
   if (Spec.isVirtual())
 continue;
@@ -334,9 +342,11 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   BaseSize += align(sizeof(InlineDescriptor));
-  Bases.push_back({BD, BaseSize, Desc, BR});
+  new (&Bases[NumRecordBases]) Record::Base{BD, BaseSize, Desc, BR};
   BaseSize += align(BR->getSize());
+  ++NumRecordBases;
 }
+assert(NumRecordBases <= NumBases);
 
 for (const CXXBaseSpecifier &Spec : CD->vbases()) {
   const auto *RT = Spec.getType()->getAs();
@@ -351,13 +361,17 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 return nullptr;
 
   VirtSize += align(sizeof(InlineDescriptor));
-  VirtBases.push_back({BD, VirtSize, Desc, BR});
+  new (&VBases[NumRecordVBases]) Record::Base{BD, VirtSize, Desc, BR};
   VirtSize += align(BR->getSize());
+  ++NumRecordVBases;
 }
+assert(NumRecordVBases <= NumVBases);
   }
 
   // Reserve space for fields.
-  Record::FieldList Fields;
+  unsigned NumFields = std::distance(RD->field_begin(), RD->field_end());
+  unsigned NumRecordFields = 0;
+  Record::Field *Fields = new (*this) Record::Field[NumFields];
   for (const FieldDecl *FD : RD->fields()) {
 FD = FD->getFirstDecl();
 // Note that we DO create fields and descriptors
@@ -382,12 +396,15 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 }
 if (!Desc)
   return nullptr;
-Fields.push_back({FD, BaseSize, Desc});
+
+new (&Fields[NumRecordFields]) Record::Field{FD, BaseSize, Desc};
 BaseSize += align(Desc->getAllocSize());
+++NumRecordFields;
   }
 
-  Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
- std::move(VirtBases), VirtSize, BaseSize);
+  Record *R =
+  new (Allocator) Record(RD, Bases, NumRecordBases, Fields, 
NumRecordFields,
+ VBases, NumRecordVBases, VirtSize, BaseSize);
   Records[RD] = R;
   return R;
 }
diff --git a/clang/lib/AST/ByteCode/Record.cpp 
b/clang/lib/AST/ByteCode/Record.cpp
index 1d4ac7103cb76..e40fb63914b61 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -12,20 +12,23 @@
 using namespace clang;
 using namespace clang::interp;
 
-Record::Record(const RecordDecl *Decl, BaseList &&SrcBase

[clang] [Clang][Driver] Revise Cygwin ToolChain to call linker directly (PR #147960)

2025-07-10 Thread via cfe-commits

https://github.com/tyan0 created 
https://github.com/llvm/llvm-project/pull/147960

...so that `libc++`, `compiler-rt`, and `libunwind` can be used by the options: 
`-stdlib=libc++`, `-rtlib=compiler-rt`, and `-unwindlib=libunwind` 
respectively. Along with this change, the test for this driver is also trimmed 
a bit.

>From 06af0fe405f2484491e6e191a96e63b81e219cde Mon Sep 17 00:00:00 2001
From: Takashi Yano 
Date: Thu, 10 Jul 2025 21:55:05 +0900
Subject: [PATCH] [Clang][Driver] Revise Cygwin ToolChain to call linker
 directly

...so that libc++, compiler-rt, and libunwind can be used by the
options: -stdlib=libc++, -rtlib=compiler-rt, and -unwindlib=libunwind
respectively. Along with this change, the test for this driver is also
trimmed a bit.

Signed-off-by: Takashi Yano 
---
 clang/lib/Driver/ToolChain.cpp|   3 +
 clang/lib/Driver/ToolChains/Cygwin.cpp| 289 ++
 clang/lib/Driver/ToolChains/Cygwin.h  |  21 ++
 .../usr/lib/gcc/i686-pc-msys/10/crtend.o  |   0
 .../usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o  |   0
 .../Inputs/basic_cygwin_tree/usr/lib/crt0.o   |   0
 .../usr/lib/gcc/i686-pc-cygwin/10/crtend.o|   0
 .../usr/lib/gcc/x86_64-pc-msys/10/crtend.o|   0
 clang/test/Driver/cygwin.cpp  |  16 +-
 9 files changed, 321 insertions(+), 8 deletions(-)
 create mode 100644 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/i686-pc-msys/10/crtend.o
 create mode 100644 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o
 create mode 100644 clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/crt0.o
 create mode 100644 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/i686-pc-cygwin/10/crtend.o
 create mode 100644 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/x86_64-pc-msys/10/crtend.o

diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3f9b808b2722e..3c9148ee51fd0 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -684,6 +684,8 @@ static StringRef getArchNameForCompilerRTLib(const 
ToolChain &TC,
 StringRef ToolChain::getOSLibName() const {
   if (Triple.isOSDarwin())
 return "darwin";
+  if (Triple.isWindowsCygwinEnvironment())
+return "cygwin";
 
   switch (Triple.getOS()) {
   case llvm::Triple::FreeBSD:
@@ -1504,6 +1506,7 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
   switch (Type) {
   case ToolChain::CST_Libcxx:
 CmdArgs.push_back("-lc++");
+CmdArgs.push_back("-lc++abi");
 if (Args.hasArg(options::OPT_fexperimental_library))
   CmdArgs.push_back("-lc++experimental");
 break;
diff --git a/clang/lib/Driver/ToolChains/Cygwin.cpp 
b/clang/lib/Driver/ToolChains/Cygwin.cpp
index d9c16347daa34..82a88065b0c9d 100644
--- a/clang/lib/Driver/ToolChains/Cygwin.cpp
+++ b/clang/lib/Driver/ToolChains/Cygwin.cpp
@@ -9,6 +9,7 @@
 #include "Cygwin.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/CommonArgs.h"
+#include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/Options.h"
 #include "llvm/Support/Path.h"
@@ -30,6 +31,8 @@ Cygwin::Cygwin(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
   Generic_GCC::PushPPaths(PPaths);
 
   path_list &Paths = getFilePaths();
+  if (GCCInstallation.isValid())
+Paths.push_back(GCCInstallation.getInstallPath().str());
 
   Generic_GCC::AddMultiarchPaths(D, SysRoot, "lib", Paths);
 
@@ -107,3 +110,289 @@ void Cygwin::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + 
"/usr/include/w32api");
 }
+
+static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
+  bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
+  if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
+const Driver &D = TC.getDriver();
+const llvm::opt::OptTable &Opts = D.getOpts();
+StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
+StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie);
+D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
+  }
+  return HasStaticPIE;
+}
+
+static bool getStatic(const ArgList &Args) {
+  return Args.hasArg(options::OPT_static) &&
+  !Args.hasArg(options::OPT_static_pie);
+}
+
+void cygwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+  const InputInfo &Output,
+  const InputInfoList &Inputs,
+  const ArgList &Args,
+  const char *LinkingOutput) const {
+  const auto &ToolChain = static_cast(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+
+  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+  const bool IsVE = ToolChain.getTriple().isVE();
+  const bool IsStaticPIE = getStaticPIE(Args, ToolChain

[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 


steakhal wrote:

BTW wouldn't this patch break the semantics of `freopen`? That one should 
invalidate the file ptr, right?
Could you demonstrate this?

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


[clang] [Clang] fixed false positive redeclaration error for using enum in nested scopes (PR #147711)

2025-07-10 Thread Oleksandr T. via cfe-commits

https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/147711

>From 20b9d9bb16f82120cee41bf6a59d3bfa34aa0d3b Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk 
Date: Wed, 9 Jul 2025 15:16:45 +0300
Subject: [PATCH] [Clang] fixed false positive redeclaration error for using
 enum in nested scopes

---
 clang/docs/ReleaseNotes.rst |  4 +++-
 clang/lib/Sema/SemaDeclCXX.cpp  |  2 +-
 clang/test/SemaCXX/cxx20-using-enum.cpp | 14 ++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 57a94242c9e61..086f0fce4975f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -770,8 +770,10 @@ Bug Fixes in This Version
 - In C23, something like ``[[/*possible attributes*/]];`` is an attribute
   declaration, not a statement. So it is not allowed by the syntax in places
   where a statement is required, specifically as the secondary block of a
-  selection or iteration statement. This differs from C++, since C++ allows 
+  selection or iteration statement. This differs from C++, since C++ allows
   declaration statements. Clang now emits a warning for these patterns. 
(#GH141659)
+- Fixed false positives for redeclaration errors of using enum in
+  nested scopes. (#GH147495)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a49a8abb677c5..5cc92ebb0171f 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13308,7 +13308,7 @@ NamedDecl *Sema::BuildUsingEnumDeclaration(Scope *S, 
AccessSpecifier AS,
 LookupResult Previous(*this, UsingEnumName, LookupUsingDeclName,
   RedeclarationKind::ForVisibleRedeclaration);
 
-LookupName(Previous, S);
+LookupQualifiedName(Previous, CurContext);
 
 for (NamedDecl *D : Previous)
   if (UsingEnumDecl *UED = dyn_cast(D))
diff --git a/clang/test/SemaCXX/cxx20-using-enum.cpp 
b/clang/test/SemaCXX/cxx20-using-enum.cpp
index 14ef4b29925a1..775b65c5a8d8e 100644
--- a/clang/test/SemaCXX/cxx20-using-enum.cpp
+++ b/clang/test/SemaCXX/cxx20-using-enum.cpp
@@ -274,4 +274,18 @@ void f(int a) {
 }
 }
 
+namespace GH147495 {
+struct S {
+  enum class E { A };
+  using enum E;
+
+  struct S1 {
+using enum E;
+  };
+
+  struct S2 {
+using E::A;
+  };
+};
+}
 #endif

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


[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)

2025-07-10 Thread Corentin Jabot via cfe-commits

cor3ntin wrote:

@antangelo @hokein ping

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


[clang-tools-extra] [clang-tidy] Add new check: `readability-use-concise-preprocessor-directives` (PR #146830)

2025-07-10 Thread Carlos Galvez via cfe-commits

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

LGTM!

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


[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits

erichkeane wrote:

> avior due to the silent stripping. Given that an atomic type is not the same 
> as its underlying type (in terms of ABI or semantics) I think we should 
> diagnose the behavior with at least a warning. I could even be convinced it 
> should be a warning which defaults to an error because this is just weird.

Yeah, I 100% agree with that.  Warn-as-error is reasonable here IMO (as are ANY 
qualifiers?, but more so for atomic)

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


[clang] Fix scope of typedefs present inside a template class (PR #146729)

2025-07-10 Thread via cfe-commits

https://github.com/ykhatav updated 
https://github.com/llvm/llvm-project/pull/146729

>From cfd949c1a70ae25c5c35e48d92166b45aef63654 Mon Sep 17 00:00:00 2001
From: "Khatavkar, Yashasvi" 
Date: Wed, 2 Jul 2025 08:23:14 -0700
Subject: [PATCH 1/3] Fix scoping of dependent typedefs

---
 clang/lib/CodeGen/CGDebugInfo.cpp  | 10 +-
 .../dependent-template-type-scope.cpp  | 18 ++
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/dependent-template-type-scope.cpp

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index ee5e3d68a5ffa..fb70b9fd13d31 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4170,9 +4170,17 @@ llvm::DICompositeType 
*CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
 break;
   }
-
+ auto *CTSD = dyn_cast(Ty->getDecl());
+   if(CTSD) {
+   CXXRecordDecl *TemplateDecl =
+CTSD->getSpecializedTemplate()->getTemplatedDecl();
+   RegionMap[TemplateDecl].reset(RealDecl);
+   TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
+   }
+ else {
   RegionMap[Ty->getDecl()].reset(RealDecl);
   TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
+}
 
   if (const auto *TSpecial = dyn_cast(RD))
 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
diff --git a/clang/test/CodeGenCXX/dependent-template-type-scope.cpp 
b/clang/test/CodeGenCXX/dependent-template-type-scope.cpp
new file mode 100644
index 0..3b2e57b700936
--- /dev/null
+++ b/clang/test/CodeGenCXX/dependent-template-type-scope.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm 
-debug-info-kind=standalone  -o - %s | FileCheck %s
+
+struct X {
+  typedef int inside;
+  inside i;
+};
+
+template 
+struct Y {
+  typedef int outside;
+  outside o;
+};
+
+X x;
+Y<> y;
+
+// CHECK: ![[Y:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, 
name: "Y", {{.*}}identifier: "_ZTS1YIiE")
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "outside", scope: ![[Y]],

>From d1404fa7e2ba716e2edfcb0468d06a6028297eda Mon Sep 17 00:00:00 2001
From: "Khatavkar, Yashasvi" 
Date: Wed, 2 Jul 2025 08:24:26 -0700
Subject: [PATCH 2/3] Apply clang-format

---
 clang/lib/CodeGen/CGDebugInfo.cpp | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index fb70b9fd13d31..a08f15418ea0b 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4170,17 +4170,16 @@ llvm::DICompositeType 
*CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
 break;
   }
- auto *CTSD = dyn_cast(Ty->getDecl());
-   if(CTSD) {
-   CXXRecordDecl *TemplateDecl =
-CTSD->getSpecializedTemplate()->getTemplatedDecl();
-   RegionMap[TemplateDecl].reset(RealDecl);
-   TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
-   }
- else {
-  RegionMap[Ty->getDecl()].reset(RealDecl);
-  TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
-}
+  auto *CTSD = dyn_cast(Ty->getDecl());
+  if (CTSD) {
+CXXRecordDecl *TemplateDecl =
+CTSD->getSpecializedTemplate()->getTemplatedDecl();
+RegionMap[TemplateDecl].reset(RealDecl);
+TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
+  } else {
+RegionMap[Ty->getDecl()].reset(RealDecl);
+TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
+  }
 
   if (const auto *TSpecial = dyn_cast(RD))
 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),

>From 10eda06ec75bed8395e697eb59c5ca58f5efa849 Mon Sep 17 00:00:00 2001
From: "Khatavkar, Yashasvi" 
Date: Thu, 10 Jul 2025 06:28:49 -0700
Subject: [PATCH 3/3] address review comments

---
 clang/lib/CodeGen/CGDebugInfo.cpp   | 3 +--
 clang/test/CodeGenCXX/dependent-template-type-scope.cpp | 6 --
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index a08f15418ea0b..8be9a296a9e4b 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4175,11 +4175,10 @@ llvm::DICompositeType 
*CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 CXXRecordDecl *TemplateDecl =
 CTSD->getSpecializedTemplate()->getTemplatedDecl();
 RegionMap[TemplateDecl].reset(RealDecl);
-TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
   } else {
 RegionMap[Ty->getDecl()].reset(RealDecl);
-TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
   }
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
 
   if (const auto *TSpecial = dyn_cast(RD))
 DBuilder.replaceArrays(RealDecl, llvm::DINodeArray(),
diff --git a/clang/test

[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits


@@ -2022,8 +2022,14 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl 
*D) {
 DeclarationName());
   if (!NewTI || SemaRef.CheckEnumUnderlyingType(NewTI))
 Enum->setIntegerType(SemaRef.Context.IntTy);
-  else
-Enum->setIntegerTypeSourceInfo(NewTI);
+  else {
+// If the underlying type is atomic, we need to adjust the type before
+// continuing. See C23 6.7.3.3p5 and Sema::ActOnTag().
+if (NewTI->getType()->isAtomicType())

erichkeane wrote:

FIXME here would be nice too.

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


[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits

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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 



@@ -1054,10 +1054,26 @@ const VarRegion *MemRegionManager::getVarRegion(const 
VarDecl *D,
 assert(!Ty.isNull());
 if (Ty.isConstQualified()) {
   sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-} else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
-  sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
 } else {
-  sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  StringRef N = D->getNameAsString();
+  QualType FILETy = D->getASTContext().getFILEType();
+  if (!FILETy.isNull())
+FILETy = FILETy.getCanonicalType();
+  Ty = Ty.getCanonicalType();
+  bool IsStdStreamVar = Ty->isPointerType() &&
+Ty->getPointeeType() == FILETy &&
+(N == "stdin" || N == "stdout" || N == "stderr");
+  // Pointer value of C standard streams is usually not modified by calls
+  // to functions declared in system headers. This means that they should
+  // not get invalidated by calls to functions declared in system headers,
+  // so they are placed in the global internal space, which is not
+  // invalidated by calls to functions declared in system headers.
+  if (Ctx.getSourceManager().isInSystemHeader(D->getLocation()) &&
+  !IsStdStreamVar) {
+sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
+  } else {
+sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  }

steakhal wrote:

So, if I understand this code correctly, we want to bless `std` streams to not 
get invalidated even on calls to fns of system headers, right?

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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 



@@ -519,14 +519,53 @@ void reopen_std_stream(void) {
   if (!fp) return;
 
   stdout = fp; // Let's make them alias.
-  clang_analyzer_eval(fp == oldStdout); // expected-warning {{UNKNOWN}}
-  clang_analyzer_eval(fp == stdout);// expected-warning {{TRUE}} 
no-FALSE
-  clang_analyzer_eval(oldStdout == stdout); // expected-warning {{UNKNOWN}}
+  clang_analyzer_eval(fp == oldStdout); // expected-warning {{FALSE}}
+  clang_analyzer_eval(fp == stdout);// expected-warning {{TRUE}}
+  clang_analyzer_eval(oldStdout == stdout); // expected-warning {{FALSE}}
 }
 
 void only_success_path_does_not_alias_with_stdout(void) {
   if (stdout) return;
   FILE *f = fopen("/tmp/foof", "r"); // no-crash
+  clang_analyzer_eval(f == 0);// expected-warning {{TRUE}} expected-warning 
{{FALSE}}
   if (!f) return;
   fclose(f);
 }
+
+extern void do_something();
+
+void test_no_invalidate_at_system_call(int use_std) {
+  FILE *fd;
+  char *buf;
+
+  if (use_std) {
+fd = stdin;
+  } else {
+if ((fd = fopen("x/y/z", "r")) == NULL)
+  return;
+
+clang_analyzer_eval(fd == stdin); // expected-warning{{FALSE}}
+buf = (char *)malloc(100);
+clang_analyzer_eval(fd == stdin); // expected-warning{{FALSE}}
+  }
+
+  if (fd != stdin)
+fclose(fd);
+}

steakhal wrote:

If I read this correctly, the test intends to check if the `stdin` system 
global would not get invalidated after calling `malloc()` (or for that matter 
any other opaque system header fn), right?

Could we simplify this into:
```c++
auto orig_stdin = stdin;
free(malloc(10)); // calling some opaque system fns
clang_analyzer_eval(stdin == orig_stdin); // TRUE
```

Same suggestion goes to the next example too.

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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 



@@ -1054,10 +1054,26 @@ const VarRegion *MemRegionManager::getVarRegion(const 
VarDecl *D,
 assert(!Ty.isNull());
 if (Ty.isConstQualified()) {
   sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-} else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
-  sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
 } else {
-  sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  StringRef N = D->getNameAsString();
+  QualType FILETy = D->getASTContext().getFILEType();
+  if (!FILETy.isNull())
+FILETy = FILETy.getCanonicalType();
+  Ty = Ty.getCanonicalType();
+  bool IsStdStreamVar = Ty->isPointerType() &&
+Ty->getPointeeType() == FILETy &&
+(N == "stdin" || N == "stdout" || N == "stderr");

steakhal wrote:

All this work is basically done to set the `IsStdStreamVar`.
This seems pretty complicated and not strictly necessary for `getVarRegion` 
itself.
This prompts me if we should hoist this into a helper function that we can call 
here. WDYT?

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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 


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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 



@@ -1054,10 +1054,26 @@ const VarRegion *MemRegionManager::getVarRegion(const 
VarDecl *D,
 assert(!Ty.isNull());
 if (Ty.isConstQualified()) {
   sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
-} else if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
-  sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
 } else {
-  sReg = getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind);
+  StringRef N = D->getNameAsString();

steakhal wrote:

`getNameAsString()` returns a `std::string` prvalue, thus we bind a view to 
this temporary that gets immediately dangling after the full-expression.

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


[clang] [clang][analyzer] Add C standard streams to the internal memory space (PR #147766)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Balázs_Kéri?= 
Message-ID:
In-Reply-To: 


https://github.com/steakhal requested changes to this pull request.

I'd suggest rephrasing the PR to something more descriptive: Preserve stdin and 
friends on system calls

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


[clang] [Clang][Driver] Revise Cygwin ToolChain to call linker directly (PR #147960)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: None (tyan0)


Changes

...so that `libc++`, `compiler-rt`, and `libunwind` can be used by the options: 
`-stdlib=libc++`, `-rtlib=compiler-rt`, and `-unwindlib=libunwind` 
respectively. Along with this change, the test for this driver is also trimmed 
a bit.

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


9 Files Affected:

- (modified) clang/lib/Driver/ToolChain.cpp (+3) 
- (modified) clang/lib/Driver/ToolChains/Cygwin.cpp (+289) 
- (modified) clang/lib/Driver/ToolChains/Cygwin.h (+21) 
- (added) 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/i686-pc-msys/10/crtend.o
 () 
- (added) 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o
 () 
- (added) clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/crt0.o () 
- (added) 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/i686-pc-cygwin/10/crtend.o
 () 
- (added) 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/x86_64-pc-msys/10/crtend.o
 () 
- (modified) clang/test/Driver/cygwin.cpp (+8-8) 


``diff
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3f9b808b2722e..3c9148ee51fd0 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -684,6 +684,8 @@ static StringRef getArchNameForCompilerRTLib(const 
ToolChain &TC,
 StringRef ToolChain::getOSLibName() const {
   if (Triple.isOSDarwin())
 return "darwin";
+  if (Triple.isWindowsCygwinEnvironment())
+return "cygwin";
 
   switch (Triple.getOS()) {
   case llvm::Triple::FreeBSD:
@@ -1504,6 +1506,7 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
   switch (Type) {
   case ToolChain::CST_Libcxx:
 CmdArgs.push_back("-lc++");
+CmdArgs.push_back("-lc++abi");
 if (Args.hasArg(options::OPT_fexperimental_library))
   CmdArgs.push_back("-lc++experimental");
 break;
diff --git a/clang/lib/Driver/ToolChains/Cygwin.cpp 
b/clang/lib/Driver/ToolChains/Cygwin.cpp
index d9c16347daa34..82a88065b0c9d 100644
--- a/clang/lib/Driver/ToolChains/Cygwin.cpp
+++ b/clang/lib/Driver/ToolChains/Cygwin.cpp
@@ -9,6 +9,7 @@
 #include "Cygwin.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/CommonArgs.h"
+#include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/Options.h"
 #include "llvm/Support/Path.h"
@@ -30,6 +31,8 @@ Cygwin::Cygwin(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
   Generic_GCC::PushPPaths(PPaths);
 
   path_list &Paths = getFilePaths();
+  if (GCCInstallation.isValid())
+Paths.push_back(GCCInstallation.getInstallPath().str());
 
   Generic_GCC::AddMultiarchPaths(D, SysRoot, "lib", Paths);
 
@@ -107,3 +110,289 @@ void Cygwin::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + 
"/usr/include/w32api");
 }
+
+static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
+  bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
+  if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
+const Driver &D = TC.getDriver();
+const llvm::opt::OptTable &Opts = D.getOpts();
+StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
+StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie);
+D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
+  }
+  return HasStaticPIE;
+}
+
+static bool getStatic(const ArgList &Args) {
+  return Args.hasArg(options::OPT_static) &&
+  !Args.hasArg(options::OPT_static_pie);
+}
+
+void cygwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+  const InputInfo &Output,
+  const InputInfoList &Inputs,
+  const ArgList &Args,
+  const char *LinkingOutput) const {
+  const auto &ToolChain = static_cast(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+
+  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+  const bool IsVE = ToolChain.getTriple().isVE();
+  const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
+  const bool IsStatic = getStatic(Args);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_s))
+CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-m");
+  switch (ToolChain.getArch()) {
+  case llvm::Triple::x86:
+CmdArgs.push_back("i386pe");
+break;
+  case llvm::Triple::x

[clang] [Clang][Driver] Revise Cygwin ToolChain to call linker directly (PR #147960)

2025-07-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (tyan0)


Changes

...so that `libc++`, `compiler-rt`, and `libunwind` can be used by the options: 
`-stdlib=libc++`, `-rtlib=compiler-rt`, and `-unwindlib=libunwind` 
respectively. Along with this change, the test for this driver is also trimmed 
a bit.

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


9 Files Affected:

- (modified) clang/lib/Driver/ToolChain.cpp (+3) 
- (modified) clang/lib/Driver/ToolChains/Cygwin.cpp (+289) 
- (modified) clang/lib/Driver/ToolChains/Cygwin.h (+21) 
- (added) 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/i686-pc-msys/10/crtend.o
 () 
- (added) 
clang/test/Driver/Inputs/basic_cross_cygwin_tree/usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o
 () 
- (added) clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/crt0.o () 
- (added) 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/i686-pc-cygwin/10/crtend.o
 () 
- (added) 
clang/test/Driver/Inputs/basic_cygwin_tree/usr/lib/gcc/x86_64-pc-msys/10/crtend.o
 () 
- (modified) clang/test/Driver/cygwin.cpp (+8-8) 


``diff
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3f9b808b2722e..3c9148ee51fd0 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -684,6 +684,8 @@ static StringRef getArchNameForCompilerRTLib(const 
ToolChain &TC,
 StringRef ToolChain::getOSLibName() const {
   if (Triple.isOSDarwin())
 return "darwin";
+  if (Triple.isWindowsCygwinEnvironment())
+return "cygwin";
 
   switch (Triple.getOS()) {
   case llvm::Triple::FreeBSD:
@@ -1504,6 +1506,7 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
   switch (Type) {
   case ToolChain::CST_Libcxx:
 CmdArgs.push_back("-lc++");
+CmdArgs.push_back("-lc++abi");
 if (Args.hasArg(options::OPT_fexperimental_library))
   CmdArgs.push_back("-lc++experimental");
 break;
diff --git a/clang/lib/Driver/ToolChains/Cygwin.cpp 
b/clang/lib/Driver/ToolChains/Cygwin.cpp
index d9c16347daa34..82a88065b0c9d 100644
--- a/clang/lib/Driver/ToolChains/Cygwin.cpp
+++ b/clang/lib/Driver/ToolChains/Cygwin.cpp
@@ -9,6 +9,7 @@
 #include "Cygwin.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/CommonArgs.h"
+#include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/Options.h"
 #include "llvm/Support/Path.h"
@@ -30,6 +31,8 @@ Cygwin::Cygwin(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
   Generic_GCC::PushPPaths(PPaths);
 
   path_list &Paths = getFilePaths();
+  if (GCCInstallation.isValid())
+Paths.push_back(GCCInstallation.getInstallPath().str());
 
   Generic_GCC::AddMultiarchPaths(D, SysRoot, "lib", Paths);
 
@@ -107,3 +110,289 @@ void Cygwin::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + 
"/usr/include/w32api");
 }
+
+static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
+  bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
+  if (HasStaticPIE && Args.hasArg(options::OPT_no_pie)) {
+const Driver &D = TC.getDriver();
+const llvm::opt::OptTable &Opts = D.getOpts();
+StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
+StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie);
+D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName;
+  }
+  return HasStaticPIE;
+}
+
+static bool getStatic(const ArgList &Args) {
+  return Args.hasArg(options::OPT_static) &&
+  !Args.hasArg(options::OPT_static_pie);
+}
+
+void cygwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+  const InputInfo &Output,
+  const InputInfoList &Inputs,
+  const ArgList &Args,
+  const char *LinkingOutput) const {
+  const auto &ToolChain = static_cast(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+
+  const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+  const bool IsVE = ToolChain.getTriple().isVE();
+  const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
+  const bool IsStatic = getStatic(Args);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_s))
+CmdArgs.push_back("-s");
+
+  CmdArgs.push_back("-m");
+  switch (ToolChain.getArch()) {
+  case llvm::Triple::x86:
+CmdArgs.push_back("i386pe");
+break;
+  case llvm::Triple::x86_64:

[clang] [Clang][Driver] Revise Cygwin ToolChain to call linker directly (PR #147960)

2025-07-10 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [clang-tools-extra] [clang] Improve nested name specifier AST representation (PR #147835)

2025-07-10 Thread Erich Keane via cfe-commits

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


[clang] [Clang][Sema] Diagnose explicit specializations with object parameters that do not match their primary template (PR #89300)

2025-07-10 Thread Corentin Jabot via cfe-commits

cor3ntin wrote:

@sdkrystian are you able to complete this?

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


[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits


@@ -17563,6 +17573,16 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind 
TUK, SourceLocation KWLoc,
   UPPC_FixedUnderlyingType))
 EnumUnderlying = Context.IntTy.getTypePtr();
 
+  // If the underlying type is atomic, we need to adjust the type before
+  // continuing. This only happens in the case we stored a TypeSourceInfo
+  // into EnumUnderlying because the other cases are error recovery up to
+  // this point. But because it's not possible to gin up a TypeSourceInfo
+  // for a non-atomic type from an atomic one, we'll store into the Type
+  // field instead.
+  if (TypeSourceInfo *TI = dyn_cast(EnumUnderlying);
+  TI && TI->getType()->isAtomicType())
+EnumUnderlying = TI->getType().getAtomicUnqualifiedType().getTypePtr();

erichkeane wrote:

Ah, gross... but yeah, I guess so.  Can I have a 'fixme' on it?  Something 
like, "we CULD just unconditionally strip this but it loses the 
TypeSourceInfo... someday figure out how to do that"

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


[clang] fix: replace report_fatal_error with Diags and exit (PR #147959)

2025-07-10 Thread via cfe-commits

hstk30-hw wrote:

Need a test case at least.

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


[clang] [C23] Accept an _Atomic underlying type (PR #147802)

2025-07-10 Thread Erich Keane via cfe-commits

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

Would like a pair of fixmes, but this is otherwise good to me.

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


[clang] [libcxx] [Clang] Diagnose forming references to nullptr (PR #143667)

2025-07-10 Thread Corentin Jabot via cfe-commits

https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/143667

>From b54f67ad5755bff3959369f8cd81022abd5dfe22 Mon Sep 17 00:00:00 2001
From: Corentin Jabot 
Date: Wed, 2 Jul 2025 15:55:41 +0200
Subject: [PATCH 1/4] Diagnose all dereferences of null pointers

---
 clang/docs/ReleaseNotes.rst   |  1 +
 .../include/clang/Basic/DiagnosticASTKinds.td |  9 +-
 clang/lib/AST/ByteCode/State.h|  1 +
 clang/lib/AST/ExprConstant.cpp| 87 +++
 clang/test/AST/ByteCode/complex.cpp   |  5 +-
 clang/test/AST/ByteCode/const-eval.c  |  2 +
 clang/test/AST/ByteCode/cxx11.cpp |  4 +-
 clang/test/AST/ByteCode/records.cpp   | 10 ++-
 clang/test/CXX/drs/cwg14xx.cpp|  2 +
 clang/test/CXX/expr/expr.const/p2-0x.cpp  |  8 +-
 clang/test/Sema/const-eval.c  |  5 +-
 .../SemaCXX/constant-expression-cxx11.cpp |  4 +-
 .../SemaCXX/constant-expression-cxx14.cpp | 56 +++-
 .../SemaCXX/constant-expression-cxx2a.cpp |  2 +-
 .../SemaCXX/constexpr-backtrace-limit.cpp |  4 +-
 .../range.zip/iterator/increment.pass.cpp |  4 +-
 16 files changed, 164 insertions(+), 40 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3d893e0aa8e2c..60e7def16d6d2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -896,6 +896,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when constant evaluating some explicit object member 
assignment operators. (#GH142835)
 - Fixed an access checking bug when substituting into concepts (#GH115838)
 - Fix a bug where private access specifier of overloaded function not 
respected. (#GH107629)
+- Diagnose binding a reference to ``*nullptr`` during constant evaluation. 
(#GH48665)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index e3be4ab47633d..7b27fa7e256a6 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -174,10 +174,11 @@ def note_constexpr_heap_alloc_limit_exceeded : Note<
 def note_constexpr_this : Note<
   "%select{|implicit }0use of 'this' pointer is only allowed within the "
   "evaluation of a call to a 'constexpr' member function">;
-def access_kind : TextSubstitution<
-  "%select{read of|read of|assignment to|increment of|decrement of|"
-  "member call on|dynamic_cast of|typeid applied to|construction of|"
-  "destruction of|read of}0">;
+def access_kind
+: TextSubstitution<
+  "%select{read of|read of|assignment to|increment of|decrement of|"
+  "member call on|dynamic_cast of|typeid applied to|construction of|"
+  "destruction of|read of|read of}0">;
 def access_kind_subobject : TextSubstitution<
   "%select{read of|read of|assignment to|increment of|decrement of|"
   "member call on|dynamic_cast of|typeid applied to|"
diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h
index 9a81fa6b7d220..6fc33222ac956 100644
--- a/clang/lib/AST/ByteCode/State.h
+++ b/clang/lib/AST/ByteCode/State.h
@@ -35,6 +35,7 @@ enum AccessKinds {
   AK_Construct,
   AK_Destroy,
   AK_IsWithinLifetime,
+  AK_Dereference
 };
 
 /// The order of this enum is important for diagnostics.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index bf9208763b1ab..7b79f2bec1dea 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1529,7 +1529,7 @@ CallStackFrame::~CallStackFrame() {
 
 static bool isRead(AccessKinds AK) {
   return AK == AK_Read || AK == AK_ReadObjectRepresentation ||
- AK == AK_IsWithinLifetime;
+ AK == AK_IsWithinLifetime || AK == AK_Dereference;
 }
 
 static bool isModification(AccessKinds AK) {
@@ -1540,6 +1540,7 @@ static bool isModification(AccessKinds AK) {
   case AK_DynamicCast:
   case AK_TypeId:
   case AK_IsWithinLifetime:
+  case AK_Dereference:
 return false;
   case AK_Assign:
   case AK_Increment:
@@ -1558,7 +1559,7 @@ static bool isAnyAccess(AccessKinds AK) {
 /// Is this an access per the C++ definition?
 static bool isFormalAccess(AccessKinds AK) {
   return isAnyAccess(AK) && AK != AK_Construct && AK != AK_Destroy &&
- AK != AK_IsWithinLifetime;
+ AK != AK_IsWithinLifetime && AK != AK_Dereference;
 }
 
 /// Is this kind of axcess valid on an indeterminate object value?
@@ -1571,6 +1572,7 @@ static bool isValidIndeterminateAccess(AccessKinds AK) {
 return false;
 
   case AK_IsWithinLifetime:
+  case AK_Dereference:
   case AK_ReadObjectRepresentation:
   case AK_Assign:
   case AK_Construct:
@@ -4424,8 +4426,9 @@ static CompleteObject findCompleteObject(EvalInfo &Info, 
const Expr *E,
   ConstexprVar = VD->isConstexpr();
 
 // Unless we're looking at a local variable or argument in a constexpr 
call,
-// the variable we'r

[clang-tools-extra] [clang-tidy] Add new check `llvm-prefer-static-over-anonymous-namespace` (PR #142839)

2025-07-10 Thread Carlos Galvez via cfe-commits

carlosgalvezp wrote:

I agree with the sentiment that it would be good to have one single check 
enforcing either one style or the other, possibly a "readability" type of 
check. Then llvm could be an alias with the proper config. 

I suppose this patch does not impede further refactoring if we want to go in 
that direction in the future.

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


[clang] [llvm] [OpenMP][clang] 6.0: parsing/sema for message/severity for parallel (PR #146093)

2025-07-10 Thread Robert Imschweiler via cfe-commits

https://github.com/ro-i updated https://github.com/llvm/llvm-project/pull/146093

>From b01bdf107f80f0f023270326e4a16b1dcadd69d8 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler 
Date: Fri, 27 Jun 2025 10:07:01 -0500
Subject: [PATCH 1/2] [OpenMP][clang] 6.0: parsing/sema for message/severity
 for parallel

Implement parsing and semantic analysis support for the message and
severity clauses that have been added to the parallel directive in
OpenMP 6.0, 12.1.
---
 clang/include/clang/AST/OpenMPClause.h|  6 +-
 clang/lib/Sema/SemaOpenMP.cpp |  4 +-
 clang/test/OpenMP/parallel_ast_print.cpp  | 24 ++---
 .../test/OpenMP/parallel_message_messages.cpp | 89 +++
 .../OpenMP/parallel_severity_messages.cpp | 70 +++
 llvm/include/llvm/Frontend/OpenMP/OMP.td  |  2 +
 6 files changed, 179 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/OpenMP/parallel_message_messages.cpp
 create mode 100644 clang/test/OpenMP/parallel_severity_messages.cpp

diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index c6f99fb21a0f0..8b602f49aefde 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1775,7 +1775,8 @@ class OMPAtClause final : public OMPClause {
   }
 };
 
-/// This represents 'severity' clause in the '#pragma omp error' directive
+/// This represents the 'severity' clause in the '#pragma omp error' and the
+/// '#pragma omp parallel' directives.
 ///
 /// \code
 /// #pragma omp error severity(fatal)
@@ -1855,7 +1856,8 @@ class OMPSeverityClause final : public OMPClause {
   }
 };
 
-/// This represents 'message' clause in the '#pragma omp error' directive
+/// This represents the 'message' clause in the '#pragma omp error' and the
+/// '#pragma omp parallel' directives.
 ///
 /// \code
 /// #pragma omp error message("GNU compiler required.")
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a30acbe9a4bca..4ecc9b0d4c5c8 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6620,6 +6620,8 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
   case OMPC_affinity:
   case OMPC_bind:
   case OMPC_filter:
+  case OMPC_severity:
+  case OMPC_message:
 continue;
   case OMPC_allocator:
   case OMPC_flush:
@@ -6637,8 +6639,6 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
   case OMPC_match:
   case OMPC_when:
   case OMPC_at:
-  case OMPC_severity:
-  case OMPC_message:
   default:
 llvm_unreachable("Unexpected clause");
   }
diff --git a/clang/test/OpenMP/parallel_ast_print.cpp 
b/clang/test/OpenMP/parallel_ast_print.cpp
index 948baaff30d89..15439ea31215a 100644
--- a/clang/test/OpenMP/parallel_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_ast_print.cpp
@@ -173,13 +173,13 @@ T tmain(T argc, T *argv) {
   foo();
 #endif
 #ifdef OMP60
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared 
(d) if (parallel:argc > 0) num_threads(strict: C) copyin(S::TS, thrp) 
proc_bind(primary) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared 
(d) if (parallel:argc > 0) num_threads(strict: C) copyin(S::TS, thrp) 
proc_bind(primary) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10]) 
message("msg") severity(fatal)
   foo();
 #endif
 #pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, 
arr[0:C][:argc]) reduction(default, && : g) reduction(task,+:argc)
   foo();
 #ifdef OMP60
-#pragma omp parallel if (C) num_threads(strict: s) proc_bind(close) 
reduction(^:e, f, arr[0:C][:argc]) reduction(default, && : g) 
reduction(task,+:argc)
+#pragma omp parallel if (C) num_threads(strict: s) proc_bind(close) 
reduction(^:e, f, arr[0:C][:argc]) reduction(default, && : g) 
reduction(task,+:argc) message("msg") severity(warning)
   foo();
 #endif
   return 0;
@@ -196,11 +196,11 @@ T tmain(T argc, T *argv) {
 // CHECK-NEXT: foo()
 // OMP51-NEXT: #pragma omp parallel default(none) private(argc,b) 
firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) 
copyin(S::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) 
reduction(max: e,arr[:C][0:10])
 // OMP51-NEXT: foo()
-// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) 
firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: C) 
copyin(S::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) 
reduction(max: e,arr[:C][0:10])
+// OMP60-NEXT: #pragma omp parallel default(none) private(argc,b) 
firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(strict: C) 
copyin(S::TS,thrp) proc_bind(primary) reduction(+: c,arr1[argc]) 
reduction(max: e,arr[:C][0:10]) message("msg") severity(fatal)
 // OMP60-NEXT: foo()
 // CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) 
reduction(^: e,f,arr[0:C][:argc

[clang-tools-extra] [clang-tidy] Add new check `llvm-prefer-static-over-anonymous-namespace` (PR #142839)

2025-07-10 Thread Carlos Galvez via cfe-commits

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


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


[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 



@@ -112,26 +112,35 @@ class CheckerRegistry {
 return true;
   }
 
-public:
-  /// Adds a checker to the registry. Use this non-templated overload when your
-  /// checker requires custom initialization.
-  void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn,
+  /// Adds a checker to the registry. This private, most general variant is
+  /// intended for loading the checker definitions from `Checkers.td`.
+  /// FIXME: The checker registry should not bother with loading `DocsUri`
+  /// because it is (as of now) never queried from the checker registry.
+  void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn,
   StringRef FullName, StringRef Desc, StringRef DocsUri,
   bool IsHidden);
 
-  /// Adds a checker to the registry. Use this templated overload when your
-  /// checker does not require any custom initialization.
-  /// This function isn't really needed and probably causes more headaches than
-  /// the tiny convenience that it provides, but external plugins might use it,
-  /// and there isn't a strong incentive to remove it.
+public:
+  /// Adds a checker to the registry. Use this for a checker defined in a
+  /// plugin if it requires custom registration functions.
+  void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn,
+  StringRef FullName, StringRef Desc, bool IsHidden = false) {
+addChecker(Fn, Sfn, FullName, Desc, "NoDocsUri", IsHidden);
+  }
+
+  /// Adds a checker to the registry. Use this for a checker defined in a
+  /// plugin if it doesn't require custom registration functions.
   template 
-  void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri,
-  bool IsHidden = false) {
-// Avoid MSVC's Compiler Error C2276:
-// http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
+  void addChecker(StringRef FullName, StringRef Desc, bool IsHidden = false) {
 addChecker(&CheckerRegistry::initializeManager,
-   &CheckerRegistry::returnTrue, FullName, Desc, DocsUri,
-   IsHidden);
+   &CheckerRegistry::returnTrue, FullName, Desc,

steakhal wrote:

just a random comment: I never understood why does `returnTrue` depend on type 
`T` if it just returns true xD

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


[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Don=C3=A1t?= Nagy ,
=?utf-8?q?Don=C3=A1t?= Nagy 
Message-ID:
In-Reply-To: 



@@ -3,12 +3,16 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
 
+// This simple plugin is used by clang/test/Analysis/checker-plugins.c
+// to test the use of a checker that is defined in a plugin.
+
 using namespace clang;
 using namespace ento;
 
 namespace {
 class MainCallChecker : public Checker> {
-  mutable std::unique_ptr BT;
+
+  BugType BT{this, "call to main", "example analyzer plugin"};

steakhal wrote:

Can you make this const?

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


[clang] [analyzer] Prettify checker registration and unittest code (PR #147797)

2025-07-10 Thread Balazs Benics via cfe-commits
=?utf-8?q?Donát?= Nagy ,
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 



@@ -112,26 +112,35 @@ class CheckerRegistry {
 return true;
   }
 
-public:
-  /// Adds a checker to the registry. Use this non-templated overload when your
-  /// checker requires custom initialization.
-  void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn,
+  /// Adds a checker to the registry. This private, most general variant is

steakhal wrote:

```suggestion
  /// Adds a checker to the registry.
  /// This private, most general overload is...
```

Could you make the `Adds a checker to the registry.` the first and dedicated 
line of all of the overloads?
That would make these stand out thus easier to read.

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


  1   2   3   4   5   >