[clang] [llvm] [LoongArch] Support la664 (PR #100068)

2024-07-23 Thread via cfe-commits

https://github.com/Ami-zhang updated 
https://github.com/llvm/llvm-project/pull/100068

>From 97051ad2c670bb0b8ae2160b032b7ab95a7b43ea Mon Sep 17 00:00:00 2001
From: Ami-zhang 
Date: Mon, 29 Apr 2024 16:58:15 +0800
Subject: [PATCH] [LoongArch] Support la664

A new ProcessorModel called `la664` is defined in LoongArch.td
to support `-march/-mtune=la664`.
---
 clang/test/Driver/loongarch-march.c   | 11 +++
 clang/test/Driver/loongarch-mtune.c   |  5 +
 clang/test/Preprocessor/init-loongarch.c  |  8 
 .../llvm/TargetParser/LoongArchTargetParser.def   |  2 ++
 .../include/llvm/TargetParser/LoongArchTargetParser.h |  3 +++
 llvm/lib/Target/LoongArch/LoongArch.td|  7 +++
 llvm/lib/TargetParser/Host.cpp|  2 ++
 llvm/test/CodeGen/LoongArch/cpus.ll   |  5 +
 8 files changed, 43 insertions(+)

diff --git a/clang/test/Driver/loongarch-march.c 
b/clang/test/Driver/loongarch-march.c
index d06da72a755cb..ad173539cb0c0 100644
--- a/clang/test/Driver/loongarch-march.c
+++ b/clang/test/Driver/loongarch-march.c
@@ -6,6 +6,8 @@
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -fsyntax-only %s -### 2>&1 
| \
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1-LA664
 // RUN: %clang --target=loongarch64 -march=loongarch64 -S -emit-llvm %s -o - | 
\
 // RUN:   FileCheck %s --check-prefix=IR-LOONGARCH64
 // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \
@@ -14,6 +16,8 @@
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IR-LA664
 
 // CC1-LOONGARCH64: "-target-cpu" "loongarch64"
 // CC1-LOONGARCH64-NOT: "-target-feature"
@@ -39,10 +43,17 @@
 // CC1-LA64V1P1-NOT: "-target-feature"
 // CC1-LA64V1P1: "-target-abi" "lp64d"
 
+// CC1-LA664: "-target-cpu" "la664"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" 
"-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" 
"-target-feature" "+ual" "-target-feature" "+frecipe"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-abi" "lp64d"
+
 // IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+f,+ual"
 // IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" 
{{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
 // IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+lsx,+ual"
 // IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+ual"
+// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" 
{{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual,+frecipe"
 
 int foo(void) {
   return 3;
diff --git a/clang/test/Driver/loongarch-mtune.c 
b/clang/test/Driver/loongarch-mtune.c
index 6f3f39e9bbd86..face12e1a1a82 100644
--- a/clang/test/Driver/loongarch-mtune.c
+++ b/clang/test/Driver/loongarch-mtune.c
@@ -8,6 +8,11 @@
 // RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la464
 
+// RUN: %clang --target=loongarch64 -mtune=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=la664
+// RUN: %clang --target=loongarch64 -mtune=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la664
+
 // RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 
2>&1 | \
 // RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu
 // RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o 
/dev/null 2>&1 | \
diff --git a/clang/test/Preprocessor/init-loongarch.c 
b/clang/test/Preprocessor/init-loongarch.c
index 788faac2f857e..3d111d77769ed 100644
--- a/clang/test/Preprocessor/init-loongarch.c
+++ b/clang/test/Preprocessor/init-loongarch.c
@@ -832,6 +832,14 @@
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=loongarch64 -DTUNE=loongarch64 %s
 // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 
-Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | 
\
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la64v1.1 -DTUNE=loongarch64 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \
+// RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la664 -DTUNE=la664 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \
+// RUN:   FileCheck --m

[clang] [llvm] [RISCV] Mark zacas as experimental again due to unresolved ABI issue (PR #99898)

2024-07-23 Thread Alex Bradbury via cfe-commits

https://github.com/asb updated https://github.com/llvm/llvm-project/pull/99898

>From 7862d7e5fc63749f68bfdc0f0d8c226d341c55e1 Mon Sep 17 00:00:00 2001
From: Alex Bradbury 
Date: Mon, 22 Jul 2024 17:58:05 +0100
Subject: [PATCH 1/3] [RISCV] Mark zacas as experimental again due to
 unresolved ABI issue

As discussed at the last sync-up call, mark Zacas as experimental until
this ABI issue is resolved
.
---
 .../test/Preprocessor/riscv-target-features.c  | 18 +-
 llvm/docs/RISCVUsage.rst   |  9 +++--
 llvm/docs/ReleaseNotes.rst |  1 -
 llvm/lib/Target/RISCV/RISCVFeatures.td |  4 ++--
 .../RISCV/atomic-cmpxchg-branch-on-result.ll   |  6 +++---
 llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll  | 12 ++--
 llvm/test/CodeGen/RISCV/atomic-rmw.ll  | 12 ++--
 llvm/test/CodeGen/RISCV/atomic-signext.ll  |  4 ++--
 llvm/test/CodeGen/RISCV/attributes.ll  |  4 ++--
 llvm/test/MC/RISCV/rv32zacas-invalid.s |  2 +-
 llvm/test/MC/RISCV/rv32zacas-valid.s   | 12 ++--
 llvm/test/MC/RISCV/rv64zacas-invalid.s |  2 +-
 llvm/test/MC/RISCV/rv64zacas-valid.s   |  6 +++---
 llvm/test/MC/RISCV/rvzabha-zacas-valid.s   | 12 ++--
 .../TargetParser/RISCVISAInfoTest.cpp  |  2 +-
 15 files changed, 51 insertions(+), 55 deletions(-)

diff --git a/clang/test/Preprocessor/riscv-target-features.c 
b/clang/test/Preprocessor/riscv-target-features.c
index fd718a126aaa7..72131108cb5f6 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -86,7 +86,6 @@
 // CHECK-NOT: __riscv_za64rs {{.*$}}
 // CHECK-NOT: __riscv_zaamo {{.*$}}
 // CHECK-NOT: __riscv_zabha {{.*$}}
-// CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalrsc {{.*$}}
 // CHECK-NOT: __riscv_zama16b {{.*$}}
 // CHECK-NOT: __riscv_zawrs {{.*$}}
@@ -182,6 +181,7 @@
 // CHECK-NOT: __riscv_sspm{{.*$}}
 // CHECK-NOT: __riscv_ssqosid{{.*$}}
 // CHECK-NOT: __riscv_supm{{.*$}}
+// CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalasr {{.*$}}
 // CHECK-NOT: __riscv_zfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zicfilp {{.*$}}
@@ -747,14 +747,6 @@
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s
 // CHECK-ZABHA-EXT: __riscv_zabha 100{{$}}
 
-// RUN: %clang --target=riscv32 \
-// RUN:   -march=rv32ia_zacas1p0 -E -dM %s \
-// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
-// RUN: %clang --target=riscv64 \
-// RUN:   -march=rv64ia_zacas1p0 -E -dM %s \
-// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
-// CHECK-ZACAS-EXT: __riscv_zacas 100{{$}}
-
 // RUN: %clang --target=riscv32 \
 // RUN:   -march=rv32i_zalrsc1p0 -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZALRSC-EXT %s
@@ -1626,6 +1618,14 @@
 // CHECK-ZVKT-EXT: __riscv_zvkt 100{{$}}
 
 // Experimental extensions
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32ia_zacas1p0 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64ia_zacas1p0 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// CHECK-ZACAS-EXT: __riscv_zacas 100{{$}}
+
 // RUN: %clang --target=riscv32 -menable-experimental-extensions \
 // RUN:   -march=rv32i_zalasr0p1 -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 4474478b6d3f8..b3c7b0e3883d0 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -153,7 +153,6 @@ on support follow.
  ``Za64rs``Supported (`See note 
<#riscv-profiles-extensions-note>`__)
  ``Zaamo`` Assembly Support
  ``Zabha`` Supported
- ``Zacas`` Supported (`See note <#riscv-zacas-note>`__)
  ``Zalrsc``Assembly Support
  ``Zama16b``   Supported (`See note 
<#riscv-profiles-extensions-note>`__)
  ``Zawrs`` Assembly Support
@@ -281,11 +280,6 @@ Supported
 ``Za128rs``, ``Za64rs``, ``Zama16b``, ``Zic64b``, ``Ziccamoa``, ``Ziccif``, 
``Zicclsm``, ``Ziccrse``, ``Shcounterenvw``, ``Shgatpa``, ``Shtvala``, 
``Shvsatpa``, ``Shvstvala``, ``Shvstvecd``, ``Ssccptr``, ``Sscounterenw``, 
``Ssstateen``, ``Ssstrict``, ``Sstvala``, ``Sstvecd``, ``Ssu64xl``, ``Svade``, 
``Svbare``
   These extensions are defined as part of the `RISC-V Profiles specification 
`__.  They do not 
introduce any new features themselves, but instead describe existing hardware 
features.
 
-  .. _riscv-zacas-note:
-
-``Zacas``
-  amocas.w will be used for i32 cmpxchg. amocas.d will be used i64 cmpxchg on 
RV64. The compiler will not generate amocas.d on RV32 or amocas.q on RV64 due 
to ABI compatibilty. These can only be used i

[clang] 70e7d26 - [RISCV] Mark zacas as experimental again due to unresolved ABI issue (#99898)

2024-07-23 Thread via cfe-commits

Author: Alex Bradbury
Date: 2024-07-23T08:06:15+01:00
New Revision: 70e7d26e560173c8b9db4c75ab4a3004cd5f021a

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

LOG: [RISCV] Mark zacas as experimental again due to unresolved ABI issue 
(#99898)

As discussed at the last sync-up call, mark Zacas as experimental until
this ABI issue is resolved
.

Don't return Zacas in getHostCPUFeatures (leaving a TODO there) as even if 
requesting detection of "native" features, the user likely doesn't want to 
automatically opt in to experimental codegen.

Added: 


Modified: 
clang/test/Preprocessor/riscv-target-features.c
llvm/docs/RISCVUsage.rst
llvm/docs/ReleaseNotes.rst
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/TargetParser/Host.cpp
llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll
llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll
llvm/test/CodeGen/RISCV/atomic-rmw.ll
llvm/test/CodeGen/RISCV/atomic-signext.ll
llvm/test/CodeGen/RISCV/attributes.ll
llvm/test/MC/RISCV/rv32zacas-invalid.s
llvm/test/MC/RISCV/rv32zacas-valid.s
llvm/test/MC/RISCV/rv64zacas-invalid.s
llvm/test/MC/RISCV/rv64zacas-valid.s
llvm/test/MC/RISCV/rvzabha-zacas-valid.s
llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Removed: 




diff  --git a/clang/test/Preprocessor/riscv-target-features.c 
b/clang/test/Preprocessor/riscv-target-features.c
index fd718a126aaa7..72131108cb5f6 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -86,7 +86,6 @@
 // CHECK-NOT: __riscv_za64rs {{.*$}}
 // CHECK-NOT: __riscv_zaamo {{.*$}}
 // CHECK-NOT: __riscv_zabha {{.*$}}
-// CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalrsc {{.*$}}
 // CHECK-NOT: __riscv_zama16b {{.*$}}
 // CHECK-NOT: __riscv_zawrs {{.*$}}
@@ -182,6 +181,7 @@
 // CHECK-NOT: __riscv_sspm{{.*$}}
 // CHECK-NOT: __riscv_ssqosid{{.*$}}
 // CHECK-NOT: __riscv_supm{{.*$}}
+// CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalasr {{.*$}}
 // CHECK-NOT: __riscv_zfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zicfilp {{.*$}}
@@ -747,14 +747,6 @@
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZABHA-EXT %s
 // CHECK-ZABHA-EXT: __riscv_zabha 100{{$}}
 
-// RUN: %clang --target=riscv32 \
-// RUN:   -march=rv32ia_zacas1p0 -E -dM %s \
-// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
-// RUN: %clang --target=riscv64 \
-// RUN:   -march=rv64ia_zacas1p0 -E -dM %s \
-// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
-// CHECK-ZACAS-EXT: __riscv_zacas 100{{$}}
-
 // RUN: %clang --target=riscv32 \
 // RUN:   -march=rv32i_zalrsc1p0 -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZALRSC-EXT %s
@@ -1626,6 +1618,14 @@
 // CHECK-ZVKT-EXT: __riscv_zvkt 100{{$}}
 
 // Experimental extensions
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32ia_zacas1p0 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64ia_zacas1p0 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// CHECK-ZACAS-EXT: __riscv_zacas 100{{$}}
+
 // RUN: %clang --target=riscv32 -menable-experimental-extensions \
 // RUN:   -march=rv32i_zalasr0p1 -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s

diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 4474478b6d3f8..b3c7b0e3883d0 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -153,7 +153,6 @@ on support follow.
  ``Za64rs``Supported (`See note 
<#riscv-profiles-extensions-note>`__)
  ``Zaamo`` Assembly Support
  ``Zabha`` Supported
- ``Zacas`` Supported (`See note <#riscv-zacas-note>`__)
  ``Zalrsc``Assembly Support
  ``Zama16b``   Supported (`See note 
<#riscv-profiles-extensions-note>`__)
  ``Zawrs`` Assembly Support
@@ -281,11 +280,6 @@ Supported
 ``Za128rs``, ``Za64rs``, ``Zama16b``, ``Zic64b``, ``Ziccamoa``, ``Ziccif``, 
``Zicclsm``, ``Ziccrse``, ``Shcounterenvw``, ``Shgatpa``, ``Shtvala``, 
``Shvsatpa``, ``Shvstvala``, ``Shvstvecd``, ``Ssccptr``, ``Sscounterenw``, 
``Ssstateen``, ``Ssstrict``, ``Sstvala``, ``Sstvecd``, ``Ssu64xl``, ``Svade``, 
``Svbare``
   These extensions are defined as part of the `RISC-V Profiles specification 
`__.  They do not 
introduce any new features themselves, but instead describe existing hardware 
features.
 
-  .. _riscv-zacas-note:
-
-``Zacas``
-  amocas.w will be used for i32 cmpxchg. amocas.d will be used i64 cmpxchg

[clang] [llvm] [RISCV] Mark zacas as experimental again due to unresolved ABI issue (PR #99898)

2024-07-23 Thread Alex Bradbury via cfe-commits

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


[clang] [llvm] [LoongArch] Support la664 (PR #100068)

2024-07-23 Thread via cfe-commits

https://github.com/Ami-zhang updated 
https://github.com/llvm/llvm-project/pull/100068

>From b88d699f9a8877d77af0a87d4955af40420142ee Mon Sep 17 00:00:00 2001
From: Ami-zhang 
Date: Mon, 29 Apr 2024 16:58:15 +0800
Subject: [PATCH] [LoongArch] Support la664

A new ProcessorModel called `la664` is defined in LoongArch.td
to support `-march/-mtune=la664`.
---
 clang/test/Driver/loongarch-march.c   | 11 +++
 clang/test/Driver/loongarch-mtune.c   |  5 +
 clang/test/Preprocessor/init-loongarch.c  |  8 
 .../llvm/TargetParser/LoongArchTargetParser.def   |  2 ++
 .../include/llvm/TargetParser/LoongArchTargetParser.h |  3 +++
 llvm/lib/Target/LoongArch/LoongArch.td|  7 +++
 llvm/lib/TargetParser/Host.cpp|  2 ++
 llvm/test/CodeGen/LoongArch/cpus.ll   |  5 +
 8 files changed, 43 insertions(+)

diff --git a/clang/test/Driver/loongarch-march.c 
b/clang/test/Driver/loongarch-march.c
index d06da72a755cb..2d5b315d962a1 100644
--- a/clang/test/Driver/loongarch-march.c
+++ b/clang/test/Driver/loongarch-march.c
@@ -6,6 +6,8 @@
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -fsyntax-only %s -### 2>&1 
| \
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1-LA664
 // RUN: %clang --target=loongarch64 -march=loongarch64 -S -emit-llvm %s -o - | 
\
 // RUN:   FileCheck %s --check-prefix=IR-LOONGARCH64
 // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \
@@ -14,6 +16,8 @@
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IR-LA664
 
 // CC1-LOONGARCH64: "-target-cpu" "loongarch64"
 // CC1-LOONGARCH64-NOT: "-target-feature"
@@ -39,10 +43,17 @@
 // CC1-LA64V1P1-NOT: "-target-feature"
 // CC1-LA64V1P1: "-target-abi" "lp64d"
 
+// CC1-LA664: "-target-cpu" "la664"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" 
"-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" 
"-target-feature" "+ual" "-target-feature" "+frecipe"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-abi" "lp64d"
+
 // IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+f,+ual"
 // IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" 
{{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
 // IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+lsx,+ual"
 // IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+ual"
+// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" 
{{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lasx,+lsx,+ual"
 
 int foo(void) {
   return 3;
diff --git a/clang/test/Driver/loongarch-mtune.c 
b/clang/test/Driver/loongarch-mtune.c
index 6f3f39e9bbd86..face12e1a1a82 100644
--- a/clang/test/Driver/loongarch-mtune.c
+++ b/clang/test/Driver/loongarch-mtune.c
@@ -8,6 +8,11 @@
 // RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la464
 
+// RUN: %clang --target=loongarch64 -mtune=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=la664
+// RUN: %clang --target=loongarch64 -mtune=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la664
+
 // RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 
2>&1 | \
 // RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu
 // RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o 
/dev/null 2>&1 | \
diff --git a/clang/test/Preprocessor/init-loongarch.c 
b/clang/test/Preprocessor/init-loongarch.c
index 788faac2f857e..3d111d77769ed 100644
--- a/clang/test/Preprocessor/init-loongarch.c
+++ b/clang/test/Preprocessor/init-loongarch.c
@@ -832,6 +832,14 @@
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=loongarch64 -DTUNE=loongarch64 %s
 // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 
-Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | 
\
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la64v1.1 -DTUNE=loongarch64 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \
+// RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la664 -DTUNE=la664 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \
+// RUN:   FileCheck --m

[clang] fcec298 - [LoongArch] Support la664 (#100068)

2024-07-23 Thread via cfe-commits

Author: Ami-zhang
Date: 2024-07-23T15:14:20+08:00
New Revision: fcec298087dba0c83f6d0bbafd6cd934c42cbf82

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

LOG: [LoongArch] Support la664 (#100068)

A new ProcessorModel called `la664` is defined in LoongArch.td to
support `-march/-mtune=la664`.

Added: 


Modified: 
clang/test/Driver/loongarch-march.c
clang/test/Driver/loongarch-mtune.c
clang/test/Preprocessor/init-loongarch.c
llvm/include/llvm/TargetParser/LoongArchTargetParser.def
llvm/include/llvm/TargetParser/LoongArchTargetParser.h
llvm/lib/Target/LoongArch/LoongArch.td
llvm/lib/TargetParser/Host.cpp
llvm/test/CodeGen/LoongArch/cpus.ll

Removed: 




diff  --git a/clang/test/Driver/loongarch-march.c 
b/clang/test/Driver/loongarch-march.c
index d06da72a755cb..2d5b315d962a1 100644
--- a/clang/test/Driver/loongarch-march.c
+++ b/clang/test/Driver/loongarch-march.c
@@ -6,6 +6,8 @@
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -fsyntax-only %s -### 2>&1 
| \
 // RUN:   FileCheck %s --check-prefix=CC1-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1-LA664
 // RUN: %clang --target=loongarch64 -march=loongarch64 -S -emit-llvm %s -o - | 
\
 // RUN:   FileCheck %s --check-prefix=IR-LOONGARCH64
 // RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \
@@ -14,6 +16,8 @@
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P0
 // RUN: %clang --target=loongarch64 -march=la64v1.1 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IR-LA64V1P1
+// RUN: %clang --target=loongarch64 -march=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IR-LA664
 
 // CC1-LOONGARCH64: "-target-cpu" "loongarch64"
 // CC1-LOONGARCH64-NOT: "-target-feature"
@@ -39,10 +43,17 @@
 // CC1-LA64V1P1-NOT: "-target-feature"
 // CC1-LA64V1P1: "-target-abi" "lp64d"
 
+// CC1-LA664: "-target-cpu" "la664"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" 
"-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" 
"-target-feature" "+ual" "-target-feature" "+frecipe"
+// CC1-LA664-NOT: "-target-feature"
+// CC1-LA664: "-target-abi" "lp64d"
+
 // IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+f,+ual"
 // IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" 
{{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
 // IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+lsx,+ual"
 // IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" 
{{.*}}"target-features"="+64bit,+d,+frecipe,+lsx,+ual"
+// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" 
{{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lasx,+lsx,+ual"
 
 int foo(void) {
   return 3;

diff  --git a/clang/test/Driver/loongarch-mtune.c 
b/clang/test/Driver/loongarch-mtune.c
index 6f3f39e9bbd86..face12e1a1a82 100644
--- a/clang/test/Driver/loongarch-mtune.c
+++ b/clang/test/Driver/loongarch-mtune.c
@@ -8,6 +8,11 @@
 // RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \
 // RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la464
 
+// RUN: %clang --target=loongarch64 -mtune=la664 -fsyntax-only %s -### 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=la664
+// RUN: %clang --target=loongarch64 -mtune=la664 -S -emit-llvm %s -o - | \
+// RUN:   FileCheck %s --check-prefix=IRATTR -DCPU=la664
+
 // RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 
2>&1 | \
 // RUN:   FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu
 // RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o 
/dev/null 2>&1 | \

diff  --git a/clang/test/Preprocessor/init-loongarch.c 
b/clang/test/Preprocessor/init-loongarch.c
index 788faac2f857e..3d111d77769ed 100644
--- a/clang/test/Preprocessor/init-loongarch.c
+++ b/clang/test/Preprocessor/init-loongarch.c
@@ -832,6 +832,14 @@
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=loongarch64 -DTUNE=loongarch64 %s
 // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 
-Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | 
\
 // RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la64v1.1 -DTUNE=loongarch64 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \
+// RUN:   FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE 
-DARCH=la664 -DTUNE=la664 %s
+// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \
+// RUN:   FileCheck --m

[clang] [llvm] [LoongArch] Support la664 (PR #100068)

2024-07-23 Thread Lu Weining via cfe-commits

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


[clang] 8a615bc - [LoongArch] Summary the release notes for LLVM 19

2024-07-23 Thread Weining Lu via cfe-commits

Author: Weining Lu
Date: 2024-07-23T15:19:07+08:00
New Revision: 8a615bcf2f8c8140c6eadae964c8ea7fb4cfee33

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

LOG: [LoongArch] Summary the release notes for LLVM 19

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
llvm/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a72e8c60b14c4..3705d698b4e92 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1228,6 +1228,14 @@ Windows Support
 LoongArch Support
 ^
 
+- ``-march=la64v1.0`` and ``-march=la64v1.1`` have been added to select the
+  ``la64v1.0`` and ``la64v1.1`` architecture respectively. And ``-march=la664``
+  is added to support the ``la664`` micro-architecture.
+- The 128-bits SIMD extension (``LSX``) is enabled by default.
+- ``-msimd=`` has beend added to select the SIMD extension(s) to be enabled.
+- Predefined macros ``__loongarch_simd_width`` and ``__loongarch_frecipe`` are
+  added.
+
 RISC-V Support
 ^^
 

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index ce4f0343aea27..a81caa160883d 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -166,6 +166,13 @@ Changes to the LoongArch Backend
 * i32 is now a native type in the datalayout string. This enables
   LoopStrengthReduce for loops with i32 induction variables, among other
   optimizations.
+* Codegen support is added for TLS Desciptor.
+* Interleaved vectorization and vector shuffle are supported on LoongArch and
+  the experimental feature ``auto-vec`` is removed.
+* Allow ``f16`` codegen with expansion to libcalls.
+* Clarify that emulated TLS is not supported.
+* A codegen issue for ``bstrins.w`` is fixed on loongarch32.
+* Assorted codegen improvements.
 
 Changes to the MIPS Backend
 ---



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


[clang-tools-extra] 2dd82c5 - [clang-tidy][NFC] Added -fexceptions to const-correctness-values.cp

2024-07-23 Thread Piotr Zegar via cfe-commits

Author: Piotr Zegar
Date: 2024-07-23T07:38:49Z
New Revision: 2dd82c5ac56623d38de977ef027b252b4908e4c5

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

LOG: [clang-tidy][NFC] Added -fexceptions to const-correctness-values.cp

Related to #99925.

Added: 


Modified: 
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

Removed: 




diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
index 2af4bfb0bd449..0d1ff0db58371 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
@@ -3,7 +3,7 @@
 // RUN: misc-const-correctness.TransformValues: true, \
 // RUN: misc-const-correctness.WarnPointersAsValues: false, \
 // RUN: misc-const-correctness.TransformPointersAsValues: false \
-// RUN:   }}" -- -fno-delayed-template-parsing
+// RUN:   }}" -- -fno-delayed-template-parsing -fexceptions
 
 // --- Provide test samples for primitive builtins -
 // - every 'p_*' variable is a 'potential_const_*' variable



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


[clang-tools-extra] 26c99c4 - [clang-tidy] fix misc-const-correctness to work with function-try-blocks (#99925)

2024-07-23 Thread Piotr Zegar via cfe-commits

Author: Thomas Schenker
Date: 2024-07-23T07:38:49Z
New Revision: 26c99c421794902b0d929fd9eff81314da55675c

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

LOG: [clang-tidy] fix misc-const-correctness to work with function-try-blocks 
(#99925)

Make the clang-tidy check misc-const-correctness work with
function-try-blocks.

Fixes #99860.

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 8b500de0c028c..e20cf6fbcb55a 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -93,13 +93,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder 
*Finder) {
   // shall be run.
   const auto FunctionScope =
   functionDecl(
-  hasBody(
-  compoundStmt(forEachDescendant(
-   declStmt(containsAnyDeclaration(
-LocalValDecl.bind("local-value")),
-unless(has(decompositionDecl(
-   .bind("decl-stmt")))
-  .bind("scope")))
+  hasBody(stmt(forEachDescendant(
+   declStmt(containsAnyDeclaration(
+LocalValDecl.bind("local-value")),
+unless(has(decompositionDecl(
+   .bind("decl-stmt")))
+  .bind("scope")))
   .bind("function-decl");
 
   Finder->addMatcher(FunctionScope, this);
@@ -109,7 +108,7 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder 
*Finder) {
 enum class VariableCategory { Value, Reference, Pointer };
 
 void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
-  const auto *LocalScope = Result.Nodes.getNodeAs("scope");
+  const auto *LocalScope = Result.Nodes.getNodeAs("scope");
   const auto *Variable = Result.Nodes.getNodeAs("local-value");
   const auto *Function = Result.Nodes.getNodeAs("function-decl");
 
@@ -198,7 +197,7 @@ void ConstCorrectnessCheck::check(const 
MatchFinder::MatchResult &Result) {
   }
 }
 
-void ConstCorrectnessCheck::registerScope(const CompoundStmt *LocalScope,
+void ConstCorrectnessCheck::registerScope(const Stmt *LocalScope,
   ASTContext *Context) {
   auto &Analyzer = ScopesCache[LocalScope];
   if (!Analyzer)

diff  --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h 
b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
index 08ffde524522a..bba060e555d00 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h
@@ -32,10 +32,10 @@ class ConstCorrectnessCheck : public ClangTidyCheck {
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
-  void registerScope(const CompoundStmt *LocalScope, ASTContext *Context);
+  void registerScope(const Stmt *LocalScope, ASTContext *Context);
 
   using MutationAnalyzer = std::unique_ptr;
-  llvm::DenseMap ScopesCache;
+  llvm::DenseMap ScopesCache;
   llvm::DenseSet TemplateDiagnosticsCache;
 
   const bool AnalyzeValues;

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 0b2c04c23761c..083b098d05d4a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -381,7 +381,8 @@ Changes in existing checks
 - Improved :doc:`misc-const-correctness
   ` check by avoiding infinite 
recursion
   for recursive functions with forwarding reference parameters and reference
-  variables which refer to themselves.
+  variables which refer to themselves. Also adapted the check to work with
+  function-try-blocks.
 
 - Improved :doc:`misc-definitions-in-headers
   ` check by replacing the local

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
index cb6bfcc1dccba..2af4bfb0bd449 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
@@ -56,6 +56,15 @@ void some_function(double np_arg0, wchar_t np_arg1) {
   np_local6--;
 }
 
+int function_try_block() try {
+  int p_local0 = 0;
+  // CHECK-MES

[clang] 6db5f4f - [Clang] Ignore empty FieldDecls when asking for the field number (#100040)

2024-07-23 Thread via cfe-commits

Author: Bill Wendling
Date: 2024-07-23T00:49:46-07:00
New Revision: 6db5f4fd2a287de9d20adc7a44cfcc66fc462c9c

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

LOG: [Clang] Ignore empty FieldDecls when asking for the field number (#100040)

A FieldDecl that's an empty struct may not show up in CGRecordLayout. Go
ahead and ignore such a field as it shouldn't make a difference to these
calculations.

Fixes: 1f6f97e2b64a ("[Clang] Loop over FieldDecls instead of all Decls 
(#99574)")
Co-authored-by: Eli Friedman 

Added: 


Modified: 
clang/lib/CodeGen/CGExpr.cpp
clang/lib/CodeGen/CGRecordLayout.h
clang/test/CodeGen/attr-counted-by.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index aa53f96358044..5f58a64d8386c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1076,6 +1076,11 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, 
const RecordDecl *RD,
   const CGRecordLayout &Layout = CGF.CGM.getTypes().getCGRecordLayout(RD);
   int64_t FieldNo = -1;
   for (const FieldDecl *FD : RD->fields()) {
+if (!Layout.containsFieldDecl(FD))
+  // This could happen if the field has a struct type that's empty. I don't
+  // know why either.
+  continue;
+
 FieldNo = Layout.getLLVMFieldNo(FD);
 if (FD == Field) {
   Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));

diff  --git a/clang/lib/CodeGen/CGRecordLayout.h 
b/clang/lib/CodeGen/CGRecordLayout.h
index 6c06ad20fbe56..44e888c93108f 100644
--- a/clang/lib/CodeGen/CGRecordLayout.h
+++ b/clang/lib/CodeGen/CGRecordLayout.h
@@ -193,6 +193,10 @@ class CGRecordLayout {
 return IsZeroInitializableAsBase;
   }
 
+  bool containsFieldDecl(const FieldDecl *FD) const {
+return FieldInfo.count(FD) != 0;
+  }
+
   /// Return llvm::StructType element number that corresponds to the
   /// field FD.
   unsigned getLLVMFieldNo(const FieldDecl *FD) const {

diff  --git a/clang/test/CodeGen/attr-counted-by.c 
b/clang/test/CodeGen/attr-counted-by.c
index 32db136076d7d..46a6c2b492dbe 100644
--- a/clang/test/CodeGen/attr-counted-by.c
+++ b/clang/test/CodeGen/attr-counted-by.c
@@ -1906,3 +1906,51 @@ struct test30_struct {
 void test30(struct test30_struct *ptr, int idx) {
   ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1);
 }
+
+struct test31_empty {};
+
+struct test31_struct {
+  struct test31_empty y;
+  int s;
+  int x[] __counted_by(s);
+};
+
+// SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31(
+// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 
noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// SANITIZE-WITH-ATTR-NEXT:  entry:
+// SANITIZE-WITH-ATTR-NEXT:[[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr 
[[PTR]], align 4
+// SANITIZE-WITH-ATTR-NEXT:[[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] 
to i64
+// SANITIZE-WITH-ATTR-NEXT:[[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2
+// SANITIZE-WITH-ATTR-NEXT:[[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 
[[TMP1]], i64 0)
+// SANITIZE-WITH-ATTR-NEXT:[[TMP3:%.*]] = trunc i64 [[TMP2]] to i32
+// SANITIZE-WITH-ATTR-NEXT:[[TMP4:%.*]] = add i32 [[TMP3]], 4
+// SANITIZE-WITH-ATTR-NEXT:[[DOTINV:%.*]] = icmp slt i32 
[[DOT_COUNTED_BY_LOAD]], 0
+// SANITIZE-WITH-ATTR-NEXT:[[CONV:%.*]] = select i1 [[DOTINV]], i32 0, i32 
[[TMP4]]
+// SANITIZE-WITH-ATTR-NEXT:ret i32 [[CONV]]
+//
+// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31(
+// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[PTR:%.*]], i32 
noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// NO-SANITIZE-WITH-ATTR-NEXT:  entry:
+// NO-SANITIZE-WITH-ATTR-NEXT:[[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr 
[[PTR]], align 4
+// NO-SANITIZE-WITH-ATTR-NEXT:[[TMP0:%.*]] = sext i32 
[[DOT_COUNTED_BY_LOAD]] to i64
+// NO-SANITIZE-WITH-ATTR-NEXT:[[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2
+// NO-SANITIZE-WITH-ATTR-NEXT:[[TMP2:%.*]] = tail call i64 
@llvm.smax.i64(i64 [[TMP1]], i64 0)
+// NO-SANITIZE-WITH-ATTR-NEXT:[[TMP3:%.*]] = trunc i64 [[TMP2]] to i32
+// NO-SANITIZE-WITH-ATTR-NEXT:[[TMP4:%.*]] = add i32 [[TMP3]], 4
+// NO-SANITIZE-WITH-ATTR-NEXT:[[DOTINV:%.*]] = icmp slt i32 
[[DOT_COUNTED_BY_LOAD]], 0
+// NO-SANITIZE-WITH-ATTR-NEXT:[[CONV:%.*]] = select i1 [[DOTINV]], i32 0, 
i32 [[TMP4]]
+// NO-SANITIZE-WITH-ATTR-NEXT:ret i32 [[CONV]]
+//
+// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31(
+// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef 
[[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] {
+// SANITIZE-WITHOUT-ATTR-NEXT:  entry:
+// SANITIZE-WITHOUT-ATTR-NEXT:ret i32 -1
+//
+// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test31(
+// NO-SANITIZE-WITH

[clang] [Clang] Ignore empty FieldDecls when asking for the field number (PR #100040)

2024-07-23 Thread Bill Wendling via cfe-commits

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


[clang] 0998e3c - [clang] Add method 'backupStr' to ASTContext (#99417)

2024-07-23 Thread via cfe-commits

Author: Youngsuk Kim
Date: 2024-07-23T04:13:04-04:00
New Revision: 0998e3c4e66ded6e42b8ce162748df05b5ddb627

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

LOG: [clang] Add method 'backupStr' to ASTContext (#99417)

Method 'backupStr' extracts common code of dynamically allocating memory
with ASTContext to hold a copy of a string's contents.

Added: 


Modified: 
clang/include/clang/AST/ASTContext.h
clang/lib/AST/ASTConcept.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/lib/Serialization/ASTReaderStmt.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index f2a17a56dc201..6d1c8ca8a2f96 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -738,6 +738,12 @@ class ASTContext : public RefCountedBase {
   }
   void Deallocate(void *Ptr) const {}
 
+  llvm::StringRef backupStr(llvm::StringRef S) const {
+char *Buf = new (*this) char[S.size()];
+std::copy(S.begin(), S.end(), Buf);
+return llvm::StringRef(Buf, S.size());
+  }
+
   /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList
   /// pool.
   DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) {

diff  --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index 95e7ac1a3d775..d8efbe44dbecb 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -28,11 +28,9 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C,
   else {
 auto &SubstitutionDiagnostic =
 *Detail.get *>();
-unsigned MessageSize = SubstitutionDiagnostic.second.size();
-char *Mem = new (C) char[MessageSize];
-memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
+StringRef Message = C.backupStr(SubstitutionDiagnostic.second);
 auto *NewSubstDiag = new (C) std::pair(
-SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
+SubstitutionDiagnostic.first, Message);
 new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag);
   }
 }

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 725b62db5e80a..8995d461362d7 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2576,16 +2576,12 @@ createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
   } else {
 ErrorLoc = Info.getLocation();
   }
-  char *MessageBuf = new (S.Context) char[Message.size()];
-  std::copy(Message.begin(), Message.end(), MessageBuf);
   SmallString<128> Entity;
   llvm::raw_svector_ostream OS(Entity);
   Printer(OS);
-  char *EntityBuf = new (S.Context) char[Entity.size()];
-  std::copy(Entity.begin(), Entity.end(), EntityBuf);
-  return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
-  StringRef(EntityBuf, Entity.size()), ErrorLoc,
-  StringRef(MessageBuf, Message.size())};
+  const ASTContext &C = S.Context;
+  return new (C) concepts::Requirement::SubstitutionDiagnostic{
+  C.backupStr(Entity), ErrorLoc, C.backupStr(Message)};
 }
 
 concepts::Requirement::SubstitutionDiagnostic *
@@ -2594,10 +2590,9 @@ concepts::createSubstDiagAt(Sema &S, SourceLocation 
Location,
   SmallString<128> Entity;
   llvm::raw_svector_ostream OS(Entity);
   Printer(OS);
-  char *EntityBuf = new (S.Context) char[Entity.size()];
-  llvm::copy(Entity, EntityBuf);
-  return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
-  /*SubstitutedEntity=*/StringRef(EntityBuf, Entity.size()),
+  const ASTContext &C = S.Context;
+  return new (C) concepts::Requirement::SubstitutionDiagnostic{
+  /*SubstitutedEntity=*/C.backupStr(Entity),
   /*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
 }
 
@@ -2773,23 +2768,21 @@ TemplateInstantiator::TransformNestedRequirement(
 assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
"by CheckConstraintSatisfaction.");
   }
+  ASTContext &C = SemaRef.Context;
   if (TransConstraint.isUsable() &&
   TransConstraint.get()->isInstantiationDependent())
-return new (SemaRef.Context)
-concepts::NestedRequirement(TransConstraint.get());
+return new (C) concepts::NestedRequirement(TransConstraint.get());
   if (TransConstraint.isInvalid() || !TransConstraint.get() ||
   Satisfaction.HasSubstitutionFailure()) {
 SmallString<128> Entity;
 llvm::raw_svector_ostream OS(Entity);
 Req->getConstraintExpr()->printPretty(OS, nullptr,
   SemaRef.getPrintingPolicy());
-char *EntityBuf = new (SemaRef.Context) char[Entity.size()];
-std::copy(Entity.begin(), Entity.end(), EntityBuf);
-return new (SemaRef.Context) concepts::NestedReq

[clang] [clang] Add method 'backupStr' to ASTContext (PR #99417)

2024-07-23 Thread Youngsuk Kim via cfe-commits

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


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

2024-07-23 Thread via cfe-commits

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

LGTM

Considering that the literal type requirement was quite literally just 
straight-up removed in C++23, returning early here is basically just doing what 
the standard did, so this change makes sense to me.

Also, one option would be to move this check up even further to be the first 
thing we check for in this function (don’t know how expensive the 
`isLiteralType` check is off the top of my head). I’m not sure it really 
matters though, so either way seems fine to me.

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


[clang] [clang] replaced the usage of `asctime` with `strftime` (PR #99075)

2024-07-23 Thread via cfe-commits


@@ -1721,11 +1723,15 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
 Diag(Tok.getLocation(), diag::warn_pp_date_time);
 // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
 // of the form "Ddd Mmm dd hh::mm::ss ", which is returned by asctime.
-const char *Result;
+std::string Result = "??? ??? ?? ??:??:?? ";
+std::stringstream TmpStream;
+TmpStream.imbue(std::locale("C"));
+TmpStream.setstate(std::ios_base::badbit);

cor3ntin wrote:

That is not needed afaik (the bad bit would be set automatically on failure)

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


[clang] [clang] replaced the usage of `asctime` with `strftime` (PR #99075)

2024-07-23 Thread via cfe-commits

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


[clang] [analyzer] Model builtin-like functions as builtin functions (PR #99886)

2024-07-23 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat commented:

LGTM.

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


[clang] [clang] [C++20] Defaulted operator== doesn't lookup in using-directive properly #97087 (PR #99542)

2024-07-23 Thread via cfe-commits


@@ -124,7 +124,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
   ? diag::warn_cxx98_compat_defaulted_deleted_function
   : diag::ext_defaulted_deleted_function)
 << 0 /* defaulted */;
-  Actions.SetDeclDefaulted(FnD, KWLoc);
+  Actions.SetDeclDefaulted(nullptr, FnD, KWLoc);

cor3ntin wrote:

```suggestion
  Actions.SetDeclDefaulted(/*Scope=*/nullptr, FnD, KWLoc);
```

Ditto everywhere you pass a nullptr.

Alternatively, declare `SetDeclDefaulted` as

``void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc, Scope *S = 
nullptr);`

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


[clang] [clang] [C++20] Defaulted operator== doesn't lookup in using-directive properly #97087 (PR #99542)

2024-07-23 Thread via cfe-commits


@@ -15,3 +32,9 @@ bool operator==(const Foo &, const Foo &) = default;  // 
expected-warning {{comp
 
 // Declare the defaulted comparison function as a non-member function. 
Arguments are passed by value.
 bool operator==(Foo, Foo) = default;  // expected-warning {{comparing floating 
point with == or != is unsafe}} expected-note {{in defaulted equality 
comparison operator for 'Foo' first required here}}
+
+// Declare the defaulted comparsion function as a non-member function. 
Arguments are passed by value. Arguments look up NS namespace.
+bool operator==(Y, Y) = default; 
+
+// Declare the defaulted comparsion function as a non-member function. 
Arguments are passed by value. Arguments look up NS namespace and use template 
struct.
+bool operator==(Z, Z) = default;

cor3ntin wrote:

Missing a new line before end of file

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


[clang] Template Diagnostic Improvements (PR #99933)

2024-07-23 Thread via cfe-commits

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


[clang] [Sema] Fix computations of "unexpanded packs" in substituted lambdas (PR #99882)

2024-07-23 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

@ilya-biryukov I'm a bit torn about how we would proceed: if Corentin insists 
on the current (which my patch continues the effort) implementation, do you 
think it feasible for me to merge part of your codes (specifically, the way we 
propagate up unexpanded flags for lambda bodies, some tests apart from those 
for lambda attributes) into #86265? Of course I'll add you as a co-author of 
that patch, if you're happy.

(The attribute part could be split up as an individual PR afterward, if I 
understand our discussion correctly?)

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


[clang] Template Diagnostic Improvements (PR #99933)

2024-07-23 Thread via cfe-commits

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

LGTM. 

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


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

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


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

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

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

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

[clang-tools-extra] [clang-tidy] Add new check bugprone-tagged-union-member-count (PR #89925)

2024-07-23 Thread via cfe-commits
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?= ,
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?= ,
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?= 
Message-ID:
In-Reply-To: 



@@ -0,0 +1,125 @@
+//===--- TaggedUnionMemberCountCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TaggedUnionMemberCountCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Casting.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  recordDecl(
+  allOf(isStruct(),
+has(fieldDecl(hasType(recordDecl(isUnion()).bind("union",
+has(fieldDecl(hasType(enumDecl().bind("tags"))
+  .bind("root"),
+  this);
+}
+
+static bool hasMultipleUnionsOrEnums(const RecordDecl *rec) {
+  int tags = 0;
+  int unions = 0;
+  for (const FieldDecl *r : rec->fields()) {
+TypeSourceInfo *info = r->getTypeSourceInfo();
+QualType qualtype = info->getType();
+const Type *type = qualtype.getTypePtr();
+if (type->isUnionType())
+  unions += 1;
+else if (type->isEnumeralType())
+  tags += 1;
+if (tags > 1 || unions > 1)
+  return true;
+  }
+  return false;
+}
+
+static int64_t getNumberOfValidEnumValues(const EnumDecl *ed) {
+  int64_t maxTagValue = std::numeric_limits::min();
+  int64_t minTagValue = std::numeric_limits::max();
+
+  // Heuristic for counter enum constants.
+  //
+  //   enum tag_with_counter {
+  // tag1,
+  // tag2,
+  // tag_count, <-- Searching for these enum constants
+  //   };
+  //
+  // The 'ce' prefix is used to abbreviate counterEnum.
+  // The final tag count is decreased by 1 if and only if:
+  // 1. The number of counting enum constants = 1,
+  int ceCount = 0;
+  // 2. The counting enum constant is the last enum constant that is defined,
+  int ceFirstIndex = 0;
+  // 3. The value of the counting enum constant is the largest out of every 
enum constant.
+  int64_t ceValue = 0;
+
+  int64_t enumConstantsCount = 0;
+  for (auto En : llvm::enumerate(ed->enumerators())) {
+enumConstantsCount += 1;
+
+int64_t enumValue = En.value()->getInitVal().getExtValue();
+StringRef enumName = En.value()->getName();
+
+if (enumValue > maxTagValue)
+  maxTagValue = enumValue;
+if (enumValue < minTagValue)
+  minTagValue = enumValue;
+
+if (enumName.ends_with_insensitive("count")) {
+  if (ceCount == 0) {
+ceFirstIndex = En.index();
+  }
+  ceValue = enumValue;
+  ceCount += 1;
+}
+  }
+
+  int64_t validValuesCount = maxTagValue - minTagValue + 1;
+  if (ceCount == 1 &&
+  ceFirstIndex == enumConstantsCount - 1 &&
+  ceValue == maxTagValue) {
+validValuesCount -= 1;
+  }
+  return validValuesCount;
+}
+
+void TaggedUnionMemberCountCheck::check(
+const MatchFinder::MatchResult &Result) {
+  const auto *root = Result.Nodes.getNodeAs("root");
+  const auto *unionMatch = Result.Nodes.getNodeAs("union");
+  const auto *tagMatch = Result.Nodes.getNodeAs("tags");
+
+  if (hasMultipleUnionsOrEnums(root))
+return;
+
+  int64_t unionMemberCount = llvm::range_size(unionMatch->fields());
+  int64_t tagCount = getNumberOfValidEnumValues(tagMatch);
+
+  // FIXME: Maybe a emit a note when a counter enum constant was found.
+  if (unionMemberCount > tagCount) {
+diag(root->getLocation(), "Tagged union has more data members than tags! "
+  "Data members: %0 Tags: %1")
+<< unionMemberCount << tagCount;
+  } else if (unionMemberCount < tagCount) {

tigbr wrote:

This diagnostic is emitted only when the `StrictMode` option to `true`, which 
is disabled by default precisely because of these cases.

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


[clang] [PS5] Adopt new compiler-rt naming scheme for the profile library. (PR #99862)

2024-07-23 Thread via cfe-commits

https://github.com/goussepi updated 
https://github.com/llvm/llvm-project/pull/99862

>From f2bbdbd5507f5d29e2d0877df135bf1f28bf753b Mon Sep 17 00:00:00 2001
From: Pierre Gousseau 
Date: Mon, 22 Jul 2024 10:49:08 +
Subject: [PATCH] [PS5] Adopt new compiler-rt naming scheme for the profile
 library

Changes the driver to look for libclang_rt.profile_nosubmission.a
instead of libclang_rt.profile-x86_64_nosubmission.a
---
 clang/lib/Driver/ToolChains/PS4CPU.h  | 2 +-
 clang/test/Driver/ps4-ps5-runtime-flags.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/PS4CPU.h 
b/clang/lib/Driver/ToolChains/PS4CPU.h
index fee80e77462f3..b248d1c256129 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.h
+++ b/clang/lib/Driver/ToolChains/PS4CPU.h
@@ -163,7 +163,7 @@ class LLVM_LIBRARY_VISIBILITY PS5CPU : public PS4PS5Base {
 llvm::opt::ArgStringList &CmdArgs, const char *Prefix,
 const char *Suffix) const override;
   const char *getProfileRTLibName() const override {
-return "libclang_rt.profile-x86_64_nosubmission.a";
+return "libclang_rt.profile_nosubmission.a";
   }
 
 protected:
diff --git a/clang/test/Driver/ps4-ps5-runtime-flags.c 
b/clang/test/Driver/ps4-ps5-runtime-flags.c
index e75ba97948d23..4b00aead6fe5c 100644
--- a/clang/test/Driver/ps4-ps5-runtime-flags.c
+++ b/clang/test/Driver/ps4-ps5-runtime-flags.c
@@ -40,5 +40,5 @@
 // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate %s -### 2>&1 | 
FileCheck --check-prefix=CHECK-PS5-PROFILE %s
 // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate 
-fno-profile-generate %s -### 2>&1 | FileCheck 
--check-prefix=CHECK-PS5-NO-PROFILE %s
 //
-// CHECK-PS5-PROFILE: 
"--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a"
-// CHECK-PS5-NO-PROFILE-NOT: 
"--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a"
+// CHECK-PS5-PROFILE: "--dependent-lib=libclang_rt.profile_nosubmission.a"
+// CHECK-PS5-NO-PROFILE-NOT: 
"--dependent-lib=libclang_rt.profile_nosubmission.a"

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


[clang] b5fb7b2 - [PS5] Adopt new compiler-rt naming scheme for the profile library. (#99862)

2024-07-23 Thread via cfe-commits

Author: goussepi
Date: 2024-07-23T10:08:40+01:00
New Revision: b5fb7b209085acdb33748ab4fe33cbfbdbfeeddf

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

LOG: [PS5] Adopt new compiler-rt naming scheme for the profile library. (#99862)

Changes the driver to look for libclang_rt.profile_nosubmission.a
instead of libclang_rt.profile-x86_64_nosubmission.a

Added: 


Modified: 
clang/lib/Driver/ToolChains/PS4CPU.h
clang/test/Driver/ps4-ps5-runtime-flags.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/PS4CPU.h 
b/clang/lib/Driver/ToolChains/PS4CPU.h
index 0be90183c637c..a33728bce5186 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.h
+++ b/clang/lib/Driver/ToolChains/PS4CPU.h
@@ -179,7 +179,7 @@ class LLVM_LIBRARY_VISIBILITY PS5CPU : public PS4PS5Base {
 llvm::opt::ArgStringList &CmdArgs, const char *Prefix,
 const char *Suffix) const override;
   const char *getProfileRTLibName() const override {
-return "libclang_rt.profile-x86_64_nosubmission.a";
+return "libclang_rt.profile_nosubmission.a";
   }
 
 protected:

diff  --git a/clang/test/Driver/ps4-ps5-runtime-flags.c 
b/clang/test/Driver/ps4-ps5-runtime-flags.c
index e75ba97948d23..4b00aead6fe5c 100644
--- a/clang/test/Driver/ps4-ps5-runtime-flags.c
+++ b/clang/test/Driver/ps4-ps5-runtime-flags.c
@@ -40,5 +40,5 @@
 // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate %s -### 2>&1 | 
FileCheck --check-prefix=CHECK-PS5-PROFILE %s
 // RUN: %clang -target x86_64-sie-ps5 -fcs-profile-generate 
-fno-profile-generate %s -### 2>&1 | FileCheck 
--check-prefix=CHECK-PS5-NO-PROFILE %s
 //
-// CHECK-PS5-PROFILE: 
"--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a"
-// CHECK-PS5-NO-PROFILE-NOT: 
"--dependent-lib=libclang_rt.profile-x86_64_nosubmission.a"
+// CHECK-PS5-PROFILE: "--dependent-lib=libclang_rt.profile_nosubmission.a"
+// CHECK-PS5-NO-PROFILE-NOT: 
"--dependent-lib=libclang_rt.profile_nosubmission.a"



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


[clang] [PS5] Adopt new compiler-rt naming scheme for the profile library. (PR #99862)

2024-07-23 Thread via cfe-commits

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

https://github.com/steakhal created 
https://github.com/llvm/llvm-project/pull/100085

'fopen' should return a new FILE handle, thus we should assume it can't alias 
with commonly used FILE handles, such as with 'stdin', 'stdout' or 'stderr'.

This problem appears in code that handles either some input/output file with 
stdin or stdout, as the business logic is basically the same no matter the 
stream being used.
However, one would should only close the stream if it was opened via 'fopen'. 
Consequently, such code usually has a condition like `if (f && f != stdout)` to 
guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking the 
guarded branch.

CPP-5306

>From c8148c88a39434501b9dacb374b3ca9d81ee8fdf Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Tue, 23 Jul 2024 08:55:16 +0200
Subject: [PATCH] [analyzer] Assume the result of 'fopen' can't alias with
 'std{in,out,err}'

'fopen' should return a new FILE handle, thus we should assume it can't
alias with commonly used FILE handles, such as with 'stdin', 'stdout' or
'stderr'.

This problem appears in code that handles either some input/output file
with stdin or stdout, as the business logic is basically the same no
matter the stream being used.
However, one would should only close the stream if it was opened via
'fopen'. Consequently, such code usually has a condition like
`if (f && f != stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking
the guarded branch.

CPP-5306
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 72 ++-
 clang/test/Analysis/stream.c  | 11 +++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto &StoreMgr = C.getStoreManager();
+auto &SVB = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call,
   CheckerContext &C) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent &Call,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext &Ctx = TU->getASTContext();
+  const auto &SM = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup(&Ctx.Idents.get(VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 
//===

[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

steakhal wrote:

I didn't mention this in the release notes as I don't think it's that impactful.

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balazs Benics (steakhal)


Changes

'fopen' should return a new FILE handle, thus we should assume it can't alias 
with commonly used FILE handles, such as with 'stdin', 'stdout' or 'stderr'.

This problem appears in code that handles either some input/output file with 
stdin or stdout, as the business logic is basically the same no matter the 
stream being used.
However, one would should only close the stream if it was opened via 'fopen'. 
Consequently, such code usually has a condition like `if (f && f != 
stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking the 
guarded branch.

CPP-5306

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


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (+71-1) 
- (modified) clang/test/Analysis/stream.c (+11) 


``diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto &StoreMgr = C.getStoreManager();
+auto &SVB = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call,
   CheckerContext &C) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent &Call,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext &Ctx = TU->getASTContext();
+  const auto &SM = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup(&Ctx.Idents.get(VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 
//===--===//
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index c924cbd36f759..c518820df6ed6 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -498,3 +498,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fread(buffer, 1, 1, f); // expected-warning {{Stream pointer might be NULL}} 
no-crash
   fclose(f);
 }
+
+extern FILE *stdout_like_ptr;
+void no_aliasing(void) {
+  FILE *f = fopen("file", "r");
+  clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
+  clang_analyzer_eval(f == stderr);  // expected-warning {{FALSE}} 
no-TRUE
+  clang_analyzer_eval(f == stdout_like_ptr); // expected-warning {{FALSE}} 
expec

[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits

https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/100085

>From c8148c88a39434501b9dacb374b3ca9d81ee8fdf Mon Sep 17 00:00:00 2001
From: Balazs Benics 
Date: Tue, 23 Jul 2024 08:55:16 +0200
Subject: [PATCH 1/2] [analyzer] Assume the result of 'fopen' can't alias with
 'std{in,out,err}'

'fopen' should return a new FILE handle, thus we should assume it can't
alias with commonly used FILE handles, such as with 'stdin', 'stdout' or
'stderr'.

This problem appears in code that handles either some input/output file
with stdin or stdout, as the business logic is basically the same no
matter the stream being used.
However, one would should only close the stream if it was opened via
'fopen'. Consequently, such code usually has a condition like
`if (f && f != stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking
the guarded branch.

CPP-5306
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 72 ++-
 clang/test/Analysis/stream.c  | 11 +++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto &StoreMgr = C.getStoreManager();
+auto &SVB = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call,
   CheckerContext &C) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent &Call,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext &Ctx = TU->getASTContext();
+  const auto &SM = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup(&Ctx.Idents.get(VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 
//===--===//
diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index c924cbd36f759..c518820df6ed6 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -498,3 +498,14 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fread(buffer, 1, 1, f); // expected-warning {{Stream pointer might be NULL}} 
no-crash
   fclose(f);
 }
+
+extern FILE *stdout_like_ptr;
+void no_aliasing(void) {
+  FILE *f = fopen("file", "r");
+  clang_analyzer_eval(f == stdout);  // expected-warning {{FALSE}} 
no-TRUE
+  clang_analy

[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread via cfe-commits


@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())

cor3ntin wrote:

could we have a function - or at least a lambda - that avoid the repetition of 
that 3 times?

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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread via cfe-commits


@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
   if (NTTP->hasPlaceholderTypeConstraint())
 HasConstrainedParameters = true;
 } else if (const auto *TTP = dyn_cast(P)) {
-  if (!IsPack &&
-  TTP->getTemplateParameters()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
-} else if (const auto *TTP = dyn_cast(P)) {
-  if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
-if (TC->getImmediatelyDeclaredConstraint()
-->containsUnexpandedParameterPack())
+  if (!IsPack) {
+if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
+else if (TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
+} else if (const auto *TTP = dyn_cast(P)) {
+  if (!IsPack && TTP->hasDefaultArgument() &&
+  TTP->getDefaultArgument()
+  .getArgument()
+  .containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
+  } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
+ TC && TC->getImmediatelyDeclaredConstraint()
+   ->containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;

cor3ntin wrote:

Do we properly handle template template parameters?

```cpp
template  typename...T>
void f() {
(([] typename U = T> {}(), T()), ...);
};
```

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


[clang] Diag mismatch 97878 (PR #99824)

2024-07-23 Thread via cfe-commits

cor3ntin wrote:

Thanks a lot of this fix, I think this makes sense.
Can you:
 - Update the title of the PR to be more descriptive
 - Add a release note? (`clang/docs/ReleaseNotes.rst`)

Thanks!

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


[clang] [Clang][Interp] `__builtin_os_log_format_buffer_size` should be an unevaluated builtin (PR #99895)

2024-07-23 Thread Mitch Phillips via cfe-commits

hctim wrote:

Hi,

Unfortunately this patch appears to have introduced a memory leak that was 
detected by the sanitizer buildbots 
(https://lab.llvm.org/buildbot/#/builders/52/builds/1079).

The issue can be reproduced with a minimal ASan build configuration, like:

```
$ cmake \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_USE_LINKER=lld \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-fsanitize=address" \
-DCMAKE_CXX_FLAGS="-fsanitize=address" \
-DLLVM_USE_SANITIZER=Address \
/path/to/llvm/llvm

$ LIT_OPTS='--filter builtins' ninja check-clang
FAIL: Clang :: CodeGen/builtins.c (501 of 506)  
 11:15:42 [210/894]
 TEST 'Clang :: CodeGen/builtins.c' FAILED 

Exit Code: 1
   

   
Command Output (stderr):
   
--  
   
RUN: at line 1: /usr/local/google/home/mitchp/llvm-build/asan-test/bin/clang 
-cc1 -internal-isystem /usr/local/google/home/mitc
hp/llvm-build/asan-test/lib/clang/19/include -nostdsysteminc -emit-llvm -o 
/usr/local/google/home/mitchp/llvm-build/asan-test/t
ools/clang/test/CodeGen/Output/builtins.c.tmp 
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c
 
+ /usr/local/google/home/mitchp/llvm-build/asan-test/bin/clang -cc1 
-internal-isystem /usr/local/google/home/mitchp/llvm-build/
asan-test/lib/clang/19/include -nostdsysteminc -emit-llvm -o 
/usr/local/google/home/mitchp/llvm-build/asan-test/tools/clang/tes
t/CodeGen/Output/builtins.c.tmp 
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c
   
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c:772:52: 
warning: invalid conversion specifier ':' [-Wformat-in
valid-specifier]
   
  772 |   __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing 
one%", data);  
  |   ~^
   
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c:772:76: 
warning: incomplete format specifier [-Wformat]   
  772 |   __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing 
one%", data);  
  | 
   ^   
2 warnings generated.   
   
RUN: at line 2: not grep __builtin 
/usr/local/google/home/mitchp/llvm-build/asan-test/tools/clang/test/CodeGen/Output/builtins.
c.tmp   
   
+ not grep __builtin 
/usr/local/google/home/mitchp/llvm-build/asan-test/tools/clang/test/CodeGen/Output/builtins.c.tmp
 
RUN: at line 3: /usr/local/google/home/mitchp/llvm-build/asan-test/bin/clang 
-cc1 -internal-isystem /usr/local/google/home/mitc
hp/llvm-build/asan-test/lib/clang/19/include -nostdsysteminc -emit-llvm -triple 
x86_64-darwin-apple -o - /usr/local/google/home
/mitchp/llvm/clang/test/CodeGen/builtins.c | 
/usr/local/google/home/mitchp/llvm-build/asan-test/bin/FileCheck 
/usr/local/google
/home/mitchp/llvm/clang/test/CodeGen/builtins.c 
   
+ /usr/local/google/home/mitchp/llvm-build/asan-test/bin/clang -cc1 
-internal-isystem /usr/local/google/home/mitchp/llvm-build/
asan-test/lib/clang/19/include -nostdsysteminc -emit-llvm -triple 
x86_64-darwin-apple -o - /usr/local/google/home/mitchp/llvm/c
lang/test/CodeGen/builtins.c
+ /usr/local/google/home/mitchp/llvm-build/asan-test/bin/FileCheck 
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builti
ns.c
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c:772:52: 
warning: invalid conversion specifier ':' [-Wformat-in
valid-specifier]
  772 |   __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing 
one%", data);
  |   ~^
/usr/local/google/home/mitchp/llvm/clang/test/CodeGen/builtins.c:772:76: 
warning: incomplete format specifier [-Wformat]
  772 |   __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing 
on

[clang] 5f05d5e - Revert "[Clang][Interp] `__builtin_os_log_format_buffer_size` should be an unevaluated builtin (#99895)"

2024-07-23 Thread Mitch Phillips via cfe-commits

Author: Mitch Phillips
Date: 2024-07-23T11:23:53+02:00
New Revision: 5f05d5ec8f9bb15c0ac29fce843a2c73165ac414

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

LOG: Revert "[Clang][Interp] `__builtin_os_log_format_buffer_size` should be an 
unevaluated builtin (#99895)"

This reverts commit 4572efea90f2ddf51c618790a119ad9b6fc2c7ed.

Reason: Introduced a memory leak that broke the sanitizer buildbots.
More information available in the original pull request
(https://github.com/llvm/llvm-project/pull/99895).

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeEmitter.cpp
clang/test/CodeGen/builtins.c

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp 
b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index fee4432a8f661..a3d4c7d7392da 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -27,8 +27,7 @@ using namespace clang::interp;
 /// Similar information is available via ASTContext::BuiltinInfo,
 /// but that is not correct for our use cases.
 static bool isUnevaluatedBuiltin(unsigned BuiltinID) {
-  return BuiltinID == Builtin::BI__builtin_classify_type ||
- BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
+  return BuiltinID == Builtin::BI__builtin_classify_type;
 }
 
 Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {

diff  --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 1f998236501d2..b41efb59e61db 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm -o %t %s
 // RUN: not grep __builtin %t
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-darwin-apple -o - %s | FileCheck 
%s
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-darwin-apple 
-fexperimental-new-constant-interpreter -o - %s | FileCheck %s
 
 int printf(const char *, ...);
 



___
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 bugprone-tagged-union-member-count (PR #89925)

2024-07-23 Thread Kristóf Umann via cfe-commits


@@ -0,0 +1,125 @@
+//===--- TaggedUnionMemberCountCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TaggedUnionMemberCountCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Casting.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  recordDecl(
+  allOf(isStruct(),
+has(fieldDecl(hasType(recordDecl(isUnion()).bind("union",
+has(fieldDecl(hasType(enumDecl().bind("tags"))
+  .bind("root"),
+  this);
+}
+
+static bool hasMultipleUnionsOrEnums(const RecordDecl *rec) {
+  int tags = 0;
+  int unions = 0;
+  for (const FieldDecl *r : rec->fields()) {
+TypeSourceInfo *info = r->getTypeSourceInfo();
+QualType qualtype = info->getType();
+const Type *type = qualtype.getTypePtr();
+if (type->isUnionType())
+  unions += 1;
+else if (type->isEnumeralType())
+  tags += 1;
+if (tags > 1 || unions > 1)
+  return true;
+  }
+  return false;
+}
+
+static int64_t getNumberOfValidEnumValues(const EnumDecl *ed) {
+  int64_t maxTagValue = std::numeric_limits::min();
+  int64_t minTagValue = std::numeric_limits::max();
+
+  // Heuristic for counter enum constants.
+  //
+  //   enum tag_with_counter {
+  // tag1,
+  // tag2,
+  // tag_count, <-- Searching for these enum constants
+  //   };
+  //
+  // The 'ce' prefix is used to abbreviate counterEnum.
+  // The final tag count is decreased by 1 if and only if:
+  // 1. The number of counting enum constants = 1,
+  int ceCount = 0;
+  // 2. The counting enum constant is the last enum constant that is defined,
+  int ceFirstIndex = 0;
+  // 3. The value of the counting enum constant is the largest out of every 
enum constant.
+  int64_t ceValue = 0;
+
+  int64_t enumConstantsCount = 0;
+  for (auto En : llvm::enumerate(ed->enumerators())) {
+enumConstantsCount += 1;
+
+int64_t enumValue = En.value()->getInitVal().getExtValue();
+StringRef enumName = En.value()->getName();
+
+if (enumValue > maxTagValue)
+  maxTagValue = enumValue;
+if (enumValue < minTagValue)
+  minTagValue = enumValue;
+
+if (enumName.ends_with_insensitive("count")) {
+  if (ceCount == 0) {
+ceFirstIndex = En.index();
+  }
+  ceValue = enumValue;
+  ceCount += 1;
+}
+  }
+
+  int64_t validValuesCount = maxTagValue - minTagValue + 1;
+  if (ceCount == 1 &&
+  ceFirstIndex == enumConstantsCount - 1 &&
+  ceValue == maxTagValue) {
+validValuesCount -= 1;
+  }
+  return validValuesCount;
+}
+
+void TaggedUnionMemberCountCheck::check(
+const MatchFinder::MatchResult &Result) {
+  const auto *root = Result.Nodes.getNodeAs("root");
+  const auto *unionMatch = Result.Nodes.getNodeAs("union");
+  const auto *tagMatch = Result.Nodes.getNodeAs("tags");
+
+  if (hasMultipleUnionsOrEnums(root))
+return;
+
+  int64_t unionMemberCount = llvm::range_size(unionMatch->fields());
+  int64_t tagCount = getNumberOfValidEnumValues(tagMatch);
+
+  // FIXME: Maybe a emit a note when a counter enum constant was found.

Szelethus wrote:

I see it the other way around -- if we use the heuristic, we should be upfront 
about it. Something like "Assuming this constant is an auxiliary value, and not 
counting it towards the number of enum values" would actually help users 
understand how the check is thinking and would ease deciding if the report is 
true or a FP.

We could just disable the whole thing, but I think the heuristic is reasonable, 
and it seems to be backed by some early results as well like this one (look for 
XSValue::DataType and mind that the warning message may have changed since the 
analysis): 
https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?review-status=Unreviewed&review-status=Confirmed%20bug&detection-status=New&detection-status=Reopened&detection-status=Unresolved&is-unique=on&run=%2atigbr_variant_baseline&newcheck=%2atigbr_variant_patched&diff-type=New&checker-name=bugprone-tagged-union-member-count&report-id=5402120&report-hash=a5b84022bf3ce1a003183dd88bc4e0d1&report-filepath=%2aXSValue.hpp

https://github.com/llvm/llvm-project/pull/89925
___
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 bugprone-tagged-union-member-count (PR #89925)

2024-07-23 Thread Kristóf Umann via cfe-commits


@@ -0,0 +1,182 @@
+//===--- TaggedUnionMemberCountCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TaggedUnionMemberCountCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+TaggedUnionMemberCountCheck::TaggedUnionMemberCountCheck(
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  StrictModeIsEnabled(Options.get(StrictModeIsEnabledOptionName, true)),
+  CountingEnumHeuristicIsEnabled(
+  Options.get(CountingEnumHeuristicIsEnabledOptionName, true)),
+  RawCountingEnumPrefixes(Options.get(CountingEnumPrefixesOptionName, "")),
+  RawCountingEnumSuffixes(
+  Options.get(CountingEnumSuffixesOptionName, "count")),
+  ParsedCountingEnumPrefixes(
+  utils::options::parseStringList(RawCountingEnumPrefixes)),
+  ParsedCountingEnumSuffixes(
+  utils::options::parseStringList(RawCountingEnumSuffixes)) {}
+
+void TaggedUnionMemberCountCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, StrictModeIsEnabledOptionName, StrictModeIsEnabled);
+  Options.store(Opts, CountingEnumHeuristicIsEnabledOptionName,
+CountingEnumHeuristicIsEnabled);
+  Options.store(Opts, CountingEnumPrefixesOptionName, RawCountingEnumPrefixes);
+  Options.store(Opts, CountingEnumSuffixesOptionName, RawCountingEnumSuffixes);
+}
+
+void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  recordDecl(
+  allOf(anyOf(isStruct(), isClass()),
+
has(fieldDecl(hasType(qualType(hasCanonicalType(recordType()
+.bind("union")),
+has(fieldDecl(hasType(qualType(hasCanonicalType(enumType()
+.bind("tags"
+  .bind("root"),
+  this);
+}
+
+static bool isUnion(const FieldDecl *R) {
+  return R->getType().getCanonicalType().getTypePtr()->isUnionType();
+}
+
+static bool isEnum(const FieldDecl *R) {
+  return R->getType().getCanonicalType().getTypePtr()->isEnumeralType();
+}
+
+static bool hasMultipleUnionsOrEnums(const RecordDecl *Rec) {
+  return llvm::count_if(Rec->fields(), isUnion) > 1 ||
+ llvm::count_if(Rec->fields(), isEnum) > 1;
+}
+
+static bool signEquals(const llvm::APSInt &A, const llvm::APSInt &B) {
+  return (A.isNegative() && B.isNegative()) ||
+ (A.isStrictlyPositive() && B.isStrictlyPositive()) ||
+ (A.isZero() && B.isZero());
+}
+
+static bool greaterBySign(const llvm::APSInt &A, const llvm::APSInt &B) {
+  return (A.isNonNegative() && B.isNegative()) ||
+ (A.isStrictlyPositive() && B.isNonPositive());
+}
+
+bool TaggedUnionMemberCountCheck::isCountingEnumLikeName(
+StringRef Name) const noexcept {
+  if (llvm::any_of(ParsedCountingEnumPrefixes,
+   [&Name](const StringRef &prefix) -> bool {
+ return Name.starts_with_insensitive(prefix);
+   }))
+return true;
+  if (llvm::any_of(ParsedCountingEnumSuffixes,
+   [&Name](const StringRef &suffix) -> bool {
+ return Name.ends_with_insensitive(suffix);
+   }))
+return true;
+  return false;
+}
+
+size_t TaggedUnionMemberCountCheck::getNumberOfValidEnumValues(
+const EnumDecl *Ed) const noexcept {
+  bool FoundMax = false;
+  llvm::APSInt MaxTagValue;
+  llvm::SmallSet EnumValues;
+
+  // Heuristic for counter enum constants.
+  //
+  //   enum tag_with_counter {
+  // tag1,
+  // tag2,
+  // tag_count, <-- Searching for these enum constants
+  //   };
+  //
+  // The final tag count is decreased by 1 if and only if:
+  // 1. There is only one counting enum constant,
+  // 2. The counting enum constant is the last enum constant that is defined,
+  // 3. The value of the counting enum constant is the largest out of every 
enum
+  //constant.
+  // The 'ce' prefix is a shorthand for 'counting enum'.
+  size_t CeCount = 0;
+  bool IsLast = false;
+  llvm::APSInt CeValue = llvm::APSInt::get(0);
+
+  for (const auto &&[index, enumerator] : llvm::enumerate(Ed->enumerators())) {
+const llvm::APSInt Val = enumerator->getInitVal();
+EnumValues.insert(Val);
+if (FoundMax) {
+  if (greaterBySign(Val, MaxTagValue) ||
+  (signEquals(Val, MaxTagValue) && Val > MaxTagValue)) {
+MaxTagValue = Val;
+  }
+} else {
+  MaxTagValue = Val;
+  FoundMax = true;
+}
+
+if (CountingEnumHeuristicIsEnabled) {
+  i

[clang] [clang][CodeGen] Don't crash on output whose size is zero. (PR #99849)

2024-07-23 Thread Yeting Kuo via cfe-commits

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


[clang] [Clang][AST] Don't use canonical type when checking dependence in Type::isOverloadable (PR #98563)

2024-07-23 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/98563

>From 5cefddec13ca2bafb58a6f714fd2bef435166c8d Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Thu, 11 Jul 2024 18:28:50 -0400
Subject: [PATCH 1/2] [Clang][AST] Don't use canonical type when checking
 dependence in Type::isOverloadable

---
 clang/include/clang/AST/Type.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a2194361abd53..8b236af78ea22 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8438,7 +8438,7 @@ inline bool Type::isUndeducedType() const {
 /// Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {
-  if (!CanonicalType->isDependentType())
+  if (!isDependentType())
 return isRecordType() || isEnumeralType();
   return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
  !isMemberPointerType();

>From d60492d7b6be408a49df1b183a1a48169fd4d03c Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Mon, 22 Jul 2024 11:39:41 -0400
Subject: [PATCH 2/2] [FOLD] add tests

---
 clang/test/SemaCXX/dependent-typeof.cpp | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 clang/test/SemaCXX/dependent-typeof.cpp

diff --git a/clang/test/SemaCXX/dependent-typeof.cpp 
b/clang/test/SemaCXX/dependent-typeof.cpp
new file mode 100644
index 0..abfbf4a24081e
--- /dev/null
+++ b/clang/test/SemaCXX/dependent-typeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template
+void f() {
+  decltype(B) x = false;
+  __typeof__(B) y = false;
+  !x;
+  !y;
+}

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


[clang] [clang] [C++20] Defaulted operator== doesn't lookup in using-directive properly #97087 (PR #99542)

2024-07-23 Thread via cfe-commits


@@ -124,7 +124,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
   ? diag::warn_cxx98_compat_defaulted_deleted_function
   : diag::ext_defaulted_deleted_function)
 << 0 /* defaulted */;
-  Actions.SetDeclDefaulted(FnD, KWLoc);
+  Actions.SetDeclDefaulted(nullptr, FnD, KWLoc);

ofAlpaca wrote:

Got it, I will go with `/*Scope=*/`.

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


[clang-tools-extra] dd23b34 - [clang-tidy][performance-unnecessary-value-param] Make `handleMoveFix` virtual (#99867)

2024-07-23 Thread via cfe-commits

Author: Clement Courbet
Date: 2024-07-23T11:32:26+02:00
New Revision: dd23b347890512ee82741648e941df24e1d666ee

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

LOG: [clang-tidy][performance-unnecessary-value-param] Make `handleMoveFix` 
virtual (#99867)

... so that downstream checks can override behaviour to do additional
processing.

Refactor the rest of the logic to `handleConstRefFix` (which is also
`virtual`).

This is otherwise and NFC.

This is similar to https://github.com/llvm/llvm-project/pull/73921 but
for `performance-unnecessary-value-param`.

Added: 


Modified: 
clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
index 5a4c2363bd8af..3a255c5c133f1 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
@@ -119,65 +119,72 @@ void UnnecessaryValueParamCheck::check(const 
MatchFinder::MatchResult &Result) {
 }
   }
 
-  const size_t Index = llvm::find(Function->parameters(), Param) -
-   Function->parameters().begin();
+  handleConstRefFix(*Function, *Param, *Result.Context);
+}
+
+void UnnecessaryValueParamCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) 
{
+  Inserter.registerPreprocessor(PP);
+}
+
+void UnnecessaryValueParamCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IncludeStyle", Inserter.getStyle());
+  Options.store(Opts, "AllowedTypes",
+utils::options::serializeStringList(AllowedTypes));
+}
+
+void UnnecessaryValueParamCheck::onEndOfTranslationUnit() {
+  MutationAnalyzerCache.clear();
+}
+
+void UnnecessaryValueParamCheck::handleConstRefFix(const FunctionDecl 
&Function,
+   const ParmVarDecl &Param,
+   ASTContext &Context) {
+  const size_t Index =
+  llvm::find(Function.parameters(), &Param) - 
Function.parameters().begin();
+  const bool IsConstQualified =
+  Param.getType().getCanonicalType().isConstQualified();
 
   auto Diag =
-  diag(Param->getLocation(),
+  diag(Param.getLocation(),
"the %select{|const qualified }0parameter %1 is copied for each "
"invocation%select{ but only used as a const reference|}0; consider 
"
"making it a %select{const |}0reference")
-  << IsConstQualified << paramNameOrIndex(Param->getName(), Index);
+  << IsConstQualified << paramNameOrIndex(Param.getName(), Index);
   // Do not propose fixes when:
   // 1. the ParmVarDecl is in a macro, since we cannot place them correctly
   // 2. the function is virtual as it might break overrides
   // 3. the function is referenced outside of a call expression within the
   //compilation unit as the signature change could introduce build errors.
   // 4. the function is an explicit template/ specialization.
-  const auto *Method = llvm::dyn_cast(Function);
-  if (Param->getBeginLoc().isMacroID() || (Method && Method->isVirtual()) ||
-  isReferencedOutsideOfCallExpr(*Function, *Result.Context) ||
-  Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+  const auto *Method = llvm::dyn_cast(&Function);
+  if (Param.getBeginLoc().isMacroID() || (Method && Method->isVirtual()) ||
+  isReferencedOutsideOfCallExpr(Function, Context) ||
+  Function.getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
 return;
-  for (const auto *FunctionDecl = Function; FunctionDecl != nullptr;
+  for (const auto *FunctionDecl = &Function; FunctionDecl != nullptr;
FunctionDecl = FunctionDecl->getPreviousDecl()) {
 const auto &CurrentParam = *FunctionDecl->getParamDecl(Index);
-Diag << utils::fixit::changeVarDeclToReference(CurrentParam,
-   *Result.Context);
+Diag << utils::fixit::changeVarDeclToReference(CurrentParam, Context);
 // The parameter of each declaration needs to be checked individually as to
 // whether it is const or not as constness can 
diff er between definition and
 // declaration.
 if (!CurrentParam.getType().getCanonicalType().isConstQualified()) {
   if (std::optional Fix = utils::fixit::addQualifierToVarDecl(
-  CurrentParam, *Result.Context, DeclSpec::TQ::TQ_const))
+  CurrentParam, Context, DeclSpec::TQ::TQ_const))
 Diag << *Fix;
 }
   }
 }
 
-v

[clang-tools-extra] [clang-tidy][performance-unnecessary-value-param] Make `handleMoveFix` virtual (PR #99867)

2024-07-23 Thread Clement Courbet via cfe-commits

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


[clang] [analyzer] Model builtin-like functions as builtin functions (PR #99886)

2024-07-23 Thread Donát Nagy via cfe-commits


@@ -570,13 +570,8 @@ void differentBranchesTest(int i) {
   {
 A a;
 a.foo() > 0 ? a.foo() : A(std::move(a)).foo();
-#ifdef DFS
-// peaceful-note@-2 {{Assuming the condition is false}}
-// peaceful-note@-3 {{'?' condition is false}}
-#else
-// peaceful-note@-5 {{Assuming the condition is true}}
-// peaceful-note@-6 {{'?' condition is true}}
-#endif

NagyDonat wrote:

I see, thanks for the explanation. I agree that this isn't an important 
question and simply adjusting the TC is the right solution.

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


[clang] [Driver] Have getTargetSubDirPath better match get_compiler_rt_target (PR #100091)

2024-07-23 Thread Rainer Orth via cfe-commits

https://github.com/rorth created 
https://github.com/llvm/llvm-project/pull/100091

As explained in [[Driver] Support non-canonical triples with new runtime lib 
layout](https://reviews.llvm.org/D133407), there are massive problems if 
`clang`'s and `compiler-rt`'s ideas of the target triple don't match. This can 
happen e.g. on Solaris/amd64 (`amd64-pc-solaris2.11`, `amd64` being the 
customary name of 64-bit x86 on that target) or Linux/sparc64 
(`sparc64-unknown-linux-gnu`, where `config.sub` returns the `sparc64` form by 
default).

While some adjustments have been made in `compiler-rt` ([[compiler-rt] Handle 
non-canonical triples with new runtime lib
layout](https://reviews.llvm.org/D133406)), the `clang` side is still unfixed 
and the previous patch doesn't work any longer.

As the stop-gap measure, this patch takes two of the adjustments made in 
`CompilerRTUtils.cmake` (`get_compiler_rt_target`) and applies them to 
`ToolChain.cpp` (`getTargetSubDirPath`) which currently takes the target triple 
as is, creating a mismatch between `clang`s idea of the layout of 
`lib/clang//` and where `compiler-rt` actually installs the 
runtime libs.

The tests had to be trimmed massively because `clang -print-runtime-dir` lies 
since PR #87866: when the runtime libs are installed in the projects/classic 
layout, `clang` still emits the nonexisting runtimes layout.

Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.

>From 4513f179765b432305bf79c71f691fcbb3fdc264 Mon Sep 17 00:00:00 2001
From: Rainer Orth 
Date: Tue, 23 Jul 2024 11:36:07 +0200
Subject: [PATCH] [Driver] Have getTargetSubDirPath better match
 get_compiler_rt_target

As explained in [[Driver] Support non-canonical triples with new runtime
lib layout](https://reviews.llvm.org/D133407), there are massive problems
if `clang`'s and `compiler-rt`'s ideas of the target triple don't match.
This can happen e.g. on Solaris/amd64 (`amd64-pc-solaris2.11`, `amd64`
being the customary name of 64-bit x86 on that target) or Linux/sparc64
(`sparc64-unknown-linux-gnu`, where `config.sub` returns the `sparc64` form
by default).

While some adjustments have been made in `compiler-rt` ([[compiler-rt]
Handle non-canonical triples with new runtime lib
layout](https://reviews.llvm.org/D133406)), the `clang` side is still
unfixed and the previous patch doesn't work any longer.

As the stop-gap measure, this patch takes two of the adjustments made in
`CompilerRTUtils.cmake` (`get_compiler_rt_target`) and applies them to
`ToolChain.cpp` (`getTargetSubDirPath`) which currently takes the target
triple as is, creating a mismatch between `clang`s idea of the layout of
`lib/clang//` and where `compiler-rt` actually installs the
runtime libs.

The tests had to be trimmed massively because `clang -print-runtime-dir`
lies since PR #87866: when the runtime libs are installed in the
projects/classic layout, `clang` still emits the nonexisting runtimes
layout.

Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.
---
 clang/lib/Driver/ToolChain.cpp| 25 -
 .../lib/sparc64-linux-gnu/Scrt1.o |  0
 .../lib/sparc64-linux-gnu/crti.o  |  0
 .../lib/sparc64-linux-gnu/crtn.o  |  0
 .../lib/gcc/sparc64-linux-gnu/12/crtbeginS.o  |  0
 .../lib/gcc/sparc64-linux-gnu/12/crtendS.o|  0
 .../usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a |  0
 .../lib/gcc/sparc64-linux-gnu/12/libgcc_s.so  |  0
 .../usr/lib/sparc64-linux-gnu/libc.so |  0
 .../usr/lib/sparc64-linux-gnu/libdl.so|  0
 .../usr/lib/sparc64-linux-gnu/libm.so |  0
 .../usr/lib/sparc64-linux-gnu/libpthread.so   |  0
 .../usr/lib/sparc64-linux-gnu/libresolv.so|  0
 .../usr/lib/sparc64-linux-gnu/librt.so|  0
 .../libclang_rt.ubsan_standalone.a|  0
 .../libclang_rt.ubsan_standalone.a|  0
 .../Driver/noncanon-per-target-runtime-dir.c  | 20 +++
 clang/test/Driver/runtime-layout.c| 35 +++
 18 files changed, 72 insertions(+), 8 deletions(-)
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so
 create mode 100644 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so
 create mode 100644 
clang/tes

[clang] [Driver] Have getTargetSubDirPath better match get_compiler_rt_target (PR #100091)

2024-07-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Rainer Orth (rorth)


Changes

As explained in [[Driver] Support non-canonical triples with new runtime lib 
layout](https://reviews.llvm.org/D133407), there are massive problems if 
`clang`'s and `compiler-rt`'s ideas of the target triple don't match. This can 
happen e.g. on Solaris/amd64 (`amd64-pc-solaris2.11`, `amd64` being the 
customary name of 64-bit x86 on that target) or Linux/sparc64 
(`sparc64-unknown-linux-gnu`, where `config.sub` returns the `sparc64` form by 
default).

While some adjustments have been made in `compiler-rt` ([[compiler-rt] Handle 
non-canonical triples with new runtime lib
layout](https://reviews.llvm.org/D133406)), the `clang` side is still unfixed 
and the previous patch doesn't work any longer.

As the stop-gap measure, this patch takes two of the adjustments made in 
`CompilerRTUtils.cmake` (`get_compiler_rt_target`) and applies them to 
`ToolChain.cpp` (`getTargetSubDirPath`) which currently takes the target triple 
as is, creating a mismatch between `clang`s idea of the layout of 
`lib/clang//` and where `compiler-rt` actually 
installs the runtime libs.

The tests had to be trimmed massively because `clang -print-runtime-dir` lies 
since PR #87866: when the runtime libs are installed in the 
projects/classic layout, `clang` still emits the nonexisting runtimes layout.

Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.

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


18 Files Affected:

- (modified) clang/lib/Driver/ToolChain.cpp (+17-8) 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so 
() 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so 
() 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libm.so 
() 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libpthread.so
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libresolv.so
 () 
- (added) 
clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/librt.so 
() 
- (added) 
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a
 () 
- (added) 
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a
 () 
- (added) clang/test/Driver/noncanon-per-target-runtime-dir.c (+20) 
- (added) clang/test/Driver/runtime-layout.c (+35) 


``diff
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 20a555afb8092..10434b987ae1d 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -766,9 +766,19 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
 return {};
   };
 
-  if (auto Path = getPathForTriple(getTriple()))
+  llvm::Triple Triple = getTriple();
+
+  // Try triple as is.
+  if (auto Path = getPathForTriple(Triple))
 return *Path;
 
+  // Match transformations in CompilerRTUtils.cmake:get_compiler_rt_target.
+  if (Triple.getArchName() == "amd64")
+Triple.setArch(Triple::x86_64);
+
+  if (Triple.getArchName() == "sparc64")
+Triple.setArch(Triple::sparcv9);
+
   // When building with per target runtime directories, various ways of naming
   // the Arm architecture may have been normalised to simply "arm".
   // For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
@@ -784,16 +794,15 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
   //
   // M profile Arm is bare metal and we know they will not be using the per
   // target runtime directory layout.
-  if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
-llvm::Triple ArmTriple = getTriple();
-ArmTriple.setArch(Triple::arm);
-if (auto Path = getPathForTriple(ArmTriple))
-  return *Path;
-  }
+  if (Triple.getArch() == Triple::arm && !Triple.isArmMClass())
+Triple.setArch(Triple::arm);
 
-  if (getTriple().isAndroid())
+  if (Triple.isAndroid())
 return getFallbackAndroidTargetPath(BaseDir);
 
+  if (auto Path = getPathForTriple(Triple))
+return *Path;
+
   return {};
 }
 
diff --git 
a/clang/test/Driver/Inputs

[clang] [clang] [C++20] Defaulted operator== doesn't lookup in using-directive properly #97087 (PR #99542)

2024-07-23 Thread via cfe-commits

https://github.com/ofAlpaca updated 
https://github.com/llvm/llvm-project/pull/99542

>From 2a381b47002db3c7a119a893c1a70e0b1604151f Mon Sep 17 00:00:00 2001
From: schiang 
Date: Thu, 18 Jul 2024 09:53:35 +0800
Subject: [PATCH 1/4] Pass 'Scope *' for 'SetDeclDefaulted()' and related utlis

---
 clang/include/clang/Sema/Sema.h| 4 ++--
 clang/lib/Parse/ParseCXXInlineMethods.cpp  | 2 +-
 clang/lib/Parse/Parser.cpp | 2 +-
 clang/lib/Sema/SemaDeclCXX.cpp | 8 
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 48dff1b76cc57..f887fc261a07e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5995,9 +5995,9 @@ class Sema final : public SemaBase {
   void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc);
   void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc,
   StringLiteral *Message = nullptr);
-  void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
+  void SetDeclDefaulted(Scope *S, Decl *dcl, SourceLocation DefaultLoc);
 
-  void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind,
+  void SetFunctionBodyKind(Scope *S, Decl *D, SourceLocation Loc, FnBodyKind 
BodyKind,
StringLiteral *DeletedMessage = nullptr);
   void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D);
   ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr);
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp 
b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 9ccbbf9a7d5d0..75a835f512144 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -124,7 +124,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
   ? diag::warn_cxx98_compat_defaulted_deleted_function
   : diag::ext_defaulted_deleted_function)
 << 0 /* defaulted */;
-  Actions.SetDeclDefaulted(FnD, KWLoc);
+  Actions.SetDeclDefaulted(nullptr, FnD, KWLoc);
   if (auto *DeclAsFunction = dyn_cast(FnD)) {
 DeclAsFunction->setRangeEnd(KWEndLoc);
   }
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 5ebe71e496a2e..f1d98bced80b2 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1479,7 +1479,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator 
&D,
   D.getMutableDeclSpec().abort();
 
   if (BodyKind != Sema::FnBodyKind::Other) {
-Actions.SetFunctionBodyKind(Res, KWLoc, BodyKind, DeletedMessage);
+Actions.SetFunctionBodyKind(getCurScope(), Res, KWLoc, BodyKind, 
DeletedMessage);
 Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;
 Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false);
 return Res;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index f24912cde275a..e57057fac10c6 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -17940,7 +17940,7 @@ void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation 
DelLoc,
   Fn->setDeletedAsWritten(true, Message);
 }
 
-void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
+void Sema::SetDeclDefaulted(Scope *S, Decl *Dcl, SourceLocation DefaultLoc) {
   if (!Dcl || Dcl->isInvalidDecl())
 return;
 
@@ -18016,7 +18016,7 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation 
DefaultLoc) {
   }
 
   if (DefKind.isComparison()) {
-if (CheckExplicitlyDefaultedComparison(nullptr, FD, 
DefKind.asComparison()))
+if (CheckExplicitlyDefaultedComparison(S, FD, DefKind.asComparison()))
   FD->setInvalidDecl();
 else
   DefineDefaultedComparison(DefaultLoc, FD, DefKind.asComparison());
@@ -18050,14 +18050,14 @@ void 
Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) {
   }
 }
 
-void Sema::SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind 
BodyKind,
+void Sema::SetFunctionBodyKind(Scope *S, Decl *D, SourceLocation Loc, 
FnBodyKind BodyKind,
StringLiteral *DeletedMessage) {
   switch (BodyKind) {
   case FnBodyKind::Delete:
 SetDeclDeleted(D, Loc, DeletedMessage);
 break;
   case FnBodyKind::Default:
-SetDeclDefaulted(D, Loc);
+SetDeclDefaulted(S, D, Loc);
 break;
   case FnBodyKind::Other:
 llvm_unreachable(
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 01432301633ed..65a755cb69048 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4856,7 +4856,7 @@ bool 
TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
: DFI);
   }
 
-  SemaRef.SetDeclDefaulted(New, Tmpl->getLocation());
+  SemaRef.SetDeclDefaulted(nullptr, New, Tmpl->getLocation());
   return false;
 }
 
@@ -

[clang] [Clang][AST] Don't use canonical type when checking dependence in Type::isOverloadable (PR #98563)

2024-07-23 Thread via cfe-commits

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

LGTM, modulo
 - missing release note
 -  can you move the test in a GH97646 namespace and put it in `decltype.cpp`,
  or rename `typeof_unqual.cpp` to typeof.cpp and put it there?

Maybe, while you are at it, add a test for `__typeof_unqual`

Thanks!

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


[clang] [Clang][CodeGen] Add metadata for load from reference (PR #98746)

2024-07-23 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

Compile-time impact: 
http://llvm-compile-time-tracker.com/compare.php?from=f0fad9f3e00dbe8e58024d1c98e36b7b9b1b17a9&to=f01369d38b67364b5c35bf87984f813a53ce18d1&stat=instructions%3Au

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


[clang] f18dd9e - Reapply "[Clang][Interp] `__builtin_os_log_format_buffer_size` should be an unevaluated builtin (#99895)"

2024-07-23 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-07-23T11:57:40+02:00
New Revision: f18dd9edec9c2135a8906d795258a8c5a24f74f3

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

LOG: Reapply "[Clang][Interp] `__builtin_os_log_format_buffer_size` should be 
an unevaluated builtin (#99895)"

This reverts commit 5f05d5ec8f9bb15c0ac29fce843a2c73165ac414.

Reapply the original commit without the test. The memory leak is caused
by a well known problem in the new constant interpreter.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeEmitter.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp 
b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index a3d4c7d7392da..fee4432a8f661 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -27,7 +27,8 @@ using namespace clang::interp;
 /// Similar information is available via ASTContext::BuiltinInfo,
 /// but that is not correct for our use cases.
 static bool isUnevaluatedBuiltin(unsigned BuiltinID) {
-  return BuiltinID == Builtin::BI__builtin_classify_type;
+  return BuiltinID == Builtin::BI__builtin_classify_type ||
+ BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
 }
 
 Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {



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


[clang-tools-extra] Draft: Create a new check to look for mis-use in calls that take iterators (PR #99917)

2024-07-23 Thread Nathan James via cfe-commits

https://github.com/njames93 updated 
https://github.com/llvm/llvm-project/pull/99917

>From e71d153d953f1e30f7480973bcae2a16bf51711f Mon Sep 17 00:00:00 2001
From: Nathan James 
Date: Tue, 23 Jul 2024 10:59:45 +0100
Subject: [PATCH] Create a new check to look for mis-use in calls that take
 iterators

Looks for various patterns of functions that take arguments calling
begin/end or similar for common mistakes
---
 .../bugprone/BugproneTidyModule.cpp   |   3 +
 .../clang-tidy/bugprone/CMakeLists.txt|   1 +
 .../bugprone/IncorrectIteratorsCheck.cpp  | 754 ++
 .../bugprone/IncorrectIteratorsCheck.h|  45 ++
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../checks/bugprone/incorrect-iterators.rst   | 121 +++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checkers/bugprone/incorrect-iterators.cpp | 239 ++
 8 files changed, 1170 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-iterators.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-iterators.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 689eb92a3d8d1..cea040b81878a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -33,6 +33,7 @@
 #include "InaccurateEraseCheck.h"
 #include "IncDecInConditionsCheck.h"
 #include "IncorrectEnableIfCheck.h"
+#include "IncorrectIteratorsCheck.h"
 #include "IncorrectRoundingsCheck.h"
 #include "InfiniteLoopCheck.h"
 #include "IntegerDivisionCheck.h"
@@ -139,6 +140,8 @@ class BugproneModule : public ClangTidyModule {
 "bugprone-inaccurate-erase");
 CheckFactories.registerCheck(
 "bugprone-incorrect-enable-if");
+CheckFactories.registerCheck(
+"bugprone-incorrect-iterators");
 CheckFactories.registerCheck(
 "bugprone-return-const-ref-from-parameter");
 CheckFactories.registerCheck(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index cb0d8ae98bac5..8425dbed0505a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule
   ImplicitWideningOfMultiplicationResultCheck.cpp
   InaccurateEraseCheck.cpp
   IncorrectEnableIfCheck.cpp
+  IncorrectIteratorsCheck.cpp
   ReturnConstRefFromParameterCheck.cpp
   SuspiciousStringviewDataUsageCheck.cpp
   SwitchMissingDefaultCaseCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
new file mode 100644
index 0..af8226d61c867
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
@@ -0,0 +1,754 @@
+//===--- IncorrectIteratorsCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "IncorrectIteratorsCheck.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/ErrorHandling.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+using SVU = llvm::SmallVector;
+/// Checks to see if a all the parameters of a template function with a given
+/// index refer to the same type.
+AST_MATCHER_P(FunctionDecl, areParametersSameTemplateType, SVU, Indexes) {
+  const auto *TemplateDecl = Node.getPrimaryTemplate();
+  if (!TemplateDecl)
+return false;
+  const auto *FuncDecl = TemplateDecl->getTemplatedDecl();
+  if (!FuncDecl)
+return false;
+  assert(!Indexes.empty());
+  if (llvm::any_of(Indexes, [Count(FuncDecl->getNumParams())](unsigned Index) {
+return Index >= Count;
+  }))
+return false;
+  const auto *FirstParam = FuncDecl->getParamDecl(Indexes.front());
+  if (

[clang-tools-extra] Draft: Create a new check to look for mis-use in calls that take iterators (PR #99917)

2024-07-23 Thread Nathan James via cfe-commits

https://github.com/njames93 updated 
https://github.com/llvm/llvm-project/pull/99917

>From 7be8e9d71b61ae669fc80e1dd0eef5e963b1d20c Mon Sep 17 00:00:00 2001
From: Nathan James 
Date: Tue, 23 Jul 2024 10:59:45 +0100
Subject: [PATCH] Create a new check to look for mis-use in calls that take
 iterators

Looks for various patterns of functions that take arguments calling
begin/end or similar for common mistakes
---
 .../bugprone/BugproneTidyModule.cpp   |   3 +
 .../clang-tidy/bugprone/CMakeLists.txt|   1 +
 .../bugprone/IncorrectIteratorsCheck.cpp  | 754 ++
 .../bugprone/IncorrectIteratorsCheck.h|  45 ++
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../checks/bugprone/incorrect-iterators.rst   | 121 +++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checkers/bugprone/incorrect-iterators.cpp | 239 ++
 8 files changed, 1170 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-iterators.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-iterators.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 689eb92a3d8d1..cea040b81878a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -33,6 +33,7 @@
 #include "InaccurateEraseCheck.h"
 #include "IncDecInConditionsCheck.h"
 #include "IncorrectEnableIfCheck.h"
+#include "IncorrectIteratorsCheck.h"
 #include "IncorrectRoundingsCheck.h"
 #include "InfiniteLoopCheck.h"
 #include "IntegerDivisionCheck.h"
@@ -139,6 +140,8 @@ class BugproneModule : public ClangTidyModule {
 "bugprone-inaccurate-erase");
 CheckFactories.registerCheck(
 "bugprone-incorrect-enable-if");
+CheckFactories.registerCheck(
+"bugprone-incorrect-iterators");
 CheckFactories.registerCheck(
 "bugprone-return-const-ref-from-parameter");
 CheckFactories.registerCheck(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index cb0d8ae98bac5..8425dbed0505a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule
   ImplicitWideningOfMultiplicationResultCheck.cpp
   InaccurateEraseCheck.cpp
   IncorrectEnableIfCheck.cpp
+  IncorrectIteratorsCheck.cpp
   ReturnConstRefFromParameterCheck.cpp
   SuspiciousStringviewDataUsageCheck.cpp
   SwitchMissingDefaultCaseCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
new file mode 100644
index 0..af8226d61c867
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
@@ -0,0 +1,754 @@
+//===--- IncorrectIteratorsCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "IncorrectIteratorsCheck.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/ErrorHandling.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+using SVU = llvm::SmallVector;
+/// Checks to see if a all the parameters of a template function with a given
+/// index refer to the same type.
+AST_MATCHER_P(FunctionDecl, areParametersSameTemplateType, SVU, Indexes) {
+  const auto *TemplateDecl = Node.getPrimaryTemplate();
+  if (!TemplateDecl)
+return false;
+  const auto *FuncDecl = TemplateDecl->getTemplatedDecl();
+  if (!FuncDecl)
+return false;
+  assert(!Indexes.empty());
+  if (llvm::any_of(Indexes, [Count(FuncDecl->getNumParams())](unsigned Index) {
+return Index >= Count;
+  }))
+return false;
+  const auto *FirstParam = FuncDecl->getParamDecl(Indexes.front());
+  if (

[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -1599,13 +1599,66 @@ createTypePackElementParameterList(const ASTContext &C, 
DeclContext *DC) {
nullptr);
 }
 
+static TemplateParameterList *createCommonTypeList(const ASTContext &C,
+   DeclContext *DC) {
+  // class... Args
+  auto *Args = TemplateTypeParmDecl::Create(
+  C, DC, {}, {}, /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,

Sirraide wrote:

For `{}` arguments, please include a comment like you did for the integers and 
`nullptr` (or alternatively, in this particular case, since they’re source 
locations, I’d probably just use `SourceLocation()` on its own; then you don’t 
need the comments).

The same applies to all the calls below ofc.

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits

https://github.com/Sirraide commented:

Overall, the implementation seems fine. 

Do we want a release note for this since it’s supposed to be an internal thing? 
CC @AaronBallman 

Also, some documentation *somewhere* as to what this builtin does would be 
nice, even if it’s just in a comment somewhere. It took me a bit to figure out 
what exactly its semantics are supposed to be.

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});

Sirraide wrote:

Yeah, the recursion seems fine here

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -1599,13 +1599,66 @@ createTypePackElementParameterList(const ASTContext &C, 
DeclContext *DC) {
nullptr);
 }
 
+static TemplateParameterList *createCommonTypeList(const ASTContext &C,
+   DeclContext *DC) {
+  // class... Args
+  auto *Args = TemplateTypeParmDecl::Create(
+  C, DC, {}, {}, /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
+  /*Typename=*/false, /*ParameterPack=*/true);
+  Args->setImplicit();

Sirraide wrote:

Is there a reason some of these template param declaration here are marked as 
implicit while others aren’t? I would have expected all of them to be marked as 
implicit.

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -6844,6 +6844,14 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType 
Ty) {
   return Results;
 }
 
+QualType Sema::getTypeMember(StringRef Name, QualType Type) {

Sirraide wrote:

```suggestion
QualType Sema::getTypeMember(QualType Type, StringRef Name) {
```

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -932,6 +932,10 @@ bool Sema::LookupBuiltin(LookupResult &R) {
   R.addDecl(getASTContext().getTypePackElementDecl());
   return true;
 }
+if (II == getASTContext().getCommonTypeName()) {
+  R.addDecl(getASTContext().getCommonTypeDecl());
+  return true;
+}

Sirraide wrote:

This part here is a bit confusing to look at because there’s an `else if` on 
the previous one, but you didn’t use one here. Of course, the `else` is 
unnecessary because we return in the `if` statement anyway, so I’d just remove 
the `else` from the `else if` here to make this a bit easier to read.

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;
+
+  // If sizeof...(T) is one, let T0 denote the sole type constituting the
+  // pack T. The member typedef-name type shall denote the same type, if any, 
as
+  // common_type_t; otherwise there shall be no member type.
+  case 1:
+return lookUpCommonType(Ts[0], Ts[0]);
+
+  // If sizeof...(T) is two, let the first and second types constituting T be
+  // denoted by T1 and T2, respectively, and let D1 and D2 denote the same 
types
+  // as decay_t and decay_t, respectively.
+  case 2: {
+QualType T1 = Ts[0].getAsType();
+QualType T2 = Ts[1].getAsType();
+QualType D1 = S.BuiltinDecay(T1, {});
+QualType D2 = S.BuiltinDecay(T2, {});
+
+// If is_same_v is false or is_same_v is false, let C 
denote
+// the same type, if any, as common_type_t.
+if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2)) {
+  return lookUpCommonType(D1, D2);
+}

Sirraide wrote:

```suggestion
if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2))
  return lookUpCommonType(D1, D2);
```
nit: no braces around single-statement `if`s (unless that single statement is 
egregiously big)

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -2282,6 +2282,10 @@ class Sema final : public SemaBase {
   /// Check to see if a given expression could have '.c_str()' called on it.
   bool hasCStrMethod(const Expr *E);
 
+  // Check whether a type member 'Type::Name' exists, and if yes, return the
+  // type. If there is no type, the QualType is null
+  QualType getTypeMember(StringRef Name, QualType Type);

Sirraide wrote:

```suggestion
  /// Check whether a type member 'Type::Name' exists, and if yes, return the
  /// type. If there is no type, the QualType is null
  QualType getTypeMember(QualType Type, StringRef Name);
```
This should probably be a doc comment.

Nit: since that entails touching this file anyway: I’d also swap the two 
parameters because reading `Type::Name` in the comment but having the first 
parameter be `Name` and the second `Type` makes it a bit harder to read, but 
that might also just be a me problem ;Þ

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -1599,13 +1599,66 @@ createTypePackElementParameterList(const ASTContext &C, 
DeclContext *DC) {
nullptr);
 }
 
+static TemplateParameterList *createCommonTypeList(const ASTContext &C,
+   DeclContext *DC) {
+  // class... Args
+  auto *Args = TemplateTypeParmDecl::Create(
+  C, DC, {}, {}, /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
+  /*Typename=*/false, /*ParameterPack=*/true);
+  Args->setImplicit();
+
+  // 
+  auto *BaseTemplateList =
+  TemplateParameterList::Create(C, {}, {}, Args, {}, nullptr);
+
+  // template  class BaseTemplate
+  auto *BaseTemplate = TemplateTemplateParmDecl::Create(
+  C, DC, {}, /*Depth=*/0, /*Position=*/0, /*ParameterPack=*/false, {},

Sirraide wrote:

In addition to what I’ve already pointed out above, I’d also use `nullptr` 
instead of `{}` for the `Id` parameter here to make this less confusing.

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;
+
+  // If sizeof...(T) is one, let T0 denote the sole type constituting the
+  // pack T. The member typedef-name type shall denote the same type, if any, 
as
+  // common_type_t; otherwise there shall be no member type.
+  case 1:
+return lookUpCommonType(Ts[0], Ts[0]);
+
+  // If sizeof...(T) is two, let the first and second types constituting T be
+  // denoted by T1 and T2, respectively, and let D1 and D2 denote the same 
types
+  // as decay_t and decay_t, respectively.
+  case 2: {
+QualType T1 = Ts[0].getAsType();
+QualType T2 = Ts[1].getAsType();
+QualType D1 = S.BuiltinDecay(T1, {});
+QualType D2 = S.BuiltinDecay(T2, {});
+
+// If is_same_v is false or is_same_v is false, let C 
denote
+// the same type, if any, as common_type_t.
+if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2)) {
+  return lookUpCommonType(D1, D2);
+}
+
+// Otherwise, if decay_t() : declval())>
+// denotes a valid type, let C denote that type.
+{
+  auto CheckConditionalOperands =
+  [&](bool ConstRefQual) -> std::optional {
+EnterExpressionEvaluationContext UnevaluatedContext(
+S, Sema::ExpressionEvaluationContext::Unevaluated);
+Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
+Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
+
+// false
+OpaqueValueExpr CondExpr({}, S.Context.BoolTy,
+ ExprValueKind::VK_PRValue);
+ExprResult Cond = &CondExpr;
+
+auto EVK =
+ConstRefQual ? ExprValueKind::VK_LValue : 
ExprValueKind::VK_PRValue;
+if (ConstRefQual) {
+  D1.addConst();
+  D2.addConst();
+}
+
+// declval()
+OpaqueValueExpr LHSExpr(TemplateLoc, D1, EVK);
+ExprResult LHS = &LHSExpr;
+
+// declval()
+OpaqueValueExpr RHSExpr(TemplateLoc, D2, EVK);
+ExprResult RHS = &RHSExpr;
+
+ExprValueKind VK = VK_PRValue;
+ExprObjectKind OK = OK_Ordinary;
+
+// decltype(false ? declval() : declval())
+QualType Result =
+S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, TemplateLoc);
+
+if (Result.isNull() || SFINAE.hasErrorOccurred())
+  return std::nullopt;
+
+// decay_t() : declval())>
+return S.BuiltinDecay(Result, TemplateLoc);
+  };
+
+  if (auto Res = CheckConditionalOperands(false))
+return Res;
+
+  // Let:
+  // CREF(A) be add_lvalue_reference_t>,
+  // COND-RES(X, Y) be
+  //   decltype(false ? declval()() : declval()()).
+
+  // C++20 only
+  // Otherwise, if COND-RES(CREF(D1), CREF(D2)) denotes a type, let C 
denote
+  // the type decay_t.
+  if (!S.Context.getLangOpts().CPlusPlus20)
+return std::nullopt;
+  return CheckConditionalOperands(true);
+}
+  }
+
+  // If sizeof...(T) is greater than two, let T1, T2, and R, respectively,
+  // denote the first, second, and (pack of) remaining types constituting T. 
Let
+  // C denote the same type, if any, as common_type_t. If there is such
+  // a type C, the member typedef-name type shall denote the same type, if any,
+  // as common_type_t. Otherwise, there shall be no

[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;
+
+  // If sizeof...(T) is one, let T0 denote the sole type constituting the
+  // pack T. The member typedef-name type shall denote the same type, if any, 
as
+  // common_type_t; otherwise there shall be no member type.
+  case 1:
+return lookUpCommonType(Ts[0], Ts[0]);
+
+  // If sizeof...(T) is two, let the first and second types constituting T be
+  // denoted by T1 and T2, respectively, and let D1 and D2 denote the same 
types
+  // as decay_t and decay_t, respectively.
+  case 2: {
+QualType T1 = Ts[0].getAsType();
+QualType T2 = Ts[1].getAsType();
+QualType D1 = S.BuiltinDecay(T1, {});
+QualType D2 = S.BuiltinDecay(T2, {});
+
+// If is_same_v is false or is_same_v is false, let C 
denote
+// the same type, if any, as common_type_t.
+if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2)) {
+  return lookUpCommonType(D1, D2);
+}
+
+// Otherwise, if decay_t() : declval())>
+// denotes a valid type, let C denote that type.
+{
+  auto CheckConditionalOperands =
+  [&](bool ConstRefQual) -> std::optional {
+EnterExpressionEvaluationContext UnevaluatedContext(
+S, Sema::ExpressionEvaluationContext::Unevaluated);
+Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
+Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
+
+// false
+OpaqueValueExpr CondExpr({}, S.Context.BoolTy,
+ ExprValueKind::VK_PRValue);
+ExprResult Cond = &CondExpr;
+
+auto EVK =
+ConstRefQual ? ExprValueKind::VK_LValue : 
ExprValueKind::VK_PRValue;

Sirraide wrote:

```suggestion
auto EVK = ConstRefQual ? VK_LValue : VK_PRValue;
```

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;
+
+  // If sizeof...(T) is one, let T0 denote the sole type constituting the
+  // pack T. The member typedef-name type shall denote the same type, if any, 
as
+  // common_type_t; otherwise there shall be no member type.
+  case 1:
+return lookUpCommonType(Ts[0], Ts[0]);
+
+  // If sizeof...(T) is two, let the first and second types constituting T be
+  // denoted by T1 and T2, respectively, and let D1 and D2 denote the same 
types
+  // as decay_t and decay_t, respectively.
+  case 2: {
+QualType T1 = Ts[0].getAsType();
+QualType T2 = Ts[1].getAsType();
+QualType D1 = S.BuiltinDecay(T1, {});
+QualType D2 = S.BuiltinDecay(T2, {});
+
+// If is_same_v is false or is_same_v is false, let C 
denote
+// the same type, if any, as common_type_t.
+if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2)) {
+  return lookUpCommonType(D1, D2);
+}
+
+// Otherwise, if decay_t() : declval())>
+// denotes a valid type, let C denote that type.
+{
+  auto CheckConditionalOperands =
+  [&](bool ConstRefQual) -> std::optional {
+EnterExpressionEvaluationContext UnevaluatedContext(
+S, Sema::ExpressionEvaluationContext::Unevaluated);
+Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
+Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
+
+// false
+OpaqueValueExpr CondExpr({}, S.Context.BoolTy,
+ ExprValueKind::VK_PRValue);
+ExprResult Cond = &CondExpr;
+
+auto EVK =
+ConstRefQual ? ExprValueKind::VK_LValue : 
ExprValueKind::VK_PRValue;
+if (ConstRefQual) {
+  D1.addConst();
+  D2.addConst();
+}
+
+// declval()
+OpaqueValueExpr LHSExpr(TemplateLoc, D1, EVK);
+ExprResult LHS = &LHSExpr;
+
+// declval()
+OpaqueValueExpr RHSExpr(TemplateLoc, D2, EVK);
+ExprResult RHS = &RHSExpr;
+
+ExprValueKind VK = VK_PRValue;
+ExprObjectKind OK = OK_Ordinary;
+
+// decltype(false ? declval() : declval())
+QualType Result =
+S.CheckConditionalOperands(Cond, LHS, RHS, VK, OK, TemplateLoc);
+
+if (Result.isNull() || SFINAE.hasErrorOccurred())
+  return std::nullopt;
+
+// decay_t() : declval())>
+return S.BuiltinDecay(Result, TemplateLoc);
+  };
+
+  if (auto Res = CheckConditionalOperands(false))
+return Res;
+
+  // Let:
+  // CREF(A) be add_lvalue_reference_t>,
+  // COND-RES(X, Y) be
+  //   decltype(false ? declval()() : declval()()).

Sirraide wrote:

Hmm, I don’t know the logic behind `common_type` too well, but I’m assuming the 
reasoning behind the mouthful that is `declval()()` is so we get a 
`const` lvalue here (because `declval`, from what I can tell, always hands you 
an rvalue)? In that case, the lambda just adding `const` and changing the value 
kind to lvalue should be equivalent, but I want to make sure I’m understanding 
this correctly.

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

[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;

Sirraide wrote:

`QualType` already has a ‘null’ state, so this could just be `return 
QualType();` (in which case the function should just return a `QualType`). Is 
there a reason why we’re using `std::optional` here? I don’t think we really 
use `std::optional` all that often...

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -3058,6 +3058,141 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
   }
 }
 
+static std::optional commonTypeImpl(Sema &S,
+  TemplateName BaseTemplate,
+  SourceLocation TemplateLoc,
+  ArrayRef Ts) {
+  auto lookUpCommonType = [&](TemplateArgument T1,
+  TemplateArgument T2) -> std::optional {
+// Don't bother looking for other specializations if both types are
+// builtins - users aren't allowed to specialize for them
+if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
+  return commonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+
+TemplateArgumentListInfo Args;
+Args.addArgument(TemplateArgumentLoc(
+T1, S.Context.getTrivialTypeSourceInfo(T1.getAsType(;
+Args.addArgument(TemplateArgumentLoc(
+T2, S.Context.getTrivialTypeSourceInfo(T2.getAsType(;
+QualType BaseTemplateInst =
+S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+if (S.RequireCompleteType(TemplateLoc, BaseTemplateInst,
+  diag::err_incomplete_type))
+  return std::nullopt;
+if (QualType Type = S.getTypeMember("type", BaseTemplateInst);
+!Type.isNull()) {
+  return Type;
+}
+return std::nullopt;
+  };
+
+  // Note A: For the common_type trait applied to a template parameter pack T 
of
+  // types, the member type shall be either defined or not present as follows:
+  switch (Ts.size()) {
+
+  // If sizeof...(T) is zero, there shall be no member type.
+  case 0:
+return std::nullopt;
+
+  // If sizeof...(T) is one, let T0 denote the sole type constituting the
+  // pack T. The member typedef-name type shall denote the same type, if any, 
as
+  // common_type_t; otherwise there shall be no member type.
+  case 1:
+return lookUpCommonType(Ts[0], Ts[0]);
+
+  // If sizeof...(T) is two, let the first and second types constituting T be
+  // denoted by T1 and T2, respectively, and let D1 and D2 denote the same 
types
+  // as decay_t and decay_t, respectively.
+  case 2: {
+QualType T1 = Ts[0].getAsType();
+QualType T2 = Ts[1].getAsType();
+QualType D1 = S.BuiltinDecay(T1, {});
+QualType D2 = S.BuiltinDecay(T2, {});
+
+// If is_same_v is false or is_same_v is false, let C 
denote
+// the same type, if any, as common_type_t.
+if (!S.Context.hasSameType(T1, D1) || !S.Context.hasSameType(T2, D2)) {
+  return lookUpCommonType(D1, D2);
+}
+
+// Otherwise, if decay_t() : declval())>
+// denotes a valid type, let C denote that type.
+{
+  auto CheckConditionalOperands =
+  [&](bool ConstRefQual) -> std::optional {
+EnterExpressionEvaluationContext UnevaluatedContext(
+S, Sema::ExpressionEvaluationContext::Unevaluated);
+Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
+Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
+
+// false
+OpaqueValueExpr CondExpr({}, S.Context.BoolTy,
+ ExprValueKind::VK_PRValue);

Sirraide wrote:

```suggestion
OpaqueValueExpr CondExpr(SourceLocation(), S.Context.BoolTy,
 VK_PRValue);
```

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


[clang] [libcxx] [Clang] Add __common_type builtin (PR #99473)

2024-07-23 Thread via cfe-commits


@@ -6844,6 +6844,14 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType 
Ty) {
   return Results;
 }
 
+QualType Sema::getTypeMember(StringRef Name, QualType Type) {

Sirraide wrote:

Also, `SemaChecking` is for ‘extra semantic checking’. It feels a bit weird to 
have this here if it’s used elsewhere. I’d probably just throw this 
implementation into e.g. `SemaType.cpp`.

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


[clang-tools-extra] Create a new check to look for mis-use in calls that take iterators (PR #99917)

2024-07-23 Thread Nathan James via cfe-commits

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


[clang-tools-extra] Create a new check to look for mis-use in calls that take iterators (PR #99917)

2024-07-23 Thread Nathan James via cfe-commits

https://github.com/njames93 updated 
https://github.com/llvm/llvm-project/pull/99917

>From 1b91c22714179e44cc494b6a7adcde2f4b6bc6d6 Mon Sep 17 00:00:00 2001
From: Nathan James 
Date: Tue, 23 Jul 2024 10:59:45 +0100
Subject: [PATCH] Create a new check to look for mis-use in calls that take
 iterators

Looks for various patterns of functions that take arguments calling
begin/end or similar for common mistakes
---
 .../bugprone/BugproneTidyModule.cpp   |   3 +
 .../clang-tidy/bugprone/CMakeLists.txt|   1 +
 .../bugprone/IncorrectIteratorsCheck.cpp  | 757 ++
 .../bugprone/IncorrectIteratorsCheck.h|  45 ++
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../checks/bugprone/incorrect-iterators.rst   | 121 +++
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checkers/bugprone/incorrect-iterators.cpp | 239 ++
 8 files changed, 1173 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/bugprone/incorrect-iterators.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-iterators.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 689eb92a3d8d1..cea040b81878a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -33,6 +33,7 @@
 #include "InaccurateEraseCheck.h"
 #include "IncDecInConditionsCheck.h"
 #include "IncorrectEnableIfCheck.h"
+#include "IncorrectIteratorsCheck.h"
 #include "IncorrectRoundingsCheck.h"
 #include "InfiniteLoopCheck.h"
 #include "IntegerDivisionCheck.h"
@@ -139,6 +140,8 @@ class BugproneModule : public ClangTidyModule {
 "bugprone-inaccurate-erase");
 CheckFactories.registerCheck(
 "bugprone-incorrect-enable-if");
+CheckFactories.registerCheck(
+"bugprone-incorrect-iterators");
 CheckFactories.registerCheck(
 "bugprone-return-const-ref-from-parameter");
 CheckFactories.registerCheck(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index cb0d8ae98bac5..8425dbed0505a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule
   ImplicitWideningOfMultiplicationResultCheck.cpp
   InaccurateEraseCheck.cpp
   IncorrectEnableIfCheck.cpp
+  IncorrectIteratorsCheck.cpp
   ReturnConstRefFromParameterCheck.cpp
   SuspiciousStringviewDataUsageCheck.cpp
   SwitchMissingDefaultCaseCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
new file mode 100644
index 0..afa31e796aad8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectIteratorsCheck.cpp
@@ -0,0 +1,757 @@
+//===--- IncorrectIteratorsCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "IncorrectIteratorsCheck.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/ErrorHandling.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+using SVU = llvm::SmallVector;
+/// Checks to see if a all the parameters of a template function with a given
+/// index refer to the same type.
+AST_MATCHER_P(FunctionDecl, areParametersSameTemplateType, SVU, Indexes) {
+  const auto *TemplateDecl = Node.getPrimaryTemplate();
+  if (!TemplateDecl)
+return false;
+  const auto *FuncDecl = TemplateDecl->getTemplatedDecl();
+  if (!FuncDecl)
+return false;
+  assert(!Indexes.empty());
+  if (llvm::any_of(Indexes, [Count(FuncDecl->getNumParams())](unsigned Index) {
+return Index >= Count;
+  }))
+return false;
+  const auto *FirstParam = FuncDecl->getParamDecl(Indexes.front());
+  if (

[clang] [libcxx] [llvm] Reapply "[Clang] Implement resolution for CWG1835 (#92957)" (PR #98547)

2024-07-23 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@KyunLFA Could you send the commit hash of the clang build which you're using? 
I'm unable to reproduce.

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


[clang] [clang] Add deprecation warning for `-Ofast` driver option (PR #98736)

2024-07-23 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

> This seems to break tests on my Windows box: 
> http://45.33.8.238/win/91548/step_6.txt

This is the failed test:
```
c:\src\llvm-project\out\gn\bin\clang.exe -Ofast -O2 -### -Werror 
C:\src\llvm-project\clang\test\Driver\Ofast.c 2>&1 | 
c:\src\llvm-project\out\gn\bin\filecheck.exe -check-prefix=CHECK-OFAST-O2
--check-prefix=CHECK-OFAST-O2-ALIASING-MSVC  
C:\src\llvm-project\clang\test\Driver\Ofast.c
# executed command: 'c:\src\llvm-project\out\gn\bin\clang.exe' -Ofast -O2 
'-###' -Werror 'C:\src\llvm-project\clang\test\Driver\Ofast.c'
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: 'c:\src\llvm-project\out\gn\bin\filecheck.exe' 
-check-prefix=CHECK-OFAST-O2 --check-prefix=CHECK-OFAST-O2-ALIASING-MSVC 
'C:\src\llvm-project\clang\test\Driver\Ofast.c'
```
Somehow `clang.exe -Ofast -O2 -### -Werror 
C:\src\llvm-project\clang\test\Driver\Ofast.c 2>&1` is not producing any output 
for you, despite `-###` being present. I'm not sure why, but all windows 
buildbots seem to be happy with this patch. Can you investigate further?

CC @AaronBallman @MaskRay 

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


[clang] 363e036 - [AST] NFC: add an assertion for invariant of CXXFoldExpr

2024-07-23 Thread Ilya Biryukov via cfe-commits

Author: Ilya Biryukov
Date: 2024-07-23T12:28:59+02:00
New Revision: 363e036ac002d5af4bb82e303052b806a98086a1

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

LOG: [AST] NFC: add an assertion for invariant of CXXFoldExpr

CXXFoldExpr relies on exactly one of the two operands to have unexpanded
parameter packs. If this invariant does not holds, results of
`getPattern()`, `isLeftFold()` and other related members are incorrect.

Asserting this on construction makes debugging the problems easier as
the failure is happening closer to the code that contains the error.

Also move the constructor to the `.cpp` file to avoid potential ODR
violations from having an `assert` in the header in combination with
precompiled libraries.

Added: 


Modified: 
clang/include/clang/AST/ExprCXX.h
clang/lib/AST/ExprCXX.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index c2feac525c1ea..f86f1818110e6 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4854,15 +4854,7 @@ class CXXFoldExpr : public Expr {
   CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
   SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
   SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
-  std::optional NumExpansions)
-  : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
-LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
-NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
-SubExprs[SubExpr::Callee] = Callee;
-SubExprs[SubExpr::LHS] = LHS;
-SubExprs[SubExpr::RHS] = RHS;
-setDependence(computeDependence(this));
-  }
+  std::optional NumExpansions);
 
   CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
 

diff  --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 8d2a1b5611ccc..e2c9643151126 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1944,3 +1944,22 @@ CXXParenListInitExpr 
*CXXParenListInitExpr::CreateEmpty(ASTContext &C,
  alignof(CXXParenListInitExpr));
   return new (Mem) CXXParenListInitExpr(Empty, NumExprs);
 }
+
+CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
+SourceLocation LParenLoc, Expr *LHS,
+BinaryOperatorKind Opcode,
+SourceLocation EllipsisLoc, Expr *RHS,
+SourceLocation RParenLoc,
+std::optional NumExpansions)
+: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary), LParenLoc(LParenLoc),
+  EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
+  NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
+  // We rely on asserted invariant to distinguish left and right folds.
+  assert(((LHS && LHS->containsUnexpandedParameterPack()) !=
+  (RHS && RHS->containsUnexpandedParameterPack())) &&
+ "Exactly one of LHS or RHS should contain an unexpanded pack");
+  SubExprs[SubExpr::Callee] = Callee;
+  SubExprs[SubExpr::LHS] = LHS;
+  SubExprs[SubExpr::RHS] = RHS;
+  setDependence(computeDependence(this));
+}



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


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

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


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

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

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

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

[clang] [clang] [C++20] Defaulted operator== doesn't lookup in using-directive properly #97087 (PR #99542)

2024-07-23 Thread Vlad Serebrennikov via cfe-commits


@@ -4856,7 +4856,7 @@ bool 
TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
: DFI);
   }
 
-  SemaRef.SetDeclDefaulted(New, Tmpl->getLocation());
+  SemaRef.SetDeclDefaulted(nullptr, New, Tmpl->getLocation());

Endilll wrote:

I did wonder if my new test (https://godbolt.org/z/hE3h4b4oM) with class 
template would fail on `nullptr`s in `SemaTemplateInstantiateDecl.cpp`, but I 
guess it doesn't. Could there be a scope that we should pass here, too?
CC @cor3ntin @mizvekov 

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


[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-23 Thread Pavel Skripkin via cfe-commits

https://github.com/pskrgag updated 
https://github.com/llvm/llvm-project/pull/98941

>From c1746eec0e985bb394ecd604129cd0c30d5c66ca Mon Sep 17 00:00:00 2001
From: Pavel Skripkin 
Date: Wed, 17 Jul 2024 16:41:20 +0300
Subject: [PATCH 1/9] clang/sema: disallow more than one 'onweship_takes' with
 different classes

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 
 clang/lib/Sema/SemaDeclAttr.cpp  | 10 ++
 clang/test/Sema/attr-ownership.c |  4 
 3 files changed, 18 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b8d97a6b14fe6..bdb7fadda7743 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3331,6 +3331,10 @@ def err_ownership_returns_index_mismatch : Error<
   "'ownership_returns' attribute index does not match; here it is %0">;
 def note_ownership_returns_index_mismatch : Note<
   "declared with index %0 here">;
+def err_ownership_takes_class_mismatch : Error<
+  "'ownership_takes' attribute class does not match; here it is '%0'">;
+def note_ownership_takes_class_mismatch : Note<
+  "declared with class '%0' here">;
 def err_format_strftime_third_parameter : Error<
   "strftime format attribute requires 3rd parameter to be 0">;
 def err_format_attribute_not : Error<"format argument not a string type">;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5fd8622c90dd8..39675422e3f9f 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1537,6 +1537,16 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const 
ParsedAttr &AL) {
 << Idx.getSourceIndex() << Ex->getSourceRange();
   return;
 }
+  } else if (K == OwnershipAttr::Takes &&
+ I->getOwnKind() == OwnershipAttr::Takes) {
+if (I->getModule()->getName() != ModuleName) {
+  S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
+  << I->getModule()->getName();
+  S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
+  << ModuleName << Ex->getSourceRange();
+
+  return;
+}
   }
 }
 OwnershipArgs.push_back(Idx);
diff --git a/clang/test/Sema/attr-ownership.c b/clang/test/Sema/attr-ownership.c
index 8157ba7145a24..084624353315c 100644
--- a/clang/test/Sema/attr-ownership.c
+++ b/clang/test/Sema/attr-ownership.c
@@ -24,3 +24,7 @@ void f15(int, int)
 void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) 
__attribute__((ownership_holds(foo, 1))); // OK, same index
 void f17(void*) __attribute__((ownership_takes(__, 1)));
 void f18() __attribute__((ownership_takes(foo, 1)));  // expected-warning 
{{'ownership_takes' attribute only applies to non-K&R-style functions}}
+
+int f19(void *)
+  __attribute__((ownership_takes(foo, 1)))// expected-error 
{{'ownership_takes' attribute class does not match; here it is 'foo'}}
+  __attribute__((ownership_takes(foo1, 1)));  // expected-note {{declared with 
class 'foo1' here}}

>From 47793876e74c5773ae6c8464fddb95c760d84507 Mon Sep 17 00:00:00 2001
From: Pavel Skripkin 
Date: Wed, 17 Jul 2024 18:38:28 +0300
Subject: [PATCH 2/9] csa/MallocChecker: turn llvm_unreachable into asserts

---
 .../StaticAnalyzer/Checkers/MallocChecker.cpp | 22 ---
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index fe202c79ed620..8ff71318073ce 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1293,7 +1293,8 @@ void MallocChecker::checkCXXNewOrCXXDelete(const 
CallEvent &Call,
AF_CXXNewArray);
 break;
   default:
-llvm_unreachable("not a new/delete operator");
+assert(false && "not a new/delete operator");
+return;
   }
 
   C.addTransition(State);
@@ -1489,8 +1490,10 @@ ProgramStateRef MallocChecker::ProcessZeroAllocCheck(
 } else {
   return State;
 }
-  } else
-llvm_unreachable("not a CallExpr or CXXNewExpr");
+  } else {
+assert(false && "not a CallExpr or CXXNewExpr");
+return nullptr;
+  }
 
   assert(Arg);
 
@@ -1925,7 +1928,7 @@ static void printExpectedAllocName(raw_ostream &os, 
AllocationFamily Family) {
 case AF_IfNameIndex: os << "'if_nameindex()'"; return;
 case AF_InnerBuffer: os << "container-specific allocator"; return;
 case AF_Alloca:
-case AF_None: llvm_unreachable("not a deallocation expression");
+case AF_None: assert(false && "not a deallocation expression");
   }
 }
 
@@ -1937,7 +1940,7 @@ static void printExpectedDeallocName(raw_ostream &os, 
AllocationFamily Family) {
 case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
 case AF_InnerBuffer: os << "container-specific deall

[clang] [clang][analyzer] Support `ownership_{returns,takes}` attributes (PR #98941)

2024-07-23 Thread Pavel Skripkin via cfe-commits

pskrgag wrote:

Rebased on top of d89f3e8df3160b3afc07bc742c81aa4738ea9646

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


[clang-tools-extra] Create a new check to look for mis-use in calls that take iterators (PR #99917)

2024-07-23 Thread Nathan James via cfe-commits

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Donát Nagy via cfe-commits

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Donát Nagy via cfe-commits

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

LGTM, this is a nice improvement. I vaguely recall that a few months ago 
somebody else on our team had trouble with false positives similar false 
positives, so it's good to see that these will be fixed.

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


[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Donát Nagy via cfe-commits


@@ -451,6 +462,10 @@ class StreamChecker : public Checker`
In your code the three standard streams have exactly identical roles (as far as 
I see), and I think it would be good to emphasize this by storing them in a 
three-element array instead of three separate independently named variables.

For example, I could imagine a solution like 
```c++
  const char *StdStreamNames[3] = {"stdin", "stdout", "stderr"};
  mutable const VarDecl *StdStreamDecls[3] = {};
  
  // ... in checkASTDecl()
  for (int i = 0; i < 3; i++) {
// inline getGlobalStreamPointerByName here to initialize
// StdStreamDecls[i] via StdStreamNames[i]
  }
  
  // ... in assumeNoAliasingWithStdStreams()
  for (const VarDecl *Var : StdStreamDecls) {
// put the definition of the lambda `assumeRetNE` here
  }
```
(This is just a rough draft, there might be more idiomatic/elegant solutions 
for some parts.)
``

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


[clang] [clang][ASTImporter] Fix import of template parameter default values. (PR #100100)

2024-07-23 Thread Balázs Kéri via cfe-commits

https://github.com/balazske created 
https://github.com/llvm/llvm-project/pull/100100

Default values of template parameters (non-type, type, template) were not 
correctly handled in the "inherited" case. This occurs if the first declaration 
contains the default value but a next one not. The default value is "inherited" 
from the first.

In ASTImporter it was only possible to set the inherited status after the 
template object was created with the template parameters that were imported 
without handling the inherited case. The import function of the template 
parameter contains not enough information (previous declaration) to set the 
inherited-from status. After the template was created, default value of the 
parameters that should be inherited is reset to inherited mode.

From 8a5280d4c7de49128d9ebabc14c41985603df748 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= 
Date: Tue, 23 Jul 2024 11:20:22 +0200
Subject: [PATCH] [clang][ASTImporter] Fix import of template parameter default
 values.

Default values of template parameters (non-type, type, template)
were not correctly handled in the "inherited" case. This occurs
if the first declaration contains the default value but a next
one not. The default value is "inherited" from the first.

In ASTImporter it was only possible to set the inherited status
after the template object was created with the template parameters
that were imported without handling the inherited case. The
import function of the template parameter contains not enough
information (previous declaration) to set the inherited-from status.
After the template was created, default value of the parameters
that should be inherited is reset to inherited mode.
---
 clang/lib/AST/ASTImporter.cpp   |  34 
 clang/unittests/AST/ASTImporterTest.cpp | 215 
 2 files changed, 179 insertions(+), 70 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 08ef09d353afc..1d9ea714780ce 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -359,6 +359,31 @@ namespace clang {
   Params, Importer.getToContext().getTranslationUnitDecl());
 }
 
+template 
+void tryUpdateTemplateParmDeclInheritedFrom(NamedDecl *RecentParm,
+NamedDecl *NewParm) {
+  if (auto *ParmT = dyn_cast(RecentParm)) {
+if (ParmT->hasDefaultArgument()) {
+  auto *P = cast(NewParm);
+  P->removeDefaultArgument();
+  P->setInheritedDefaultArgument(Importer.ToContext, ParmT);
+}
+  }
+}
+
+void updateTemplateParametersInheritedFrom(
+const TemplateParameterList &RecentParams,
+TemplateParameterList &NewParams) {
+  for (auto [Idx, Param] : enumerate(RecentParams)) {
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+  }
+}
+
   public:
 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
 
@@ -6138,6 +6163,9 @@ ExpectedDecl 
ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 }
 
 D2->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  **TemplateParamsOrErr);
   }
 
   return D2;
@@ -6452,6 +6480,9 @@ ExpectedDecl 
ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
 ToTemplated->setPreviousDecl(PrevTemplated);
 }
 ToVarTD->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  **TemplateParamsOrErr);
   }
 
   return ToVarTD;
@@ -6724,6 +6755,9 @@ 
ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
 TemplatedFD->setPreviousDecl(PrevTemplated);
 }
 ToFunc->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  *Params);
   }
 
   return ToFunc;
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 6d987cc7e9ec6..5f6d9fec7052b 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9681,59 +9681,40 @@ AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, 
ConstName) {
   return false;
 }
 
-TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) {
-  const char *Code =
+TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnum) {
+  const char *ToCode =
   R"(
   struct A {
-enum { E1, E2 } x;
-enum { E3, E4 } y;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
-  Decl *FromTU = getTuDecl(Code, Lang_CXX11);

[clang] [clang][ASTImporter] Fix import of template parameter default values. (PR #100100)

2024-07-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Balázs Kéri (balazske)


Changes

Default values of template parameters (non-type, type, template) were not 
correctly handled in the "inherited" case. This occurs if the first declaration 
contains the default value but a next one not. The default value is "inherited" 
from the first.

In ASTImporter it was only possible to set the inherited status after the 
template object was created with the template parameters that were imported 
without handling the inherited case. The import function of the template 
parameter contains not enough information (previous declaration) to set the 
inherited-from status. After the template was created, default value of the 
parameters that should be inherited is reset to inherited mode.

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


2 Files Affected:

- (modified) clang/lib/AST/ASTImporter.cpp (+34) 
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+145-70) 


``diff
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 08ef09d353afc..1d9ea714780ce 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -359,6 +359,31 @@ namespace clang {
   Params, Importer.getToContext().getTranslationUnitDecl());
 }
 
+template 
+void tryUpdateTemplateParmDeclInheritedFrom(NamedDecl *RecentParm,
+NamedDecl *NewParm) {
+  if (auto *ParmT = dyn_cast(RecentParm)) {
+if (ParmT->hasDefaultArgument()) {
+  auto *P = cast(NewParm);
+  P->removeDefaultArgument();
+  P->setInheritedDefaultArgument(Importer.ToContext, ParmT);
+}
+  }
+}
+
+void updateTemplateParametersInheritedFrom(
+const TemplateParameterList &RecentParams,
+TemplateParameterList &NewParams) {
+  for (auto [Idx, Param] : enumerate(RecentParams)) {
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+tryUpdateTemplateParmDeclInheritedFrom(
+Param, NewParams.getParam(Idx));
+  }
+}
+
   public:
 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
 
@@ -6138,6 +6163,9 @@ ExpectedDecl 
ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 }
 
 D2->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  **TemplateParamsOrErr);
   }
 
   return D2;
@@ -6452,6 +6480,9 @@ ExpectedDecl 
ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
 ToTemplated->setPreviousDecl(PrevTemplated);
 }
 ToVarTD->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  **TemplateParamsOrErr);
   }
 
   return ToVarTD;
@@ -6724,6 +6755,9 @@ 
ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
 TemplatedFD->setPreviousDecl(PrevTemplated);
 }
 ToFunc->setPreviousDecl(Recent);
+
+updateTemplateParametersInheritedFrom(*(Recent->getTemplateParameters()),
+  *Params);
   }
 
   return ToFunc;
diff --git a/clang/unittests/AST/ASTImporterTest.cpp 
b/clang/unittests/AST/ASTImporterTest.cpp
index 6d987cc7e9ec6..5f6d9fec7052b 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -9681,59 +9681,40 @@ AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, 
ConstName) {
   return false;
 }
 
-TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) {
-  const char *Code =
+TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnum) {
+  const char *ToCode =
   R"(
   struct A {
-enum { E1, E2 } x;
-enum { E3, E4 } y;
+enum { E1, E2} x;
+enum { E3, E4} y;
   };
   )";
-  Decl *FromTU = getTuDecl(Code, Lang_CXX11);
-  auto *FromEnumE1 = FirstDeclMatcher().match(
-  FromTU, enumDecl(hasEnumConstName("E1")));
-  auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
-  EXPECT_TRUE(ImportedEnumE1);
-  auto *FromEnumE3 = FirstDeclMatcher().match(
-  FromTU, enumDecl(hasEnumConstName("E3")));
-  auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
-  EXPECT_TRUE(ImportedEnumE3);
-  EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
-}
-
-TEST_P(ASTImporterOptionSpecificTestBase, ImportFreeStandingAnonymousEnums) {
+  Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
+  auto *ToE1 = FirstDeclMatcher().match(
+  ToTU, enumDecl(hasEnumConstName("E1")));
+  auto *ToE3 = FirstDeclMatcher().match(
+  ToTU, enumDecl(hasEnumConstName("E3")));
   const char *Code =
   R"(
   struct A {
-enum { E1, E2 };
-enum { E3, E4 };
+enum { E1, E2} x;
+enum { E3, E4} 

[clang] [llvm] [coroutine] Implement llvm.coro.await.suspend intrinsic (PR #79712)

2024-07-23 Thread Martin Storsjö via cfe-commits

mstorsjo wrote:

FYI, as a headsup - I've bisected a regression down to this PR/commit. Before 
this change, all libcxx tests pass on Windows/armv7, but after this change, a 
bunch of coroutine tests fail on this target - see 
https://github.com/llvm/llvm-project/issues/100101.

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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread Ilya Biryukov via cfe-commits

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

>From ad2d2f42282d5493761fa0af13b77dc7aab73bba Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 22 Jul 2024 15:19:07 +0200
Subject: [PATCH 1/2] [Sema] Default arguments for template parameters affect
 ContainsUnexpandedPacks

This addresses the FIXME in the code. There are tests for the new
behavior in a follow up fix for #99877, which also addresses other bugs
that prevent exposing the wrong results of `ContainsUnexpandedPacks` in
the outputs of the compiler without crashes.
---
 clang/lib/AST/DeclTemplate.cpp | 38 --
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 722c7fcf0b0df..f95be88e6c087 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
   if (NTTP->hasPlaceholderTypeConstraint())
 HasConstrainedParameters = true;
 } else if (const auto *TTP = dyn_cast(P)) {
-  if (!IsPack &&
-  TTP->getTemplateParameters()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
-} else if (const auto *TTP = dyn_cast(P)) {
-  if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
-if (TC->getImmediatelyDeclaredConstraint()
-->containsUnexpandedParameterPack())
+  if (!IsPack) {
+if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
+else if (TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
+} else if (const auto *TTP = dyn_cast(P)) {
+  if (!IsPack && TTP->hasDefaultArgument() &&
+  TTP->getDefaultArgument()
+  .getArgument()
+  .containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
+  } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
+ TC && TC->getImmediatelyDeclaredConstraint()
+   ->containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
   }
   if (TTP->hasTypeConstraint())
 HasConstrainedParameters = true;
 } else {
   llvm_unreachable("unexpected template parameter type");
 }
-// FIXME: If a default argument contains an unexpanded parameter pack, the
-// template parameter list does too.
   }
 
   if (HasRequiresClause) {

>From 34a18e0c78c2915df201aea368f6c2763f885fbe Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Tue, 23 Jul 2024 13:01:10 +0200
Subject: [PATCH 2/2] fixup! [Sema] Default arguments for template parameters
 affect ContainsUnexpandedPacks

Add a helper function to avoid code duplication.
---
 clang/lib/AST/DeclTemplate.cpp | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index f95be88e6c087..5d207cfbecb97 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -45,6 +45,14 @@ using namespace clang;
 
//===--===//
 
 
+namespace {
+template
+bool DefaultArgumentContainsUnexpandedPack(const TemplateParam& P) {
+  return P.hasDefaultArgument() &&
+ 
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
+}
+}
+
 TemplateParameterList::TemplateParameterList(const ASTContext& C,
  SourceLocation TemplateLoc,
  SourceLocation LAngleLoc,
@@ -64,10 +72,7 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
   if (!IsPack) {
 if (NTTP->getType()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
-else if (NTTP->hasDefaultArgument() &&
- NTTP->getDefaultArgument()
- .getArgument()
- .containsUnexpandedParameterPack())
+else if (DefaultArgumentContainsUnexpandedPack(*NTTP))
   Contains

[clang] [llvm] [RISCV] Mark zacas as experimental again due to unresolved ABI issue (PR #99898)

2024-07-23 Thread Mehdi Amini via cfe-commits

joker-eph wrote:

It seems that this broke the CI: 
https://lab.llvm.org/buildbot/#/builders/153/builds/3898

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


[clang] Template Diagnostic Improvements (PR #99933)

2024-07-23 Thread Braden Helmer via cfe-commits

bradenhelmer wrote:

I don't have write access, if someone could merge that would be great!

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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 363e036ac002d5af4bb82e303052b806a98086a1 
34a18e0c78c2915df201aea368f6c2763f885fbe --extensions cpp -- 
clang/lib/AST/DeclTemplate.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 5d207cfbec..c1a4181d9b 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -44,14 +44,13 @@ using namespace clang;
 // TemplateParameterList Implementation
 
//===--===//
 
-
 namespace {
-template
-bool DefaultArgumentContainsUnexpandedPack(const TemplateParam& P) {
+template 
+bool DefaultArgumentContainsUnexpandedPack(const TemplateParam &P) {
   return P.hasDefaultArgument() &&
  
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
 }
-}
+} // namespace
 
 TemplateParameterList::TemplateParameterList(const ASTContext& C,
  SourceLocation TemplateLoc,

``




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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread Ilya Biryukov via cfe-commits


@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())

ilya-biryukov wrote:

Done.

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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread Ilya Biryukov via cfe-commits


@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
   if (NTTP->hasPlaceholderTypeConstraint())
 HasConstrainedParameters = true;
 } else if (const auto *TTP = dyn_cast(P)) {
-  if (!IsPack &&
-  TTP->getTemplateParameters()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
-} else if (const auto *TTP = dyn_cast(P)) {
-  if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
-if (TC->getImmediatelyDeclaredConstraint()
-->containsUnexpandedParameterPack())
+  if (!IsPack) {
+if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
+else if (TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
+} else if (const auto *TTP = dyn_cast(P)) {
+  if (!IsPack && TTP->hasDefaultArgument() &&
+  TTP->getDefaultArgument()
+  .getArgument()
+  .containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
+  } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
+ TC && TC->getImmediatelyDeclaredConstraint()
+   ->containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;

ilya-biryukov wrote:

This code on line 84 does the right thing, assuming the `TempateArgument` 
returns correct values for `containsUnexpandedParameterPack()`.

If `TemplateArgument` is wrong, I would argue it's a problem for another patch, 
I'll make sure we test this when fixing the fold expressions (I don't know any 
other way to notice if we're getting the result wrong here).

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


[clang] [Clang] Fix confusing diagnostic with explicit 'this' parameters. (PR #99824)

2024-07-23 Thread Braden Helmer via cfe-commits

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


[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)

2024-07-23 Thread Ilya Biryukov via cfe-commits

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

>From ad2d2f42282d5493761fa0af13b77dc7aab73bba Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Mon, 22 Jul 2024 15:19:07 +0200
Subject: [PATCH 1/3] [Sema] Default arguments for template parameters affect
 ContainsUnexpandedPacks

This addresses the FIXME in the code. There are tests for the new
behavior in a follow up fix for #99877, which also addresses other bugs
that prevent exposing the wrong results of `ContainsUnexpandedPacks` in
the outputs of the compiler without crashes.
---
 clang/lib/AST/DeclTemplate.cpp | 38 --
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 722c7fcf0b0df..f95be88e6c087 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
 
 bool IsPack = P->isTemplateParameterPack();
 if (const auto *NTTP = dyn_cast(P)) {
-  if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
+  if (!IsPack) {
+if (NTTP->getType()->containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
   if (NTTP->hasPlaceholderTypeConstraint())
 HasConstrainedParameters = true;
 } else if (const auto *TTP = dyn_cast(P)) {
-  if (!IsPack &&
-  TTP->getTemplateParameters()->containsUnexpandedParameterPack())
-ContainsUnexpandedParameterPack = true;
-} else if (const auto *TTP = dyn_cast(P)) {
-  if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
-if (TC->getImmediatelyDeclaredConstraint()
-->containsUnexpandedParameterPack())
+  if (!IsPack) {
+if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
+else if (TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+  ContainsUnexpandedParameterPack = true;
+  }
+} else if (const auto *TTP = dyn_cast(P)) {
+  if (!IsPack && TTP->hasDefaultArgument() &&
+  TTP->getDefaultArgument()
+  .getArgument()
+  .containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
+  } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
+ TC && TC->getImmediatelyDeclaredConstraint()
+   ->containsUnexpandedParameterPack()) {
+ContainsUnexpandedParameterPack = true;
   }
   if (TTP->hasTypeConstraint())
 HasConstrainedParameters = true;
 } else {
   llvm_unreachable("unexpected template parameter type");
 }
-// FIXME: If a default argument contains an unexpanded parameter pack, the
-// template parameter list does too.
   }
 
   if (HasRequiresClause) {

>From 34a18e0c78c2915df201aea368f6c2763f885fbe Mon Sep 17 00:00:00 2001
From: Ilya Biryukov 
Date: Tue, 23 Jul 2024 13:01:10 +0200
Subject: [PATCH 2/3] fixup! [Sema] Default arguments for template parameters
 affect ContainsUnexpandedPacks

Add a helper function to avoid code duplication.
---
 clang/lib/AST/DeclTemplate.cpp | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index f95be88e6c087..5d207cfbecb97 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -45,6 +45,14 @@ using namespace clang;
 
//===--===//
 
 
+namespace {
+template
+bool DefaultArgumentContainsUnexpandedPack(const TemplateParam& P) {
+  return P.hasDefaultArgument() &&
+ 
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
+}
+}
+
 TemplateParameterList::TemplateParameterList(const ASTContext& C,
  SourceLocation TemplateLoc,
  SourceLocation LAngleLoc,
@@ -64,10 +72,7 @@ TemplateParameterList::TemplateParameterList(const 
ASTContext& C,
   if (!IsPack) {
 if (NTTP->getType()->containsUnexpandedParameterPack())
   ContainsUnexpandedParameterPack = true;
-else if (NTTP->hasDefaultArgument() &&
- NTTP->getDefaultArgument()
- .getArgument()
- .containsUnexpandedParameterPack())
+else if (DefaultArgumentContainsUnexpandedPack(*NTTP))
   Contains

[clang] [SystemZ][z/OS] Implement z/OS XPLINK ABI (PR #91384)

2024-07-23 Thread Ulrich Weigand via cfe-commits

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

LGTM now, thanks!

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


[clang] [Clang] Fix confusing diagnostic with explicit 'this' parameters. (PR #99824)

2024-07-23 Thread Braden Helmer via cfe-commits

https://github.com/bradenhelmer updated 
https://github.com/llvm/llvm-project/pull/99824

>From e4c3701ea6be894b1094f45d0590c61e5aa44897 Mon Sep 17 00:00:00 2001
From: Braden Helmer 
Date: Sun, 21 Jul 2024 14:10:17 -0400
Subject: [PATCH 1/3] Fix diag mismatch

---
 clang/lib/Sema/SemaOverload.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5ea6b06121c7c..102cb5f7baef2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11152,7 +11152,8 @@ static void DiagnoseBadConversion(Sema &S, 
OverloadCandidate *Cand,
   // non-constructor method.  Note that 'I' corresponds the
   // conversion-slot index.
   bool isObjectArgument = false;
-  if (isa(Fn) && !isa(Fn)) {
+  if (isa(Fn) && !isa(Fn) &&
+  !Fn->hasCXXExplicitFunctionObjectParameter()) {
 if (I == 0)
   isObjectArgument = true;
 else

>From 7f15d3d1a58f11c0ec2b6e646131c0fc0b7a9d5b Mon Sep 17 00:00:00 2001
From: Braden Helmer 
Date: Sun, 21 Jul 2024 15:37:09 -0400
Subject: [PATCH 2/3] Small change and add test

---
 clang/lib/Sema/SemaOverload.cpp| 5 ++---
 clang/test/SemaCXX/cxx2b-deducing-this.cpp | 8 
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 1ef43b2103a9b..ac90ccd5643c1 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11146,11 +11146,10 @@ static void DiagnoseBadConversion(Sema &S, 
OverloadCandidate *Cand,
   // non-constructor method.  Note that 'I' corresponds the
   // conversion-slot index.
   bool isObjectArgument = false;
-  if (isa(Fn) && !isa(Fn) &&
-  !Fn->hasCXXExplicitFunctionObjectParameter()) {
+  if (isa(Fn) && !isa(Fn)) {
 if (I == 0)
   isObjectArgument = true;
-else
+else if (!Fn->hasCXXExplicitFunctionObjectParameter())
   I--;
   }
 
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp 
b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 5cbc1f735383b..6ad54b9b2c63d 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -959,3 +959,11 @@ void f();
 };
 void a::f(this auto) {} // expected-error {{an explicit object parameter 
cannot appear in a non-member function}}
 }
+
+struct R {
+  void f(this auto &&self, int &&r_value_ref) {} // expected-note {{candidate 
function template not viable: expects an rvalue for 2nd argument}}
+  void g(int &&r_value_ref) {
+   f(r_value_ref); // expected-error {{no matching member function for 
call to 'f'}}
+  }
+};
+

>From 19c05ce1b9b30a75ca72de1393d15b4e07e4c5e1 Mon Sep 17 00:00:00 2001
From: Braden Helmer 
Date: Tue, 23 Jul 2024 07:09:50 -0400
Subject: [PATCH 3/3] Add release note

---
 clang/docs/ReleaseNotes.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4638b91b48f95..481b6313974ea 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -746,6 +746,8 @@ Improvements to Clang's diagnostics
 - Clang now diagnoses dangling assignments for pointer-like objects (annotated 
with `[[gsl::Pointer]]`) under `-Wdangling-assignment-gsl` (off by default)
   Fixes #GH63310.
 
+- Clang now has improved diagnostics for functions with explicit 'this' 
parameters. Fixes #GH97878
+
 Improvements to Clang's time-trace
 --
 

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


[clang] [Sema] Fix computations of "unexpanded packs" in substituted lambdas (PR #99882)

2024-07-23 Thread Ilya Biryukov via cfe-commits

ilya-biryukov wrote:

> @ilya-biryukov I'm a bit torn about how we would proceed: if Corentin insists 
> on the current (which my patch continues the effort) implementation, do you 
> think it feasible for me to merge part of your codes (specifically, the way 
> we propagate up unexpanded flags for lambda bodies, some tests apart from 
> those for lambda attributes) into #86265? Of course I'll add you as a 
> co-author of that patch, if you're happy.
> 
> (The attribute part could be split up as an individual PR afterward, if I 
> understand our discussion correctly?)

Yes, absolutely, feel free to borrow the stuff from here, both tests and code!

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


[clang] 20d7fff - [clang][Interp] Fix atomic builtins with integral pointers

2024-07-23 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-07-23T13:15:32+02:00
New Revision: 20d7fff5eaaa9d78807035d63e5c503bfc1b497e

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

LOG: [clang][Interp] Fix atomic builtins with integral pointers

Check the integral pointer value.

Added: 


Modified: 
clang/lib/AST/Interp/InterpBuiltin.cpp
clang/test/AST/Interp/atomic.c

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 98928b3c22d7c..c170042144acc 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -942,15 +942,29 @@ static bool interp__builtin_atomic_lock_free(InterpState 
&S, CodePtr OpPC,
   if (Ptr.isZero())
 return returnBool(true);
 
-  QualType PointeeType = Call->getArg(1)
- ->IgnoreImpCasts()
- ->getType()
- ->castAs()
- ->getPointeeType();
-  // OK, we will inline operations on this object.
-  if (!PointeeType->isIncompleteType() &&
-  S.getCtx().getTypeAlignInChars(PointeeType) >= Size)
-return returnBool(true);
+  if (Ptr.isIntegralPointer()) {
+uint64_t IntVal = Ptr.getIntegerRepresentation();
+if (APSInt(APInt(64, IntVal, false), 
true).isAligned(Size.getAsAlign()))
+  return returnBool(true);
+  }
+
+  const Expr *PtrArg = Call->getArg(1);
+  // Otherwise, check if the type's alignment against Size.
+  if (const auto *ICE = dyn_cast(PtrArg)) {
+// Drop the potential implicit-cast to 'const volatile void*', getting
+// the underlying type.
+if (ICE->getCastKind() == CK_BitCast)
+  PtrArg = ICE->getSubExpr();
+  }
+
+  if (auto PtrTy = PtrArg->getType()->getAs()) {
+QualType PointeeType = PtrTy->getPointeeType();
+if (!PointeeType->isIncompleteType() &&
+S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
+  // OK, we will inline operations on this object.
+  return returnBool(true);
+}
+  }
 }
   }
 

diff  --git a/clang/test/AST/Interp/atomic.c b/clang/test/AST/Interp/atomic.c
index c5fd9ab222934..c8469d4a938b8 100644
--- a/clang/test/AST/Interp/atomic.c
+++ b/clang/test/AST/Interp/atomic.c
@@ -58,3 +58,16 @@ _Static_assert(atomic_is_lock_free((atomic_short*)0), "");
 _Static_assert(atomic_is_lock_free((atomic_int*)0), "");
 _Static_assert(atomic_is_lock_free((atomic_long*)0), "");
 _Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), "");
+
+_Static_assert(__atomic_always_lock_free(1, (void*)1), "");
+_Static_assert(__atomic_always_lock_free(1, (void*)-1), "");
+_Static_assert(!__atomic_always_lock_free(4, (void*)2), "");
+_Static_assert(!__atomic_always_lock_free(4, (void*)-2), "");
+_Static_assert(__atomic_always_lock_free(4, (void*)4), "");
+_Static_assert(__atomic_always_lock_free(4, (void*)-4), "");
+
+_Static_assert(__atomic_always_lock_free(1, "string"), "");
+_Static_assert(!__atomic_always_lock_free(2, "string"), "");
+_Static_assert(__atomic_always_lock_free(2, (int[2]){}), "");
+void dummyfn();
+_Static_assert(__atomic_always_lock_free(2, dummyfn) || 1, "");



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


[clang] [Clang][Parse] Fix ambiguity with nested-name-specifiers that may declarative (PR #96364)

2024-07-23 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/96364

>From 0d0a1e242db6a117ffb37ab4ce3d72e6adf26a2e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 12 Jun 2024 14:14:26 -0400
Subject: [PATCH 1/6] [Clang][Parse] Fix ambiguity with nested-name-specifiers
 that may be declarative

---
 clang/include/clang/Lex/Preprocessor.h| 14 +++-
 clang/include/clang/Parse/Parser.h| 13 ++-
 clang/lib/Lex/PPCaching.cpp   | 39 -
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 41 +
 clang/lib/Parse/ParseDecl.cpp | 83 ---
 clang/lib/Parse/ParseExprCXX.cpp  | 19 ++---
 .../CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp  | 64 ++
 clang/test/CXX/temp/temp.res/p3.cpp   | 10 +--
 8 files changed, 182 insertions(+), 101 deletions(-)
 create mode 100644 clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp

diff --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index fc7d0053f2323..b2dbd7d5375b5 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -1160,6 +1160,9 @@ class Preprocessor {
   /// invoked (at which point the last position is popped).
   std::vector BacktrackPositions;
 
+  std::vector>
+  UnannotatedBacktrackPositions;
+
   /// True if \p Preprocessor::SkipExcludedConditionalBlock() is running.
   /// This is used to guard against calling this function recursively.
   ///
@@ -1722,7 +1725,7 @@ class Preprocessor {
   /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
   /// tokens will continue indefinitely.
   ///
-  void EnableBacktrackAtThisPos();
+  void EnableBacktrackAtThisPos(bool Unannotated = false);
 
   /// Disable the last EnableBacktrackAtThisPos call.
   void CommitBacktrackedTokens();
@@ -1733,7 +1736,11 @@ class Preprocessor {
 
   /// True if EnableBacktrackAtThisPos() was called and
   /// caching of tokens is on.
+
   bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
+  bool isUnannotatedBacktrackEnabled() const {
+return !UnannotatedBacktrackPositions.empty();
+  }
 
   /// Lex the next token for this preprocessor.
   void Lex(Token &Result);
@@ -1841,8 +1848,9 @@ class Preprocessor {
   void RevertCachedTokens(unsigned N) {
 assert(isBacktrackEnabled() &&
"Should only be called when tokens are cached for backtracking");
-assert(signed(CachedLexPos) - signed(N) >= 
signed(BacktrackPositions.back())
- && "Should revert tokens up to the last backtrack position, not 
more");
+assert(signed(CachedLexPos) - signed(N) >=
+   signed(BacktrackPositions.back() >> 1) &&
+   "Should revert tokens up to the last backtrack position, not more");
 assert(signed(CachedLexPos) - signed(N) >= 0 &&
"Corrupted backtrack positions ?");
 CachedLexPos -= N;
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 93e60be512aae..4b0387889645d 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1033,7 +1033,7 @@ class Parser : public CodeCompletionHandler {
 bool isActive;
 
   public:
-explicit TentativeParsingAction(Parser &p)
+explicit TentativeParsingAction(Parser &p, bool Unannotated = false)
 : P(p), PrevPreferredType(P.PreferredType) {
   PrevTok = P.Tok;
   PrevTentativelyDeclaredIdentifierCount =
@@ -1041,7 +1041,7 @@ class Parser : public CodeCompletionHandler {
   PrevParenCount = P.ParenCount;
   PrevBracketCount = P.BracketCount;
   PrevBraceCount = P.BraceCount;
-  P.PP.EnableBacktrackAtThisPos();
+  P.PP.EnableBacktrackAtThisPos(Unannotated);
   isActive = true;
 }
 void Commit() {
@@ -1072,13 +1072,11 @@ class Parser : public CodeCompletionHandler {
   class RevertingTentativeParsingAction
   : private Parser::TentativeParsingAction {
   public:
-RevertingTentativeParsingAction(Parser &P)
-: Parser::TentativeParsingAction(P) {}
+using TentativeParsingAction::TentativeParsingAction;
+
 ~RevertingTentativeParsingAction() { Revert(); }
   };
 
-  class UnannotatedTentativeParsingAction;
-
   /// ObjCDeclContextSwitch - An object used to switch context from
   /// an objective-c decl context to its enclosing decl context and
   /// back.
@@ -1983,7 +1981,8 @@ class Parser : public CodeCompletionHandler {
   CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors,
   bool EnteringContext, bool *MayBePseudoDestructor = nullptr,
   bool IsTypename = false, const IdentifierInfo **LastII = nullptr,
-  bool OnlyNamespace = false, bool InUsingDeclaration = false);
+  bool OnlyNamespace = false, bool InUsingDeclaration = false,
+  bool Disambiguation = false);
 
   
//======//
   // C++11 5.1.2: Lambda e

[clang] [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (PR #100085)

2024-07-23 Thread Balazs Benics via cfe-commits


@@ -451,6 +462,10 @@ class StreamChecker : public Checker StdFileStreamDecls = {};
 
   void evalFopen(const FnDescription *Desc, const CallEvent &Call,
  CheckerContext &C) const;
@@ -919,9 +918,8 @@ ProgramStateRef 
StreamChecker::assumeNoAliasingWithStdStreams(
   };
 
   assert(State);
-  State = assumeRetNE(State, StdinDecl);
-  State = assumeRetNE(State, StdoutDecl);
-  State = assumeRetNE(State, StderrDecl);
+  for (const VarDecl *VD : StdFileStreamDecls)
+State = assumeRetNE(State, VD);
   assert(State);
   return State;
 }
@@ -2082,9 +2080,11 @@ getGlobalStreamPointerByName(const TranslationUnitDecl 
*TU, StringRef VarName) {
 
 void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
  AnalysisManager &, BugReporter &) const {
-  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
-  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
-  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+  std::array DeclNames{"stdin", "stdout", "stderr"};
+  for (const auto &[DeclSlot, DeclName] :
+   llvm::zip_equal(StdFileStreamDecls, DeclNames)) {
+DeclSlot = getGlobalStreamPointerByName(TU, DeclName);
+  }
 }
 
 
//===--===//
```

In total, it replaces 9 lines with other 9 lines of code that is a lot more 
complicated and does an indirection. I'd say, not worth it.

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


[clang] b60fec2 - [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' (#100085)

2024-07-23 Thread via cfe-commits

Author: Balazs Benics
Date: 2024-07-23T13:22:58+02:00
New Revision: b60fec27fd1bbab8c2c7a77b4be7836a1beb326f

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

LOG: [analyzer] Assume the result of 'fopen' can't alias with 'std{in,out,err}' 
(#100085)

'fopen' should return a new FILE handle, thus we should assume it can't
alias with commonly used FILE handles, such as with 'stdin', 'stdout' or
'stderr'.

This problem appears in code that handles either some input/output file
with stdin or stdout, as the business logic is basically the same no
matter the stream being used.
However, one would should only close the stream if it was opened via
'fopen'. Consequently, such code usually has a condition like `if (f &&
f != stdout)` to guard the `fclose()` call.

This patch brings this assumption, thus eliminates FPs for not taking
the guarded branch.

CPP-5306

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
clang/test/Analysis/stream.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index e8d538388e56c..53770532609d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -254,7 +254,8 @@ inline void assertStreamStateOpened(const StreamState *SS) {
 }
 
 class StreamChecker : public Checker 
{
+ check::DeadSymbols, check::PointerEscape,
+ check::ASTDecl> {
   BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"};
   BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"};
   BugType BT_UseAfterOpenFailed{this, "Invalid stream",
@@ -276,11 +277,21 @@ class StreamChecker : public Checker ProgramStateRef {
+if (!Var)
+  return State;
+const auto *LCtx = C.getLocationContext();
+auto &StoreMgr = C.getStoreManager();
+auto &SVB = C.getSValBuilder();
+SVal VarValue = State->getSVal(StoreMgr.getLValueVar(Var, LCtx));
+auto NoAliasState =
+SVB.evalBinOp(State, BO_NE, RetVal, VarValue, SVB.getConditionType())
+.castAs();
+return State->assume(NoAliasState, true);
+  };
+
+  assert(State);
+  State = assumeRetNE(State, StdinDecl);
+  State = assumeRetNE(State, StdoutDecl);
+  State = assumeRetNE(State, StderrDecl);
+  assert(State);
+  return State;
+}
+
 void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call,
   CheckerContext &C) const {
   ProgramStateRef State = C.getState();
@@ -899,6 +938,7 @@ void StreamChecker::evalFopen(const FnDescription *Desc, 
const CallEvent &Call,
   assert(RetSym && "RetVal must be a symbol here.");
 
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+  State = assumeNoAliasingWithStdStreams(State, RetVal, C);
 
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
@@ -2017,6 +2057,36 @@ ProgramStateRef StreamChecker::checkPointerEscape(
   return State;
 }
 
+static const VarDecl *
+getGlobalStreamPointerByName(const TranslationUnitDecl *TU, StringRef VarName) 
{
+  ASTContext &Ctx = TU->getASTContext();
+  const auto &SM = Ctx.getSourceManager();
+  const QualType FileTy = Ctx.getFILEType();
+
+  if (FileTy.isNull())
+return nullptr;
+
+  const QualType FilePtrTy = Ctx.getPointerType(FileTy).getCanonicalType();
+
+  auto LookupRes = TU->lookup(&Ctx.Idents.get(VarName));
+  for (const Decl *D : LookupRes) {
+if (auto *VD = dyn_cast_or_null(D)) {
+  if (SM.isInSystemHeader(VD->getLocation()) && VD->hasExternalStorage() &&
+  VD->getType().getCanonicalType() == FilePtrTy) {
+return VD;
+  }
+}
+  }
+  return nullptr;
+}
+
+void StreamChecker::checkASTDecl(const TranslationUnitDecl *TU,
+ AnalysisManager &, BugReporter &) const {
+  StdinDecl = getGlobalStreamPointerByName(TU, "stdin");
+  StdoutDecl = getGlobalStreamPointerByName(TU, "stdout");
+  StderrDecl = getGlobalStreamPointerByName(TU, "stderr");
+}
+
 
//===--===//
 // Checker registration.
 
//===--===//

diff  --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c
index c924cbd36f759..b3a47ce4153d3 100644
--- a/clang/test/Analysis/stream.c
+++ b/clang/test/Analysis/stream.c
@@ -498,3 +498,15 @@ void gh_93408_regression_ZeroSized(struct ZeroSized 
*buffer) {
   fread(buffer, 1, 1, f); // expected-warning {{Stream pointer might be NULL}} 
no-crash
   fclose(f);
 }
+
+extern FILE *stdout_like_ptr;
+void no_aliasing(void) {
+  FILE *f = fopen("fil

  1   2   3   4   5   6   >