[clang] [clang] Fix __builtin_mul_overflow for big _BitInts (PR #145497)
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/145497 For long enough _BitInt types we use different types for memory, storing-loading and operations. Makes sure it is correct for mixed sign __builtin_mul_overflow cases. Using pointer element type as a result type doesn't work, because it will be "in-memory" type which is usually bigger than "operations" type and that caused crashes because clang was trying to emit trunc to a bigger type. Fixes https://github.com/llvm/llvm-project/issues/144771 >From 8397b9438b6bdf9b63ac9a925ab374acf3e2fdd5 Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" Date: Tue, 24 Jun 2025 04:07:56 -0700 Subject: [PATCH] [clang] Fix __builtin_mul_overflow for big _BitInts For long enough _BitInt types we use different types for memory, storing-loading and operations. Makes sure it is correct for __builtin_mul_overflow cases. Fixes https://github.com/llvm/llvm-project/issues/144771 --- clang/lib/CodeGen/CGBuiltin.cpp| 2 +- clang/test/CodeGen/builtins-overflow.c | 12 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 2c011a9519860..2a871f24b 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2356,7 +2356,7 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, llvm::Type *OpTy = Signed->getType(); llvm::Value *Zero = llvm::Constant::getNullValue(OpTy); Address ResultPtr = CGF.EmitPointerWithAlignment(ResultArg); - llvm::Type *ResTy = ResultPtr.getElementType(); + llvm::Type *ResTy = CGF.getTypes().ConvertType(ResultQTy); unsigned OpWidth = std::max(Op1Info.Width, Op2Info.Width); // Take the absolute value of the signed operand. diff --git a/clang/test/CodeGen/builtins-overflow.c b/clang/test/CodeGen/builtins-overflow.c index 7c524723f76e8..0e04191b9e2ac 100644 --- a/clang/test/CodeGen/builtins-overflow.c +++ b/clang/test/CodeGen/builtins-overflow.c @@ -604,3 +604,15 @@ long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) { return LongLongErrorCode; return result; } + +_BitInt(65) test_mixed_sign_mul_overflow_bitint(unsigned _BitInt(65) y, _BitInt(119) a) { +// CHECK: call { i119, i1 } @llvm.umul.with.overflow.i119 +// CHECK: select i1 %{{.*}}, i119 %{{.*}}, i119 %{{.*}} +// CHECK: trunc i119 +// CHECK: zext i65 +// CHECK: store + unsigned _BitInt(65) result; + if (__builtin_mul_overflow(a, y, &result)) +return LongLongErrorCode; + return result; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Fix crash on VLS calling convention (PR #145489)
@@ -143,52 +143,82 @@ void __attribute__((riscv_vls_cc)) test_too_large(int32x64_t arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_too_large_256( noundef %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_too_large_256(int32x64_t arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_256(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr1(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr1_256(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr4(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr4_256(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr8(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr8_256(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x2(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x2_256(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x8x2(struct st_i32x8x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x8x2_256(struct st_i32x8x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x64x2(ptr noundef %arg) void __attribute__((riscv_vls_cc)) test_st_i32x64x2(struct st_i32x64x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x64x2_256(ptr noundef %arg) void __attribute__((riscv_vls_cc(256))) test_st_i32x64x2_256(struct st_i32x64x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x3(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x3_256(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x8(struc
[clang] [clang][RISCV] Fix crash on VLS calling convention (PR #145489)
llvmbot wrote: @llvm/pr-subscribers-backend-risc-v Author: Brandon Wu (4vtomat) Changes This patch handle struct of fixed vector and struct of array of fixed vector correctly for VLS calling convention in EmitFunctionProlog, EmitFunctionEpilog and EmitCall. --- Full diff: https://github.com/llvm/llvm-project/pull/145489.diff 3 Files Affected: - (modified) clang/lib/CodeGen/CGCall.cpp (+28-11) - (modified) clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c (+46-16) - (modified) clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.cpp (+16-16) ``diff diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index fd75de42515da..46182f9f418c2 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1329,6 +1329,19 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, llvm::TypeSize DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty); if (llvm::StructType *SrcSTy = dyn_cast(SrcTy)) { +if (Ty->isScalableTy() || Ty->isRISCVVectorTupleTy()) { + // In RISCV VLS calling convention, struct of fixed vector might be + // lowered using scalable vector, we consider it as a valid load, e.g. + // struct i32x4 { + // __attribute__((vector_size(16))) int i; + // }; + // is lowered to + // when ABI_VLEN = 128 bits, please checkout + // clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c + // for more information. + Src = Src.withElementType(Ty); + return CGF.Builder.CreateLoad(Src); +} Src = EnterStructPointerForCoercedAccess(Src, SrcSTy, DstSize.getFixedValue(), CGF); SrcTy = Src.getElementType(); @@ -1412,6 +1425,21 @@ void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst, if (SrcTy != Dst.getElementType()) { if (llvm::StructType *DstSTy = dyn_cast(Dst.getElementType())) { + if (SrcTy->isScalableTy() || SrcTy->isRISCVVectorTupleTy()) { +// In RISCV VLS calling convention, struct of fixed vector might be +// lowered using scalable vector, we consider it as a valid load, e.g. +// struct i32x4 { +// __attribute__((vector_size(16))) int i; +// }; +// is lowered to +// when ABI_VLEN = 128 bits, please checkout +// clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c +// for more information. +Dst = Dst.withElementType(SrcTy); +auto *I = Builder.CreateStore(Src, Dst, DstIsVolatile); +addInstToCurrentSourceAtom(I, Src); +return; + } assert(!SrcSize.isScalable()); Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy, SrcSize.getFixedValue(), *this); @@ -3328,17 +3356,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, } } - // Struct of fixed-length vectors and struct of array of fixed-length - // vector in VLS calling convention are coerced to vector tuple - // type(represented as TargetExtType) and scalable vector type - // respectively, they're no longer handled as struct. - if (ArgI.isDirect() && isa(ConvertType(Ty)) && - (isa(ArgI.getCoerceToType()) || - isa(ArgI.getCoerceToType( { -ArgVals.push_back(ParamValue::forDirect(AI)); -break; - } - llvm::StructType *STy = dyn_cast(ArgI.getCoerceToType()); Address Alloca = diff --git a/clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c b/clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c index 3044d91f1c31c..5799c6bd811b0 100644 --- a/clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c +++ b/clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c @@ -143,34 +143,34 @@ void __attribute__((riscv_vls_cc)) test_too_large(int32x64_t arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_too_large_256( noundef %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_too_large_256(int32x64_t arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_256(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr1(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg) +// CHECK-LLVM: define
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
@@ -46,7 +50,7 @@ class SymbolRegionValue : public SymbolData { friend class SymExprAllocator; SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) - : SymbolData(SymbolRegionValueKind, sym), R(r) { + : SymbolData(ClassKind, sym), R(r) { balazs-benics-sonarsource wrote: I do depend on this, although it could be technically split from this PR. I need to compile time check if a `T` is a subclass of `SymbolData`, thus I need a constexpr type-trait (`classof`). If we have a `SymbolData` then the `acquire` can never hit max symbol complexity, thus we always return the type that was requested. Otherwise, we "complicate" a symbol which may return a substitute symbol instead of type `T`. I'll try to split it from this PR. https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [win][clang] Align scalar deleting destructors with MSABI (PR #139566)
@@ -2886,6 +2887,16 @@ class CXXDestructorDecl : public CXXMethodDecl { return getCanonicalDecl()->OperatorDelete; } + const FunctionDecl *getOperatorGlobalDelete() const { +return getCanonicalDecl()->OperatorGlobalDelete; + } + + void setOperatorGlobalDelete(FunctionDecl *OD) { Fznamznon wrote: @tahonermann The only difference between `isReplaceableGlobalAllocationFunction()` and `isUsableAsGlobalAllocationFunctionInConstantEvaluation()` is that `isReplaceableGlobalAllocationFunction()` always returns false for type aware operator delete. I think we want a usual deallocation function which includes type-aware operator delete, because if I'm reading https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2719r5.html#basic.stc.dynamic.deallocation correctly, it is. The check for delete operator is already present. https://github.com/llvm/llvm-project/pull/139566 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
@@ -46,7 +50,7 @@ class SymbolRegionValue : public SymbolData { friend class SymExprAllocator; SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) - : SymbolData(SymbolRegionValueKind, sym), R(r) { + : SymbolData(ClassKind, sym), R(r) { NagyDonat wrote: Thanks for the explanation! https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix __builtin_mul_overflow for big _BitInts (PR #145497)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/145497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [KeyInstr][Clang] Atomic ops atoms (PR #141624)
https://github.com/jmorse edited https://github.com/llvm/llvm-project/pull/141624 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [KeyInstr][Clang] Atomic ops atoms (PR #141624)
@@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -x c++ -std=c++17 %s -debug-info-kind=line-tables-only -emit-llvm -o - -gno-column-info \ +// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank +// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - -gno-column-info \ +// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank + +// Check that atomic handling code gets Key Instruction annotations. + +_Atomic(unsigned int) x; +unsigned int y; +void fun() { + unsigned int r1 = __c11_atomic_fetch_add(&x,- 1, __ATOMIC_RELAXED); +// CHECK: store i32 -1, ptr %.atomictmp, align 4,!dbg [[LINE11_G2R1:!.*]] +// CHECK-NEXT: %0 = load i32, ptr %.atomictmp, align 4, !dbg [[LINE11:!.*]] +// CHECK-NEXT: %1 = atomicrmw add ptr @x, i32 %0 monotonic, align 4, !dbg [[LINE11_G2R2:!.*]] +// CHECK-NEXT: store i32 %1, ptr %atomic-temp, align 4, !dbg [[LINE11_G2R1]] jmorse wrote: So it's deliberate + desirable that both this and the earlier store of -1 are group-two-rank-one? (I suppose the buoy-based KIs will float the breakpoint upwards) https://github.com/llvm/llvm-project/pull/141624 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle Trailing Whitespace After Line Continuation (P2223R2) (PR #145243)
@@ -1205,14 +1206,23 @@ static size_t countLeadingWhitespace(StringRef Text) { while (Cur < End) { if (isspace(Cur[0])) { ++Cur; -} else if (Cur[0] == '\\' && (Cur[1] == '\n' || Cur[1] == '\r')) { - // A '\' followed by a newline always escapes the newline, regardless - // of whether there is another '\' before it. +} else if (Cur[0] == '\\') { + // A '\' followed by a optional horizontal whitespace (P22232R2) and then + // newline always escapes the newline, regardless of whether there is + // another '\' before it. // The source has a null byte at the end. So the end of the entire input // isn't reached yet. Also the lexer doesn't break apart an escaped // newline. - assert(End - Cur >= 2); - Cur += 2; + const unsigned char *Lookahead = Cur + 1; owenca wrote: ```suggestion const auto *Lookahead = Cur + 1; ``` https://github.com/llvm/llvm-project/pull/145243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Improve Markup Rendering (PR #140498)
https://github.com/emaxx-google edited https://github.com/llvm/llvm-project/pull/140498 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
https://github.com/NagyDonat edited https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC] Move areCompatibleSveTypes etc. from ASTContext to SemaARM. (PR #145429)
https://github.com/cor3ntin approved this pull request. https://github.com/llvm/llvm-project/pull/145429 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -0,0 +1,157 @@ +//===- AMDGPUExpandFeaturePredicates.cpp - Feature Predicate Expander Pass ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// This file implements a pass that deals with expanding AMDGCN generic feature +// predicates into target specific quantities / sequences. In this context, a +// generic feature predicate is an implementation detail global variable that +// is inserted by the FE as a consequence of using either the __builtin_cpu_is +// or the __builtin_amdgcn_is_invocable special builtins on an abstract target +// (AMDGCNSPIRV). These placeholder globals are used to guide target specific +// lowering, once the concrete target is known, by way of constant folding their +// value all the way into a terminator (i.e. a controlled block) or into a no +// live use scenario. The pass makes a best effort attempt to look through +// calls, i.e. a constant evaluatable passthrough of a predicate value will +// generally work, however we hard fail if the folding fails, to avoid obtuse +// BE errors or opaque run time errors. This pass should run as early as +// possible / immediately after Clang CodeGen, so that the optimisation pipeline +// and the BE operate with concrete target data. +//===--===// + +#include "AMDGPU.h" +#include "AMDGPUTargetMachine.h" +#include "GCNSubtarget.h" + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Local.h" + +#include +#include + +using namespace llvm; + +namespace { +template void collectUsers(Value *V, C &Container) { + assert(V && "Must pass an existing Value!"); + + for (auto &&U : V->users()) +if (auto *I = dyn_cast(U)) + Container.insert(Container.end(), I); +} + +inline void setPredicate(const GCNSubtarget &ST, GlobalVariable *P) { + const auto IsFeature = P->getName().starts_with("llvm.amdgcn.has"); + const auto Offset = + IsFeature ? sizeof("llvm.amdgcn.has") : sizeof("llvm.amdgcn.is"); + + auto PV = P->getName().substr(Offset).str(); + if (IsFeature) { +auto Dx = PV.find(','); +while (Dx != std::string::npos) { + PV.insert(++Dx, {'+'}); + + Dx = PV.find(',', Dx); +} +PV.insert(PV.cbegin(), '+'); + } + + auto *PTy = P->getValueType(); + P->setLinkage(GlobalValue::PrivateLinkage); + P->setExternallyInitialized(false); + + if (IsFeature) +P->setInitializer(ConstantInt::getBool(PTy, ST.checkFeatures(PV))); + else +P->setInitializer(ConstantInt::getBool(PTy, PV == ST.getCPU())); +} + +std::pair +unfoldableFound(Function *Caller, GlobalVariable *P, Instruction *NoFold) { + std::string W; + raw_string_ostream OS(W); + + OS << "Impossible to constant fold feature predicate: " << *P << " used by " + << *NoFold << ", please simplify.\n"; + + Caller->getContext().diagnose( + DiagnosticInfoUnsupported(*Caller, W, NoFold->getDebugLoc(), DS_Error)); + + return {PreservedAnalyses::none(), false}; +} + +std::pair handlePredicate(const GCNSubtarget &ST, + GlobalVariable *P) { AlexVlx wrote: > So to clarify, optimizations will never be applied during the compilation to > amdgcnspirv? If that's the case, I guess it's not likely that IR will be > transformed in problematic ways. > Yes, this is the intention, it is still ongoing work - empirically we are not running into any of the potential issues you brought up, which is why I went ahead with upstreaming this part which is fairly important for library work (hard to author high-performance generic libs without this sort of mechanism). By the end of this year we should end up generating SPIRV from Clang's LLVMIR output, with no optimisations applied. > It did occur to me that a way to guarantee that the folding works is by using > a callbr intrinsic, something like this: > > ```llvm > callbr void @llvm.amdgcn.processor.is(metadata "gfx803") to label > %unsupported [label %supported] > ``` > > This would make the check fundamentally inseparable from the control flow. > > But I guess you'd have trouble round-tripping that via SPIRV... Ah, I actually hadn't thought of that but having had a glance yes, it's difficult to round trip. Something to consider in the future and if / when we try to make this generic rather than target specific, if there is interest. https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-com
[clang] [clang][SYCL] Add sycl_external attribute and restrict emitting device code (PR #140282)
https://github.com/tahonermann edited https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Expose simple access to child StorageLocation presence. (PR #145520)
https://github.com/bazuzi closed https://github.com/llvm/llvm-project/pull/145520 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SYCL] Add sycl_external attribute and restrict emitting device code (PR #140282)
@@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify %s + +// Semantic tests for sycl_external attribute + +[[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}} +static void func1() {} + +namespace { + [[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}} + void func2() {} + + struct UnnX {}; +} + +[[clang::sycl_external]] // expected-error {{'sycl_external' can only be applied to functions with external linkage}} + void func4(UnnX) {} + +// FIXME: The first declaration of a function is required to have the attribute. +// The attribute may be optionally present on subsequent declarations +int foo(int c); + +[[clang::sycl_external]] void foo(); + +class C { + [[clang::sycl_external]] void member(); +}; + +[[clang::sycl_external]] int main() // expected-error {{'sycl_external' cannot be applied to main function}} +{ +return 0; +} + +class D { + [[clang::sycl_external]] void del() = delete; // expected-error {{'sycl_external' cannot be applied to explicitly deleted functions}} +}; + +class A { + [[clang::sycl_external]] + A() {} + + [[clang::sycl_external]] void func3() {} +}; + +class B { +public: + [[clang::sycl_external]] virtual void foo() {} + + [[clang::sycl_external]] virtual void bar() = 0; +}; + +[[clang::sycl_external]] int *func0() { return nullptr; } + +[[clang::sycl_external]] void func2(int *) {} + tahonermann wrote: Let's add tests for functions declared `constexpr` and `consteval` as well. `consteval` requires C++20, so the `RUN` line will have to be updated accordingly. I suggest running the test for both C++17 and C++20 with the portion that exercises C++20 features appropriately #ifdef'd. I wonder if we should reject use of the attribute with functions declared `consteval` since no symbols are emitted for such functions. I'm on the fence since the attribute doesn't do any harm there. Perhaps a warning about a useless attribute use would be appropriate? https://github.com/llvm/llvm-project/pull/140282 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
https://github.com/NagyDonat commented: Thanks @haoNoQ for this great idea and @balazs-benics-sonarsource for the quick implementation! I'm completely satisfied with the current direction of development on this PR -- using this fresh symbol type instead of `Unknown`s and `nullopt`s and early returns addresses my concerns about code complexity issues. https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LLVM][Clang] Add and enable strict mode for `getTrailingObjects` (PR #144930)
jurahul wrote: Sure: The first line of the description attempts to define it: > Under strict mode, the templated getTrailingObjects can be called only when > there is > 1 trailing types. I essentially used this strict mode to find all templated calls to `getTrailingObjects` that could be converted to the simplified non-templated form `getTrailingObjects` in the series of PRs I did over last month. Essentially, what this will do is that any future user of TrailingObjects with a single trailing type will be forced to use the non-templated `getTrailingObjects`. https://github.com/llvm/llvm-project/pull/144930 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Support for Packed BCD conversion builtins (PR #142723)
https://github.com/lei137 approved this pull request. LGTM with nit. https://github.com/llvm/llvm-project/pull/142723 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for bitfields in unions (PR #145096)
https://github.com/bcardosolopes closed https://github.com/llvm/llvm-project/pull/145096 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for __builtin_expect (PR #144726)
@@ -2446,4 +2446,41 @@ def AssumeOp : CIR_Op<"assume"> { }]; } +//===--===// +// Branch Probability Operations +//===--===// + +def ExpectOp : CIR_Op<"expect", + [Pure, AllTypesMatch<["result", "val", "expected"]>]> { + let summary = "Tell the optimizer that two values are likely to be equal."; + let description = [{ +The `cir.expect` operation may take 2 or 3 arguments. + +When the argument `prob` is missing, this operation effectively models the +`__builtin_expect` builtin function. It tells the optimizer that `val` and +`expected` are likely to be equal. + +When the argumen `prob` is present, this operation effectively models the +`__builtin_expect_with_probability` builtin function. It tells the +optimizer that `val` and `expected` are equal to each other with a certain +probability. + +`val` and `expected` must be integers and their types must match. Lancern wrote: The `@llvm.expect` intrinsic function accepts `i1`, `i32`, and `i64` as arguments. We may take it as a reference. https://github.com/llvm/llvm-project/pull/144726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
@@ -1518,14 +1518,19 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call, if (!CE) return; - const auto LinePtr = - getPointeeVal(Call.getArgSVal(0), State)->getAs(); - const auto Size = - getPointeeVal(Call.getArgSVal(1), State)->getAs(); - if (!LinePtr || !Size || !LinePtr->getAsRegion()) + const auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State); + const auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State); + if (!LinePtrOpt || !SizeOpt || LinePtrOpt->isUnknownOrUndef() || + SizeOpt->isUnknownOrUndef()) vbvictor wrote: Looking at `CallEvent::getArgSVal` we have `Call::getArgExpr()` that may return `nullptr` if there is no argument. ```cpp SVal CallEvent::getArgSVal(unsigned Index) const { const Expr *ArgE = getArgExpr(Index); if (!ArgE) return UnknownVal(); return getSVal(ArgE); } ``` `getPointee` would accept it and return `std::nullopt`: ```cpp std::optional getPointeeVal(SVal PtrSVal, ProgramStateRef State) { if (const auto *Ptr = PtrSVal.getAsRegion()) { return State->getSVal(Ptr); } return std::nullopt; } ``` In outer code, we called `Call.getArgExpr()` directly and passed potential `nullptr`'s into `EnsurePtrNotNull` and `EnsureGetdelimBufferAndSizeCorrect` methods that don't have handling of `nullptr`. Another approach would be to remove `Call.getNumArgs() < 2` and add null handling in `Ensure-` method family. https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
@@ -1518,14 +1518,19 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call, if (!CE) return; - const auto LinePtr = - getPointeeVal(Call.getArgSVal(0), State)->getAs(); - const auto Size = - getPointeeVal(Call.getArgSVal(1), State)->getAs(); - if (!LinePtr || !Size || !LinePtr->getAsRegion()) + const auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State); + const auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State); + if (!LinePtrOpt || !SizeOpt || LinePtrOpt->isUnknownOrUndef() || + SizeOpt->isUnknownOrUndef()) vbvictor wrote: UPD, I forgot about: ```cpp const CallDescriptionMap PostFnMap{ // NOTE: the following CallDescription also matches the C++ standard // library function std::getline(); the callback will filter it out. {{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::checkGetdelim}, {{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::checkGetdelim}, }; ``` I suppose `CallDescriptionMap` would take care of it. We just need to make sure that we have extract correct types from arguments. https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
erichkeane wrote: > This attempts to fix #26078. However I have couple of fundamental questions > with the 7.1.5 consexpr note "[ Note: An explicit specialization can differ > from the template declaration with respect to the constexpr specifier. — end > note ]" Current quote: https://eel.is/c++draft/dcl.constexpr#note-1 is the same. > > 1. Does it also apply to member specializations which are not function > templates themselves ? (as in the example https://godbolt.org/z/c4bYY8rxb) I read that to do so, yes. It applies to ALL templates. An explicit specialization can change the constexpr/constevalness. > > 2. if yes, then should it also apply to special member functions ? > (constructors, destructors) I would say yes, it should. Any templated SMFs also can have it changed with an explicit specialization. This is actually related to a topic that came up for Reflection last week in EWG. An 'explicit specialization' is a morally different 'entity'. So it is allowed to change quite a bit more from the primary template than we might otherwise expect. In this case, it is allowed to add/remove constexpr/consteval. https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Non constant size and offset in DWARF (PR #141106)
https://github.com/dwblaikie approved this pull request. Yeah, let's just go with this as a single patch. Looking closer, in retrospect/for next time, perhaps this could've been a few smaller patches (I guess the strtuct, member, and bit field member are all separate except that they depend on the new `MDUnsignedOrMDField` - either that could've been included in one of the patches that needed it, and the other two patches dependent on that one arbitrarily chosen - or if that could've been added/tested independently, then all 3 functional patches independently depend on it - (plus the already discussed clang change that could've been done separately - but yeah, annoying to have a dependent patch for such a small change, so probably fine to keep it in in situations like this then just send a tiny PR real quick to go in before the rest once approved))) https://github.com/llvm/llvm-project/pull/141106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Non constant size and offset in DWARF (PR #141106)
@@ -1301,4 +1301,33 @@ TEST(DIBuilder, CompositeTypes) { EXPECT_EQ(Enum->getTag(), dwarf::DW_TAG_enumeration_type); } +TEST(DIBuilder, DynamicOffsetAndSize) { + LLVMContext Ctx; + std::unique_ptr M(new Module("MyModule", Ctx)); dwblaikie wrote: Prefer `std::make_unique` and optionally omit the type on the LHS since it'll be clear from the RHS, like this: ``` auto M = std::make_unique("MyModule", Ctx); ``` https://github.com/llvm/llvm-project/pull/141106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Non constant size and offset in DWARF (PR #141106)
https://github.com/dwblaikie edited https://github.com/llvm/llvm-project/pull/141106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Support for Packed BCD conversion builtins (PR #142723)
@@ -567,6 +567,12 @@ TARGET_BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "", "power9-vector") TARGET_BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "", "power9-vector") TARGET_BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "", "power9-vector") +// P9 Binary-coded decimal (BCD) builtins. +TARGET_BUILTIN(__builtin_ppc_national2packed, "V16UcV16UcUc", "t", "power9-vector") +TARGET_BUILTIN(__builtin_ppc_packed2national, "V16UcV16Uc", "", "power9-vector") +TARGET_BUILTIN(__builtin_ppc_packed2zoned, "V16UcV16UcUc", "t", "power9-vector") +TARGET_BUILTIN(__builtin_ppc_zoned2packed, "V16UcV16UcUc", "t", "power9-vector") lei137 wrote: nit: can we move these to just below `// P8 BCD builtins.` so that we have all the bcd builtin def together? https://github.com/llvm/llvm-project/pull/142723 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
https://github.com/erichkeane commented: it would be great to track down the history of this (https://github.com/cplusplus/draft) to see what changed around this, in case there is more we have to think about. We ALSO might be able to move the tests into the CWG issues section (though likely, not for functions!). Also-also: this needs a release note. https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
@@ -12163,6 +12163,23 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } + // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr erichkeane wrote: Update this to the latest wording please! it is actually no longer specific to functions. https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 418b409 - [CIR] Add support for member initialization from constructors (#144583)
Author: Andy Kaylor Date: 2025-06-24T10:05:48-07:00 New Revision: 418b409df8538bdf1b4865556607c220dc139fa8 URL: https://github.com/llvm/llvm-project/commit/418b409df8538bdf1b4865556607c220dc139fa8 DIFF: https://github.com/llvm/llvm-project/commit/418b409df8538bdf1b4865556607c220dc139fa8.diff LOG: [CIR] Add support for member initialization from constructors (#144583) Upstream the code to handle member variable initialization in a constructor. At this point only simple scalar values (including members of anonymous unions) are handled. Added: Modified: clang/include/clang/CIR/MissingFeatures.h clang/lib/CIR/CodeGen/CIRGenClass.cpp clang/lib/CIR/CodeGen/CIRGenExpr.cpp clang/lib/CIR/CodeGen/CIRGenFunction.cpp clang/lib/CIR/CodeGen/CIRGenFunction.h clang/lib/CIR/CodeGen/CIRGenModule.cpp clang/lib/CIR/CodeGen/CIRGenTypeCache.h clang/test/CIR/CodeGen/ctor.cpp Removed: diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 3ba363772316c..bf370a9850d75 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -242,6 +242,7 @@ struct MissingFeatures { static bool builtinCallMathErrno() { return false; } static bool nonFineGrainedBitfields() { return false; } static bool armComputeVolatileBitfields() { return false; } + static bool ctorMemcpyizer() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index e59a1fdb837cb..278cc8931f308 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -53,19 +53,133 @@ bool CIRGenFunction::isConstructorDelegationValid( return true; } +static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, +CXXCtorInitializer *memberInit, +LValue &lhs) { + FieldDecl *field = memberInit->getAnyMember(); + if (memberInit->isIndirectMemberInitializer()) { +// If we are initializing an anonymous union field, drill down to the field. +IndirectFieldDecl *indirectField = memberInit->getIndirectMember(); +for (const auto *nd : indirectField->chain()) { + auto *fd = cast(nd); + lhs = cgf.emitLValueForFieldInitialization(lhs, fd, fd->getName()); +} + } else { +lhs = cgf.emitLValueForFieldInitialization(lhs, field, field->getName()); + } +} + +static void emitMemberInitializer(CIRGenFunction &cgf, + const CXXRecordDecl *classDecl, + CXXCtorInitializer *memberInit, + const CXXConstructorDecl *constructor, + FunctionArgList &args) { + assert(memberInit->isAnyMemberInitializer() && + "Mush have member initializer!"); + assert(memberInit->getInit() && "Must have initializer!"); + + assert(!cir::MissingFeatures::generateDebugInfo()); + + // non-static data member initializers + FieldDecl *field = memberInit->getAnyMember(); + QualType fieldType = field->getType(); + + mlir::Value thisPtr = cgf.loadCXXThis(); + QualType recordTy = cgf.getContext().getTypeDeclType(classDecl); + + // If a base constructor is being emitted, create an LValue that has the + // non-virtual alignment. + LValue lhs = (cgf.curGD.getCtorType() == Ctor_Base) + ? cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy) + : cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy); + + emitLValueForAnyFieldInitialization(cgf, memberInit, lhs); + + // Special case: If we are in a copy or move constructor, and we are copying + // an array off PODs or classes with trivial copy constructors, ignore the AST + // and perform the copy we know is equivalent. + // FIXME: This is hacky at best... if we had a bit more explicit information + // in the AST, we could generalize it more easily. + const ConstantArrayType *array = + cgf.getContext().getAsConstantArrayType(fieldType); + if (array && constructor->isDefaulted() && + constructor->isCopyOrMoveConstructor()) { +QualType baseElementTy = cgf.getContext().getBaseElementType(array); +// NOTE(cir): CodeGen allows record types to be memcpy'd if applicable, +// whereas ClangIR wants to represent all object construction explicitly. +if (!baseElementTy->isRecordType()) { + cgf.cgm.errorNYI(memberInit->getSourceRange(), + "emitMemberInitializer: array of non-record type"); + return; +} + } + + cgf.emitInitializerForField(field, lhs, memberInit->getInit()); +} + /// This routine generates necessary code to initialize base classes and /// non-static data members belonging to this constructor. void CI
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
necto wrote: > Should I measure the perf of this change? I think so, because the patch is substantially different. For example, the overly complex symbol tree is now preserved, even if it is apparently not traversed in its entirety any longer. That makes it not obvious if the initial performance gains are still there. https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Warn about misuse of sizeof operator in loops. (PR #143205)
https://github.com/malavikasamak updated https://github.com/llvm/llvm-project/pull/143205 >From 52e4413ea1e701dfe0b24cf957a26bb72732f066 Mon Sep 17 00:00:00 2001 From: MalavikaSamak Date: Wed, 21 May 2025 16:06:44 -0700 Subject: [PATCH 01/11] Place holder message for sizeof operator in loops. --- .../bugprone/SizeofExpressionCheck.cpp| 17 +- .../bugprone/SizeofExpressionCheck.h | 1 + .../checkers/bugprone/sizeof-expression.cpp | 31 +++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index f3d4c2255d86e..ee66a880792b8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -72,7 +72,8 @@ SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name, Options.get("WarnOnSizeOfPointerToAggregate", true)), WarnOnSizeOfPointer(Options.get("WarnOnSizeOfPointer", false)), WarnOnOffsetDividedBySizeOf( - Options.get("WarnOnOffsetDividedBySizeOf", true)) {} + Options.get("WarnOnOffsetDividedBySizeOf", true)), + WarnOnLoopExprSizeOf(Options.get("WarnOnLoopExprSizeOf", true)) {} void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "WarnOnSizeOfConstant", WarnOnSizeOfConstant); @@ -86,6 +87,7 @@ void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "WarnOnSizeOfPointer", WarnOnSizeOfPointer); Options.store(Opts, "WarnOnOffsetDividedBySizeOf", WarnOnOffsetDividedBySizeOf); + Options.store(Opts, "WarnOnLoopExprSizeOf", WarnOnLoopExprSizeOf); } void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { @@ -93,6 +95,11 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { // Some of the checks should not match in template code to avoid false // positives if sizeof is applied on template argument. + auto LoopExpr = + [](const ast_matchers::internal::Matcher &InnerMatcher) { +return stmt(anyOf(forStmt(InnerMatcher), whileStmt(InnerMatcher))); + }; + const auto IntegerExpr = ignoringParenImpCasts(integerLiteral()); const auto ConstantExpr = ignoringParenImpCasts( anyOf(integerLiteral(), unaryOperator(hasUnaryOperand(IntegerExpr)), @@ -130,6 +137,11 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { this); } + if (WarnOnLoopExprSizeOf) { +Finder->addMatcher( +LoopExpr(has(binaryOperator(has(SizeOfExpr.bind("loop-expr"), this); + } + // Detect sizeof(kPtr) where kPtr is 'const char* kPtr = "abc"'; const auto CharPtrType = pointerType(pointee(isAnyCharacter())); const auto ConstStrLiteralDecl = @@ -353,6 +365,9 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) { diag(E->getBeginLoc(), "suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?") << E->getSourceRange(); + } else if (const auto *E = Result.Nodes.getNodeAs("loop-expr")) { +diag(E->getBeginLoc(), "suspicious usage of 'sizeof' in the loop") +<< E->getSourceRange(); } else if (const auto *E = Result.Nodes.getNodeAs("sizeof-pointer")) { if (Result.Nodes.getNodeAs("struct-type")) { diag(E->getBeginLoc(), diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h index fbd62cb80fb2d..f7dccf39687a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h @@ -32,6 +32,7 @@ class SizeofExpressionCheck : public ClangTidyCheck { const bool WarnOnSizeOfPointerToAggregate; const bool WarnOnSizeOfPointer; const bool WarnOnOffsetDividedBySizeOf; + const bool WarnOnLoopExprSizeOf; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp index 5e6f394152e9d..52b71277466b1 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp @@ -164,6 +164,37 @@ int Test2(MyConstChar* A) { return sum; } +struct A { + int array[10]; +}; + +struct B { + struct A a; +}; + +int square(int num, struct B b) { +struct A arr[10]; +// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression] +for(int i = 0; i < sizeof(arr); i++) { + struct A a = arr[i]; +} +// CHECK-MESSAGES: :[[@LINE+2]]:24: warning: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression] +// CHECK-MESSAGES: :[[@LINE
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
@@ -12163,6 +12163,23 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } + // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr + // function can differ from the template declaration with respect to + // the constexpr specifier. + if (IsMemberSpecialization) { +FunctionDecl *InstantiationFunction = +OldDecl ? OldDecl->getAsFunction() : nullptr; +if (InstantiationFunction && +InstantiationFunction->getTemplateSpecializationKind() == +TSK_ImplicitInstantiation && +(NewFD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization || + NewFD->getTemplateSpecializationKind() == TSK_Undeclared)) { erichkeane wrote: What is going on here? Why do you not need to handle `TSK_ExplicitInstantiationDeclaration` and `TSK_ExplicitInstantiationDefinition`? Can you play with examples a bit more to see if/when those should be applied? https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Warn about misuse of sizeof operator in loops. (PR #143205)
@@ -353,6 +372,22 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) { diag(E->getBeginLoc(), "suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?") << E->getSourceRange(); + } else if (const auto *E = Result.Nodes.getNodeAs("loop-expr")) { +auto *SizeofArgTy = Result.Nodes.getNodeAs("sizeof-arg-type"); +if (const auto member = dyn_cast(SizeofArgTy)) + SizeofArgTy = member->getPointeeType().getTypePtr(); + +auto Loc = Result.Nodes.getNodeAs("sizeof-expr"); malavikasamak wrote: Fixed in new version. https://github.com/llvm/llvm-project/pull/143205 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow explicit member specialization to differ from template declaration wrt constexpr (PR #145272)
@@ -12163,6 +12163,23 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } + // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr + // function can differ from the template declaration with respect to + // the constexpr specifier. + if (IsMemberSpecialization) { +FunctionDecl *InstantiationFunction = +OldDecl ? OldDecl->getAsFunction() : nullptr; +if (InstantiationFunction && +InstantiationFunction->getTemplateSpecializationKind() == +TSK_ImplicitInstantiation && erichkeane wrote: The old-decl should be a primary template, right? What sort of thigns are we looking to avoid here? https://github.com/llvm/llvm-project/pull/145272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][OpenMP] Capture mapped pointers on `target` by reference. (PR #145454)
@@ -8811,8 +8829,19 @@ class MappableExprsHandler { ++EI; } } -llvm::stable_sort(DeclComponentLists, [](const MapData &LHS, - const MapData &RHS) { +llvm::stable_sort(DeclComponentLists, [VD](const MapData &LHS, + const MapData &RHS) { + // For cases like map(p, p[0], p[0][0]), the shortest map, like map(p) + // in this case, should be handled first, to ensure that it gets the + // TARGET_PARAM flag. + OMPClauseMappableExprCommon::MappableExprComponentListRef Components = + std::get<0>(LHS); + OMPClauseMappableExprCommon::MappableExprComponentListRef ComponentsR = + std::get<0>(RHS); + if (VD && VD->getType()->isAnyPointerType() && Components.size() == 1 && + ComponentsR.size() > 1) +return true; abhinavgaba wrote: Is there a case you have in mind? If the number of components is same, then this should not return anything, and we continue to the existing logic and return based on that in line 8855. The new return should only kick-in if the current component list has one entry and the other one has more. I originally wanted to use the following, which is broader, (and the comment still is in line with this): ```cpp if (VD && VD->getType()->isAnyPointerType() && Components.size() != ComponentsR.size()) return Components.size() < ComponentsR.size(); ``` because even when we have `map(p[0][0], p[0])`, the `map(p[0])` should contribute to the kernel argument. `p` is predetermined `firstprivate because `p` is the base-pointer of `map(p[0])`. The base-pointer for `int **p; ... map(p[0][0])` is `p[0]`, so it has no effect on the data-sharing/mapping of `p`, and hence should not determine the kernel argument. But technically we don't need to sort between `p[0][0]` and `p[0][0][0]` since neither of them should ideally contribute to the determination of the data-sharing/mapping clause on `p`. Note that sorting between `p[0]` and `p[0][0]` is not needed _yet_, since both `p[0][0]` and `p[0]` use PTR_AND_OBJ mappings that start with `p`. Future Plans: I am working on a change to support OpenMP 5.0/6.1 compliant pointer-attachment that avoids using the PTR_AND_OBJ mapping for them, and instead uses a new ATTACH map-type bit. With that, the map-chain emitted for `map(present, to: p[0][0]) map(from: p[0])` would look like the following: ```c // For p[0][0] &p[0][0], &p[0][0], sizeof(p[0][0]), TO | PRESENT &p[0], &p[0][0], sizeof(ptr), ATTACH // For p[0] &p[0], &p[0], sizeof(p[0]), FROM | PARAM &p, &p[0], ATTACH ATTACH: * New map-type bit which means don't increase the ref-count, only do an attachment iff either `&p`'s ref-count is 1, or `&p[0]`'s ref-count is 1 after finishing all maps, including mappers. * Can be combined with ALWAYS for `attach(always)` map-type-modifier to force the attachment even if the ref-counts are more than 1. * Can be removed if the user says `attach(never)` (OpenMP 6.1) ``` Once the above is supported, we would need the PARAM bit to apply to the map of `p[0]`, which would likely require sorting between the component-lists, even if neither is of size 1. https://github.com/llvm/llvm-project/pull/145454 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][OpenMP] Capture mapped pointers on `target` by reference. (PR #145454)
@@ -8811,8 +8829,19 @@ class MappableExprsHandler { ++EI; } } -llvm::stable_sort(DeclComponentLists, [](const MapData &LHS, - const MapData &RHS) { +llvm::stable_sort(DeclComponentLists, [VD](const MapData &LHS, + const MapData &RHS) { + // For cases like map(p, p[0], p[0][0]), the shortest map, like map(p) + // in this case, should be handled first, to ensure that it gets the + // TARGET_PARAM flag. + OMPClauseMappableExprCommon::MappableExprComponentListRef Components = + std::get<0>(LHS); + OMPClauseMappableExprCommon::MappableExprComponentListRef ComponentsR = + std::get<0>(RHS); + if (VD && VD->getType()->isAnyPointerType() && Components.size() == 1 && + ComponentsR.size() > 1) +return true; alexey-bataev wrote: > Is there a case you have in mind? If the number of components is same, then > this should not return anything, and we continue to the existing logic and > return based on that in line 8855. > > The new return should only kick-in if the current component list has one > entry and the other one has more. > > I originally wanted to use the following, which is broader, (and the comment > still is in line with this): > > ```c++ > if (VD && VD->getType()->isAnyPointerType() && Components.size() != > ComponentsR.size()) > return Components.size() < ComponentsR.size(); > ``` > > because even when we have `map(p[0][0], p[0])`, the `map(p[0])` should > contribute to the kernel argument. `p` is predetermined `firstprivate because > `p`is the base-pointer of`map(p[0])`. I think this one works better. > > The base-pointer for `int **p; ... map(p[0][0])` is `p[0]`, so it has no > effect on the data-sharing/mapping of `p`, and hence should not determine the > kernel argument. > > But technically we don't need to sort between `p[0][0]` and `p[0][0][0]` > since neither of them should ideally contribute to the determination of the > data-sharing/mapping clause on `p`. > > Note that sorting between `p[0]` and `p[0][0]` is not needed _yet_, since > both `p[0][0]` and `p[0]` use PTR_AND_OBJ mappings that start with `p`. > > Future Plans: > > I am working on a change to support OpenMP 5.0/6.1 compliant > pointer-attachment that avoids using the PTR_AND_OBJ mapping for them, and > instead uses a new ATTACH map-type bit. With that, the map-chain emitted for > `map(present, to: p[0][0]) map(from: p[0])` would look like the following: > > ```c > // For p[0][0] > &p[0][0], &p[0][0], sizeof(p[0][0]), TO | PRESENT > &p[0], &p[0][0], sizeof(ptr), ATTACH > > // For p[0] > &p[0], &p[0], sizeof(p[0]), FROM | PARAM > &p, &p[0], ATTACH > > ATTACH: > * New map-type bit which means don't increase the ref-count, only do an > attachment iff either `&p`'s ref-count is 1, or `&p[0]`'s ref-count is 1 > after finishing all maps, including mappers. > * Can be combined with ALWAYS for `attach(always)` map-type-modifier to force > the attachment even if the ref-counts are more than 1. > * Can be removed if the user says `attach(never)` (OpenMP 6.1) > ``` > > Once the above is supported, we would need the PARAM bit to apply to the map > of `p[0]`, which would likely require sorting between the component-lists, > even if neither is of size 1. https://github.com/llvm/llvm-project/pull/145454 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Thread Safety Analysis: Warn when using negative reentrant capability (PR #141599)
@@ -7223,4 +7225,10 @@ class TestNegativeWithReentrantMutex { } }; +typedef int __attribute__((capability("role"), reentrant_capability)) ThreadRole; +ThreadRole FlightControl1, FlightControl2; +void dispatch_log(const char *msg) __attribute__((requires_capability(!FlightControl1 && !FlightControl2))) {} // \ + // expected-warning{{'ThreadRole' (aka 'int') is marked reentrant but used as a negative capability; this may be contradictory}} \ AaronBallman wrote: My point is more that the `RUN` line for the test is not opting into the pedantic diagnostics but we're still getting the pedantic diagnostic. That's happening because we're adding `ThreadSafetyPedantic` to the `ThreadSafety` group in `DiagnosticGroups.td`, which means that passing `-Wthread-safety` will automatically enable `-Wthread-safety-pedantic`. I think what we want is to leave `DefaultIgnore` on the diagnostic, but *not* add it to `-Wthread-safety` in `DiagnosticGroups.td`. So users have to explicitly pass the warning flag to enable the diagnostics. That leaves the question of what to do if the user passes `-Wthread-safety-pedantic` but never passes `-Wthread-safety`. I suppose the result there is that they get no thread safety diagnostics, but maybe we want to catch that in the driver and tell the user "did you mean to pass -Wthread-safety as well?". https://github.com/llvm/llvm-project/pull/141599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Back out the source location workaround for CXXConstructExpr (PR #145260)
@@ -98,7 +98,36 @@ namespace { CXXCastPath BasePath; bool IsARCUnbridgedCast; -SourceRange OpRange; +struct OpRangeType { + SourceLocation Ranges[3]; erichkeane wrote: This is a strange variable name here... `Ranges` for a series of locations? https://github.com/llvm/llvm-project/pull/145260 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix NYI AAPCS bit-fields by skipping unsupported case (PR #145560)
https://github.com/andykaylor edited https://github.com/llvm/llvm-project/pull/145560 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][scan-deps] Add option to disable caching stat failures (PR #144000)
qinkunbao wrote: Hi, I've reverted this PR according to https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy Please feel free to revise the patch and make the title Reland "..." provide a description of what broke and how it was fixed in the new version. https://github.com/llvm/llvm-project/pull/144000 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Test 142948, please ignore (PR #144873)
https://github.com/DeinAlptraum updated https://github.com/llvm/llvm-project/pull/144873 >From 704d36bdd22efd4645feaf8988e918ccfdf641a5 Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Thu, 5 Jun 2025 13:40:26 +0200 Subject: [PATCH 1/5] [clang][python][test] Move python binding tests to lit framework As discussed in PR #142353, the current testsuite of the `clang` Python bindings has several issues: - It `libclang.so` cannot be loaded into `python` to run the testsuite, the whole `ninja check-all` aborts. - The result of running the testsuite isn't report like the `lit`-based tests, rendering them almost invisible. - The testsuite is disabled in a non-obvious way (`RUN_PYTHON_TESTS`) in `tests/CMakeLists.txt`, which again doesn't show up in the test results. All these issues can be avoided by integrating the Python bindings tests with `lit`, which is what this patch does: - The actual test lives in `clang/test/bindings/python/bindings.sh` and is run by `lit`. - The current `clang/bindings/python/tests` directory (minus the now-subperfluous `CMakeLists.txt`) is moved into the same directory. - The check if `libclang` is loadable (originally from PR #142353) is now handled via a new `lit` feature, `libclang-loadable`. - The various ways to disable the tests have been turned into `XFAIL`s as appropriate. This isn't complete and not completely tested yet. Tested on `sparc-sun-solaris2.11`, `sparcv9-sun-solaris2.11`, `i386-pc-solaris2.11`, `amd64-pc-solaris2.11`, `i686-pc-linux-gnu`, and `x86_64-pc-linux-gnu`. --- clang/CMakeLists.txt | 1 - clang/bindings/python/tests/CMakeLists.txt| 66 --- clang/test/bindings/python/bindings.sh| 48 ++ clang/test/bindings/python/lit.local.cfg | 22 +++ .../bindings/python/tests/__init__.py | 0 .../bindings/python/tests/cindex/INPUTS/a.inc | 0 .../bindings/python/tests/cindex/INPUTS/b.inc | 0 .../tests/cindex/INPUTS/compile_commands.json | 0 .../python/tests/cindex/INPUTS/header1.h | 0 .../python/tests/cindex/INPUTS/header2.h | 0 .../python/tests/cindex/INPUTS/header3.h | 0 .../python/tests/cindex/INPUTS/hello.cpp | 0 .../python/tests/cindex/INPUTS/include.cpp| 0 .../tests/cindex/INPUTS/parse_arguments.c | 0 .../python/tests/cindex/INPUTS/testfile.c | 0 .../bindings/python/tests/cindex/__init__.py | 0 .../tests/cindex/test_access_specifiers.py| 0 .../bindings/python/tests/cindex/test_cdb.py | 0 .../tests/cindex/test_code_completion.py | 0 .../python/tests/cindex/test_comment.py | 0 .../python/tests/cindex/test_cursor.py| 0 .../python/tests/cindex/test_cursor_kind.py | 0 .../python/tests/cindex/test_diagnostics.py | 0 .../python/tests/cindex/test_enums.py | 0 .../test_exception_specification_kind.py | 0 .../bindings/python/tests/cindex/test_file.py | 0 .../python/tests/cindex/test_index.py | 0 .../bindings/python/tests/cindex/test_lib.py | 0 .../python/tests/cindex/test_linkage.py | 0 .../python/tests/cindex/test_location.py | 0 .../python/tests/cindex/test_rewrite.py | 0 .../python/tests/cindex/test_source_range.py | 0 .../python/tests/cindex/test_tls_kind.py | 0 .../python/tests/cindex/test_token_kind.py| 0 .../python/tests/cindex/test_tokens.py| 0 .../tests/cindex/test_translation_unit.py | 0 .../bindings/python/tests/cindex/test_type.py | 0 .../bindings/python/tests/cindex/util.py | 0 38 files changed, 70 insertions(+), 67 deletions(-) delete mode 100644 clang/bindings/python/tests/CMakeLists.txt create mode 100755 clang/test/bindings/python/bindings.sh create mode 100644 clang/test/bindings/python/lit.local.cfg rename clang/{ => test}/bindings/python/tests/__init__.py (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/a.inc (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/b.inc (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/compile_commands.json (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/header1.h (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/header2.h (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/header3.h (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/hello.cpp (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/include.cpp (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/parse_arguments.c (100%) rename clang/{ => test}/bindings/python/tests/cindex/INPUTS/testfile.c (100%) rename clang/{ => test}/bindings/python/tests/cindex/__init__.py (100%) rename clang/{ => test}/bindings/python/tests/cindex/test_access_specifiers.py (100%) rename clang/{ => test}/bindings/python/tests/cindex/test_cdb.py (100%) rename clang/{ => test}/bindings/python/tests/cindex/test_code_completion.py (100%)
[clang] [clang Dependency Scanning] Enhance File Caching Diagnostics (PR #144105)
@@ -220,13 +221,34 @@ class DependencyScanningFilesystemSharedCache { CacheShard &getShardForFilename(StringRef Filename) const; CacheShard &getShardForUID(llvm::sys::fs::UniqueID UID) const; - /// Visits all cached entries and re-stat an entry using FS if - /// it is negatively stat cached. If re-stat succeeds on a path, - /// the path is added to InvalidPaths, indicating that the cache - /// may have erroneously negatively cached it. The caller can then - /// use InvalidPaths to issue diagnostics. - std::vector - getInvalidNegativeStatCachedPaths(llvm::vfs::FileSystem &UnderlyingFS) const; + struct OutOfDateEntry { +// A null terminated string that contains a path. +const char *Path = nullptr; + +struct NegativelyCachedInfo {}; +struct SizeChangedInfo { + uint64_t CachedSize = 0; + uint64_t ActualSize = 0; +}; + +std::variant Info; + +OutOfDateEntry(const char *Path) +: Path(Path), Info(NegativelyCachedInfo{}) {} + +OutOfDateEntry(const char *Path, uint64_t CachedSize, uint64_t ActualSize) +: Path(Path), Info(SizeChangedInfo{CachedSize, ActualSize}) {} + }; + + /// Visits all cached entries and re-stat an entry using UnderlyingFS to check + /// if the cache contains out-of-date entries. An entry can be out-of-date for + /// two reasons: + /// 1. The entry contains a stat error, indicating the file did not exist + /// in the cache, but the file exists on the UnderlyingFS. + /// 2. The entry is associated with a file whose size is different from the + /// size of the file on the same path on the UnderlyingFS. + std::vector + getInvalidEntryDiagInfo(llvm::vfs::FileSystem &UnderlyingFS) const; jansvoboda11 wrote: Maybe `getOutOfDateEntries` or something? https://github.com/llvm/llvm-project/pull/144105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang][Preprocessor] Refine the implementation of isNextPPTokenOneOf (PR #145546)
@@ -2304,7 +2304,8 @@ class Preprocessor { /// Check whether the next pp-token is one of the specificed token kind. this /// method should have no observable side-effect on the lexed tokens. - template bool isNextPPTokenOneOf() { + template + bool isNextPPTokenOneOf(tok::TokenKind K, Ts... Ks) { erichkeane wrote: Could we make it: ```suggestion bool isNextPPTokenOneOf(Ts... Ks) { ``` ? Though I guess an empty pack here ends up going through all of the other work, which is... awkward. But a `static_assert(sizeof(Ks) > 0)` accomplishes that too? IDK, something to think about. https://github.com/llvm/llvm-project/pull/145546 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Suppress noreturn warning if last statement in a function is a throw (PR #145166)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/145166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
@@ -1518,14 +1518,19 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call, if (!CE) return; - const auto LinePtr = - getPointeeVal(Call.getArgSVal(0), State)->getAs(); - const auto Size = - getPointeeVal(Call.getArgSVal(1), State)->getAs(); - if (!LinePtr || !Size || !LinePtr->getAsRegion()) + const auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State); + const auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State); + if (!LinePtrOpt || !SizeOpt || LinePtrOpt->isUnknownOrUndef() || + SizeOpt->isUnknownOrUndef()) steakhal wrote: Sure it is. https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL][RootSignature] Add `hlsl-rootsig-ver` option to specify root signature version (PR #144813)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/144813 >From 6af81bb12430c28f22eba073a38abd7875a2e348 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Wed, 18 Jun 2025 21:47:31 + Subject: [PATCH 1/5] [HLSL][RootSignature] Add option to specify version of RootSignatureDecl This pr provides the ability to specify the root signature version as a compiler option and to retain this in the root signature decl. It also updates the methods to serialize the version when dumping the declaration and to output the version when generating the metadata. - Update `DXILABI` to define the root signature versions - Update `Options.td` and `LangOpts.h` to define the `fdx-rootsig-ver` Clang/CC1 compiler option - Update `Options.td` to specify DXC compatible aliases `force-rootsig-ver` and `force_rootsig-ver` - Update `Decl.[h|cpp]` and `SeamHLSL.cpp` so that `RootSignatureDecl` will retain its version type - Updates `CGHLSLRuntime.cpp` to generate the extra metadata field - Add tests to illustrate --- clang/include/clang/AST/Decl.h | 7 + clang/include/clang/Basic/LangOptions.h | 5 clang/include/clang/Driver/Options.td| 11 clang/lib/AST/Decl.cpp | 16 +++- clang/lib/AST/TextNodeDumper.cpp | 10 clang/lib/CodeGen/CGHLSLRuntime.cpp | 27 clang/lib/Driver/ToolChains/Clang.cpp| 3 ++- clang/lib/Driver/ToolChains/HLSL.cpp | 8 ++ clang/lib/Frontend/CompilerInvocation.cpp| 4 +++ clang/lib/Sema/SemaHLSL.cpp | 2 +- clang/test/AST/HLSL/RootSignatures-AST.hlsl | 8 ++ clang/test/Driver/dxc_hlsl-rootsig-ver.hlsl | 25 ++ llvm/include/llvm/BinaryFormat/DXContainer.h | 6 + 13 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 clang/test/Driver/dxc_hlsl-rootsig-ver.hlsl diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 05aac15b30cd6..dd1876f4ae73b 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -41,6 +41,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Frontend/HLSL/HLSLRootSignature.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -5179,6 +5180,8 @@ class HLSLRootSignatureDecl final llvm::hlsl::rootsig::RootElement> { friend TrailingObjects; + llvm::dxbc::RootSignatureVersion Version; + unsigned NumElems; llvm::hlsl::rootsig::RootElement *getElems() { return getTrailingObjects(); } @@ -5188,16 +5191,20 @@ class HLSLRootSignatureDecl final } HLSLRootSignatureDecl(DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, +llvm::dxbc::RootSignatureVersion Verison, unsigned NumElems); public: static HLSLRootSignatureDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, + llvm::dxbc::RootSignatureVersion Version, ArrayRef RootElements); static HLSLRootSignatureDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + llvm::dxbc::RootSignatureVersion getVersion() const { return Version; } + ArrayRef getRootElements() const { return {getElems(), NumElems}; } diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 491e8bee9fd5c..b7c5ed994c992 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -24,6 +24,7 @@ #include "clang/Basic/Visibility.h" #include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/TargetParser/Triple.h" #include #include @@ -623,6 +624,10 @@ class LangOptions : public LangOptionsBase { // implementation on real-world examples. std::string OpenACCMacroOverride; + /// The HLSL root signature version for dxil. + llvm::dxbc::RootSignatureVersion HLSLRootSigVer = + llvm::dxbc::RootSignatureVersion::V1_1; + // Indicates if the wasm-opt binary must be ignored in the case of a // WebAssembly target. bool NoWasmOpt = false; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0ffd8c40da7da..69e5c579097dd 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -9288,6 +9288,17 @@ def fcgl : DXCFlag<"fcgl">, Alias; def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias, HelpText<"Enable 16-bit types and disable min precision types." "Available in HLSL 2018 and shader model 6.2.">; +def fdx_rootsig_ver : + Joined<["-"], "fdx-rootsig-ver=">, + Group, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Root Signatu
[clang] [llvm] [HLSL][RootSignature] Add `hlsl-rootsig-ver` option to specify root signature version (PR #144813)
@@ -66,17 +66,17 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) { DXILValMD->addOperand(Val); } -void addRootSignature(ArrayRef Elements, +void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer, + ArrayRef Elements, llvm::Function *Fn, llvm::Module &M) { auto &Ctx = M.getContext(); + IRBuilder<> Builder(Ctx); bogner wrote: `IRB` is also a common name for IRBuilders. Might make the code slightly clearer to have `IRB` and `RSBuilder` so you never need to wonder which builder `Builder` is when reading this. https://github.com/llvm/llvm-project/pull/144813 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL][RootSignature] Add `hlsl-rootsig-ver` option to specify root signature version (PR #144813)
@@ -5188,16 +5191,20 @@ class HLSLRootSignatureDecl final } HLSLRootSignatureDecl(DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID, +llvm::dxbc::RootSignatureVersion Verison, bogner wrote: ```suggestion llvm::dxbc::RootSignatureVersion Version, ``` https://github.com/llvm/llvm-project/pull/144813 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL][RootSignature] Add `hlsl-rootsig-ver` option to specify root signature version (PR #144813)
https://github.com/bogner edited https://github.com/llvm/llvm-project/pull/144813 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL][RootSignature] Add `hlsl-rootsig-ver` option to specify root signature version (PR #144813)
https://github.com/bogner approved this pull request. Looks good. A few minor comments below. https://github.com/llvm/llvm-project/pull/144813 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Expose simple access to child StorageLocation presence. (PR #145520)
llvmbot wrote: @llvm/pr-subscribers-clang-analysis @llvm/pr-subscribers-clang Author: Samira Bakon (bazuzi) Changes `getChild` does not offer this knowledge, and a map lookup is significantly cheaper than iteration over `children()`. --- Full diff: https://github.com/llvm/llvm-project/pull/145520.diff 1 Files Affected: - (modified) clang/include/clang/Analysis/FlowSensitive/StorageLocation.h (+2) ``diff diff --git a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h index 8fcc6a44027a0..8b263b16d5b1e 100644 --- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h +++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h @@ -168,6 +168,8 @@ class RecordStorageLocation final : public StorageLocation { return {Children.begin(), Children.end()}; } + bool hasChild(const ValueDecl &D) const { return Children.contains(&D); } + private: FieldToLoc Children; SyntheticFieldMap SyntheticFields; `` https://github.com/llvm/llvm-project/pull/145520 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Analysis] Avoid some warnings about exit from noreturn function (PR #144408)
@@ -399,6 +401,145 @@ static bool isNoexcept(const FunctionDecl *FD) { return false; } +/// Checks if the given variable, which is assumed to be a function pointer, is +/// initialized with a function having 'noreturn' attribute. +static bool isInitializedWithNoReturn(const VarDecl *VD) { erichkeane wrote: Hmm... We are checking the initializer here, but we don't check to make sure it wasn't assigned since then, right? IMO it seems this is a failure of `[[noreturn]]` not being part of the type :) https://github.com/llvm/llvm-project/pull/144408 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LLVM][Clang] Add and enable strict mode for `getTrailingObjects` (PR #144930)
erichkeane wrote: > Just to be precise, it's not the number of items but the number of trailing > types. I half expected the comment to make it a different function. I'll do > that Ah right, I was using 'items' to mean 'types' too, so we were clear there :) Sorry for my lack of precision. https://github.com/llvm/llvm-project/pull/144930 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add BCDCOPYSIGN and BCDSETSIGN Instruction Support (PR #144874)
@@ -515,6 +515,10 @@ TARGET_BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "", "power9-vector") TARGET_BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "", "power9-vector") TARGET_BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "", "power9-vector") +//P9 BCD builtins +TARGET_BUILTIN(__builtin_ppc_bcdcopysign, "V16UcV16UcV16Uc", "", "power9-vector") AditiRM wrote: This is another power9 instruction according to the documentation : [[documentation of XLC compiler](https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1.0?topic=end-builtin-bcdcopysign-clang-based-front)] Since bcdcopysign and bcdsetsign operate on vector types and are specific to Power9, the appropriate feature for these builtins is power9-vector. https://github.com/llvm/llvm-project/pull/144874 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -0,0 +1,157 @@ +//===- AMDGPUExpandFeaturePredicates.cpp - Feature Predicate Expander Pass ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// This file implements a pass that deals with expanding AMDGCN generic feature +// predicates into target specific quantities / sequences. In this context, a +// generic feature predicate is an implementation detail global variable that +// is inserted by the FE as a consequence of using either the __builtin_cpu_is +// or the __builtin_amdgcn_is_invocable special builtins on an abstract target +// (AMDGCNSPIRV). These placeholder globals are used to guide target specific +// lowering, once the concrete target is known, by way of constant folding their +// value all the way into a terminator (i.e. a controlled block) or into a no +// live use scenario. The pass makes a best effort attempt to look through +// calls, i.e. a constant evaluatable passthrough of a predicate value will +// generally work, however we hard fail if the folding fails, to avoid obtuse +// BE errors or opaque run time errors. This pass should run as early as +// possible / immediately after Clang CodeGen, so that the optimisation pipeline +// and the BE operate with concrete target data. +//===--===// + +#include "AMDGPU.h" +#include "AMDGPUTargetMachine.h" +#include "GCNSubtarget.h" + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Local.h" + +#include +#include + +using namespace llvm; + +namespace { +template void collectUsers(Value *V, C &Container) { + assert(V && "Must pass an existing Value!"); + + for (auto &&U : V->users()) +if (auto *I = dyn_cast(U)) + Container.insert(Container.end(), I); +} + +inline void setPredicate(const GCNSubtarget &ST, GlobalVariable *P) { + const auto IsFeature = P->getName().starts_with("llvm.amdgcn.has"); + const auto Offset = + IsFeature ? sizeof("llvm.amdgcn.has") : sizeof("llvm.amdgcn.is"); + + auto PV = P->getName().substr(Offset).str(); + if (IsFeature) { +auto Dx = PV.find(','); +while (Dx != std::string::npos) { + PV.insert(++Dx, {'+'}); + + Dx = PV.find(',', Dx); +} +PV.insert(PV.cbegin(), '+'); + } + + auto *PTy = P->getValueType(); + P->setLinkage(GlobalValue::PrivateLinkage); + P->setExternallyInitialized(false); + + if (IsFeature) +P->setInitializer(ConstantInt::getBool(PTy, ST.checkFeatures(PV))); + else +P->setInitializer(ConstantInt::getBool(PTy, PV == ST.getCPU())); +} + +std::pair +unfoldableFound(Function *Caller, GlobalVariable *P, Instruction *NoFold) { + std::string W; + raw_string_ostream OS(W); + + OS << "Impossible to constant fold feature predicate: " << *P << " used by " + << *NoFold << ", please simplify.\n"; + + Caller->getContext().diagnose( + DiagnosticInfoUnsupported(*Caller, W, NoFold->getDebugLoc(), DS_Error)); + + return {PreservedAnalyses::none(), false}; +} + +std::pair handlePredicate(const GCNSubtarget &ST, + GlobalVariable *P) { AlexVlx wrote: Oh, this is a good question, it's probably gotten lost in the lengthy conversation. We have two cases, let me try to clarify: 1. We are targeting a concrete `gfx###` target, for which the features and capabilities are fully known at compile time / we know what we are lowering for -> the predicates get expanded and resolved in the FE, they never reach codegen / get emitted in IR; 2. We are targeting `amdgcnspirv`, which is abstract and for which the actual concrete target is only known at run time i.e. there's a lack of information / temporal decoupling: - the predicates allow one to write code that adapts to the capabilities of the actual target that the code will execute on; - we only know the target once we resume compilation for the concrete target, hence the need to emit them in IR, and then expand. The ultimate state of affairs (not there yet due to historical issues / ongoing work) is that for the 2nd case the IR we generate SPIRV from is directly the pristine Clang output (+transforms needed for SPIRV, which do not impact these), so when we resume compilation at run time, it's on un-optimised FE-output IR. Furthermore, the expansion pass runs unconditionally, and is independent from optimisation level (which also implies it needs to be better about cleaning after itself, which I still owe an answer for). Hopefully that helps
[clang] [clang-format] Handle Trailing Whitespace After Line Continuation (P2223R2) (PR #145243)
https://github.com/naveen-seth edited https://github.com/llvm/llvm-project/pull/145243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Enforce not making overly complicated symbols (PR #144327)
@@ -134,6 +137,101 @@ class SymbolConjured : public SymbolData { static constexpr bool classof(Kind K) { return K == ClassKind; } }; +/// A symbol representing the result of an expression that became too +/// complicated. In other words, its complexity would have surpassed the +/// MaxSymbolComplexity threshold. +/// TODO: When the MaxSymbolComplexity is reached, we should propagate the taint +/// info to it. +class SymbolTooComplex final : public SymbolData { + // Pointer to either "SymExpr" or "APSInt". + const void *LHS; + const void *RHS = nullptr; // optional + QualType Ty; + using OpKindType = std::make_unsigned_t< + std::common_type_t>; + OpKindType Op = 0; balazs-benics-sonarsource wrote: I explored the direction of creating the overly complicated symbol, and then just wrapping that in bb82e63b88d1bd233a7895129d25d2cc3b5bc5e4. I think this is what you asked. Note that this approach has the slight disadvantage of actually creating overly complicated symbols to wrap. Sometimes this new symbol will have a complexity equal to max complexity, and other times well over that complexity in case we combined two max complexity symbols by a binop like `+`. Remember, complexity is calculated by `complexity(LHS) + complexity(RHS)`. This simplifies the code quite a bit though. Besides aesthetics, it should not change the overall behavior too much. https://github.com/llvm/llvm-project/pull/144327 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)
vbvictor wrote: Also updated names of function in `MallocChecker` to match corresponding functions names in `UnixApiChecker` https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Diagnose unsatisfied `std::is_assignable`. (PR #144836)
erichkeane wrote: > Thanks! Could I also have one of you merge this for me once everybody's > happy? 🙏 Ah, a little late in my day to be doing that (the 'click merge and take off' strat is one fraught with error :) ), but if no one else has by my morning, I'll do so. https://github.com/llvm/llvm-project/pull/144836 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Preprocessor] Handle the first pp-token in EnterMainSourceFile (PR #145244)
@@ -351,7 +351,7 @@ class Preprocessor { bool LastTokenWasAt = false; /// First pp-token in current translation unit. yronglin wrote: Good catch! Updated. https://github.com/llvm/llvm-project/pull/145244 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix __builtin_mul_overflow for big _BitInts (PR #145497)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Mariya Podchishchaeva (Fznamznon) Changes For long enough _BitInt types we use different types for memory, storing-loading and operations. Makes sure it is correct for mixed sign __builtin_mul_overflow cases. Using pointer element type as a result type doesn't work, because it will be "in-memory" type which is usually bigger than "operations" type and that caused crashes because clang was trying to emit trunc to a bigger type. Fixes https://github.com/llvm/llvm-project/issues/144771 --- Full diff: https://github.com/llvm/llvm-project/pull/145497.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1-1) - (modified) clang/test/CodeGen/builtins-overflow.c (+12) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 2c011a9519860..2a871f24b 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2356,7 +2356,7 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, llvm::Type *OpTy = Signed->getType(); llvm::Value *Zero = llvm::Constant::getNullValue(OpTy); Address ResultPtr = CGF.EmitPointerWithAlignment(ResultArg); - llvm::Type *ResTy = ResultPtr.getElementType(); + llvm::Type *ResTy = CGF.getTypes().ConvertType(ResultQTy); unsigned OpWidth = std::max(Op1Info.Width, Op2Info.Width); // Take the absolute value of the signed operand. diff --git a/clang/test/CodeGen/builtins-overflow.c b/clang/test/CodeGen/builtins-overflow.c index 7c524723f76e8..0e04191b9e2ac 100644 --- a/clang/test/CodeGen/builtins-overflow.c +++ b/clang/test/CodeGen/builtins-overflow.c @@ -604,3 +604,15 @@ long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) { return LongLongErrorCode; return result; } + +_BitInt(65) test_mixed_sign_mul_overflow_bitint(unsigned _BitInt(65) y, _BitInt(119) a) { +// CHECK: call { i119, i1 } @llvm.umul.with.overflow.i119 +// CHECK: select i1 %{{.*}}, i119 %{{.*}}, i119 %{{.*}} +// CHECK: trunc i119 +// CHECK: zext i65 +// CHECK: store + unsigned _BitInt(65) result; + if (__builtin_mul_overflow(a, y, &result)) +return LongLongErrorCode; + return result; +} `` https://github.com/llvm/llvm-project/pull/145497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Restore the underscore in dso_local (PR #145551)
https://github.com/andykaylor created https://github.com/llvm/llvm-project/pull/145551 The CIR handling of `dso_local` for globals was upstreamed without the underscore, making it inconsistent with the incubator and LLVM IR. This change restores the underscore. >From f3927e3fd07cad46f183e434129f6dc91cb89e3e Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Tue, 24 Jun 2025 09:53:54 -0700 Subject: [PATCH] [CIR] Restore the underscore in dso_local The CIR handling of `dso_local` for globals was upstreamed without the underscore, making it inconsistent with the incubator and LLVM IR. This change restores the underscore. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 4 ++-- .../include/clang/CIR/Interfaces/CIROpInterfaces.td | 4 ++-- clang/include/clang/CIR/MissingFeatures.h| 2 +- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 +++--- clang/test/CIR/CodeGen/builtin_printf.cpp| 4 ++-- clang/test/CIR/CodeGen/deferred-defs.cpp | 2 +- clang/test/CIR/CodeGen/namespace.cpp | 2 +- clang/test/CIR/CodeGen/static-vars.c | 12 ++-- clang/test/CIR/CodeGen/static-vars.cpp | 12 ++-- clang/test/CIR/CodeGen/string-literals.c | 6 +++--- clang/test/CIR/CodeGen/string-literals.cpp | 2 +- clang/test/CIR/global-var-linkage.cpp| 2 +- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index d2eeeafc60ba3..372e117981ea6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1610,7 +1610,7 @@ def GlobalOp : CIR_Op<"global", CIR_GlobalLinkageKind:$linkage, OptionalAttr:$initial_value, UnitAttr:$comdat, - UnitAttr:$dsolocal, + UnitAttr:$dso_local, OptionalAttr:$alignment); let assemblyFormat = [{ @@ -1618,7 +1618,7 @@ def GlobalOp : CIR_Op<"global", (`` $global_visibility^)? $linkage (`comdat` $comdat^)? -(`dsolocal` $dsolocal^)? +(`dso_local` $dso_local^)? $sym_name custom($sym_type, $initial_value) attr-dict diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td index 203e42f7c575e..5817b91b49e31 100644 --- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td +++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td @@ -138,13 +138,13 @@ let cppNamespace = "::cir" in { InterfaceMethod<"", "void", "setDSOLocal", (ins "bool":$val), [{}], /*defaultImplementation=*/[{ -$_op.setDsolocal(val); +$_op.setDsoLocal(val); }] >, InterfaceMethod<"", "bool", "isDSOLocal", (ins), [{}], /*defaultImplementation=*/[{ -return $_op.getDsolocal(); +return $_op.getDsoLocal(); }] >, InterfaceMethod<"", diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 3ba363772316c..752d4165c8664 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -74,7 +74,7 @@ struct MissingFeatures { static bool opFuncOpenCLKernelMetadata() { return false; } static bool opFuncCallingConv() { return false; } static bool opFuncExtraAttrs() { return false; } - static bool opFuncDsolocal() { return false; } + static bool opFuncDsoLocal() { return false; } static bool opFuncLinkage() { return false; } static bool opFuncVisibility() { return false; } static bool opFuncNoProto() { return false; } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 5f41e340e2474..106ec38105a9a 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1016,7 +1016,7 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { cir::FuncType fnType = op.getFunctionType(); - assert(!cir::MissingFeatures::opFuncDsolocal()); + assert(!cir::MissingFeatures::opFuncDsoLocal()); bool isDsoLocal = false; mlir::TypeConverter::SignatureConversion signatureConversion( fnType.getNumInputs()); @@ -1103,7 +1103,7 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp( const bool isConst = false; assert(!cir::MissingFeatures::addressSpace()); const unsigned addrSpace = 0; - const bool isDsoLocal = op.getDsolocal(); + const bool isDsoLocal = op.getDsoLocal(); assert(!cir::MissingFeatures::opGlobalThreadLocal()); const bool isThreadLocal = false; const uint64_t alignment = op.getAlignment().value_or(0); @@ -1157,7 +1157,7 @@ mlir::LogicalResult
[clang] [X86] [clang] Add missing check line for diamondrapids (NFC) (PR #145542)
https://github.com/e-kud edited https://github.com/llvm/llvm-project/pull/145542 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix __builtin_mul_overflow for big _BitInts (PR #145497)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Mariya Podchishchaeva (Fznamznon) Changes For long enough _BitInt types we use different types for memory, storing-loading and operations. Makes sure it is correct for mixed sign __builtin_mul_overflow cases. Using pointer element type as a result type doesn't work, because it will be "in-memory" type which is usually bigger than "operations" type and that caused crashes because clang was trying to emit trunc to a bigger type. Fixes https://github.com/llvm/llvm-project/issues/144771 --- Full diff: https://github.com/llvm/llvm-project/pull/145497.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1-1) - (modified) clang/test/CodeGen/builtins-overflow.c (+12) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 2c011a9519860..2a871f24b 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2356,7 +2356,7 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1, llvm::Type *OpTy = Signed->getType(); llvm::Value *Zero = llvm::Constant::getNullValue(OpTy); Address ResultPtr = CGF.EmitPointerWithAlignment(ResultArg); - llvm::Type *ResTy = ResultPtr.getElementType(); + llvm::Type *ResTy = CGF.getTypes().ConvertType(ResultQTy); unsigned OpWidth = std::max(Op1Info.Width, Op2Info.Width); // Take the absolute value of the signed operand. diff --git a/clang/test/CodeGen/builtins-overflow.c b/clang/test/CodeGen/builtins-overflow.c index 7c524723f76e8..0e04191b9e2ac 100644 --- a/clang/test/CodeGen/builtins-overflow.c +++ b/clang/test/CodeGen/builtins-overflow.c @@ -604,3 +604,15 @@ long long test_mixed_sign_mul_overflow_extend_unsigned(int x, unsigned y) { return LongLongErrorCode; return result; } + +_BitInt(65) test_mixed_sign_mul_overflow_bitint(unsigned _BitInt(65) y, _BitInt(119) a) { +// CHECK: call { i119, i1 } @llvm.umul.with.overflow.i119 +// CHECK: select i1 %{{.*}}, i119 %{{.*}}, i119 %{{.*}} +// CHECK: trunc i119 +// CHECK: zext i65 +// CHECK: store + unsigned _BitInt(65) result; + if (__builtin_mul_overflow(a, y, &result)) +return LongLongErrorCode; + return result; +} `` https://github.com/llvm/llvm-project/pull/145497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang Dependency Scanning] Enhance File Caching Diagnostics (PR #144105)
@@ -220,13 +221,34 @@ class DependencyScanningFilesystemSharedCache { CacheShard &getShardForFilename(StringRef Filename) const; CacheShard &getShardForUID(llvm::sys::fs::UniqueID UID) const; - /// Visits all cached entries and re-stat an entry using FS if - /// it is negatively stat cached. If re-stat succeeds on a path, - /// the path is added to InvalidPaths, indicating that the cache - /// may have erroneously negatively cached it. The caller can then - /// use InvalidPaths to issue diagnostics. - std::vector - getInvalidNegativeStatCachedPaths(llvm::vfs::FileSystem &UnderlyingFS) const; + struct OutOfDateEntry { +// A null terminated string that contains a path. +const char *Path = nullptr; + +struct NegativelyCachedInfo {}; +struct SizeChangedInfo { + uint64_t CachedSize = 0; + uint64_t ActualSize = 0; +}; + +std::variant Info; + +OutOfDateEntry(const char *Path) +: Path(Path), Info(NegativelyCachedInfo{}) {} + +OutOfDateEntry(const char *Path, uint64_t CachedSize, uint64_t ActualSize) +: Path(Path), Info(SizeChangedInfo{CachedSize, ActualSize}) {} + }; + + /// Visits all cached entries and re-stat an entry using UnderlyingFS to check + /// if the cache contains out-of-date entries. An entry can be out-of-date for + /// two reasons: + /// 1. The entry contains a stat error, indicating the file did not exist + /// in the cache, but the file exists on the UnderlyingFS. + /// 2. The entry is associated with a file whose size is different from the + /// size of the file on the same path on the UnderlyingFS. + std::vector + getInvalidEntryDiagInfo(llvm::vfs::FileSystem &UnderlyingFS) const; qiongsiwu wrote: Good catch! Fixed. https://github.com/llvm/llvm-project/pull/144105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for function linkage and visibility (PR #145600)
@@ -406,14 +406,34 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, /*DontDefer=*/true, ForDefinition); } + // Already emitted. + if (!funcOp.isDeclaration()) erichkeane wrote: So this was a little jarring to me... any chance we could add a `isDefinition` to `cir::FuncOp` (or `isDefined`?) and use that instead? Took me 2-3 reads to figure out What is going on here :) https://github.com/llvm/llvm-project/pull/145600 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for function linkage and visibility (PR #145600)
@@ -170,6 +187,26 @@ static bool omitRegionTerm(mlir::Region &r) { return singleNonEmptyBlock && yieldsNothing(); } +void printVisibilityAttr(OpAsmPrinter &printer, + cir::VisibilityAttr &visibility) { + switch (visibility.getValue()) { + case cir::VisibilityKind::Hidden: +printer << "hidden"; +break; + case cir::VisibilityKind::Protected: erichkeane wrote: What other values here are there? Can we skip the `default` here and just have it try to print all? https://github.com/llvm/llvm-project/pull/145600 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for function linkage and visibility (PR #145600)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/145600 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64] Add option -msve-streaming-vector-bits= . (PR #144611)
https://github.com/efriedma-quic updated https://github.com/llvm/llvm-project/pull/144611 >From c28804a471a9fe6be24479ffbfd7d4aa6c774125 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 17 Jun 2025 11:48:47 -0700 Subject: [PATCH 1/4] [AArch64] Add option -msve-streaming-vector-bits= . This is similar to -msve-vector-bits, but for streaming mode: it constrains the legal values of "vscale", allowing optimizations based on that constraint. This also fixes conversions between SVE vectors and fixed-width vectors in streaming functions with -msve-vector-bits and -msve-streaming-vector-bits. This currently doesn't touch the __ARM_FEATURE_SVE_BITS define or the arm_sve_vector_bits attribute. --- clang/include/clang/AST/ASTContext.h | 9 -- clang/include/clang/Basic/LangOptions.def | 3 + clang/include/clang/Driver/Options.td | 19 clang/include/clang/Sema/SemaARM.h| 9 ++ clang/lib/AST/ASTContext.cpp | 81 clang/lib/Basic/Targets/AArch64.cpp | 8 +- clang/lib/Driver/ToolChains/Clang.cpp | 29 -- clang/lib/Frontend/CompilerInvocation.cpp | 5 + clang/lib/Sema/SemaARM.cpp| 97 +++ clang/lib/Sema/SemaChecking.cpp | 16 +-- clang/lib/Sema/SemaExpr.cpp | 5 +- clang/lib/Sema/SemaOverload.cpp | 9 +- .../arm-sve-vector-bits-vscale-range.c| 58 --- clang/test/Driver/aarch64-sve-vector-bits.c | 4 + ...rch64-streaming-sve-vector-conversions.cpp | 53 ++ 15 files changed, 277 insertions(+), 128 deletions(-) create mode 100644 clang/test/SemaCXX/aarch64-streaming-sve-vector-conversions.cpp diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3abb49312255a..64d4c5547341e 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2486,15 +2486,6 @@ class ASTContext : public RefCountedBase { /// types. bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec); - /// Return true if the given types are an SVE builtin and a VectorType that - /// is a fixed-length representation of the SVE builtin for a specific - /// vector-length. - bool areCompatibleSveTypes(QualType FirstType, QualType SecondType); - - /// Return true if the given vector types are lax-compatible SVE vector types, - /// false otherwise. - bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); - /// Return true if the given types are an RISC-V vector builtin type and a /// VectorType that is a fixed-length representation of the RISC-V vector /// builtin type for a specific vector-length. diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 789761c1f3647..8054be1bb4e88 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -503,6 +503,9 @@ LANGOPT(OmitVTableRTTI, 1, 0, LANGOPT(VScaleMin, 32, 0, "Minimum vscale value") LANGOPT(VScaleMax, 32, 0, "Maximum vscale value") +LANGOPT(VScaleStreamingMin, 32, 0, "Minimum streaming vscale value") +LANGOPT(VScaleStreamingMax, 32, 0, "Maximum streaming vscale value") + ENUM_LANGOPT(ExtendIntArgs, ExtendArgsKind, 1, ExtendArgsKind::ExtendTo32, "Controls how scalar integer arguments are extended in calls " "to unprototyped and varargs functions") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 152df89118a6a..2e8d5b18483d7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5173,6 +5173,14 @@ def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">, Group, HelpText<"Specify the size in bits of an SVE vector register. Defaults to the" " vector length agnostic value of \"scalable\". (AArch64 only)">; +def msve_streaming_vector_bits_EQ +: Joined<["-"], "msve-streaming-vector-bits=">, + Group, + Visibility<[ClangOption, FlangOption]>, + HelpText< + "Specify the size in bits of an SVE vector register in streaming " + "mode. Defaults to the vector length agnostic value of " + "\"scalable\". (AArch64 only)">; } // let Flags = [TargetSpecific] def mvscale_min_EQ : Joined<["-"], "mvscale-min=">, @@ -5184,6 +5192,17 @@ def mvscale_max_EQ : Joined<["-"], "mvscale-max=">, HelpText<"Specify the vscale maximum. Defaults to the" " vector length agnostic value of \"0\". (AArch64/RISC-V only)">, MarshallingInfoInt>; +def mvscale_streaming_min_EQ +: Joined<["-"], "mvscale-streaming-min=">, + Visibility<[CC1Option, FC1Option]>, + HelpText<"Specify the vscale minimum. Defaults to \"1\". (AArch64 only)">, + MarshallingInfoInt>; +def mvscale_streaming_max_EQ +: Joined<["-"], "mvscale-streaming-max=">, + Visibility<[CC1Option, FC1Option]>, + H
[clang] [clang-format] Handle Trailing Whitespace After Line Continuation (P2223R2) (PR #145243)
@@ -25768,6 +25768,29 @@ TEST_F(FormatTest, OperatorPassedAsAFunctionPtr) { verifyFormat("foo(operator, , -42);", Style); } +TEST_F(FormatTest, LineSpliceWithTrailingWhitespace) { + // Test that each sequence of a backslash (\) immediately followed by zero or + // more horizontal whitespace characters and then a new-line character is + // treated as a single logical line while formatting (as per P2223R2). + FormatStyle Style = getLLVMStyle(); + Style.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; + Style.UseTab = FormatStyle::UT_Never; + + verifyFormat("int i;", + " \\ \n" + " int i;", + Style); + verifyFormat("#define FOO(args) \\\n struct a {};\n", + "#define FOO( args ) \\ \n" + "struct a{\\\t\t\t\n" + " };\n", + Style); + verifyFormat("comment here", + "comment \\ \n" + "here", + Style); naveen-seth wrote: Sorry, I forgot the leading `//`. Currently, `clang-format` already detects line-splicing in comments, even with trailing whitespace. However, unlike with directives and other cases, trailing whitespace in comment splices is not removed. For example, with the current behavior, the following test passes: ```cpp verifyFormat("//comment \\ \n" "here", "//comment \\ \n" "here", Style); ``` instead of trimming the whitespace as it does elsewhere. This is what I would have expected: ```cpp verifyFormat("//comment \\\n" "here", "//comment \\ \n" "here", Style); ``` I wasn't sure whether this should be addressed in this patch or if it's intended behavior, so I’ve deleted the test for now. Please let me know if this needs fixing, and thank you for the review. https://github.com/llvm/llvm-project/pull/145243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Pass TargetMachine from from Clang to `BitcodeWriter`and `ThinLTOBitcodeWriter` pass for thin and fat LTO respectively. (PR #143692)
t-8ch wrote: This does works for the compilation step, for me it isn't sufficient to link the resulting object file: ```sh $ clang -I ./include -c ./src/use_macro.c -flto # Fixed by this PR $ ld.lld use_macro.o ld.lld: error: :1:10: Could not find include file 'macro.s' .include "macro.s" ^ ld.lld: error: ld-temp.o :2:10: Could not find include file 'macro.s' .include "macro.s" ``` https://github.com/llvm/llvm-project/pull/143692 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL][DXIL] Implement `refract` intrinsic (PR #136026)
@@ -16,88 +16,90 @@ namespace clang { SemaSPIRV::SemaSPIRV(Sema &S) : SemaBase(S) {} +/// Checks if the first `NumArgsToCheck` arguments of a function call are of +/// vector type. If any of the arguments is not a vector type, it emits a +/// diagnostic error and returns `true`. Otherwise, it returns `false`. +/// +/// \param TheCall The function call expression to check. +/// \param NumArgsToCheck The number of arguments to check for vector type. +/// \return `true` if any of the arguments is not a vector type, `false` +/// otherwise. + +bool SemaSPIRV::CheckVectorArgs(CallExpr *TheCall, unsigned NumArgsToCheck) { + for (unsigned i = 0; i < NumArgsToCheck; ++i) { +ExprResult Arg = TheCall->getArg(i); +QualType ArgTy = Arg.get()->getType(); +auto *VTy = ArgTy->getAs(); +if (VTy == nullptr) { + SemaRef.Diag(Arg.get()->getBeginLoc(), + diag::err_typecheck_convert_incompatible) + << ArgTy + << SemaRef.Context.getVectorType(ArgTy, 2, VectorKind::Generic) << 1 + << 0 << 0; + return true; +} + } + return false; +} + bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { switch (BuiltinID) { case SPIRV::BI__builtin_spirv_distance: { if (SemaRef.checkArgCount(TheCall, 2)) return true; -ExprResult A = TheCall->getArg(0); -QualType ArgTyA = A.get()->getType(); -auto *VTyA = ArgTyA->getAs(); -if (VTyA == nullptr) { - SemaRef.Diag(A.get()->getBeginLoc(), - diag::err_typecheck_convert_incompatible) - << ArgTyA - << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1 - << 0 << 0; - return true; -} - -ExprResult B = TheCall->getArg(1); -QualType ArgTyB = B.get()->getType(); -auto *VTyB = ArgTyB->getAs(); -if (VTyB == nullptr) { - SemaRef.Diag(A.get()->getBeginLoc(), - diag::err_typecheck_convert_incompatible) - << ArgTyB - << SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1 - << 0 << 0; +// Use the helper function to check both arguments +if (CheckVectorArgs(TheCall, 2)) return true; -} -QualType RetTy = VTyA->getElementType(); +QualType RetTy = +TheCall->getArg(0)->getType()->getAs()->getElementType(); TheCall->setType(RetTy); break; } case SPIRV::BI__builtin_spirv_length: { if (SemaRef.checkArgCount(TheCall, 1)) return true; -ExprResult A = TheCall->getArg(0); -QualType ArgTyA = A.get()->getType(); -auto *VTy = ArgTyA->getAs(); -if (VTy == nullptr) { - SemaRef.Diag(A.get()->getBeginLoc(), - diag::err_typecheck_convert_incompatible) - << ArgTyA - << SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1 - << 0 << 0; + +// Use the helper function to check the argument +if (CheckVectorArgs(TheCall, 1)) spall wrote: same question here about if you should be checking if the element type is float. And Same comment about the style from SemaHLSL https://github.com/llvm/llvm-project/pull/136026 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle Trailing Whitespace After Line Continuation (P2223R2) (PR #145243)
@@ -1295,13 +1305,18 @@ FormatToken *FormatTokenLexer::getNextToken() { case '/': // The text was entirely whitespace when this loop was entered. Thus // this has to be an escape sequence. -assert(Text.substr(i, 2) == "\\\r" || Text.substr(i, 2) == "\\\n" || - Text.substr(i, 4) == "\?\?/\r" || +assert(Text.substr(i, 4) == "\?\?/\r" || Text.substr(i, 4) == "\?\?/\n" || (i >= 1 && (Text.substr(i - 1, 4) == "\?\?/\r" || Text.substr(i - 1, 4) == "\?\?/\n")) || (i >= 2 && (Text.substr(i - 2, 4) == "\?\?/\r" || - Text.substr(i - 2, 4) == "\?\?/\n"))); + Text.substr(i - 2, 4) == "\?\?/\n")) || + (Text[i] == '\\' && [&]() -> bool { + size_t j = i + 1; + while (j < Text.size() && isHorizontalWhitespace(Text[j])) + ++j; + return j < Text.size() && (Text[j] == '\n' || Text[j] == '\r'); + }())); naveen-seth wrote: The latest commit (ed80aca), which addresses the other feedback, doesn’t change anything here. I’m also having trouble understanding this, so I’ll wait for @sstwcw’s input. https://github.com/llvm/llvm-project/pull/145243 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e8976e9 - [clang][Preprocessor] Add peekNextPPToken, makes look ahead next token without side-effects (#143898)
Author: yronglin Date: 2025-06-24T18:55:21+08:00 New Revision: e8976e92f655f8c358081ffae01e10ea159cd37d URL: https://github.com/llvm/llvm-project/commit/e8976e92f655f8c358081ffae01e10ea159cd37d DIFF: https://github.com/llvm/llvm-project/commit/e8976e92f655f8c358081ffae01e10ea159cd37d.diff LOG: [clang][Preprocessor] Add peekNextPPToken, makes look ahead next token without side-effects (#143898) This PR introduce a new function `peekNextPPToken`. It's an extension of `isNextPPTokenLParen` and can makes look ahead one token in preprocessor without side-effects. It's also the 1st part of https://github.com/llvm/llvm-project/pull/107168 and it was used to look ahead next token then determine whether current lexing pp directive is one of pp-import or pp-module directive. At the start of phase 4 an import or module token is treated as starting a directive and are converted to their respective keywords iff: - After skipping horizontal whitespace are - at the start of a logical line, or - preceded by an export at the start of the logical line. - Are followed by an identifier pp token (before macro expansion), or - <, ", or : (but not ::) pp tokens for import, or - ; for module Otherwise the token is treated as an identifier. - Signed-off-by: yronglin Added: Modified: clang/include/clang/Lex/Lexer.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Lex/TokenLexer.h clang/lib/Lex/Lexer.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Lex/PPMacroExpansion.cpp clang/lib/Lex/Preprocessor.cpp clang/lib/Lex/TokenLexer.cpp Removed: diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h index ca812ba1583fb..7a178b5b5c85b 100644 --- a/clang/include/clang/Lex/Lexer.h +++ b/clang/include/clang/Lex/Lexer.h @@ -124,7 +124,7 @@ class Lexer : public PreprocessorLexer { //======// // Context that changes as the file is lexed. // NOTE: any state that mutates when in raw mode must have save/restore code - // in Lexer::isNextPPTokenLParen. + // in Lexer::peekNextPPToken. // BufferPtr - Current pointer into the buffer. This is the next character // to be lexed. @@ -645,10 +645,10 @@ class Lexer : public PreprocessorLexer { BufferPtr = TokEnd; } - /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a - /// tok::l_paren token, 0 if it is something else and 2 if there are no more - /// tokens in the buffer controlled by this lexer. - unsigned isNextPPTokenLParen(); + /// peekNextPPToken - Return std::nullopt if there are no more tokens in the + /// buffer controlled by this lexer, otherwise return the next unexpanded + /// token. + std::optional peekNextPPToken(); //======// // Lexer character reading interfaces. diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 47830b428c8ad..0ec1cb4d0c5d8 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2302,10 +2302,41 @@ class Preprocessor { } } - /// Determine whether the next preprocessor token to be - /// lexed is a '('. If so, consume the token and return true, if not, this + /// Check whether the next pp-token is one of the specificed token kind. this /// method should have no observable side-effect on the lexed tokens. - bool isNextPPTokenLParen(); + template bool isNextPPTokenOneOf() { +// Do some quick tests for rejection cases. +std::optional Val; +if (CurLexer) + Val = CurLexer->peekNextPPToken(); +else + Val = CurTokenLexer->peekNextPPToken(); + +if (!Val) { + // We have run off the end. If it's a source file we don't + // examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the + // macro stack. + if (CurPPLexer) +return false; + for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) { +if (Entry.TheLexer) + Val = Entry.TheLexer->peekNextPPToken(); +else + Val = Entry.TheTokenLexer->peekNextPPToken(); + +if (Val) + break; + +// Ran off the end of a source file? +if (Entry.ThePPLexer) + return false; + } +} + +// Okay, we found the token and return. Otherwise we found the end of the +// translation unit. +return Val->is(K) || (... || Val->is(Ks)); + } private: /// Identifiers used for SEH handling in Borland. These are only diff --git a/clang/include/clang/Lex/TokenLexer.h b/clang/include/clang/Lex/TokenLexer.h index 4d229ae610674..777b4e6266c71 100644 --- a/clang/include/clang/Lex/TokenLexer.h +++ b/clang/include/clang/Lex/TokenLexer.h @@ -139,10 +139,9 @@ class TokenLexer {
[clang] [clang][Preprocessor] Handle the first pp-token in EnterMainSourceFile (PR #145244)
https://github.com/yronglin edited https://github.com/llvm/llvm-project/pull/145244 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Fix crash on VLS calling convention (PR #145489)
@@ -143,52 +143,82 @@ void __attribute__((riscv_vls_cc)) test_too_large(int32x64_t arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_too_large_256( noundef %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_too_large_256(int32x64_t arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_256(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr1(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr1_256(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr4(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr4_256(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr8(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr8_256(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x2(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x2_256(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x8x2(struct st_i32x8x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x8x2_256(struct st_i32x8x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x64x2(ptr noundef %arg) void __attribute__((riscv_vls_cc)) test_st_i32x64x2(struct st_i32x64x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x64x2_256(ptr noundef %arg) void __attribute__((riscv_vls_cc(256))) test_st_i32x64x2_256(struct st_i32x64x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x3(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x3_256(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x8(struc
[clang] [clang-tools-extra] [clang-tidy] `bugprone-unchecked-optional-access`: handle `BloombergLP::bdlb:NullableValue::makeValue` to prevent false-positives (PR #144313)
@@ -985,6 +985,20 @@ auto buildTransferMatchSwitch() { isOptionalMemberCallWithNameMatcher(hasName("isNull")), transferOptionalIsNullCall) + // NullableValue::makeValue, NullableValue::makeValueInplace + // Only NullableValue has these methods, but this + // will also pass for other types + .CaseOfCFGStmt( + isOptionalMemberCallWithNameMatcher( + hasAnyName("makeValue", "makeValueInplace")), + [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &, + LatticeTransferState &State) { +if (RecordStorageLocation *Loc = +getImplicitObjectLocation(*E, State.Env)) { + setHasValue(*Loc, State.Env.getBoolLiteralValue(true), State.Env); +} + }) + vbvictor wrote: But if it works like option1 right now, I don't oppose implementing option1. I suppose we could harden it in the future if ever needed. My example with `optional1` and `optional2` wouldn't appear in real life IMO. https://github.com/llvm/llvm-project/pull/144313 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] `bugprone-unchecked-optional-access`: handle `BloombergLP::bdlb:NullableValue::makeValue` to prevent false-positives (PR #144313)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/144313 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add BCDCOPYSIGN and BCDSETSIGN Instruction Support (PR #144874)
https://github.com/AditiRM edited https://github.com/llvm/llvm-project/pull/144874 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add new check `readability-use-numeric-limits` (PR #127430)
earnol wrote: For C the macro constants from limits.h can be used: `UCHAR_MAX` instead of `std::numeric_limits::max()`. Please refer to https://en.cppreference.com/w/c/header/limits. Please also check compatibility requirement because list of available constants depends on the selected standard. https://github.com/llvm/llvm-project/pull/127430 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] fix crash when modelling 'getline' function in checkers (PR #145229)
vbvictor wrote: > I would prefer keeping this bugfix and that internal architectural > improvement in two separate commits if that isn't too much trouble. Yes, making `Signature` class should be a separate refactor change. I think we should come to a consensus in which checks (or a subset of functions inside checks) we want to have strict type-matching https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][OpenMP] Capture mapped pointers on `target` by reference. (PR #145454)
@@ -8811,8 +8829,19 @@ class MappableExprsHandler { ++EI; } } -llvm::stable_sort(DeclComponentLists, [](const MapData &LHS, - const MapData &RHS) { +llvm::stable_sort(DeclComponentLists, [VD](const MapData &LHS, + const MapData &RHS) { + // For cases like map(p, p[0], p[0][0]), the shortest map, like map(p) + // in this case, should be handled first, to ensure that it gets the + // TARGET_PARAM flag. + OMPClauseMappableExprCommon::MappableExprComponentListRef Components = + std::get<0>(LHS); + OMPClauseMappableExprCommon::MappableExprComponentListRef ComponentsR = + std::get<0>(RHS); + if (VD && VD->getType()->isAnyPointerType() && Components.size() == 1 && + ComponentsR.size() > 1) +return true; alexey-bataev wrote: Not sure this provides strict weak ordering https://github.com/llvm/llvm-project/pull/145454 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] fix crash when modelling 'getline' function in checkers (PR #145229)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/145229 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [flang] [libc] [libcxx] [lldb] [llvm] [mlir] Rsan (PR #145540)
Martin =?utf-8?q?Storsjö?= ,Hubert Tong ,Tom Stellard ,Tom Stellard ,Tom Stellard ,David Green ,Sam Tebbs , =?utf-8?q?Michał_Górny?= , =?utf-8?q?Michał_Górny?= ,Ben Langmuir ,Vitaly Buka ,Ben Langmuir ,Florian Hahn ,Tom Stellard ,Brad Smith ,Benjamin Maxwell ,Alexandros Lamprineas ,Tom Stellard ,Craig Topper ,Phoebe Wang ,Yingwei Zheng ,Jonas Devlieghere ,Jonas Devlieghere ,Pavel Labath ,Pavel Labath ,Mark de Wever ,"s.vgys" <83276820+samvangyse...@users.noreply.github.com>,Nikita Popov ,Nikita Popov , kadir =?utf-8?q?çetinkaya?= ,Brad Smith ,David Sherwood ,David Sherwood ,Nikita Popov ,Tom Stellard ,Phoebe Wang , kadir =?utf-8?q?çetinkaya?= ,Joseph Huber ,Peter Smith ,CarolineConcatto ,David Green ,David Spickett ,Louis Dionne ,Tom Tromey ,beetrees ,Michael Park ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Lang Hames ,Nikita Popov ,Jonas Paulsson ,Florian Hahn ,Craig Topper ,Chuanqi Xu ,Diego Caballero ,Oliver Stannard ,Amr Hesham ,Amr Hesham ,Nico Weber ,David Green ,Florian Hahn ,Fangrui Song ,Nikita Popov ,Yingwei Zheng ,Brad Smith ,Louis Dionne ,Alexey Bataev ,Benjamin Maxwell ,Benjamin Maxwell ,Louis Dionne ,Simon Pilgrim ,Nico Weber ,Daniil Kovalev ,Nikita Popov ,Nikita Popov ,Nikita Popov ,Nikolas Klauser ,Joseph Huber ,Joseph Huber ,Fangrui Song ,Joseph Huber ,higher-performance ,Chuanqi Xu , =?utf-8?q?Mikołaj_Piróg?= , =?utf-8?q?Mikołaj_Piróg?= ,Nikita Popov ,Nikita Popov ,Nikita Popov ,Nikita Popov ,Nikita Popov ,Owen Pan ,Amr Hesham ,Florian Hahn ,Vigneshwar Jayakumar ,Vigneshwar Jayakumar ,Yingwei Zheng ,Lang Hames ,Piyou Chen ,Tom Stellard ,David Green , =?utf-8?q?Michał_Górny?= ,Nikita Popov ,CarolineConcatto ,Owen Pan ,Owen Pan ,Tristan Ross ,Nathan Ridge ,Sylvestre Ledru ,Harald van Dijk ,Petr Hosek ,Haojian Wu ,Owen Pan ,Owen Pan ,Alexey Bataev ,Tom Stellard ,Lang Hames ,Florian Mayer ,Brad Smith ,Mark de Wever ,Craig Topper ,Fangrui Song ,Fangrui Song ,Fangrui Song ,Yingwei Zheng ,Jeremy Morse ,Brad Smith ,Florian Hahn ,Matheus Izvekov ,Mark de Wever ,Brian Cain ,Owen Pan ,Fraser Cormack ,Haojian Wu ,Vigneshwar Jayakumar ,Nikolas Klauser ,Louis Dionne ,Tom Stellard ,Kerry McLaughlin ,Mark de Wever ,Tom Stellard ,"A. Jiang" ,David Green ,Younan Zhang ,Zixu Wang <9819235+zix...@users.noreply.github.com>,Matheus Izvekov ,Louis Dionne ,Matt Arsenault ,Tom Stellard ,Alexander Richardson ,Mariya Podchishchaeva ,Hassnaa Hamdi ,Matheus Izvekov ,Sudharsan Veeravalli ,Matt Arsenault ,Hans Wennborg , Sebastian =?utf-8?q?Jodłowski?= ,Louis Dionne ,Louis Dionne ,Joseph Huber ,Matt Arsenault ,Alexey Bataev ,Nikita Popov ,Joseph Huber ,Chuanqi Xu ,Yingwei Zheng ,David Truby ,Younan Zhang ,Chuanqi Xu ,Yingwei Zheng ,Matt Arsenault ,Jonas Hahnfeld ,Alexandre Ganea ,Ikhlas Ajbar ,Stephen Tozer ,Amy Kwan ,Nikita Popov ,Tom Stellard ,Tom Stellard ,Tom Stellard ,Tom Stellard ,Tom Stellard ,Owen Pan ,Nathan Ridge ,Tom Stellard ,Tom Stellard ,Martin =?utf-8?q?Storsjö?= ,Elvis Wang ,Jonathan Albrecht ,Louis Dionne ,pkarveti ,Jordan R AW ,Jordan R AW ,Yingwei Zheng ,David Green ,Owen Pan ,Phoebe Wang ,Yingwei Zheng ,David Green ,David Green ,Yingwei Zheng ,Eli Friedman ,David Spickett ,DianQK ,aankit-ca ,DianQK ,Lu Weining ,Paul Osmialowski ,Joseph Huber ,Simon Pilgrim ,Jonas Paulsson ,Nikita Popov ,Younan Zhang , Daniel =?utf-8?q?Rodríguez_Troitiño?=,Matt Arsenault ,higher-performance ,yonghong-song ,Younan Zhang ,Florian Hahn ,Louis Dionne ,"A. Jiang" ,"Yaxun (Sam) Liu" ,cor3ntin ,Corentin Jabot ,Corentin Jabot ,yonghong-song ,Yingwei Zheng ,Takuto Ikuta ,Tom Stellard ,Evgenii Kudriashov , Martin =?utf-8?q?Storsjö?= ,David Green ,David Green ,Nicholas Guy ,David Tellenbach ,Alexey Karyakin ,Abinaya Saravanan =?utf-8?q?,?=Qi Zhao , Martin =?utf-8?q?Storsjö?= , Martin =?utf-8?q?Storsjö?= ,Younan Zhang ,Matheus Izvekov ,Brian Cain ,aankit-ca ,Lei Huang ,Ikhlas Ajbar ,Alexey Karyakin ,Tom Stellard ,Eli Friedman ,Owen Pan , Martin =?utf-8?q?Storsjö?= ,R-Goc ,Fangrui Song ,David Green ,Lei Huang ,Tom Stellard ,Paul Schwabauer ,ZhaoQi ,wanglei ,wanglei ,Anutosh Bhat ,Tom Stellard ,dianqk ,Utkarsh Saxena ,Mariusz Borsa ,Carlos Galvez ,Austin Schuh =?utf-8?q?,?=Louis Dionne ,Aaron Puchert ,Martin =?utf-8?q?Storsjö?= ,Tiezhu Yang ,Owen Pan ,Paul Kirth ,Owen Pan ,Stefan Schmidt ,Yingwei Zheng , Miro =?utf-8?q?Hrončok?= ,Marc Auberer ,Mariya Podchishchaeva ,Mariya Podchishchaeva ,Kazu Hirata ,Hua Tian ,Hua Tian ,Yingwei Zheng ,"Wang, Phoebe" ,Phoebe Wang ,ZhaoQi ,Pavel Labath ,Louis Dionne ,Louis Dionne ,Dominik Adamski ,Florian Hahn ,Florian Hahn ,Aaron Ballman ,Younan Zhang ,Louis Dionne ,Ikhlas Ajbar , Alex =?utf-8?q?Rønne?= Petersen ,Tom Stellard ,Nikita Popov ,aankit-ca ,leecheechen ,Nathan Ridge ,Ebuka Ezike ,D
[clang] [clang][analyzer] fix crash when modelling 'getline' function in checkers (PR #145229)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/145229 >From ba9f1edfc2ea1fb1e41366721ccbf795ec998707 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Mon, 23 Jun 2025 23:55:57 +0300 Subject: [PATCH 1/5] [clang][analyzer] fix crash when modelling 'getline' function in checkers --- clang/docs/ReleaseNotes.rst | 3 + .../StaticAnalyzer/Checkers/MallocChecker.cpp | 13 +- .../Checkers/UnixAPIChecker.cpp | 39 -- .../getline-unixapi-invalid-signatures.c | 127 ++ 4 files changed, 169 insertions(+), 13 deletions(-) create mode 100644 clang/test/Analysis/getline-unixapi-invalid-signatures.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 12816eed2e8b5..b6f6dce29a87b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1060,6 +1060,9 @@ impact the linker behaviour like the other `-static-*` flags. Crash and bug fixes ^^^ +- Fixed a crash in ``UnixAPIMisuseChecker`` and ``MallocChecker`` when analyzing + code with non-standard ``getline`` or ``getdelim`` function signatures. + Improvements diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 35e98a5e2719a..cf9837a378430 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1518,10 +1518,15 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call, if (!CE) return; - const auto LinePtr = - getPointeeVal(Call.getArgSVal(0), State)->getAs(); - const auto Size = - getPointeeVal(Call.getArgSVal(1), State)->getAs(); + auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State); + if (!LinePtrOpt) +return; + const auto LinePtr = LinePtrOpt->getAs(); + + auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State); + if (!SizeOpt) +return; + const auto Size = SizeOpt->getAs(); if (!LinePtr || !Size || !LinePtr->getAsRegion()) return; diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp index 79d10d99e11d0..77bc9e92e3520 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -332,13 +332,21 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect( // We have a pointer to a pointer to the buffer, and a pointer to the size. // We want what they point at. - auto LinePtrSVal = getPointeeVal(LinePtrPtrSVal, State)->getAs(); + auto LinePtrValOpt = getPointeeVal(LinePtrPtrSVal, State); + if (!LinePtrValOpt) +return nullptr; + + auto LinePtrSVal = LinePtrValOpt->getAs(); auto NSVal = getPointeeVal(SizePtrSVal, State); if (!LinePtrSVal || !NSVal || NSVal->isUnknown()) return nullptr; assert(LinePtrPtrExpr && SizePtrExpr); + // Add defensive check to ensure we can handle the assume operation + if (!LinePtrSVal->getAs()) +return nullptr; + const auto [LinePtrNotNull, LinePtrNull] = State->assume(*LinePtrSVal); if (LinePtrNotNull && !LinePtrNull) { // If `*lineptr` is not null, but `*n` is undefined, there is UB. @@ -350,9 +358,16 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect( // If it is defined, and known, its size must be less than or equal to // the buffer size. auto NDefSVal = NSVal->getAs(); +if (!NDefSVal) + return LinePtrNotNull; + auto &SVB = C.getSValBuilder(); -auto LineBufSize = -getDynamicExtent(LinePtrNotNull, LinePtrSVal->getAsRegion(), SVB); + +const MemRegion *LinePtrRegion = LinePtrSVal->getAsRegion(); +if (!LinePtrRegion) + return LinePtrNotNull; + +auto LineBufSize = getDynamicExtent(LinePtrNotNull, LinePtrRegion, SVB); auto LineBufSizeGtN = SVB.evalBinOp(LinePtrNotNull, BO_GE, LineBufSize, *NDefSVal, SVB.getConditionType()) .getAs(); @@ -370,23 +385,29 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect( void UnixAPIMisuseChecker::CheckGetDelim(CheckerContext &C, const CallEvent &Call) const { ProgramStateRef State = C.getState(); + if (Call.getNumArgs() < 2) +return; + + const Expr *Arg0 = Call.getArgExpr(0); + const Expr *Arg1 = Call.getArgExpr(1); + + if (!Arg0->getType()->isPointerType() || !Arg1->getType()->isPointerType()) +return; // The parameter `n` must not be NULL. SVal SizePtrSval = Call.getArgSVal(1); - State = EnsurePtrNotNull(SizePtrSval, Call.getArgExpr(1), C, State, "Size"); + State = EnsurePtrNotNull(SizePtrSval, Arg1, C, State, "Size"); if (!State) return; // The parameter `lineptr` must not be NULL. SVal LinePtrPtrSVal = Call.getArgSVal(0); - State = - Ensur
[clang] [analyzer][NFC] Make SymExpr::classof methods constexpr (PR #145526)
https://github.com/NagyDonat approved this pull request. https://github.com/llvm/llvm-project/pull/145526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU][clang][CodeGen][opt] Add late-resolved feature identifying predicates (PR #134016)
@@ -0,0 +1,157 @@ +//===- AMDGPUExpandFeaturePredicates.cpp - Feature Predicate Expander Pass ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// This file implements a pass that deals with expanding AMDGCN generic feature +// predicates into target specific quantities / sequences. In this context, a +// generic feature predicate is an implementation detail global variable that +// is inserted by the FE as a consequence of using either the __builtin_cpu_is +// or the __builtin_amdgcn_is_invocable special builtins on an abstract target +// (AMDGCNSPIRV). These placeholder globals are used to guide target specific +// lowering, once the concrete target is known, by way of constant folding their +// value all the way into a terminator (i.e. a controlled block) or into a no +// live use scenario. The pass makes a best effort attempt to look through +// calls, i.e. a constant evaluatable passthrough of a predicate value will +// generally work, however we hard fail if the folding fails, to avoid obtuse +// BE errors or opaque run time errors. This pass should run as early as +// possible / immediately after Clang CodeGen, so that the optimisation pipeline +// and the BE operate with concrete target data. +//===--===// + +#include "AMDGPU.h" +#include "AMDGPUTargetMachine.h" +#include "GCNSubtarget.h" + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Local.h" + +#include +#include + +using namespace llvm; + +namespace { +template void collectUsers(Value *V, C &Container) { + assert(V && "Must pass an existing Value!"); + + for (auto &&U : V->users()) +if (auto *I = dyn_cast(U)) + Container.insert(Container.end(), I); +} + +inline void setPredicate(const GCNSubtarget &ST, GlobalVariable *P) { + const auto IsFeature = P->getName().starts_with("llvm.amdgcn.has"); + const auto Offset = + IsFeature ? sizeof("llvm.amdgcn.has") : sizeof("llvm.amdgcn.is"); + + auto PV = P->getName().substr(Offset).str(); + if (IsFeature) { +auto Dx = PV.find(','); +while (Dx != std::string::npos) { + PV.insert(++Dx, {'+'}); + + Dx = PV.find(',', Dx); +} +PV.insert(PV.cbegin(), '+'); + } + + auto *PTy = P->getValueType(); + P->setLinkage(GlobalValue::PrivateLinkage); + P->setExternallyInitialized(false); + + if (IsFeature) +P->setInitializer(ConstantInt::getBool(PTy, ST.checkFeatures(PV))); + else +P->setInitializer(ConstantInt::getBool(PTy, PV == ST.getCPU())); +} + +std::pair +unfoldableFound(Function *Caller, GlobalVariable *P, Instruction *NoFold) { + std::string W; + raw_string_ostream OS(W); + + OS << "Impossible to constant fold feature predicate: " << *P << " used by " + << *NoFold << ", please simplify.\n"; + + Caller->getContext().diagnose( + DiagnosticInfoUnsupported(*Caller, W, NoFold->getDebugLoc(), DS_Error)); + + return {PreservedAnalyses::none(), false}; +} + +std::pair handlePredicate(const GCNSubtarget &ST, + GlobalVariable *P) { nikic wrote: So to clarify, optimizations will never be applied during the compilation to amdgcnspirv? If that's the case, I guess it's not likely that IR will be transformed in problematic ways. It did occur to me that a way to guarantee that the folding works is by using a callbr intrinsic, something like this: ```llvm callbr void @llvm.amdgcn.processor.is(metadata "gfx803") to label %unsupported [label %supported] ``` This would make the check fundamentally inseparable from the control flow. But I guess you'd have trouble round-tripping that via SPIRV... https://github.com/llvm/llvm-project/pull/134016 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Check constexpr int->enum conversions consistently. (PR #143034)
efriedma-quic wrote: @erichkeane already added release note in #144407; please take a look to see if it makes sense. https://github.com/llvm/llvm-project/pull/143034 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Fix crash on VLS calling convention (PR #145489)
@@ -143,52 +143,82 @@ void __attribute__((riscv_vls_cc)) test_too_large(int32x64_t arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_too_large_256( noundef %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_too_large_256(int32x64_t arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_256(struct st_i32x4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr1( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr1(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr1_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr1_256(struct st_i32x4_arr1 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr4( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr4(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr4_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr4_256(struct st_i32x4_arr4 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4_arr8( %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4_arr8(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4_arr8_256( %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4_arr8_256(struct st_i32x4_arr8 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x2(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x2_256(struct st_i32x4x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x8x2(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x8x2(struct st_i32x8x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x8x2_256(target("riscv.vector.tuple", , 2) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x8x2_256(struct st_i32x8x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x64x2(ptr noundef %arg) void __attribute__((riscv_vls_cc)) test_st_i32x64x2(struct st_i32x64x2 arg) {} // CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x64x2_256(ptr noundef %arg) void __attribute__((riscv_vls_cc(256))) test_st_i32x64x2_256(struct st_i32x64x2 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x3(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x3(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(256) void @test_st_i32x4x3_256(target("riscv.vector.tuple", , 3) %arg.coerce) void __attribute__((riscv_vls_cc(256))) test_st_i32x4x3_256(struct st_i32x4x3 arg) {} -// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg) +// CHECK-LLVM: define dso_local riscv_vls_cc(128) void @test_st_i32x4x8(target("riscv.vector.tuple", , 8) %arg.coerce) void __attribute__((riscv_vls_cc)) test_st_i32x4x8(struc
[clang] [HLSL][RootSignature] Enable resource range analysis for remaining `RootElement`s (PR #145109)
https://github.com/inbelic closed https://github.com/llvm/llvm-project/pull/145109 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fix __builtin_mul_overflow for big _BitInts (PR #145497)
https://github.com/rjmccall approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/145497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Add support for member initialization from constructors (PR #144583)
https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/144583 >From 79e712f0f3bd9ff64308a8dc30fb48eff2fd1706 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Mon, 16 Jun 2025 16:39:15 -0700 Subject: [PATCH 1/3] [CIR] Add support for member initialization from constructors Upstream the code to handle member variable initialization in a constructor. At this point only simple scalar values (including members of anonymous unions) are handled. --- clang/include/clang/CIR/MissingFeatures.h | 1 + clang/lib/CIR/CodeGen/CIRGenClass.cpp | 154 +- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 28 clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 9 ++ clang/lib/CIR/CodeGen/CIRGenFunction.h| 33 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 4 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 +- clang/test/CIR/CodeGen/ctor.cpp | 106 +++ 8 files changed, 340 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 3ba363772316c..bf370a9850d75 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -242,6 +242,7 @@ struct MissingFeatures { static bool builtinCallMathErrno() { return false; } static bool nonFineGrainedBitfields() { return false; } static bool armComputeVolatileBitfields() { return false; } + static bool ctorMemcpyizer() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index e59a1fdb837cb..25f3e19befa48 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -53,19 +53,135 @@ bool CIRGenFunction::isConstructorDelegationValid( return true; } +static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, +CXXCtorInitializer *memberInit, +LValue &lhs) { + FieldDecl *field = memberInit->getAnyMember(); + if (memberInit->isIndirectMemberInitializer()) { +// If we are initializing an anonymous union field, drill down to the field. +IndirectFieldDecl *indirectField = memberInit->getIndirectMember(); +for (const auto *nd : indirectField->chain()) { + auto *fd = cast(nd); + lhs = cgf.emitLValueForFieldInitialization(lhs, fd, fd->getName()); +} + } else { +lhs = cgf.emitLValueForFieldInitialization(lhs, field, field->getName()); + } +} + +static void emitMemberInitializer(CIRGenFunction &cgf, + const CXXRecordDecl *classDecl, + CXXCtorInitializer *memberInit, + const CXXConstructorDecl *constructor, + FunctionArgList &args) { + assert(memberInit->isAnyMemberInitializer() && + "Mush have member initializer!"); + assert(memberInit->getInit() && "Must have initializer!"); + + assert(!cir::MissingFeatures::generateDebugInfo()); + + // non-static data member initializers + FieldDecl *field = memberInit->getAnyMember(); + QualType fieldType = field->getType(); + + mlir::Value thisPtr = cgf.loadCXXThis(); + QualType recordTy = cgf.getContext().getTypeDeclType(classDecl); + LValue lhs; + + // If a base constructor is being emitted, create an LValue that has the + // non-virtual alignment. + if (cgf.curGD.getCtorType() == Ctor_Base) +lhs = cgf.makeNaturalAlignPointeeAddrLValue(thisPtr, recordTy); + else +lhs = cgf.makeNaturalAlignAddrLValue(thisPtr, recordTy); + + emitLValueForAnyFieldInitialization(cgf, memberInit, lhs); + + // Special case: If we are in a copy or move constructor, and we are copying + // an array off PODs or classes with tirival copy constructors, ignore the AST + // and perform the copy we know is equivalent. + // FIXME: This is hacky at best... if we had a bit more explicit information + // in the AST, we could generalize it more easily. + const ConstantArrayType *array = + cgf.getContext().getAsConstantArrayType(fieldType); + if (array && constructor->isDefaulted() && + constructor->isCopyOrMoveConstructor()) { +QualType baseElementTy = cgf.getContext().getBaseElementType(array); +// NOTE(cir): CodeGen allows record types to be memcpy'd if applicable, +// whereas ClangIR wants to represent all object construction explicitly. +if (!baseElementTy->isRecordType()) { + cgf.cgm.errorNYI(memberInit->getSourceRange(), + "emitMemberInitializer: array of non-record type"); + return; +} + } + + cgf.emitInitializerForField(field, lhs, memberInit->getInit()); +} + /// This routine generates necessary code to initialize base classes and /// non-static data members belonging to this constructor. void CIRGenFunction::emitCtorPrologue(const CX
[clang] [X86] [clang] Add missing check line for diamondrapids (PR #145542)
https://github.com/mikolaj-pirog created https://github.com/llvm/llvm-project/pull/145542 As in title. Without it, the test doesn't check for dmr From ac887983c860a3f88a38a02ec308e543bdee9bbb Mon Sep 17 00:00:00 2001 From: "Pirog, Mikolaj Maciej" Date: Tue, 24 Jun 2025 18:10:04 +0200 Subject: [PATCH] Add missing testing --- clang/test/CodeGen/attr-target-mv.c | 4 1 file changed, 4 insertions(+) diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c index 6911b55203b7e..07f47d93cd29c 100644 --- a/clang/test/CodeGen/attr-target-mv.c +++ b/clang/test/CodeGen/attr-target-mv.c @@ -201,6 +201,8 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret i32 25 // ITANIUM: define{{.*}} i32 @foo.arch_clearwaterforest() // ITANIUM: ret i32 26 +// ITANIUM: define{{.*}} i32 @foo.arch_diamondrapids() +// ITANIUM: ret i32 27 // ITANIUM: define{{.*}} i32 @foo() // ITANIUM: ret i32 2 // ITANIUM: define{{.*}} i32 @bar() @@ -258,6 +260,8 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: ret i32 25 // WINDOWS: define dso_local i32 @foo.arch_clearwaterforest() // WINDOWS: ret i32 26 +// WINDOWS: define dso_local i32 @foo.arch_diamondrapids() +// WINDOWS: ret i32 27 // WINDOWS: define dso_local i32 @foo() // WINDOWS: ret i32 2 // WINDOWS: define dso_local i32 @bar() ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits