[clang] [clang][bytecode] Fix delete[] dtor order (PR #128411)

2025-02-23 Thread Timm Baeder via cfe-commits

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

As always, call array dtors in reverse order.

>From c8d9fba32d6c97e89d320533fd680f6fa2f80a78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 23 Feb 2025 10:57:47 +0100
Subject: [PATCH] [clang][bytecode] Fix delete[] dtor order

As always, call array dtors in reverse order.
---
 clang/lib/AST/ByteCode/Interp.cpp  |  5 -
 clang/test/AST/ByteCode/new-delete.cpp | 20 
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index dfa59a50b2711..43a062ce0c19b 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1015,11 +1015,14 @@ static bool RunDestructors(InterpState &S, CodePtr 
OpPC, const Block *B) {
   assert(Desc->isRecord() || Desc->isCompositeArray());
 
   if (Desc->isCompositeArray()) {
+unsigned N = Desc->getNumElems();
+if (N == 0)
+  return true;
 const Descriptor *ElemDesc = Desc->ElemDesc;
 assert(ElemDesc->isRecord());
 
 Pointer RP(const_cast(B));
-for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
+for (int I = static_cast(N) - 1; I >= 0; --I) {
   if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc))
 return false;
 }
diff --git a/clang/test/AST/ByteCode/new-delete.cpp 
b/clang/test/AST/ByteCode/new-delete.cpp
index 5be1bb944c18c..a85ddaf29caf4 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -942,6 +942,26 @@ namespace ArrayBaseCast {
   static_assert(test());
 }
 
+namespace PR45350 {
+  int q;
+  struct V { int n; int *p = &n; constexpr ~V() { *p = *p * 10 + n; }};
+  constexpr int f(int n) {
+int k = 0;
+V *p = new V[n];
+for (int i = 0; i != n; ++i) {
+  if (p[i].p != &p[i].n) return -1;
+  p[i].n = i;
+  p[i].p = &k;
+}
+delete[] p;
+return k;
+  }
+  // [expr.delete]p6:
+  //   In the case of an array, the elements will be destroyed in order of
+  //   decreasing address
+  static_assert(f(6) == 543210);
+}
+
 #else
 /// Make sure we reject this prior to C++20
 constexpr int a() { // both-error {{never produces a constant expression}}

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


[clang] [clang][bytecode] Fix delete[] dtor order (PR #128411)

2025-02-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

As always, call array dtors in reverse order.

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


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-1) 
- (modified) clang/test/AST/ByteCode/new-delete.cpp (+20) 


``diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index dfa59a50b2711..43a062ce0c19b 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1015,11 +1015,14 @@ static bool RunDestructors(InterpState &S, CodePtr 
OpPC, const Block *B) {
   assert(Desc->isRecord() || Desc->isCompositeArray());
 
   if (Desc->isCompositeArray()) {
+unsigned N = Desc->getNumElems();
+if (N == 0)
+  return true;
 const Descriptor *ElemDesc = Desc->ElemDesc;
 assert(ElemDesc->isRecord());
 
 Pointer RP(const_cast(B));
-for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
+for (int I = static_cast(N) - 1; I >= 0; --I) {
   if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc))
 return false;
 }
diff --git a/clang/test/AST/ByteCode/new-delete.cpp 
b/clang/test/AST/ByteCode/new-delete.cpp
index 5be1bb944c18c..a85ddaf29caf4 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -942,6 +942,26 @@ namespace ArrayBaseCast {
   static_assert(test());
 }
 
+namespace PR45350 {
+  int q;
+  struct V { int n; int *p = &n; constexpr ~V() { *p = *p * 10 + n; }};
+  constexpr int f(int n) {
+int k = 0;
+V *p = new V[n];
+for (int i = 0; i != n; ++i) {
+  if (p[i].p != &p[i].n) return -1;
+  p[i].n = i;
+  p[i].p = &k;
+}
+delete[] p;
+return k;
+  }
+  // [expr.delete]p6:
+  //   In the case of an array, the elements will be destroyed in order of
+  //   decreasing address
+  static_assert(f(6) == 543210);
+}
+
 #else
 /// Make sure we reject this prior to C++20
 constexpr int a() { // both-error {{never produces a constant expression}}

``




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


[clang] [clang][bytecode] Reject calls to pure virtual functions (PR #128412)

2025-02-23 Thread Timm Baeder via cfe-commits

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

None

>From 5bb0213254e070c3c24492d6b7ec6810b13f5455 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 23 Feb 2025 11:10:43 +0100
Subject: [PATCH] [clang][bytecode] Reject calls to pure virtual functions

---
 clang/lib/AST/ByteCode/Interp.cpp | 14 +-
 clang/test/AST/ByteCode/cxx2a.cpp | 10 ++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index dfa59a50b2711..61f67fbdba81f 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1377,6 +1377,18 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const 
Function *Func,
   size_t ArgSize = Func->getArgSize() + VarArgSize;
   size_t ThisOffset = ArgSize - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
   Pointer &ThisPtr = S.Stk.peek(ThisOffset);
+  const FunctionDecl *Callee = Func->getDecl();
+
+  // C++2a [class.abstract]p6:
+  //   the effect of making a virtual call to a pure virtual function [...] is
+  //   undefined
+  if (Callee->isPureVirtual()) {
+S.FFDiag(S.Current->getSource(OpPC), 
diag::note_constexpr_pure_virtual_call,
+ 1)
+<< Callee;
+S.Note(Callee->getLocation(), diag::note_declared_at);
+return false;
+  }
 
   const CXXRecordDecl *DynamicDecl = nullptr;
   {
@@ -1393,7 +1405,7 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const 
Function *Func,
   assert(DynamicDecl);
 
   const auto *StaticDecl = cast(Func->getParentDecl());
-  const auto *InitialFunction = cast(Func->getDecl());
+  const auto *InitialFunction = cast(Callee);
   const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction(
   DynamicDecl, StaticDecl, InitialFunction);
 
diff --git a/clang/test/AST/ByteCode/cxx2a.cpp 
b/clang/test/AST/ByteCode/cxx2a.cpp
index 72ef58ca0b1d1..d9541aca225b9 100644
--- a/clang/test/AST/ByteCode/cxx2a.cpp
+++ b/clang/test/AST/ByteCode/cxx2a.cpp
@@ -177,3 +177,13 @@ consteval int f(int i) {
 return 2 * i;
 }
 static_assert(test(42));
+
+namespace PureVirtual {
+  struct Abstract {
+constexpr virtual void f() = 0; // both-note {{declared here}}
+constexpr Abstract() { do_it(); } // both-note {{in call to}}
+constexpr void do_it() { f(); } // both-note {{pure virtual function 
'PureVirtual::Abstract::f' called}}
+  };
+  struct PureVirtualCall : Abstract { void f(); }; // both-note {{in call to 
'Abstract}}
+  constexpr PureVirtualCall pure_virtual_call; // both-error {{constant 
expression}} both-note {{in call to 'PureVirtualCall}}
+}

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


[clang] [clang][bytecode] Reject calls to pure virtual functions (PR #128412)

2025-02-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes



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


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.cpp (+13-1) 
- (modified) clang/test/AST/ByteCode/cxx2a.cpp (+10) 


``diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index dfa59a50b2711..61f67fbdba81f 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1377,6 +1377,18 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const 
Function *Func,
   size_t ArgSize = Func->getArgSize() + VarArgSize;
   size_t ThisOffset = ArgSize - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
   Pointer &ThisPtr = S.Stk.peek(ThisOffset);
+  const FunctionDecl *Callee = Func->getDecl();
+
+  // C++2a [class.abstract]p6:
+  //   the effect of making a virtual call to a pure virtual function [...] is
+  //   undefined
+  if (Callee->isPureVirtual()) {
+S.FFDiag(S.Current->getSource(OpPC), 
diag::note_constexpr_pure_virtual_call,
+ 1)
+<< Callee;
+S.Note(Callee->getLocation(), diag::note_declared_at);
+return false;
+  }
 
   const CXXRecordDecl *DynamicDecl = nullptr;
   {
@@ -1393,7 +1405,7 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const 
Function *Func,
   assert(DynamicDecl);
 
   const auto *StaticDecl = cast(Func->getParentDecl());
-  const auto *InitialFunction = cast(Func->getDecl());
+  const auto *InitialFunction = cast(Callee);
   const CXXMethodDecl *Overrider = S.getContext().getOverridingFunction(
   DynamicDecl, StaticDecl, InitialFunction);
 
diff --git a/clang/test/AST/ByteCode/cxx2a.cpp 
b/clang/test/AST/ByteCode/cxx2a.cpp
index 72ef58ca0b1d1..d9541aca225b9 100644
--- a/clang/test/AST/ByteCode/cxx2a.cpp
+++ b/clang/test/AST/ByteCode/cxx2a.cpp
@@ -177,3 +177,13 @@ consteval int f(int i) {
 return 2 * i;
 }
 static_assert(test(42));
+
+namespace PureVirtual {
+  struct Abstract {
+constexpr virtual void f() = 0; // both-note {{declared here}}
+constexpr Abstract() { do_it(); } // both-note {{in call to}}
+constexpr void do_it() { f(); } // both-note {{pure virtual function 
'PureVirtual::Abstract::f' called}}
+  };
+  struct PureVirtualCall : Abstract { void f(); }; // both-note {{in call to 
'Abstract}}
+  constexpr PureVirtualCall pure_virtual_call; // both-error {{constant 
expression}} both-note {{in call to 'PureVirtualCall}}
+}

``




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


[clang-tools-extra] [DRAFT][clang-tidy] modernize-replace-with-stdcopy (PR #113046)

2025-02-23 Thread Kuba Migdał via cfe-commits

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


[clang] [analyzer] Update the undefined assignment checker diagnostics to not use the term 'garbage' (PR #126596)

2025-02-23 Thread David Tarditi via cfe-commits

https://github.com/dtarditi updated 
https://github.com/llvm/llvm-project/pull/126596

>From 06eb6682196249f4cae9801963380d0881d27296 Mon Sep 17 00:00:00 2001
From: David Tarditi 
Date: Mon, 10 Feb 2025 11:35:45 -0800
Subject: [PATCH 1/3] [analyzer] Update undefined assignment diagnostics to not
 use 'garbage'

A clang user pointed out that messages for the static analyzer undefined
assignment checker use the term 'garbage'.  This is kind of snarky and
also imprecise. This change replaces the term 'garbage' in those messages
with 'not meaningful'. It moves the term 'undefined' to be first in the
messages because of the possible ambiguous parsing of the term 'not
 meaningful and undefined'. That could be parsed as '(not meaningful)
and undefined' or 'not (meaningful and undefined').

The use of the term 'meaningless' was considered, but not chosen because
it has two meanings in English. One meaning is 'without meaning'. The
other meaning is 'having no point'. The 2nd meaning could be construed
as indicating the computation could be deleted.

rdar://133418644
---
 .../Checkers/UndefinedAssignmentChecker.cpp   | 13 
 .../Inputs/expected-plists/edges-new.mm.plist | 10 +++
 .../expected-plists/plist-output.m.plist  | 10 +++
 clang/test/Analysis/a_flaky_crash.cpp |  2 +-
 .../analysis-after-multiple-dtors.cpp |  2 +-
 clang/test/Analysis/array-init-loop.cpp   |  6 ++--
 clang/test/Analysis/array-punned-region.c |  2 +-
 clang/test/Analysis/builtin_overflow_notes.c  |  4 +--
 clang/test/Analysis/call-invalidation.cpp |  4 +--
 clang/test/Analysis/ctor-array.cpp| 22 +++---
 .../diagnostics/no-store-func-path-notes.m|  4 +--
 clang/test/Analysis/fread.c   | 20 ++---
 .../Analysis/implicit-ctor-undef-value.cpp| 12 
 clang/test/Analysis/initialization.c  | 16 +-
 clang/test/Analysis/initialization.cpp| 26 
 clang/test/Analysis/misc-ps.c |  4 +--
 clang/test/Analysis/operator-calls.cpp|  8 ++---
 clang/test/Analysis/stack-addr-ps.cpp |  2 +-
 clang/test/Analysis/uninit-const.c| 20 ++---
 clang/test/Analysis/uninit-const.cpp  |  4 +--
 .../uninit-structured-binding-array.cpp   | 30 +--
 .../uninit-structured-binding-struct.cpp  | 12 
 .../uninit-structured-binding-tuple.cpp   |  4 +--
 clang/test/Analysis/uninit-vals.m |  8 ++---
 .../test/Analysis/zero-size-non-pod-array.cpp |  4 +--
 25 files changed, 125 insertions(+), 124 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index ddc6cc9e8202c..f13de315ed7b5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -23,7 +23,7 @@ using namespace ento;
 namespace {
 class UndefinedAssignmentChecker
   : public Checker {
-  const BugType BT{this, "Assigned value is garbage or undefined"};
+  const BugType BT{this, "Assigned value is undefined and not meaningful"};
 
 public:
   void checkBind(SVal location, SVal val, const Stmt *S,
@@ -57,8 +57,8 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  OS << "The expression is an uninitialized value. "
-"The computed value will also be garbage";
+  OS << "The expression is an uninitialized value, so the computed value "
+ << "is not meaningful";
 
   ex = U->getSubExpr();
   break;
@@ -68,7 +68,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
   OS << "The left expression of the compound assignment is an "
-"uninitialized value. The computed value will also be garbage";
+ << "uninitialized value, so the computed value is not meaningful";
   ex = B->getLHS();
   break;
 }
@@ -88,8 +88,9 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
   if (CD->isImplicit()) {
 for (auto *I : CD->inits()) {
   if (I->getInit()->IgnoreImpCasts() == StoreE) {
-OS << "Value assigned to field '" << I->getMember()->getName()
-   << "' in implicit constructor is garbage or undefined";
+OS << "Value assigned to field '"
+   << I->getMember()->getName()
+   << "' in implicit constructor is undefined and not meaningful.";
 break;
   }
 }
diff --git a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist 
b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index 31b6286b4465e..dd731e705c9b0 100644
--- a/clang/test/Analysis/Inputs/expected-plists/

[clang] [analyzer] Update the undefined assignment checker diagnostics to not use the term 'garbage' (PR #126596)

2025-02-23 Thread David Tarditi via cfe-commits

dtarditi wrote:

@haoNoQ I think sticking with uninitialized is good.  I've updated the patch 
with new error messages using that.   Please take a look at it and let me know 
what you think.  I think the right path is to issue a more precise error 
message for out-of-bounds reads.  As you point, we could do that by including 
the bounds checker as part of core checkers.   If that checker is too noisy for 
that, we could create a more limited version that covers the cases that are 
making it to this checker.  



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


[clang] [analyzer] Update the undefined assignment checker diagnostics to not use the term 'garbage' (PR #126596)

2025-02-23 Thread David Tarditi via cfe-commits

https://github.com/dtarditi updated 
https://github.com/llvm/llvm-project/pull/126596

>From 06eb6682196249f4cae9801963380d0881d27296 Mon Sep 17 00:00:00 2001
From: David Tarditi 
Date: Mon, 10 Feb 2025 11:35:45 -0800
Subject: [PATCH 1/3] [analyzer] Update undefined assignment diagnostics to not
 use 'garbage'

A clang user pointed out that messages for the static analyzer undefined
assignment checker use the term 'garbage'.  This is kind of snarky and
also imprecise. This change replaces the term 'garbage' in those messages
with 'not meaningful'. It moves the term 'undefined' to be first in the
messages because of the possible ambiguous parsing of the term 'not
 meaningful and undefined'. That could be parsed as '(not meaningful)
and undefined' or 'not (meaningful and undefined').

The use of the term 'meaningless' was considered, but not chosen because
it has two meanings in English. One meaning is 'without meaning'. The
other meaning is 'having no point'. The 2nd meaning could be construed
as indicating the computation could be deleted.

rdar://133418644
---
 .../Checkers/UndefinedAssignmentChecker.cpp   | 13 
 .../Inputs/expected-plists/edges-new.mm.plist | 10 +++
 .../expected-plists/plist-output.m.plist  | 10 +++
 clang/test/Analysis/a_flaky_crash.cpp |  2 +-
 .../analysis-after-multiple-dtors.cpp |  2 +-
 clang/test/Analysis/array-init-loop.cpp   |  6 ++--
 clang/test/Analysis/array-punned-region.c |  2 +-
 clang/test/Analysis/builtin_overflow_notes.c  |  4 +--
 clang/test/Analysis/call-invalidation.cpp |  4 +--
 clang/test/Analysis/ctor-array.cpp| 22 +++---
 .../diagnostics/no-store-func-path-notes.m|  4 +--
 clang/test/Analysis/fread.c   | 20 ++---
 .../Analysis/implicit-ctor-undef-value.cpp| 12 
 clang/test/Analysis/initialization.c  | 16 +-
 clang/test/Analysis/initialization.cpp| 26 
 clang/test/Analysis/misc-ps.c |  4 +--
 clang/test/Analysis/operator-calls.cpp|  8 ++---
 clang/test/Analysis/stack-addr-ps.cpp |  2 +-
 clang/test/Analysis/uninit-const.c| 20 ++---
 clang/test/Analysis/uninit-const.cpp  |  4 +--
 .../uninit-structured-binding-array.cpp   | 30 +--
 .../uninit-structured-binding-struct.cpp  | 12 
 .../uninit-structured-binding-tuple.cpp   |  4 +--
 clang/test/Analysis/uninit-vals.m |  8 ++---
 .../test/Analysis/zero-size-non-pod-array.cpp |  4 +--
 25 files changed, 125 insertions(+), 124 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index ddc6cc9e8202c..f13de315ed7b5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -23,7 +23,7 @@ using namespace ento;
 namespace {
 class UndefinedAssignmentChecker
   : public Checker {
-  const BugType BT{this, "Assigned value is garbage or undefined"};
+  const BugType BT{this, "Assigned value is undefined and not meaningful"};
 
 public:
   void checkBind(SVal location, SVal val, const Stmt *S,
@@ -57,8 +57,8 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  OS << "The expression is an uninitialized value. "
-"The computed value will also be garbage";
+  OS << "The expression is an uninitialized value, so the computed value "
+ << "is not meaningful";
 
   ex = U->getSubExpr();
   break;
@@ -68,7 +68,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
   OS << "The left expression of the compound assignment is an "
-"uninitialized value. The computed value will also be garbage";
+ << "uninitialized value, so the computed value is not meaningful";
   ex = B->getLHS();
   break;
 }
@@ -88,8 +88,9 @@ void UndefinedAssignmentChecker::checkBind(SVal location, 
SVal val,
   if (CD->isImplicit()) {
 for (auto *I : CD->inits()) {
   if (I->getInit()->IgnoreImpCasts() == StoreE) {
-OS << "Value assigned to field '" << I->getMember()->getName()
-   << "' in implicit constructor is garbage or undefined";
+OS << "Value assigned to field '"
+   << I->getMember()->getName()
+   << "' in implicit constructor is undefined and not meaningful.";
 break;
   }
 }
diff --git a/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist 
b/clang/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index 31b6286b4465e..dd731e705c9b0 100644
--- a/clang/test/Analysis/Inputs/expected-plists/

[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread via cfe-commits


@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy -std=c99 %s bugprone-true-macro %t
+// RUN: %check_clang_tidy -std=c11 %s bugprone-true-macro %t
+// RUN: %check_clang_tidy -std=c17 %s bugprone-true-macro %t

isuckatcs wrote:

That's from `C23-and-later`, but the check is not enabled in such cases.

```C++
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
  return LangOpts.C99 || LangOpts.C11 || LangOpts.C17;
}
```
IIRC, we don't test the other cases either when the check is not available, so 
I don't see why we would make an exception.

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


[clang-tools-extra] [clang-tidy]improve performance-unnecessary-value-param performance (PR #128383)

2025-02-23 Thread Piotr Zegar via cfe-commits

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

LGTM but put some entry in check documentation.

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


[clang-tools-extra] [clangd] Store full decl/def range with symbol locations (PR #118102)

2025-02-23 Thread via cfe-commits

damnskippy wrote:

Been following this thread with much interest albeit selfishly a bit since I 
was of the impression this PR will pave the way for supporting LocationLink.  
[Ref: clangd/clangd/discussions/2274]

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


[clang] [Clang] Implement CWG2918 'Consideration of constraints for address of overloaded function' (PR #127773)

2025-02-23 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/127773

>From 2d9c248c70b6d24f277982a32f36e2ef1bde2829 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Wed, 19 Feb 2025 17:13:56 +0800
Subject: [PATCH 1/5] [Clang] Implement CWG2918 'Consideration of constraints
 for address of overloaded function'

---
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/Sema/Sema.h  |   3 +-
 clang/lib/Sema/SemaConcept.cpp   |   5 +-
 clang/lib/Sema/SemaOverload.cpp  | 110 ++-
 clang/lib/Sema/SemaTemplateDeduction.cpp |   9 +-
 clang/test/CXX/drs/cwg29xx.cpp   |  84 +
 clang/www/cxx_dr_status.html |   2 +-
 7 files changed, 187 insertions(+), 30 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a91c764860ccd..b876b48c63717 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -88,6 +88,10 @@ Resolutions to C++ Defect Reports
   two releases. The improvements to template template parameter matching 
implemented
   in the previous release, as described in P3310 and P3579, made this flag 
unnecessary.
 
+- Implemented `CWG2918 Consideration of constraints for address of overloaded `
+  `function `_
+
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c55b964650323..3270e7afb3796 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10466,7 +10466,8 @@ class Sema final : public SemaBase {
   /// returned.
   FunctionDecl *ResolveSingleFunctionTemplateSpecialization(
   OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = 
nullptr,
-  TemplateSpecCandidateSet *FailedTSC = nullptr);
+  TemplateSpecCandidateSet *FailedTSC = nullptr,
+  bool ForTypeDeduction = false);
 
   // Resolve and fix an overloaded expression that can be resolved
   // because it identifies a single function template specialization.
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 8a77cbf8c9477..f8bc176c1d8b5 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1773,6 +1773,7 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
   NamedDecl *D2,
   MutableArrayRef AC2,
   bool &Result) {
+#ifndef NDEBUG
   if (const auto *FD1 = dyn_cast(D1)) {
 auto IsExpectedEntity = [](const FunctionDecl *FD) {
   FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind();
@@ -1780,13 +1781,11 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
  Kind == FunctionDecl::TK_FunctionTemplate;
 };
 const auto *FD2 = dyn_cast(D2);
-(void)IsExpectedEntity;
-(void)FD1;
-(void)FD2;
 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
"use non-instantiated function declaration for constraints partial "
"ordering");
   }
+#endif
 
   if (AC1.empty()) {
 Result = AC2.empty();
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8d5b5ac190b5b..77fc78dd8ce99 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10369,20 +10369,16 @@ static bool allowAmbiguity(ASTContext &Context, const 
FunctionDecl *F1,
 /// [over.match.best.general]p2.6
 /// F1 and F2 are non-template functions with the same
 /// non-object-parameter-type-lists, and F1 is more constrained than F2 [...]
-static bool sameFunctionParameterTypeLists(Sema &S,
-   const OverloadCandidate &Cand1,
-   const OverloadCandidate &Cand2) {
-  if (!Cand1.Function || !Cand2.Function)
-return false;
-
-  FunctionDecl *Fn1 = Cand1.Function;
-  FunctionDecl *Fn2 = Cand2.Function;
-
+static bool sameFunctionParameterTypeLists(Sema &S, FunctionDecl *Fn1,
+   FunctionDecl *Fn2,
+   bool IsFn1Reversed,
+   bool IsFn2Reversed) {
+  assert(Fn1 && Fn2);
   if (Fn1->isVariadic() != Fn2->isVariadic())
 return false;
 
-  if (!S.FunctionNonObjectParamTypesAreEqual(
-  Fn1, Fn2, nullptr, Cand1.isReversed() ^ Cand2.isReversed()))
+  if (!S.FunctionNonObjectParamTypesAreEqual(Fn1, Fn2, nullptr,
+ IsFn1Reversed ^ IsFn2Reversed))
 return false;
 
   auto *Mem1 = dyn_cast(Fn1);
@@ -10403,6 +10399,30 @@ static bool sameFunctionParameterTypeLists(Sema &S,
   return true;
 }
 
+static FunctionDecl *
+getMorePartialOrderingConstrained(Sema &S, FunctionDecl *Fn1, FunctionDecl 
*Fn2,
+  bool IsFn1Reversed, bool IsFn2Reversed) {
+  if (!Fn1 || !Fn2)
+return nullptr;
+
+  // C++ [te

[clang] [Clang] Implement CWG2918 'Consideration of constraints for address of overloaded function' (PR #127773)

2025-02-23 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/127773

>From 2d9c248c70b6d24f277982a32f36e2ef1bde2829 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Wed, 19 Feb 2025 17:13:56 +0800
Subject: [PATCH 1/6] [Clang] Implement CWG2918 'Consideration of constraints
 for address of overloaded function'

---
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/Sema/Sema.h  |   3 +-
 clang/lib/Sema/SemaConcept.cpp   |   5 +-
 clang/lib/Sema/SemaOverload.cpp  | 110 ++-
 clang/lib/Sema/SemaTemplateDeduction.cpp |   9 +-
 clang/test/CXX/drs/cwg29xx.cpp   |  84 +
 clang/www/cxx_dr_status.html |   2 +-
 7 files changed, 187 insertions(+), 30 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a91c764860ccd..b876b48c63717 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -88,6 +88,10 @@ Resolutions to C++ Defect Reports
   two releases. The improvements to template template parameter matching 
implemented
   in the previous release, as described in P3310 and P3579, made this flag 
unnecessary.
 
+- Implemented `CWG2918 Consideration of constraints for address of overloaded `
+  `function `_
+
+
 C Language Changes
 --
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c55b964650323..3270e7afb3796 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10466,7 +10466,8 @@ class Sema final : public SemaBase {
   /// returned.
   FunctionDecl *ResolveSingleFunctionTemplateSpecialization(
   OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = 
nullptr,
-  TemplateSpecCandidateSet *FailedTSC = nullptr);
+  TemplateSpecCandidateSet *FailedTSC = nullptr,
+  bool ForTypeDeduction = false);
 
   // Resolve and fix an overloaded expression that can be resolved
   // because it identifies a single function template specialization.
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 8a77cbf8c9477..f8bc176c1d8b5 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1773,6 +1773,7 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
   NamedDecl *D2,
   MutableArrayRef AC2,
   bool &Result) {
+#ifndef NDEBUG
   if (const auto *FD1 = dyn_cast(D1)) {
 auto IsExpectedEntity = [](const FunctionDecl *FD) {
   FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind();
@@ -1780,13 +1781,11 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
  Kind == FunctionDecl::TK_FunctionTemplate;
 };
 const auto *FD2 = dyn_cast(D2);
-(void)IsExpectedEntity;
-(void)FD1;
-(void)FD2;
 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
"use non-instantiated function declaration for constraints partial "
"ordering");
   }
+#endif
 
   if (AC1.empty()) {
 Result = AC2.empty();
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8d5b5ac190b5b..77fc78dd8ce99 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10369,20 +10369,16 @@ static bool allowAmbiguity(ASTContext &Context, const 
FunctionDecl *F1,
 /// [over.match.best.general]p2.6
 /// F1 and F2 are non-template functions with the same
 /// non-object-parameter-type-lists, and F1 is more constrained than F2 [...]
-static bool sameFunctionParameterTypeLists(Sema &S,
-   const OverloadCandidate &Cand1,
-   const OverloadCandidate &Cand2) {
-  if (!Cand1.Function || !Cand2.Function)
-return false;
-
-  FunctionDecl *Fn1 = Cand1.Function;
-  FunctionDecl *Fn2 = Cand2.Function;
-
+static bool sameFunctionParameterTypeLists(Sema &S, FunctionDecl *Fn1,
+   FunctionDecl *Fn2,
+   bool IsFn1Reversed,
+   bool IsFn2Reversed) {
+  assert(Fn1 && Fn2);
   if (Fn1->isVariadic() != Fn2->isVariadic())
 return false;
 
-  if (!S.FunctionNonObjectParamTypesAreEqual(
-  Fn1, Fn2, nullptr, Cand1.isReversed() ^ Cand2.isReversed()))
+  if (!S.FunctionNonObjectParamTypesAreEqual(Fn1, Fn2, nullptr,
+ IsFn1Reversed ^ IsFn2Reversed))
 return false;
 
   auto *Mem1 = dyn_cast(Fn1);
@@ -10403,6 +10399,30 @@ static bool sameFunctionParameterTypeLists(Sema &S,
   return true;
 }
 
+static FunctionDecl *
+getMorePartialOrderingConstrained(Sema &S, FunctionDecl *Fn1, FunctionDecl 
*Fn2,
+  bool IsFn1Reversed, bool IsFn2Reversed) {
+  if (!Fn1 || !Fn2)
+return nullptr;
+
+  // C++ [te

[clang-tools-extra] [clang-tidy] Add new check bugprone-unintended-char-ostream-output (PR #127720)

2025-02-23 Thread Oliver Stöneberg via cfe-commits


@@ -0,0 +1,30 @@
+.. title:: clang-tidy - bugprone-unintended-char-ostream-output
+
+bugprone-unintended-char-ostream-output
+===
+
+Finds unintended character output from ``unsigned char`` and ``signed char`` 
to an
+``ostream``.
+
+Normally, when ``unsigned char (uint8_t)`` or ``signed char (int8_t)`` is 
used, it
+is more likely a number than a character. However, when it is passed directly 
to
+``std::ostream``'s ``operator<<``, resulting in character-based output instead
+of numeric value. This often contradicts the developer's intent to print
+integer values.
+
+.. code-block:: c++
+
+uint8_t v = 9;
+std::cout << v; // output '\t' instead of '9'
+
+It could be fixed as
+
+.. code-block:: c++
+
+std::cout << static_cast(v);

firewave wrote:

It is "magic" but I think it might make sense to make sure that the warning is 
not triggered by it.

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


[clang-tools-extra] [clang-tidy] Add new check bugprone-unintended-char-ostream-output (PR #127720)

2025-02-23 Thread Oliver Stöneberg via cfe-commits


@@ -0,0 +1,69 @@
+//===--- UnintendedCharOstreamOutputCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UnintendedCharOstreamOutputCheck.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+
+// check if the type is unsigned char or signed char
+AST_MATCHER(Type, isNumericChar) {
+  const auto *BT = dyn_cast(&Node);
+  if (BT == nullptr)
+return false;
+  const BuiltinType::Kind K = BT->getKind();
+  return K == BuiltinType::UChar || K == BuiltinType::SChar;
+}
+
+// check if the type is char
+AST_MATCHER(Type, isChar) {
+  const auto *BT = dyn_cast(&Node);
+  if (BT == nullptr)
+return false;
+  const BuiltinType::Kind K = BT->getKind();
+  return K == BuiltinType::Char_U || K == BuiltinType::Char_S;
+}
+
+} // namespace
+
+void UnintendedCharOstreamOutputCheck::registerMatchers(MatchFinder *Finder) {
+  auto BasicOstream =
+  cxxRecordDecl(hasName("::std::basic_ostream"),
+// only basic_ostream has overload operator<<
+// with char / unsigned char / signed char
+classTemplateSpecializationDecl(
+hasTemplateArgument(0, refersToType(isChar();
+  Finder->addMatcher(
+  cxxOperatorCallExpr(
+  hasOverloadedOperatorName("<<"),
+  hasLHS(hasType(hasUnqualifiedDesugaredType(
+  recordType(hasDeclaration(cxxRecordDecl(
+  anyOf(BasicOstream, isDerivedFrom(BasicOstream,
+  hasRHS(hasType(hasUnqualifiedDesugaredType(isNumericChar()
+  .bind("x"),
+  this);
+}
+
+void UnintendedCharOstreamOutputCheck::check(
+const MatchFinder::MatchResult &Result) {
+  const auto *Call = Result.Nodes.getNodeAs("x");
+  const Expr *Value = Call->getArg(1);
+  diag(Call->getOperatorLoc(),
+   "%0 passed to 'operator<<' outputs as character instead of integer. "
+   "cast to 'unsigned' to print numeric value or cast to 'char' to print "
+   "as character")
+  << Value->getType() << Value->getSourceRange();

firewave wrote:

Given the range only suggesting `int` should be safe. Adding `unsigned` in case 
the underlying type would make it more clearer though.

As in other cases I think it should be coding guideline agnostic and suggest 
the least intrusive (e.g. `std::int32_t` requires the `` include). But 
let's not start that discussion again...

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits

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


[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread via cfe-commits


@@ -91,6 +91,16 @@ Improvements to clang-tidy
 New checks
 ^^
 
+- New :doc:`bugprone-true-macro
+  ` check.
+
+  In C++, ``true`` is considered a keyword by the preprocessor so an ``#if 
true``
+  enters the true branch, while in C, ``true`` is not treated as a special 
+  keyword by the preprocessor, so the false branch is entered. 
+  
+  The check identifies such cases, when ``true`` is used without being defined

EugeneZelenko wrote:

Once sentence is enough. See previous release Release Notes as example of such 
sentences.

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


[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread via cfe-commits


@@ -0,0 +1,38 @@
+//===--- TrueMacroCheck.h - clang-tidy --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TRUEMACROCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TRUEMACROCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::bugprone {
+
+/// In C++, `true` is considered a keyword by the preprocessor so an `#if
+/// true` enters the true branch, while in C, `true` is not treated as a
+/// special keyword by the preprocessor, so the false branch is entered.
+///
+/// The check identifies such cases, when `true` is used without being
+/// defined first and also offers fix-its in some cases.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/true-macro.html
+class TrueMacroCheck : public ClangTidyCheck {
+public:
+  TrueMacroCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+return LangOpts.C99 || LangOpts.C11 || LangOpts.C17;

EugeneZelenko wrote:

What about C89?

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


[clang-tools-extra] [clang-tidy] Fix performance-move-const-arg false negative in ternary… (PR #128402)

2025-02-23 Thread David Rivera via cfe-commits

RiverDave wrote:

Thx @HerrCai0907, your feedback has been addresed.

https://github.com/llvm/llvm-project/pull/128402
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Baranov Victor via cfe-commits


@@ -0,0 +1,57 @@
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
+
+readability-ambiguous-smartptr-reset-call
+=
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr ptr = std::make_unique();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
+
+
+.. note::
+
+  The check may emit invalid fix-its and misleading warning messages when
+  specifying custom smart pointers or other classes in the
+  :option:`SmartPointers` option. For example, ``boost::scoped_ptr`` does not
+  have an ``operator=`` which makes fix-its invalid.
+
+
+Options
+---
+
+.. option:: SmartPointers
+
+Semicolon-separated list of fully qualified class names of custom smart
+pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
+::boost::shared_ptr`.

vbvictor wrote:

I think here my code is correct since `::boost::scoped_ptr` does not have 
`operator=` which causes fix-its to be invalid.

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


[clang-tools-extra] [clang-tidy] Fix performance-move-const-arg false negative in ternary… (PR #128402)

2025-02-23 Thread David Rivera via cfe-commits

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


[clang-tools-extra] [clang-tidy] Fix performance-move-const-arg false negative in ternary… (PR #128402)

2025-02-23 Thread David Rivera via cfe-commits

https://github.com/RiverDave updated 
https://github.com/llvm/llvm-project/pull/128402

>From 5eef2a52de7de53b0fb24781f40a7b02b55025b9 Mon Sep 17 00:00:00 2001
From: Riverdave 
Date: Sat, 22 Feb 2025 03:57:35 -0500
Subject: [PATCH] [clang-tidy] Fix performance-move-const-arg false negative in
 ternary operators

---
 .../performance/MoveConstArgCheck.cpp | 11 +++--
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 
 .../checkers/performance/move-const-arg.cpp   | 23 +++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
index 421ce003975bc..553c1d20cbf1d 100644
--- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
@@ -44,6 +44,10 @@ void MoveConstArgCheck::registerMatchers(MatchFinder 
*Finder) {
unless(isInTemplateInstantiation()))
   .bind("call-move");
 
+  // Match ternary expressions where either branch contains std::move
+  auto TernaryWithMoveMatcher =
+  conditionalOperator(hasDescendant(MoveCallMatcher));
+
   Finder->addMatcher(
   expr(anyOf(
   castExpr(hasSourceExpression(MoveCallMatcher)),
@@ -58,13 +62,16 @@ void MoveConstArgCheck::registerMatchers(MatchFinder 
*Finder) {
   qualType(rValueReferenceType()).bind("invocation-parm-type");
   // Matches respective ParmVarDecl for a CallExpr or CXXConstructExpr.
   auto ArgumentWithParamMatcher = forEachArgumentWithParam(
-  MoveCallMatcher, parmVarDecl(anyOf(hasType(ConstTypeParmMatcher),
+  anyOf(MoveCallMatcher, TernaryWithMoveMatcher),
+  parmVarDecl(anyOf(hasType(ConstTypeParmMatcher),
  hasType(RValueTypeParmMatcher)))
.bind("invocation-parm"));
   // Matches respective types of arguments for a CallExpr or CXXConstructExpr
   // and it works on calls through function pointers as well.
   auto ArgumentWithParamTypeMatcher = forEachArgumentWithParamType(
-  MoveCallMatcher, anyOf(ConstTypeParmMatcher, RValueTypeParmMatcher));
+  anyOf(MoveCallMatcher, TernaryWithMoveMatcher),
+  anyOf(ConstTypeParmMatcher, RValueTypeParmMatcher));
+
 
   Finder->addMatcher(
   invocation(anyOf(ArgumentWithParamMatcher, ArgumentWithParamTypeMatcher))
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 41ff1c1016f25..2eb65d61f5e78 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -115,6 +115,10 @@ Changes in existing checks
   ` check by providing additional
   examples and fixing some macro related false positives.
 
+- Improved :doc:`performance-move-const-arg
+  ` check by fixing false 
negatives
+  on ternary operators calling ``std::move``.
+
 Removed checks
 ^^
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp
index 8e325b0ae6ca3..e616cbe78bc3a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp
@@ -560,3 +560,26 @@ struct Result {
   // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: passing result of 
std::move() as a const reference argument; no move will actually happen 
[performance-move-const-arg]
 };
 } // namespace GH111450
+
+namespace GH126515 {
+
+struct TernaryMoveCall {
+TernaryMoveCall();
+TernaryMoveCall(const TernaryMoveCall&);
+TernaryMoveCall operator=(const TernaryMoveCall&);
+
+void TernaryCheckTriviallyCopyable(const char * c) {}
+
+void testTernaryMove() {
+  TernaryMoveCall t1;
+  TernaryMoveCall other(false ? TernaryMoveCall() : 
TernaryMoveCall(std::move(t1)) );
+  // CHECK-MESSAGES: :[[@LINE-1]]:69: warning: passing result of std::move() 
as a const reference argument; no move will actually happen 
[performance-move-const-arg]
+  // CHECK-MESSAGES: :[[@LINE-11]]:8: note: 'TernaryMoveCall' is not move 
assignable/constructible
+
+  const char* a = "a";
+  TernaryCheckTriviallyCopyable(true ? std::move(a) : "" );
+  // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: std::move of the variable 'a' 
of the trivially-copyable type 'const char *' has no effect; remove std::move() 
[performance-move-const-arg]
+}
+
+};
+} // namespace GH126515

___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Baranov Victor via cfe-commits


@@ -0,0 +1,57 @@
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
+
+readability-ambiguous-smartptr-reset-call
+=
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr ptr = std::make_unique();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
+
+
+.. note::
+
+  The check may emit invalid fix-its and misleading warning messages when
+  specifying custom smart pointers or other classes in the
+  :option:`SmartPointers` option. For example, ``boost::scoped_ptr`` does not
+  have an ``operator=`` which makes fix-its invalid.
+
+
+Options
+---
+
+.. option:: SmartPointers
+
+Semicolon-separated list of fully qualified class names of custom smart
+pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
+::boost::shared_ptr`.

vbvictor wrote:

As I said in 
https://github.com/llvm/llvm-project/pull/121291#issuecomment-2676086944, I 
think it's better to provide default pointers whose fixes will be 100% correct 
(hopefully).
You think we should put values that provide incorrect fix-its sometimes?

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


[clang] [Driver] Replace /usr/lib/../$OSLibDir with /usr/$OSLibDir (PR #128428)

2025-02-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Fangrui Song (MaskRay)


Changes

The latter is simpler and generalizes the OpenEmbedded special case introduced 
in https://reviews.llvm.org/D48862
(they have /usr/lib64 but not /usr/lib)

---

Patch is 169.23 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/128428.diff


10 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Linux.cpp (+1-8) 
- (modified) clang/test/Driver/csky-toolchain.c (+2-4) 
- (modified) clang/test/Driver/linux-cross.cpp (+6-6) 
- (modified) clang/test/Driver/linux-ld.c (+17-17) 
- (modified) clang/test/Driver/loongarch-toolchain.c (+1-1) 
- (modified) clang/test/Driver/mips-cs.cpp (+95-95) 
- (modified) clang/test/Driver/mips-fsf.cpp (+240-240) 
- (modified) clang/test/Driver/mips-img-v2.cpp (+48-48) 
- (modified) clang/test/Driver/mips-img.cpp (+8-8) 
- (modified) clang/test/Driver/mips-mti.cpp (+64-64) 


``diff
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp 
b/clang/lib/Driver/ToolChains/Linux.cpp
index 0767fe6c58796..1e9bd3de75f04 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -343,14 +343,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, 
const ArgList &Args)
   }
 
   addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
-  // 64-bit OpenEmbedded sysroots may not have a /usr/lib dir. So they cannot
-  // find /usr/lib64 as it is referenced as /usr/lib/../lib64. So we handle
-  // this here.
-  if (Triple.getVendor() == llvm::Triple::OpenEmbedded &&
-  Triple.isArch64Bit())
-addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
-  else
-addPathIfExists(D, concat(SysRoot, "/usr/lib/..", OSLibDir), Paths);
+  addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
   if (IsRISCV) {
 StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
 addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);
diff --git a/clang/test/Driver/csky-toolchain.c 
b/clang/test/Driver/csky-toolchain.c
index 638ce64ec98cd..8b0dd1b03956d 100644
--- a/clang/test/Driver/csky-toolchain.c
+++ b/clang/test/Driver/csky-toolchain.c
@@ -15,12 +15,11 @@
 // C-CSKY-LINUX-MULTI: 
"--sysroot={{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc"
 // C-CSKY-LINUX-MULTI: "-m" "cskyelf_linux"
 // C-CSKY-LINUX-MULTI: "-dynamic-linker" "/lib/ld.so.1"
-// C-CSKY-LINUX-MULTI: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/usr/lib/../lib/crt1.o"
+// C-CSKY-LINUX-MULTI: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/usr{{/|}}lib/crt1.o"
 // C-CSKY-LINUX-MULTI: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crti.o"
 // C-CSKY-LINUX-MULTI: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/crtbegin.o"
 // C-CSKY-LINUX-MULTI: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0"
 // C-CSKY-LINUX-MULTI: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/lib/../lib"
-// C-CSKY-LINUX-MULTI: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/usr/lib/../lib"
 // C-CSKY-LINUX-MULTI: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/lib"
 // C-CSKY-LINUX-MULTI: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/usr/lib"
 
@@ -31,11 +30,10 @@
 // C-CSKY-LINUX-CK860V: 
"--sysroot={{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/ck860v"
 // C-CSKY-LINUX-CK860V: "-m" "cskyelf_linux"
 // C-CSKY-LINUX-CK860V: "-dynamic-linker" "/lib/ld.so.1"
-// C-CSKY-LINUX-CK860V: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/ck860v/usr/lib/../lib/crt1.o"
+// C-CSKY-LINUX-CK860V: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/libc/ck860v/usr{{/|}}lib/crt1.o"
 // C-CSKY-LINUX-CK860V: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crti.o"
 // C-CSKY-LINUX-CK860V: 
"{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v/crtbegin.o"
 // C-CSKY-LINUX-CK860V: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/ck860v"
 // C-CSKY-LINUX-CK860V: 
"-L{{.*}}/Inputs/multilib_csky_linux_sdk/lib/gcc/csky-linux-gnuabiv2/6.3.0/../../..{{/|}}..{{/|}}csky-linux-gnuabiv2/

[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL commented:

1. Wrong category, maybe better would be 'portability'
2. To short check name, maybe better would be 
portability-undefined-bool-literal or something similar.
3. What about 'false' ?
4. This issue is detected by -Wundef compiler warning in both clang and gcc.

Consider:
1. Not adding check if -Wundef is sufficient
2. Create check that forbids usage of true/false in processor as an 
non-portable thing (could be in portability category)
3. Extracting 'true' case from -Wundef into separate warning like -Wundef-true

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


[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy -std=c99 %s bugprone-true-macro %t
+// RUN: %check_clang_tidy -std=c11 %s bugprone-true-macro %t
+// RUN: %check_clang_tidy -std=c17 %s bugprone-true-macro %t
+
+#define FOO true
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: in C 'true' is treated as an 
undefined macro and evaluates to a falsy value; consider replacing it with '1' 
[bugprone-true-macro]
+// CHECK-FIXES: 1
+
+#if true
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: in C 'true' is treated as an 
undefined macro and evaluates to a falsy value; consider replacing it with '1' 
[bugprone-true-macro]
+// CHECK-FIXES: 1
+#endif
+
+#if false || true
+// CHECK-MESSAGES: :[[@LINE-1]]:2: warning: in C 'true' in the condition is 
treated as an undefined macro and evaluates to a falsy value; consider 
replacing it with '1' [bugprone-true-macro]

PiotrZSL wrote:

maybe instead falsy, just write 'false'

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


[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread Piotr Zegar via cfe-commits

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


[clang-tools-extra] [clang-tidy] Fix performance-move-const-arg false negative in ternary… (PR #128402)

2025-02-23 Thread David Rivera via cfe-commits


@@ -44,6 +44,12 @@ void MoveConstArgCheck::registerMatchers(MatchFinder 
*Finder) {
unless(isInTemplateInstantiation()))
   .bind("call-move");
 
+  // Match ternary expressions where either branch contains std::move
+  auto TernaryWithMoveMatcher =
+  conditionalOperator(
+hasDescendant(MoveCallMatcher)
+  ).bind("ternary-move");

RiverDave wrote:

Amazing! Appreciate your feedback, all of your comments should be addressed by 
now.

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


[clang-tools-extra] [clang-tidy] warn when `true` is used as a preprocessor keyword in C (PR #128265)

2025-02-23 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL edited 
https://github.com/llvm/llvm-project/pull/128265
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,57 @@
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
+
+readability-ambiguous-smartptr-reset-call
+=
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr ptr = std::make_unique();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
+
+

PiotrZSL wrote:

Mention in documentation that fixes are enabled via `--fix-notes`

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,129 @@
+//===--- AmbiguousSmartptrResetCallCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "AmbiguousSmartptrResetCallCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) {
+  for (const auto *Param : Node.parameters()) {
+if (!Param->hasDefaultArg())
+  return false;
+  }
+
+  return true;
+}
+
+const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr;"
+  "::boost::shared_ptr";
+} // namespace
+
+AmbiguousSmartptrResetCallCheck::AmbiguousSmartptrResetCallCheck(
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  SmartPointers(utils::options::parseStringList(
+  Options.get("SmartPointers", DefaultSmartPointers))) {}
+
+void AmbiguousSmartptrResetCallCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "SmartPointers",
+utils::options::serializeStringList(SmartPointers));
+}
+
+void AmbiguousSmartptrResetCallCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsSmartptr = hasAnyName(SmartPointers);
+
+  const auto ResetMethod =
+  cxxMethodDecl(hasName("reset"), hasOnlyDefaultParameters());
+
+  const auto TypeWithReset =
+  anyOf(cxxRecordDecl(hasMethod(ResetMethod)),
+classTemplateSpecializationDecl(
+hasSpecializedTemplate(classTemplateDecl(has(ResetMethod);
+
+  const auto SmartptrWithReset = expr(hasType(hasUnqualifiedDesugaredType(
+  recordType(hasDeclaration(classTemplateSpecializationDecl(
+  IsSmartptr,
+  hasTemplateArgument(
+  0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(TypeWithReset;
+
+  Finder->addMatcher(
+  cxxMemberCallExpr(
+  callee(ResetMethod),
+  unless(hasAnyArgument(expr(unless(cxxDefaultArgExpr(),
+  anyOf(on(SmartptrWithReset),
+on(cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
+   hasArgument(0, SmartptrWithReset))
+   .bind("ArrowOp"
+  .bind("MemberCall"),
+  this);
+}
+
+void AmbiguousSmartptrResetCallCheck::check(
+const MatchFinder::MatchResult &Result) {
+
+  if (const auto *Arrow =
+  Result.Nodes.getNodeAs("ArrowOp")) {
+const auto *ObjectResetCall =
+Result.Nodes.getNodeAs("MemberCall");

PiotrZSL wrote:

duplicated member call, just move it before if and use in both if's

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL edited 
https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,129 @@
+//===--- AmbiguousSmartptrResetCallCheck.cpp - clang-tidy 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "AmbiguousSmartptrResetCallCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) {
+  for (const auto *Param : Node.parameters()) {
+if (!Param->hasDefaultArg())
+  return false;
+  }
+
+  return true;
+}
+
+const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr;"
+  "::boost::shared_ptr";
+} // namespace
+
+AmbiguousSmartptrResetCallCheck::AmbiguousSmartptrResetCallCheck(
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context),
+  SmartPointers(utils::options::parseStringList(
+  Options.get("SmartPointers", DefaultSmartPointers))) {}
+
+void AmbiguousSmartptrResetCallCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "SmartPointers",
+utils::options::serializeStringList(SmartPointers));
+}
+
+void AmbiguousSmartptrResetCallCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsSmartptr = hasAnyName(SmartPointers);
+
+  const auto ResetMethod =
+  cxxMethodDecl(hasName("reset"), hasOnlyDefaultParameters());
+
+  const auto TypeWithReset =
+  anyOf(cxxRecordDecl(hasMethod(ResetMethod)),
+classTemplateSpecializationDecl(
+hasSpecializedTemplate(classTemplateDecl(has(ResetMethod);
+
+  const auto SmartptrWithReset = expr(hasType(hasUnqualifiedDesugaredType(
+  recordType(hasDeclaration(classTemplateSpecializationDecl(
+  IsSmartptr,
+  hasTemplateArgument(
+  0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(TypeWithReset;
+
+  Finder->addMatcher(
+  cxxMemberCallExpr(
+  callee(ResetMethod),
+  unless(hasAnyArgument(expr(unless(cxxDefaultArgExpr(),
+  anyOf(on(SmartptrWithReset),
+on(cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
+   hasArgument(0, SmartptrWithReset))
+   .bind("ArrowOp"
+  .bind("MemberCall"),
+  this);
+}
+
+void AmbiguousSmartptrResetCallCheck::check(
+const MatchFinder::MatchResult &Result) {
+
+  if (const auto *Arrow =
+  Result.Nodes.getNodeAs("ArrowOp")) {
+const auto *ObjectResetCall =
+Result.Nodes.getNodeAs("MemberCall");
+
+const CharSourceRange SmartptrSourceRange =
+Lexer::getAsCharRange(Arrow->getArg(0)->getSourceRange(),

PiotrZSL wrote:

maybe just 'bind' an object to some variable and read it like an MemberCall

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits

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

In general looks fine.
Few nits.

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,57 @@
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
+
+readability-ambiguous-smartptr-reset-call
+=
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr ptr = std::make_unique();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
+
+
+.. note::
+
+  The check may emit invalid fix-its and misleading warning messages when
+  specifying custom smart pointers or other classes in the
+  :option:`SmartPointers` option. For example, ``boost::scoped_ptr`` does not
+  have an ``operator=`` which makes fix-its invalid.
+
+
+Options
+---
+
+.. option:: SmartPointers
+
+Semicolon-separated list of fully qualified class names of custom smart
+pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
+::boost::shared_ptr`.

PiotrZSL wrote:

```suggestion
::boost::scoped_ptr`.
```

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s readability-ambiguous-smartptr-reset-call %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  {readability-ambiguous-smartptr-reset-call.SmartPointers: 
"::std::unique_ptr;::other_ptr"}}' \
+// RUN: --fix-notes --
+
+namespace std {
+
+template 

PiotrZSL wrote:

consider including 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/smart-ptr/shared_ptr.h
 and 
clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/smart-ptr/unique_ptr.h
 instead

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,57 @@
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
+
+readability-ambiguous-smartptr-reset-call
+=
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr ptr = std::make_unique();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
+
+
+.. note::
+
+  The check may emit invalid fix-its and misleading warning messages when
+  specifying custom smart pointers or other classes in the
+  :option:`SmartPointers` option. For example, ``boost::scoped_ptr`` does not
+  have an ``operator=`` which makes fix-its invalid.
+
+
+Options
+---
+
+.. option:: SmartPointers
+
+Semicolon-separated list of fully qualified class names of custom smart
+pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
+::boost::shared_ptr`.

PiotrZSL wrote:

That's not about fixes, it is about default settings for configuration option.

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


[clang] [Driver] Replace /usr/lib/../$OSLibDir with /usr/$OSLibDir (PR #128428)

2025-02-23 Thread Fangrui Song via cfe-commits

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


[clang-tools-extra] [clang-tidy] Add new check bugprone-unintended-char-ostream-output (PR #127720)

2025-02-23 Thread Carlos Galvez via cfe-commits


@@ -0,0 +1,69 @@
+//===--- UnintendedCharOstreamOutputCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "UnintendedCharOstreamOutputCheck.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+
+// check if the type is unsigned char or signed char
+AST_MATCHER(Type, isNumericChar) {
+  const auto *BT = dyn_cast(&Node);
+  if (BT == nullptr)
+return false;
+  const BuiltinType::Kind K = BT->getKind();
+  return K == BuiltinType::UChar || K == BuiltinType::SChar;
+}
+
+// check if the type is char
+AST_MATCHER(Type, isChar) {
+  const auto *BT = dyn_cast(&Node);
+  if (BT == nullptr)
+return false;
+  const BuiltinType::Kind K = BT->getKind();
+  return K == BuiltinType::Char_U || K == BuiltinType::Char_S;
+}
+
+} // namespace
+
+void UnintendedCharOstreamOutputCheck::registerMatchers(MatchFinder *Finder) {
+  auto BasicOstream =
+  cxxRecordDecl(hasName("::std::basic_ostream"),
+// only basic_ostream has overload operator<<
+// with char / unsigned char / signed char
+classTemplateSpecializationDecl(
+hasTemplateArgument(0, refersToType(isChar();
+  Finder->addMatcher(
+  cxxOperatorCallExpr(
+  hasOverloadedOperatorName("<<"),
+  hasLHS(hasType(hasUnqualifiedDesugaredType(
+  recordType(hasDeclaration(cxxRecordDecl(
+  anyOf(BasicOstream, isDerivedFrom(BasicOstream,
+  hasRHS(hasType(hasUnqualifiedDesugaredType(isNumericChar()
+  .bind("x"),
+  this);
+}
+
+void UnintendedCharOstreamOutputCheck::check(
+const MatchFinder::MatchResult &Result) {
+  const auto *Call = Result.Nodes.getNodeAs("x");
+  const Expr *Value = Call->getArg(1);
+  diag(Call->getOperatorLoc(),
+   "%0 passed to 'operator<<' outputs as character instead of integer. "
+   "cast to 'unsigned' to print numeric value or cast to 'char' to print "
+   "as character")
+  << Value->getType() << Value->getSourceRange();

carlosgalvezp wrote:

> requires the  include

Fair point. Perhaps just cast to `int` is the best compromise. It is also what 
unary plus does. If users need more flexibility we can add an option later.

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


[clang] [FatLTO] Detect LLD linker more reliably (PR #128285)

2025-02-23 Thread Vincent Lee via cfe-commits

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


[clang] 40b0619 - [FatLTO] Detect LLD linker more reliably (#128285)

2025-02-23 Thread via cfe-commits

Author: Vincent Lee
Date: 2025-02-23T12:03:37-08:00
New Revision: 40b0619a53231eafaa879d085b7a7a10441c7f34

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

LOG: [FatLTO] Detect LLD linker more reliably (#128285)

It's possible to have an `ld-path` point to a linker that doesn't have
the `ld.lld` filename (e.g. linker wrapper that may emit telemetry
before invoking the linker). This was causing mis-compilations with
fatLTO since the check couldn't reliably detect that it was using lld.
Instead, rely on the value from `-fuse-ld` to determine whether lld is
enabled.

Added: 

clang/test/Driver/Inputs/basic_cross_linux_tree/usr/x86_64-unknown-linux-gnu/bin/lld-wrapper

Modified: 
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/test/Driver/fat-lto-objects.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 360754bdb3161..b43472a52038b 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -862,13 +862,15 @@ void tools::addLTOOptions(const ToolChain &ToolChain, 
const ArgList &Args,
   const llvm::Triple &Triple = ToolChain.getTriple();
   const bool IsOSAIX = Triple.isOSAIX();
   const bool IsAMDGCN = Triple.isAMDGCN();
-  const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
+  StringRef Linker = Args.getLastArgValue(options::OPT_fuse_ld_EQ);
+  const char *LinkerPath = Args.MakeArgString(ToolChain.GetLinkerPath());
   const Driver &D = ToolChain.getDriver();
   const bool IsFatLTO = Args.hasFlag(options::OPT_ffat_lto_objects,
  options::OPT_fno_fat_lto_objects, false);
   const bool IsUnifiedLTO = Args.hasArg(options::OPT_funified_lto);
-  if (llvm::sys::path::filename(Linker) != "ld.lld" &&
-  llvm::sys::path::stem(Linker) != "ld.lld" && !Triple.isOSOpenBSD()) {
+  if (Linker != "lld" && Linker != "lld-link" &&
+  llvm::sys::path::filename(LinkerPath) != "ld.lld" &&
+  llvm::sys::path::stem(LinkerPath) != "ld.lld" && !Triple.isOSOpenBSD()) {
 // Tell the linker to load the plugin. This has to come before
 // AddLinkerInputs as gold requires -plugin and AIX ld requires -bplugin to
 // come before any -plugin-opt/-bplugin_opt that -Wl might forward.

diff  --git 
a/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/x86_64-unknown-linux-gnu/bin/lld-wrapper
 
b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/x86_64-unknown-linux-gnu/bin/lld-wrapper
new file mode 12
index 0..9b032ee3b3f1d
--- /dev/null
+++ 
b/clang/test/Driver/Inputs/basic_cross_linux_tree/usr/x86_64-unknown-linux-gnu/bin/lld-wrapper
@@ -0,0 +1 @@
+ld.lld
\ No newline at end of file

diff  --git a/clang/test/Driver/fat-lto-objects.c 
b/clang/test/Driver/fat-lto-objects.c
index fae64ea7fd1a1..7b87e2b468886 100644
--- a/clang/test/Driver/fat-lto-objects.c
+++ b/clang/test/Driver/fat-lto-objects.c
@@ -49,5 +49,8 @@
 // RUN:   -fuse-ld=lld -flto -ffat-lto-objects -### 2>&1 | FileCheck 
--check-prefix=LTO %s
 // RUN: %clang --target=x86_64-unknown-linux-gnu 
--sysroot=%S/Inputs/basic_cross_linux_tree %s \
 // RUN:   -fuse-ld=lld -fno-lto -ffat-lto-objects -### 2>&1 | FileCheck 
--check-prefix=NOLTO %s
+// RUN: %clang --target=x86_64-unknown-linux-gnu 
--sysroot=%S/Inputs/basic_cross_linux_tree %s \
+// RUN:   -fuse-ld=lld 
--ld-path=%S/Inputs/basic_cross_linux_tree/usr/x86_64-unknown-linux-gnu/bin/lld-wrapper
 \
+// RUN:   -flto -ffat-lto-objects -### 2>&1 | FileCheck --check-prefix=LTO %s
 // LTO: "--fat-lto-objects"
 // NOLTO-NOT: "--fat-lto-objects"



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


[clang-tools-extra] [clangd] Reduce superfluous rename conflicts (PR #121515)

2025-02-23 Thread Chris B via cfe-commits

https://github.com/llvm-beanz approved this pull request.

Looks reasonable to me, sorry for the review delay.

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


[clang] [Sema] Add code completion for if constexpr and consteval (PR #124315)

2025-02-23 Thread Letu Ren via cfe-commits

https://github.com/FantasqueX updated 
https://github.com/llvm/llvm-project/pull/124315

>From 576dcfa4a403b95665e98f9ff225ab5353192e23 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Sat, 25 Jan 2025 01:23:52 +0800
Subject: [PATCH 1/6] [Sema] Add code completion for if constexpr

C++17 supports `if constexpr` statement. This patch implements this in
code completion.
---
 clang/include/clang/Sema/SemaCodeCompletion.h |  1 +
 clang/lib/Parse/ParseStmt.cpp |  8 
 clang/lib/Sema/SemaCodeComplete.cpp   | 15 +++
 3 files changed, 24 insertions(+)

diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h 
b/clang/include/clang/Sema/SemaCodeCompletion.h
index e931596c215d3..af44745d5d123 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -152,6 +152,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteDesignator(const QualType BaseType,
   llvm::ArrayRef InitExprs,
   const Designation &D);
+  void CodeCompleteIfConstExpr(Scope *S) const;
   void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
 
   void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool 
EnteringContext,
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index cd4504630f871..3f9900dd997ad 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1553,6 +1553,14 @@ StmtResult Parser::ParseIfStatement(SourceLocation 
*TrailingElseLoc) {
   IsConsteval = true;
   ConstevalLoc = ConsumeToken();
 }
+
+if (Tok.is(tok::code_completion)) {
+  if (getLangOpts().CPlusPlus17) {
+cutOffParsing();
+Actions.CodeCompletion().CodeCompleteIfConstExpr(getCurScope());
+return StmtError();
+  }
+}
   }
   if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {
 Diag(Tok, diag::err_expected_lparen_after) << "if";
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 80ae87e7c5725..bcc0cb18b8739 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6749,6 +6749,21 @@ void SemaCodeCompletion::CodeCompleteInitializer(Scope 
*S, Decl *D) {
   CodeCompleteExpression(S, Data);
 }
 
+void SemaCodeCompletion::CodeCompleteIfConstExpr(Scope *S) const {
+  ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
+CodeCompleter->getCodeCompletionTUInfo(),
+CodeCompletionContext::CCC_SymbolOrNewName);
+  Results.EnterNewScope();
+
+  Results.AddResult(CodeCompletionResult("constexpr"));
+
+  Results.ExitScope();
+
+  HandleCodeCompleteResults(&SemaRef, CodeCompleter,
+Results.getCompletionContext(), Results.data(),
+Results.size());
+}
+
 void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
   ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
 CodeCompleter->getCodeCompletionTUInfo(),

>From e7b7a6f2cfa4d056b643716e28e9d91ee5ab9738 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Mon, 3 Feb 2025 22:49:38 +0800
Subject: [PATCH 2/6] Add test for if constexpr completion

---
 clang/test/CodeCompletion/if-constexpr.cpp | 4 
 1 file changed, 4 insertions(+)
 create mode 100644 clang/test/CodeCompletion/if-constexpr.cpp

diff --git a/clang/test/CodeCompletion/if-constexpr.cpp 
b/clang/test/CodeCompletion/if-constexpr.cpp
new file mode 100644
index 0..48a89b4799cbc
--- /dev/null
+++ b/clang/test/CodeCompletion/if-constexpr.cpp
@@ -0,0 +1,4 @@
+void test() {
+  if c
+  // RUN: %clang_cc1 -fsyntax-only -std=c++17 
-code-completion-at=%s:%(line-1):7 %s -o - | FileCheck -check-prefix=CHECK-CC1 
%s
+  // CHECK-CC1: constexpr

>From 7b4e81efe53e263e9410dd2994f126b5bdac5ef3 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Sat, 15 Feb 2025 18:03:38 +0800
Subject: [PATCH 3/6] rename function

---
 clang/include/clang/Sema/SemaCodeCompletion.h | 2 +-
 clang/lib/Parse/ParseStmt.cpp | 2 +-
 clang/lib/Sema/SemaCodeComplete.cpp   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h 
b/clang/include/clang/Sema/SemaCodeCompletion.h
index af44745d5d123..c79e6ec13634b 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -152,7 +152,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteDesignator(const QualType BaseType,
   llvm::ArrayRef InitExprs,
   const Designation &D);
-  void CodeCompleteIfConstExpr(Scope *S) const;
+  void CodeCompleteIfConstexpr(Scope *S) const;
   void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
 
   void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool 
EnteringContext,
diff --git a/c

[clang] [Sema] Add code completion for if constexpr and consteval (PR #124315)

2025-02-23 Thread via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 9d1fbbd2b9a00248eb8ea578c4047af4ec4da990 
914e63cbc8ac24c808da647fe9516e1d10866c87 --extensions h,cpp -- 
clang/test/CodeCompletion/if-const.cpp 
clang/include/clang/Sema/SemaCodeCompletion.h clang/lib/Parse/ParseStmt.cpp 
clang/lib/Sema/SemaCodeComplete.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index b3351387ac..f4f3970cb6 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6753,7 +6753,8 @@ void SemaCodeCompletion::CodeCompleteIfConst(Scope *S) 
const {
   ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
 CodeCompleter->getCodeCompletionTUInfo(),
 CodeCompletionContext::CCC_Other);
-  CodeCompletionBuilder Builder(Results.getAllocator(), 
Results.getCodeCompletionTUInfo());
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+Results.getCodeCompletionTUInfo());
   Results.EnterNewScope();
   if (getLangOpts().CPlusPlus17) {
 if (Results.includeCodePatterns()) {

``




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


[clang] [Sema] Add code completion for if constexpr and consteval (PR #124315)

2025-02-23 Thread Letu Ren via cfe-commits

FantasqueX wrote:

Hi @HighCommander4 thanks for your suggestions. I'm happy to add snippets 
support for `if constexpr` and `if consteval`. Since `if 
constexp` and `if !consteval` is valid, I 
decided to add code snippet completion in the specific code completion function 
instead of in statement completion. Do you think it is OK?

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


[clang] [Sema] Add code completion for if constexpr and consteval (PR #124315)

2025-02-23 Thread Letu Ren via cfe-commits

https://github.com/FantasqueX updated 
https://github.com/llvm/llvm-project/pull/124315

>From 576dcfa4a403b95665e98f9ff225ab5353192e23 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Sat, 25 Jan 2025 01:23:52 +0800
Subject: [PATCH 1/7] [Sema] Add code completion for if constexpr

C++17 supports `if constexpr` statement. This patch implements this in
code completion.
---
 clang/include/clang/Sema/SemaCodeCompletion.h |  1 +
 clang/lib/Parse/ParseStmt.cpp |  8 
 clang/lib/Sema/SemaCodeComplete.cpp   | 15 +++
 3 files changed, 24 insertions(+)

diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h 
b/clang/include/clang/Sema/SemaCodeCompletion.h
index e931596c215d3..af44745d5d123 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -152,6 +152,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteDesignator(const QualType BaseType,
   llvm::ArrayRef InitExprs,
   const Designation &D);
+  void CodeCompleteIfConstExpr(Scope *S) const;
   void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
 
   void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool 
EnteringContext,
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index cd4504630f871..3f9900dd997ad 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1553,6 +1553,14 @@ StmtResult Parser::ParseIfStatement(SourceLocation 
*TrailingElseLoc) {
   IsConsteval = true;
   ConstevalLoc = ConsumeToken();
 }
+
+if (Tok.is(tok::code_completion)) {
+  if (getLangOpts().CPlusPlus17) {
+cutOffParsing();
+Actions.CodeCompletion().CodeCompleteIfConstExpr(getCurScope());
+return StmtError();
+  }
+}
   }
   if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {
 Diag(Tok, diag::err_expected_lparen_after) << "if";
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 80ae87e7c5725..bcc0cb18b8739 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6749,6 +6749,21 @@ void SemaCodeCompletion::CodeCompleteInitializer(Scope 
*S, Decl *D) {
   CodeCompleteExpression(S, Data);
 }
 
+void SemaCodeCompletion::CodeCompleteIfConstExpr(Scope *S) const {
+  ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
+CodeCompleter->getCodeCompletionTUInfo(),
+CodeCompletionContext::CCC_SymbolOrNewName);
+  Results.EnterNewScope();
+
+  Results.AddResult(CodeCompletionResult("constexpr"));
+
+  Results.ExitScope();
+
+  HandleCodeCompleteResults(&SemaRef, CodeCompleter,
+Results.getCompletionContext(), Results.data(),
+Results.size());
+}
+
 void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
   ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
 CodeCompleter->getCodeCompletionTUInfo(),

>From e7b7a6f2cfa4d056b643716e28e9d91ee5ab9738 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Mon, 3 Feb 2025 22:49:38 +0800
Subject: [PATCH 2/7] Add test for if constexpr completion

---
 clang/test/CodeCompletion/if-constexpr.cpp | 4 
 1 file changed, 4 insertions(+)
 create mode 100644 clang/test/CodeCompletion/if-constexpr.cpp

diff --git a/clang/test/CodeCompletion/if-constexpr.cpp 
b/clang/test/CodeCompletion/if-constexpr.cpp
new file mode 100644
index 0..48a89b4799cbc
--- /dev/null
+++ b/clang/test/CodeCompletion/if-constexpr.cpp
@@ -0,0 +1,4 @@
+void test() {
+  if c
+  // RUN: %clang_cc1 -fsyntax-only -std=c++17 
-code-completion-at=%s:%(line-1):7 %s -o - | FileCheck -check-prefix=CHECK-CC1 
%s
+  // CHECK-CC1: constexpr

>From 7b4e81efe53e263e9410dd2994f126b5bdac5ef3 Mon Sep 17 00:00:00 2001
From: Letu Ren 
Date: Sat, 15 Feb 2025 18:03:38 +0800
Subject: [PATCH 3/7] rename function

---
 clang/include/clang/Sema/SemaCodeCompletion.h | 2 +-
 clang/lib/Parse/ParseStmt.cpp | 2 +-
 clang/lib/Sema/SemaCodeComplete.cpp   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h 
b/clang/include/clang/Sema/SemaCodeCompletion.h
index af44745d5d123..c79e6ec13634b 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -152,7 +152,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteDesignator(const QualType BaseType,
   llvm::ArrayRef InitExprs,
   const Designation &D);
-  void CodeCompleteIfConstExpr(Scope *S) const;
+  void CodeCompleteIfConstexpr(Scope *S) const;
   void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
 
   void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool 
EnteringContext,
diff --git a/c

[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s readability-ambiguous-smartptr-reset-call %t \

PiotrZSL wrote:

you could merge this file into main test, just have 2 RUN commands there and 
specify custom suffix for this one (you may need to include current default 
values also)

https://github.com/llvm/llvm-project/pull/121291
___
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 bugprone-smartptr-reset-ambiguous-call check (PR #121291)

2025-02-23 Thread Baranov Victor via cfe-commits

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


[clang-tools-extra] [clangd] Reduce superfluous rename conflicts (PR #121515)

2025-02-23 Thread Ujan RoyBandyopadhyay via cfe-commits

https://github.com/ujan-r updated 
https://github.com/llvm/llvm-project/pull/121515

>From 5d86f27c5dc04217252c2569edca23cc0d7edc23 Mon Sep 17 00:00:00 2001
From: Ujan RoyBandyopadhyay <116058173+uja...@users.noreply.github.com>
Date: Thu, 2 Jan 2025 00:20:52 -0600
Subject: [PATCH] [clangd] Reduce superfluous rename conflicts

Check namespaces before reporting a conflict, allowing `bar` to be
renamed to `foo` in the following snippet:

```c
typedef struct foo {} Foo;
Foo bar;
```

Previously, such a rename would fail because a declaration for `foo`
already exists in the same scope.
---
 clang-tools-extra/clangd/refactor/Rename.cpp  | 14 +---
 .../clangd/unittests/RenameTests.cpp  | 33 +++
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp 
b/clang-tools-extra/clangd/refactor/Rename.cpp
index c85e13dbdfe97..b7894b8918eed 100644
--- a/clang-tools-extra/clangd/refactor/Rename.cpp
+++ b/clang-tools-extra/clangd/refactor/Rename.cpp
@@ -338,7 +338,8 @@ const NamedDecl 
*lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
 for (const auto &Child : DS->getDeclGroup())
   if (const auto *ND = dyn_cast(Child))
 if (ND != &RenamedDecl && ND->getDeclName().isIdentifier() &&
-ND->getName() == Name)
+ND->getName() == Name &&
+ND->getIdentifierNamespace() & 
RenamedDecl.getIdentifierNamespace())
   return ND;
 return nullptr;
   };
@@ -380,7 +381,9 @@ const NamedDecl 
*lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
 // Also check if there is a name collision with function arguments.
 if (const auto *Function = ScopeParent->get())
   for (const auto *Parameter : Function->parameters())
-if (Parameter->getName() == NewName)
+if (Parameter->getName() == NewName &&
+Parameter->getIdentifierNamespace() &
+RenamedDecl.getIdentifierNamespace())
   return Parameter;
 return nullptr;
   }
@@ -405,7 +408,9 @@ const NamedDecl 
*lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
   if (const auto *EnclosingFunction = Parent->get()) {
 // Check for conflicts with other arguments.
 for (const auto *Parameter : EnclosingFunction->parameters())
-  if (Parameter != &RenamedDecl && Parameter->getName() == NewName)
+  if (Parameter != &RenamedDecl && Parameter->getName() == NewName &&
+  Parameter->getIdentifierNamespace() &
+  RenamedDecl.getIdentifierNamespace())
 return Parameter;
 // FIXME: We don't modify all references to function parameters when
 // renaming from forward declaration now, so using a name colliding with
@@ -450,7 +455,8 @@ const NamedDecl *lookupSiblingsWithinContext(ASTContext 
&Ctx,
   }
   // Lookup may contain the RenameDecl itself, exclude it.
   for (const auto *D : LookupResult)
-if (D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl())
+if (D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl() &&
+D->getIdentifierNamespace() & RenamedDecl.getIdentifierNamespace())
   return D;
   return nullptr;
 }
diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp 
b/clang-tools-extra/clangd/unittests/RenameTests.cpp
index 142ed171d1a1c..879d76e03f2a6 100644
--- a/clang-tools-extra/clangd/unittests/RenameTests.cpp
+++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp
@@ -1269,6 +1269,39 @@ TEST(RenameTest, Renameable) {
   )cpp",
"conflict", !HeaderFile, "Conflict"},
 
+  {R"cpp(
+struct conflict {};
+enum v^ar {};
+  )cpp",
+   "conflict", !HeaderFile, "conflict"},
+
+  {R"cpp(
+struct conflict {};
+int [[v^ar]];
+  )cpp",
+   nullptr, !HeaderFile, "conflict"},
+
+  {R"cpp(
+enum conflict {};
+int [[v^ar]];
+  )cpp",
+   nullptr, !HeaderFile, "conflict"},
+
+  {R"cpp(
+void func(int conflict) {
+  struct [[t^ag]] {};
+}
+  )cpp",
+   nullptr, !HeaderFile, "conflict"},
+
+  {R"cpp(
+void func(void) {
+  struct conflict {};
+  int [[v^ar]];
+}
+  )cpp",
+   nullptr, !HeaderFile, "conflict"},
+
   {R"cpp(
 void func(int);
 void [[o^therFunc]](double);

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


[clang] [llvm] [OpenEmbedded] Fix include and lib paths for multilib targets (PR #121302)

2025-02-23 Thread Fangrui Song via cfe-commits

MaskRay wrote:

The include and library path code in the driver needs more love. I have cleaned 
up some a few years ago but there is still quite a bit tech debt.

In particular, the 2018 commit you mentioned (https://reviews.llvm.org/D48862) 
introduced
```
  if (Triple.getVendor() == llvm::Triple::OpenEmbedded &&
  Triple.isArch64Bit())
addPathIfExists(D, SysRoot + "/usr/" + OSLibDir, Paths);
  else
addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
```

which could be simplified to `/usr/ + OSLibDir`, and the latter `/usr/lib` 
could be removed  if OSLibDir is "lib". 
I am testing https://github.com/llvm/llvm-project/pull/128428 and will push it 
when the Windows tests pass (it's annoying but Windows uses \\, making a lot of 
tests ugly..)

---

A lot of ELF-specific Triple::VendorType should not have been added in the 
first place.

Can you confirm whether you added new OpenEmbedded VendorType due to the 
following customization?
This is an unfortunate special case and I hope that OpenEmbedded moves away 
from the difference. Just pick gcc/ or gcc-cross/ or install symlinks so that 
Clang doesn't need to more probing.
It does not scale if there are similar projects like OpenEmbedded that do a 
similar thing and want to add a new VendorType to LLVM just to make their 
upstream divergent customization working.

```
  // This is the normal place.
  {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists},

  // Debian puts cross-compilers in gcc-cross.
  {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists},

  // The Freescale PPC SDK has the gcc libraries in
  // /usr/lib//x.y.z so have a look there as well. Only do
  // this on Freescale triples, though, since some systems put a *lot* of
  // files in that location, not just GCC installation data.
  {CandidateTriple.str(), "..",
   TargetTriple.getVendor() == llvm::Triple::Freescale ||
   TargetTriple.getVendor() == llvm::Triple::OpenEmbedded}};
```


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


[clang] [FatLTO] Detect LLD linker more reliably (PR #128285)

2025-02-23 Thread Fangrui Song via cfe-commits

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


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


[clang] [HLSL] Allow arrays to be returned by value in HLSL (PR #127896)

2025-02-23 Thread Sarah Spall via cfe-commits

https://github.com/spall updated 
https://github.com/llvm/llvm-project/pull/127896

>From 362b64d31e5f70e4a26ea04c99a58fd5f5ca50ca Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Fri, 14 Feb 2025 12:59:56 -0800
Subject: [PATCH 1/2] Allow arrays to be returned by value in HLSL + test

---
 clang/lib/Sema/SemaExpr.cpp   |  3 +-
 clang/lib/Sema/SemaType.cpp   |  6 ++--
 .../BasicFeatures/ArrayReturn.hlsl| 33 +++
 3 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fad15bf95c415..f3a83642ed4e5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20681,7 +20681,8 @@ ExprResult 
RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
   const FunctionType *FnType = CalleeType->castAs();
 
   // Verify that this is a legal result type of a function.
-  if (DestType->isArrayType() || DestType->isFunctionType()) {
+  if ((DestType->isArrayType() && !S.getLangOpts().HLSL) ||
+  DestType->isFunctionType()) {
 unsigned diagID = diag::err_func_returning_array_function;
 if (Kind == FK_BlockPointer)
   diagID = diag::err_block_returning_array_function;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index db0177f9750e0..115d2431e020c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2530,7 +2530,7 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr 
*NumRows, Expr *NumCols,
 }
 
 bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
-  if (T->isArrayType() || T->isFunctionType()) {
+  if ((T->isArrayType() && !getLangOpts().HLSL) || T->isFunctionType()) {
 Diag(Loc, diag::err_func_returning_array_function)
   << T->isFunctionType() << T;
 return true;
@@ -4934,7 +4934,9 @@ static TypeSourceInfo 
*GetFullTypeForDeclarator(TypeProcessingState &state,
 
   // C99 6.7.5.3p1: The return type may not be a function or array type.
   // For conversion functions, we'll diagnose this particular error later.
-  if (!D.isInvalidType() && (T->isArrayType() || T->isFunctionType()) &&
+  if (!D.isInvalidType() &&
+  ((T->isArrayType() && !S.getLangOpts().HLSL) ||
+   T->isFunctionType()) &&
   (D.getName().getKind() !=
UnqualifiedIdKind::IK_ConversionFunctionId)) {
 unsigned diagID = diag::err_func_returning_array_function;
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl 
b/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl
new file mode 100644
index 0..832c4ac9b10f5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/BasicFeatures/ArrayReturn.hlsl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes 
-emit-llvm -finclude-default-header -o - %s | FileCheck %s
+
+typedef int Foo[2];
+
+// CHECK-LABEL: define void {{.*}}boop{{.*}}(ptr dead_on_unwind noalias 
writable sret([2 x i32]) align 4 %agg.result)
+// CHECK: [[G:%.*]] = alloca [2 x i32], align 4
+// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[G]], ptr align 4 
{{.*}}, i32 8, i1 false)
+// CHECK-NEXT: [[AIB:%.*]] = getelementptr inbounds [2 x i32], ptr 
%agg.result, i32 0, i32 0
+// CHECK-NEXT: br label %arrayinit.body
+// CHECK: arrayinit.body:
+// CHECK-NEXT: [[AII:%.*]] = phi i32 [ 0, %entry ], [ %arrayinit.next, 
%arrayinit.body ]
+// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds i32, ptr [[AIB]], i32 [[AII]]
+// CHECK-NEXT: [[AI:%.*]] = getelementptr inbounds nuw [2 x i32], ptr [[G]], 
i32 0, i32 [[AII]]
+// CHECK-NEXT: [[Y:%.*]] = load i32, ptr [[AI]], align 4
+// CHECK-NEXT: store i32 [[Y]], ptr [[X]], align 4
+// CHECK-NEXT: [[AIN:%.*]] = add nuw i32 [[AII]], 1
+// CHECK-NEXT: [[AID:%.*]] = icmp eq i32 [[AIN]], 2
+// CHECK-NEXT: br i1 [[AID]], label %arrayinit.end, label %arrayinit.body
+// CHECK: arrayinit.end:   
+// CHECK-NEXT: ret void
+export Foo boop() {
+  Foo G = {1,2};
+  return G;
+}
+
+// CHECK-LABEL: define void {{.*}}foo{{.*}}(ptr dead_on_unwind noalias 
writable sret([2 x i32]) align 4 %agg.result)
+// CHECK: store i32 1, ptr %agg.result, align 4
+// CHECK-NEXT: [[E:%.*]] = getelementptr inbounds i32, ptr %agg.result, i32 1
+// CHECK-NEXT: store i32 2, ptr [[E]], align 4
+// CHECK-NEXT: ret void
+export int foo()[2] {
+  return {1,2};
+}

>From 2598db2039c1a8c93f088b928d669228bf6ff0ab Mon Sep 17 00:00:00 2001
From: Sarah Spall 
Date: Sun, 23 Feb 2025 15:06:56 -0800
Subject: [PATCH 2/2] address pr comments

---
 clang/include/clang/AST/ASTContext.h | 4 
 clang/lib/Sema/SemaExpr.cpp  | 5 +++--
 clang/lib/Sema/SemaType.cpp  | 5 +++--
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index d275873651786..d23b08721cfea 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/

[clang] [Clang] Force expressions with UO_Not to not be non-negative (PR #126846)

2025-02-23 Thread Yutong Zhu via cfe-commits

https://github.com/YutongZhuu updated 
https://github.com/llvm/llvm-project/pull/126846

>From d7404029e8998c8c8945cfaa34cf99b743ec2b70 Mon Sep 17 00:00:00 2001
From: Yutong Zhu 
Date: Sun, 23 Feb 2025 18:16:06 -0500
Subject: [PATCH] Fix no warning for comparison of integers of different signs

---
 clang/docs/ReleaseNotes.rst |  3 +++
 clang/lib/Sema/SemaChecking.cpp | 18 ++
 clang/test/Sema/compare.c   |  8 
 3 files changed, 29 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6344c4b36e357..e8de334c93a2e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -135,6 +135,9 @@ Improvements to Clang's diagnostics
 - Fixed a bug where Clang's Analysis did not correctly model the destructor 
behavior of ``union`` members (#GH119415).
 - A statement attribute applied to a ``case`` label no longer suppresses
   'bypassing variable initialization' diagnostics (#84072).
+- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) 
and minus(-) as signed integers 
+  except for the case where the operand is an unsigned integer
+  and throws warning if they are compared with unsigned integers (##18878).
 
 Improvements to Clang's time-trace
 --
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 66c233de4ef30..8dd586f8ab2a8 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -10069,6 +10069,24 @@ static std::optional 
TryGetExprRange(ASTContext &C, const Expr *E,
 case UO_AddrOf: // should be impossible
   return IntRange::forValueOfType(C, GetExprType(E));
 
+case UO_Minus:
+case UO_Not: {
+  if (E->getType()->isUnsignedIntegerType()) {
+return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, 
InConstantContext,
+   Approximate);
+  }
+
+  std::optional SubRange = TryGetExprRange(
+  C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
+
+  if (!SubRange)
+return std::nullopt;
+
+  // The width increments by 1 if the sub-expression cannot be negative
+  // since it now can be.
+  return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);
+}
+
 default:
   return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
  Approximate);
diff --git a/clang/test/Sema/compare.c b/clang/test/Sema/compare.c
index 17cf0351ef4f5..950793631c38c 100644
--- a/clang/test/Sema/compare.c
+++ b/clang/test/Sema/compare.c
@@ -419,3 +419,11 @@ void pr36008(enum PR36008EnumTest lhs) {
   if (x == y) x = y; // no warning
   if (y == x) y = x; // no warning
 }
+
+int test13(unsigned a, int b) {
+return a > ~(95 != b); // expected-warning {{comparison of integers of 
different signs}}
+}
+
+int test14(unsigned a, int b) {
+return a > -(95 != b); // expected-warning {{comparison of integers of 
different signs}}
+}

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


[clang] [Clang] Force expressions with UO_Not to not be non-negative (PR #126846)

2025-02-23 Thread Yutong Zhu via cfe-commits


@@ -10069,6 +10069,17 @@ static std::optional 
TryGetExprRange(ASTContext &C, const Expr *E,
 case UO_AddrOf: // should be impossible
   return IntRange::forValueOfType(C, GetExprType(E));
 
+case UO_Not: {
+  std::optional SubRange = TryGetExprRange(
+  C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
+  if (!SubRange)
+return std::nullopt;
+
+  // The width increments by 1 if the sub-expression cannot be negative
+  // since it now can be.
+  return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);

YutongZhuu wrote:

Fixed as suggested. Thanks for the help!

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -625,6 +625,43 @@ static Attr *handleHLSLControlFlowHint(Sema &S, Stmt *St, 
const ParsedAttr &A,
   return ::new (S.Context) HLSLControlFlowHintAttr(S.Context, A);
 }
 
+static Attr *handleAtomicAttr(Sema &S, Stmt *St, const ParsedAttr &A,
+  SourceRange Range) {
+  if (!isa(St)) {
+S.Diag(St->getBeginLoc(), diag::err_attribute_wrong_decl_type)
+<< A << "compound statement";
+return nullptr;
+  }
+
+  llvm::SmallVector OptionStrings;
+  AtomicOptionsOverride AOO;
+
+  for (unsigned i = 0; i < A.getNumArgs(); ++i) {
+IdentifierLoc *Arg = A.getArgAsIdent(i);
+if (!Arg || !Arg->Ident) {
+  S.Diag(A.getLoc(), diag::err_attribute_argument_type)
+  << A << AANT_ArgumentIdentifier;
+  continue;
+}
+llvm::StringRef Option = Arg->Ident->getName();
+bool value = false;
+auto KindOpt = AtomicOptionsOverride::parseAtomicOverrideKey(Option, 
value);
+if (KindOpt) {
+  AOO.setAtomicOverride(*KindOpt, value);
+  OptionStrings.push_back(Option);
+} else {
+  S.Diag(Arg->Loc, diag::err_attribute_invalid_atomic_argument)
+  << Option << A;
+  return nullptr;
+}
+  }
+
+  auto *AA = ::new (S.Context)
+  AtomicAttr(S.Context, A, OptionStrings.data(), OptionStrings.size());
+  AA->setAtomicOptionsOverride(AOO);

yxsamliu wrote:

Yes we no longer needs AtomicOptionsOverride since we could use AtomicAttr to 
override AtomicOptions during clang codegen. Will remove AtomicOptionsOverride 

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -1101,6 +1107,187 @@ inline void FPOptions::applyChanges(FPOptionsOverride 
FPO) {
   *this = FPO.applyOverrides(*this);
 }
 
+// The three atomic code-generation options.
+// The canonical (positive) names are:
+//   "remote_memory", "fine_grained_memory", and "ignore_denormal_mode".
+// In attribute or command-line parsing, a token prefixed with "no_" inverts 
its
+// value.
+enum class AtomicOptionKind {
+  RemoteMemory,   // true means remote memory is enabled.
+  FineGrainedMemory,  // true means fine-grained memory is enabled.
+  IgnoreDenormalMode, // true means ignore floating-point denormals.
+  LANGOPT_ATOMIC_OPTION_LAST
+};
+
+struct AtomicOptions {
+  // Bitfields for each option.
+  unsigned remote_memory : 1;
+  unsigned fine_grained_memory : 1;
+  unsigned ignore_denormal_mode : 1;
+
+  AtomicOptions()
+  : remote_memory(0), fine_grained_memory(0), ignore_denormal_mode(0) {}
+
+  bool getOption(AtomicOptionKind Kind) const {
+switch (Kind) {
+case AtomicOptionKind::RemoteMemory:
+  return remote_memory;
+case AtomicOptionKind::FineGrainedMemory:
+  return fine_grained_memory;
+case AtomicOptionKind::IgnoreDenormalMode:
+  return ignore_denormal_mode;
+default:
+  llvm_unreachable("Invalid AtomicOptionKind");
+}
+  }
+
+  void setOption(AtomicOptionKind Kind, bool Value) {
+switch (Kind) {
+case AtomicOptionKind::RemoteMemory:
+  remote_memory = Value;
+  break;
+case AtomicOptionKind::FineGrainedMemory:
+  fine_grained_memory = Value;
+  break;
+case AtomicOptionKind::IgnoreDenormalMode:
+  ignore_denormal_mode = Value;
+  break;
+default:
+  llvm_unreachable("Invalid AtomicOptionKind");
+}
+  }
+
+  LLVM_DUMP_METHOD void dump() const {
+llvm::errs() << "\n remote_memory: " << remote_memory
+ << "\n fine_grained_memory: " << fine_grained_memory
+ << "\n ignore_denormal_mode: " << ignore_denormal_mode << 
"\n";
+  }
+
+  // The canonical names for each option.
+  static constexpr const char *OptionNames[] = {
+  "remote_memory",   // canonical name for RemoteMemory option.
+  "fine_grained_memory", // canonical name for FineGrainedMemory option.
+  "ignore_denormal_mode" // canonical name for IgnoreDenormalMode option.
+  };
+};
+
+/// Represents overrides for atomic options.
+class AtomicOptionsOverride {
+  AtomicOptions Options;
+  // Bitmask for active overrides.
+  unsigned OverrideMask;

yxsamliu wrote:

will remove AtomicOptionsOverride and use AtomicAttr to override AtomicOptions

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -4979,3 +4979,16 @@ def NoTrivialAutoVarInit: InheritableAttr {
   let Documentation = [NoTrivialAutoVarInitDocs];
   let SimpleHandler = 1;
 }
+
+def Atomic : StmtAttr {
+  let Spellings = [Clang<"atomic">];
+  let Args = [VariadicStringArgument<"Options">];

yxsamliu wrote:

will use VariadicEnumArgument

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


[clang] [clang modules] Setting `DebugCompilationDir` when it is safe to ignore current working directory (PR #128446)

2025-02-23 Thread Qiongsi Wu via cfe-commits

https://github.com/qiongsiwu created 
https://github.com/llvm/llvm-project/pull/128446

This PR explicitly sets `DebugCompilationDir` to the system's root directory if 
it is safe to ignore the current working directory. 

This fixes a problem where a PCM file's embedded debug information can lead to 
compilation failure. The compiler may have decided it is indeed safe to ignore 
the current working directory. In this case, the PCM file's content is 
functionally correct regardless of the current working directory because no 
inputs use relative paths (see 
https://github.com/llvm/llvm-project/pull/124786). However, a PCM may contain 
debug info. If debug info is requested, the compiler uses the current working 
directory value to set `DW_AT_comp_dir`.  This may lead to the following 
situation: 
1. Two different compilations need the same PCM file. 
2. The PCM file is compiled assuming a working directory, which is embedded in 
the debug info, but otherwise has no effect. 
3. The second compilation assumes a different working directory, hence expects 
an identically-sized pcm file. However, it cannot find such a PCM, because the 
existing PCM file has been compiled assuming a different `DW_AT_comp_dir `, 
which is embedded in the debug info. 

This PR resets the  `DebugCompilationDir` if it is functionally safe to ignore 
the working directory so the above situation is avoided, since all debug 
information will share the same working directory.

>From c8eda8b9192cf4bdad4121063336beeb14cbe689 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu 
Date: Sun, 23 Feb 2025 16:47:18 -0800
Subject: [PATCH] Initial commit

---
 .../DependencyScanning/ModuleDepCollector.cpp | 17 +-
 clang/test/ClangScanDeps/modules-debug-dir.c  | 22 +++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/ClangScanDeps/modules-debug-dir.c

diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp 
b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 1c5f4c4b50ab6..8a94535d3806c 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -492,8 +492,23 @@ static std::string getModuleContextHash(const ModuleDeps 
&MD,
   auto &FSOpts = const_cast(CI.getFileSystemOpts());
   if (CWD && !IgnoreCWD)
 HashBuilder.add(*CWD);
-  else
+  else {
 FSOpts.WorkingDir.clear();
+auto &CGOpts = const_cast(CI.getCodeGenOpts());
+if (CGOpts.DwarfVersion && CWD) {
+  // It is necessary to explicitly set the DebugCompilationDir
+  // to a common directory (e.g. root) if IgnoreCWD is true.
+  // When IgnoreCWD is true, the module's content should not depend
+  // on the current working directory. However, if dwarf information
+  // is needed (when CGOpts.DwarfVersion is non-zero), and if
+  // CGOpts.DebugCompilationDir is not explicitly set,
+  // the current working directory will be automatically embedded
+  // in the dwarf information in the pcm, contradicting the assumption
+  // that it is safe to ignore the CWD. Thus in such cases,
+  // CGOpts.DebugCompilationDir is explicitly set to a common directory.
+  CGOpts.DebugCompilationDir = llvm::sys::path::root_path(*CWD);
+}
+  }
 
   // Hash the BuildInvocation without any input files.
   SmallString<0> ArgVec;
diff --git a/clang/test/ClangScanDeps/modules-debug-dir.c 
b/clang/test/ClangScanDeps/modules-debug-dir.c
new file mode 100644
index 0..580f72205e68f
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-debug-dir.c
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -format \
+// RUN:   experimental-full > %t/result.json
+
+//--- cdb.json.in
+[{
+  "directory": "DIR",
+  "command": "clang -g -fdebug-info-for-profiling DIR/tu.c -fmodules 
-fmodules-cache-path=DIR/cache -IDIR/include/ -o DIR/tu.o",
+  "file": "DIR/tu.c"
+}]
+
+//--- include/module.modulemap
+module mod {
+  header "mod.h"
+}
+
+//--- include/mod.h
+
+//--- tu.c
+#include "mod.h"

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


[clang] [clang modules] Setting `DebugCompilationDir` when it is safe to ignore current working directory (PR #128446)

2025-02-23 Thread Qiongsi Wu via cfe-commits

qiongsiwu wrote:

Note to reviewers: 
This fixes rdar://145249881, but I'd like to get some input on two things. 

1. I am not sure if it is a good idea to always set `DebugCompilationDir` to 
root. I chose it because I think it is safe and all systems should have the 
root directory. I am all ears for a different choice. 
2. I have not figured out a good way to test this. For some reason, I cannot 
get the module compilation command to produce debug information in the test 
(through `-g`, or `-dwarf-version` options). I don't think we _always_ want to 
hardcode `DebugCompilationDir` to `root`, so I think we want to set it only if 
dwarf info is needed. May I get some pointers to get the compiler to generate 
debug info when compiling the pcm? 

Thanks! 

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -625,6 +625,43 @@ static Attr *handleHLSLControlFlowHint(Sema &S, Stmt *St, 
const ParsedAttr &A,
   return ::new (S.Context) HLSLControlFlowHintAttr(S.Context, A);
 }
 
+static Attr *handleAtomicAttr(Sema &S, Stmt *St, const ParsedAttr &A,
+  SourceRange Range) {
+  if (!isa(St)) {

yxsamliu wrote:

Yes we still need this. The infrastructure from Attr.td parses the attribute 
and creates ParsedAttr. The AtomicAttr in AST still needs to be created in Sema 
by this handler. However, we could avoid the specific parsing function for 
AtomicAttr in ParseDecl.cpp

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -111,8 +111,13 @@ class SValExplainer : public 
FullSValVisitor {
   }
 
   std::string VisitSymbolConjured(const SymbolConjured *S) {
-return "symbol of type '" + S->getType().getAsString() +
-   "' conjured at statement '" + printStmt(S->getStmt()) + "'";
+std::string Str;
+llvm::raw_string_ostream OS(Str);
+OS << "symbol of type '" + S->getType().getAsString() +
+  "' conjured at statement '";
+S->getCFGElementRef()->dumpToStream(OS);

isuckatcs wrote:

Yes, but you can extract the "dumping to an ostream" logic into a separate 
function and tweak it there however you want. This is what I ment by similar to 
`printStmt()`.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -113,8 +113,18 @@ class SValExplainer : public 
FullSValVisitor {
   }
 
   std::string VisitSymbolConjured(const SymbolConjured *S) {
-return "symbol of type '" + S->getType().getAsString() +
-   "' conjured at statement '" + printStmt(S->getStmt()) + "'";
+std::string Str;
+llvm::raw_string_ostream OS(Str);
+OS << "symbol of type '" + S->getType().getAsString() +
+  "' conjured at statement '";
+S->getCFGElementRef()->dumpToStream(OS);
+// HACK: dumpToStream will output a new line in the end, this is
+// undesireable, thus we remove it.
+if (Str.back() == '\n') {

isuckatcs wrote:

What if we are on windows and the line ending is `\r\n`?

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -467,7 +467,7 @@ void IteratorModeling::handleComparison(CheckerContext &C, 
const Expr *CE,
   SymbolRef Sym;
   if (!LPos || !RPos) {
 auto &SymMgr = C.getSymbolManager();
-Sym = SymMgr.conjureSymbol(CE, C.getLocationContext(),

isuckatcs wrote:

`CE` is unused parameter.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -2261,7 +2265,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, 
const CallEvent &Call,
 // If this is a stpcpy-style copy, but we were unable to check for a buffer
 // overflow, we still need a result. Conjure a return value.
 if (ReturnEnd && Result.isUnknown()) {
-  Result = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(), 
LCtx,
+  Result = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
+C.getCFGElementRef(), LCtx,

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -130,8 +130,9 @@ void 
ErrnoTesterChecker::evalSetErrnoIfErrorRange(CheckerContext &C,
 
   ProgramStateRef StateFailure = State->BindExpr(
   Call.getOriginExpr(), C.getLocationContext(), SVB.makeIntVal(1, true));
-  DefinedOrUnknownSVal ErrnoVal = SVB.conjureSymbolVal(
-  nullptr, Call.getOriginExpr(), C.getLocationContext(), C.blockCount());
+  DefinedOrUnknownSVal ErrnoVal =
+  SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), C.getCFGElementRef(),

isuckatcs wrote:

Same as multiple previous question about the call.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -171,19 +172,11 @@ class SValBuilder {
 
   // Forwarding methods to SymbolManager.
 
-  const SymbolConjured* conjureSymbol(const Stmt *stmt,
-  const LocationContext *LCtx,
-  QualType type,
-  unsigned visitCount,
-  const void *symbolTag = nullptr) {
-return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
-  }
-
-  const SymbolConjured* conjureSymbol(const Expr *expr,
-  const LocationContext *LCtx,
-  unsigned visitCount,
-  const void *symbolTag = nullptr) {
-return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
+  const SymbolConjured *
+  conjureSymbol(const CFGBlock::ConstCFGElementRef ElemRef,

isuckatcs wrote:

Here we had an overload without a `QualType`, don't we need it?

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -1665,8 +1666,9 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const 
CallEvent &Call,
 State = CheckBufferAccess(C, State, Left, Size, AccessKind::read, CK);
 if (State) {
   // The return value is the comparison result, which we don't know.
-  SVal CmpV = Builder.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
-   C.blockCount());
+  SVal CmpV =
+  Builder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
+   C.getCFGElementRef(), LCtx, C.blockCount());

isuckatcs wrote:

Same here

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -695,6 +695,18 @@ class CFGBlock {
 void dump() const {
   dumpToStream(llvm::errs());
 }
+
+void Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddPointer(Parent);
+  ID.AddInteger(Index);
+}
+
+int64_t getID() const {
+  return Parent->getParent()
+  ->getAllocator()
+  .template identifyKnownAlignedObject(
+  &*(Parent->begin() + Index));

isuckatcs wrote:

I think both `Parent` and `Parent->getParent()` can be a `nullptr`.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -229,7 +230,7 @@ DefinedSVal makeRetVal(CheckerContext &C, const CallExpr 
*CE) {
 
   const LocationContext *LCtx = C.getLocationContext();
   return C.getSValBuilder()
-  .conjureSymbolVal(nullptr, CE, LCtx, C.blockCount())

isuckatcs wrote:

`CE` in unused.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -2469,14 +2475,14 @@ void CStringChecker::evalStrsep(CheckerContext &C,
 // further along in the same string, or NULL if there are no more tokens.
 State =
 State->bindLoc(*SearchStrLoc,
-   SVB.conjureSymbolVal(getTag(), Call.getOriginExpr(),
+   SVB.conjureSymbolVal(getTag(), C.getCFGElementRef(),

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -260,7 +260,7 @@ ProgramStateRef setErrnoStdMustBeChecked(ProgramStateRef 
State,
   const MemRegion *ErrnoR = State->get();
   if (!ErrnoR)
 return State;
-  State = State->invalidateRegions(ErrnoR, InvalE, C.blockCount(),

isuckatcs wrote:

`InvalE` is an unused parameter, the element reference should point to that I 
think.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -2520,7 +2526,8 @@ void CStringChecker::evalStdCopyCommon(CheckerContext &C,
   SValBuilder &SVB = C.getSValBuilder();
 
   SVal ResultVal =
-  SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx, 
C.blockCount());
+  SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), C.getCFGElementRef(),

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -326,7 +330,7 @@ void ContainerModeling::handleAssignment(CheckerContext &C, 
SVal Cont,
   auto &SVB = C.getSValBuilder();
   // Then generate and assign a new "end" symbol for the new container.
   auto NewEndSym =
-  SymMgr.conjureSymbol(CE, C.getLocationContext(),

isuckatcs wrote:

This makes `CE` an unused parameter.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -80,17 +81,18 @@ class SymbolRegionValue : public SymbolData {
 /// A symbol representing the result of an expression in the case when we do
 /// not know anything about what the expression is.
 class SymbolConjured : public SymbolData {
-  const Stmt *S;
+  const CFGBlock::ConstCFGElementRef ElemRef;
   QualType T;
   unsigned Count;
   const LocationContext *LCtx;
   const void *SymbolTag;
 
   friend class SymExprAllocator;
-  SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
- QualType t, unsigned count, const void *symbolTag)
-  : SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count),
-LCtx(lctx), SymbolTag(symbolTag) {
+  SymbolConjured(SymbolID sym, CFGBlock::ConstCFGElementRef elemRef,
+ const LocationContext *lctx, QualType t, unsigned count,
+ const void *symbolTag)
+  : SymbolData(SymbolConjuredKind, sym), ElemRef(elemRef), T(t),
+Count(count), LCtx(lctx), SymbolTag(symbolTag) {
 // FIXME: 's' might be a nullptr if we're conducting invalidation

isuckatcs wrote:

This FIXME is no longer valid, because a `ConstCFGElementRef` is never a 
`nullptr`, IIUC.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -494,7 +494,7 @@ void IteratorModeling::handleComparison(CheckerContext &C, 
const Expr *CE,
 auto &SymMgr = C.getSymbolManager();
 auto *LCtx = C.getLocationContext();
 RetVal = nonloc::SymbolVal(SymMgr.conjureSymbol(
-CE, LCtx, C.getASTContext().BoolTy, C.blockCount()));

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -113,8 +113,18 @@ class SValExplainer : public 
FullSValVisitor {
   }
 
   std::string VisitSymbolConjured(const SymbolConjured *S) {
-return "symbol of type '" + S->getType().getAsString() +
-   "' conjured at statement '" + printStmt(S->getStmt()) + "'";
+std::string Str;
+llvm::raw_string_ostream OS(Str);
+OS << "symbol of type '" + S->getType().getAsString() +
+  "' conjured at statement '";
+S->getCFGElementRef()->dumpToStream(OS);
+// HACK: dumpToStream will output a new line in the end, this is
+// undesireable, thus we remove it.
+if (Str.back() == '\n') {
+  Str.pop_back();
+}
+OS << "'";

isuckatcs wrote:

```suggestion
OS << '\'';
```

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -1794,7 +1797,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext 
&C,
 // value, so it can be used in constraints, at least.
 if (result.isUnknown()) {
   result = C.getSValBuilder().conjureSymbolVal(
-  nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+  nullptr, Call.getOriginExpr(), C.getCFGElementRef(), LCtx,
+  C.blockCount());

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -2469,14 +2475,14 @@ void CStringChecker::evalStrsep(CheckerContext &C,
 // further along in the same string, or NULL if there are no more tokens.
 State =
 State->bindLoc(*SearchStrLoc,
-   SVB.conjureSymbolVal(getTag(), Call.getOriginExpr(),
+   SVB.conjureSymbolVal(getTag(), C.getCFGElementRef(),
 LCtx, CharPtrTy, C.blockCount()),
LCtx);
   } else {
 assert(SearchStrVal.isUnknown());
 // Conjure a symbolic value. It's the best we can do.
-Result = SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(), LCtx,
-  C.blockCount());
+Result = SVB.conjureSymbolVal(nullptr, Call.getOriginExpr(),
+  C.getCFGElementRef(), LCtx, C.blockCount());

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -2361,8 +2366,9 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, 
const CallEvent &Call,
   const StringLiteral *RightStrLiteral =
   getCStringLiteral(C, state, Right.Expression, RightVal);
   bool canComputeResult = false;
-  SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
-LCtx, C.blockCount());
+  SVal resultVal =
+  svalBuilder.conjureSymbolVal(nullptr, Call.getOriginExpr(),
+   C.getCFGElementRef(), LCtx, C.blockCount());

isuckatcs wrote:

.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -151,6 +151,11 @@ class CheckerContext {
 return Pred->getSVal(S);
   }
 
+  /// Get the CFG Element Ref from the ExprEngine

isuckatcs wrote:

I think you can remove this comment. It's obvious what the function does even 
without it.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits

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

I didn't have enough time to check the whole patch, I'll get back to it later.

The general patterns seems to be that when a conjured symbol is created, it's 
always the reference to the current CFG element that is passed as the source 
statement instead of some other statement that was passed in the past. 

I think every place, where we conjure a symbol should be double checked, so 
that we make sure we pass the CFG element reference to the correct statement, 
that actually conjured the value.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -1515,7 +1515,8 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, 
const CallEvent &Call,
   // conjure a return value for later.
   if (lastElement.isUnknown())
 lastElement = C.getSValBuilder().conjureSymbolVal(
-nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+nullptr, Call.getOriginExpr(), C.getCFGElementRef(), LCtx,

isuckatcs wrote:

At this point, isn't it the `Call` that conjured the symbol? Shouldn't we pass 
a `CFGElementRef` to the `Call` instead?

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -533,18 +538,12 @@ class SymbolManager {
   template 
   const SymExprT *acquire(Args &&...args);
 
-  const SymbolConjured *conjureSymbol(const Stmt *E,
-  const LocationContext *LCtx, QualType T,
-  unsigned VisitCount,
-  const void *SymbolTag = nullptr) {
-return acquire(E, LCtx, T, VisitCount, SymbolTag);
-  }
+  const SymbolConjured *
+  conjureSymbol(const CFGBlock::ConstCFGElementRef ElemRef,

isuckatcs wrote:

An overload without a type is missing.

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


[clang] [clang modules] Setting `DebugCompilationDir` when it is safe to ignore current working directory (PR #128446)

2025-02-23 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Qiongsi Wu (qiongsiwu)


Changes

This PR explicitly sets `DebugCompilationDir` to the system's root directory if 
it is safe to ignore the current working directory. 

This fixes a problem where a PCM file's embedded debug information can lead to 
compilation failure. The compiler may have decided it is indeed safe to ignore 
the current working directory. In this case, the PCM file's content is 
functionally correct regardless of the current working directory because no 
inputs use relative paths (see 
https://github.com/llvm/llvm-project/pull/124786). However, a PCM may contain 
debug info. If debug info is requested, the compiler uses the current working 
directory value to set `DW_AT_comp_dir`.  This may lead to the following 
situation: 
1. Two different compilations need the same PCM file. 
2. The PCM file is compiled assuming a working directory, which is embedded in 
the debug info, but otherwise has no effect. 
3. The second compilation assumes a different working directory, hence expects 
an identically-sized pcm file. However, it cannot find such a PCM, because the 
existing PCM file has been compiled assuming a different `DW_AT_comp_dir `, 
which is embedded in the debug info. 

This PR resets the  `DebugCompilationDir` if it is functionally safe to ignore 
the working directory so the above situation is avoided, since all debug 
information will share the same working directory.

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


2 Files Affected:

- (modified) clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp 
(+16-1) 
- (added) clang/test/ClangScanDeps/modules-debug-dir.c (+22) 


``diff
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp 
b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 1c5f4c4b50ab6..8a94535d3806c 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -492,8 +492,23 @@ static std::string getModuleContextHash(const ModuleDeps 
&MD,
   auto &FSOpts = const_cast(CI.getFileSystemOpts());
   if (CWD && !IgnoreCWD)
 HashBuilder.add(*CWD);
-  else
+  else {
 FSOpts.WorkingDir.clear();
+auto &CGOpts = const_cast(CI.getCodeGenOpts());
+if (CGOpts.DwarfVersion && CWD) {
+  // It is necessary to explicitly set the DebugCompilationDir
+  // to a common directory (e.g. root) if IgnoreCWD is true.
+  // When IgnoreCWD is true, the module's content should not depend
+  // on the current working directory. However, if dwarf information
+  // is needed (when CGOpts.DwarfVersion is non-zero), and if
+  // CGOpts.DebugCompilationDir is not explicitly set,
+  // the current working directory will be automatically embedded
+  // in the dwarf information in the pcm, contradicting the assumption
+  // that it is safe to ignore the CWD. Thus in such cases,
+  // CGOpts.DebugCompilationDir is explicitly set to a common directory.
+  CGOpts.DebugCompilationDir = llvm::sys::path::root_path(*CWD);
+}
+  }
 
   // Hash the BuildInvocation without any input files.
   SmallString<0> ArgVec;
diff --git a/clang/test/ClangScanDeps/modules-debug-dir.c 
b/clang/test/ClangScanDeps/modules-debug-dir.c
new file mode 100644
index 0..580f72205e68f
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-debug-dir.c
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -format \
+// RUN:   experimental-full > %t/result.json
+
+//--- cdb.json.in
+[{
+  "directory": "DIR",
+  "command": "clang -g -fdebug-info-for-profiling DIR/tu.c -fmodules 
-fmodules-cache-path=DIR/cache -IDIR/include/ -o DIR/tu.o",
+  "file": "DIR/tu.c"
+}]
+
+//--- include/module.modulemap
+module mod {
+  header "mod.h"
+}
+
+//--- include/mod.h
+
+//--- tu.c
+#include "mod.h"

``




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


[clang] [clang modules] Setting `DebugCompilationDir` when it is safe to ignore current working directory (PR #128446)

2025-02-23 Thread Qiongsi Wu via cfe-commits

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -3101,6 +3101,11 @@ class Parser : public CodeCompletionHandler {
   std::optional ParseAvailabilitySpec();
   ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
 
+  void ParseAtomicAttribute(IdentifierInfo &AttrName,

yxsamliu wrote:

will use VariadicEnumArgument 

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


[clang] Add clang atomic control options and attribute (PR #114841)

2025-02-23 Thread Yaxun Liu via cfe-commits


@@ -1101,6 +1107,187 @@ inline void FPOptions::applyChanges(FPOptionsOverride 
FPO) {
   *this = FPO.applyOverrides(*this);
 }
 
+// The three atomic code-generation options.
+// The canonical (positive) names are:
+//   "remote_memory", "fine_grained_memory", and "ignore_denormal_mode".
+// In attribute or command-line parsing, a token prefixed with "no_" inverts 
its
+// value.
+enum class AtomicOptionKind {
+  RemoteMemory,   // true means remote memory is enabled.
+  FineGrainedMemory,  // true means fine-grained memory is enabled.
+  IgnoreDenormalMode, // true means ignore floating-point denormals.
+  LANGOPT_ATOMIC_OPTION_LAST
+};
+
+struct AtomicOptions {
+  // Bitfields for each option.
+  unsigned remote_memory : 1;
+  unsigned fine_grained_memory : 1;
+  unsigned ignore_denormal_mode : 1;
+
+  AtomicOptions()
+  : remote_memory(0), fine_grained_memory(0), ignore_denormal_mode(0) {}
+
+  bool getOption(AtomicOptionKind Kind) const {
+switch (Kind) {
+case AtomicOptionKind::RemoteMemory:
+  return remote_memory;
+case AtomicOptionKind::FineGrainedMemory:
+  return fine_grained_memory;
+case AtomicOptionKind::IgnoreDenormalMode:
+  return ignore_denormal_mode;
+default:
+  llvm_unreachable("Invalid AtomicOptionKind");
+}
+  }
+
+  void setOption(AtomicOptionKind Kind, bool Value) {
+switch (Kind) {
+case AtomicOptionKind::RemoteMemory:
+  remote_memory = Value;
+  break;
+case AtomicOptionKind::FineGrainedMemory:
+  fine_grained_memory = Value;
+  break;
+case AtomicOptionKind::IgnoreDenormalMode:
+  ignore_denormal_mode = Value;
+  break;
+default:
+  llvm_unreachable("Invalid AtomicOptionKind");
+}
+  }
+
+  LLVM_DUMP_METHOD void dump() const {
+llvm::errs() << "\n remote_memory: " << remote_memory
+ << "\n fine_grained_memory: " << fine_grained_memory
+ << "\n ignore_denormal_mode: " << ignore_denormal_mode << 
"\n";
+  }
+
+  // The canonical names for each option.
+  static constexpr const char *OptionNames[] = {
+  "remote_memory",   // canonical name for RemoteMemory option.
+  "fine_grained_memory", // canonical name for FineGrainedMemory option.
+  "ignore_denormal_mode" // canonical name for IgnoreDenormalMode option.
+  };
+};
+
+/// Represents overrides for atomic options.
+class AtomicOptionsOverride {
+  AtomicOptions Options;
+  // Bitmask for active overrides.
+  unsigned OverrideMask;
+
+  static constexpr unsigned getMask(AtomicOptionKind Kind) {
+return 1u << static_cast(Kind);
+  }
+
+public:
+  template  static void forEachOption(Func &&func) {
+for (unsigned I = 0; I < static_cast(
+ AtomicOptionKind::LANGOPT_ATOMIC_OPTION_LAST);
+ ++I)
+  func(static_cast(I));
+  }
+
+  static constexpr unsigned DefaultMask =
+  (1u << static_cast(
+   AtomicOptionKind::LANGOPT_ATOMIC_OPTION_LAST)) -
+  1;
+
+  AtomicOptionsOverride() : Options(), OverrideMask(0) {}
+  AtomicOptionsOverride(AtomicOptions AO)
+  : Options(AO), OverrideMask(DefaultMask) {}
+  AtomicOptionsOverride(AtomicOptions AO, unsigned Mask)
+  : Options(AO), OverrideMask(Mask) {}
+  AtomicOptionsOverride(const LangOptions &LO) : Options(), OverrideMask(0) {
+setAtomicOverride(AtomicOptionKind::RemoteMemory, LO.AtomicRemoteMemory);
+setAtomicOverride(AtomicOptionKind::FineGrainedMemory,
+  LO.AtomicFineGrainedMemory);
+setAtomicOverride(AtomicOptionKind::IgnoreDenormalMode,
+  LO.AtomicIgnoreDenormalMode);
+  }
+  // Parses a token (e.g. "fine_grained_memory" or "no_fine_grained_memory").
+  // If the token begins with "no_", the prefix is stripped and the resulting
+  // string is compared against the canonical name. If it matches, Value is set
+  // to false. Otherwise, if the token exactly matches the canonical name, 
Value
+  // is true.
+  static std::optional
+  parseAtomicOverrideKey(llvm::StringRef Key, bool &Value) {

yxsamliu wrote:

You mean VariadicEnumArgument? Yes using that can avoid the parsing function. 
will do

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -198,32 +191,24 @@ class SValBuilder {
   /// The advantage of symbols derived/built from other symbols is that we
   /// preserve the relation between related(or even equivalent) expressions, so
   /// conjured symbols should be used sparingly.
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
-const Expr *expr,
-const LocationContext *LCtx,
-unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Stmt *S,
-const LocationContext *LCtx,
-QualType type, unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
-const LocationContext *LCtx,
-QualType type,
-unsigned visitCount);
+  DefinedOrUnknownSVal
+  conjureSymbolVal(const void *symbolTag, const Expr *expr,
+   const CFGBlock::ConstCFGElementRef elemRef,

isuckatcs wrote:

Why do we need both a `const Expr *` and a `const 
CFGBlock::ConstCFGElementRef`? I'd imagine, the `ConstCFGElementRef` points to 
the `Expr`.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -171,19 +172,11 @@ class SValBuilder {
 
   // Forwarding methods to SymbolManager.
 
-  const SymbolConjured* conjureSymbol(const Stmt *stmt,
-  const LocationContext *LCtx,
-  QualType type,
-  unsigned visitCount,
-  const void *symbolTag = nullptr) {
-return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
-  }
-
-  const SymbolConjured* conjureSymbol(const Expr *expr,
-  const LocationContext *LCtx,
-  unsigned visitCount,
-  const void *symbolTag = nullptr) {
-return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
+  const SymbolConjured *
+  conjureSymbol(const CFGBlock::ConstCFGElementRef ElemRef,

fangyi-zhou wrote:

The type needs to come from the expression, which we don't pass in as an 
argument any more.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread via cfe-commits


@@ -1770,7 +1772,8 @@ void CStringChecker::evalstrLengthCommon(CheckerContext 
&C,
   // All we know is the return value is the min of the string length
   // and the limit. This is better than nothing.
   result = C.getSValBuilder().conjureSymbolVal(
-  nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+  nullptr, Call.getOriginExpr(), C.getCFGElementRef(), LCtx,
+  C.blockCount());

isuckatcs wrote:

And here.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -198,32 +191,24 @@ class SValBuilder {
   /// The advantage of symbols derived/built from other symbols is that we
   /// preserve the relation between related(or even equivalent) expressions, so
   /// conjured symbols should be used sparingly.
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
-const Expr *expr,
-const LocationContext *LCtx,
-unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Stmt *S,
-const LocationContext *LCtx,
-QualType type, unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
-const LocationContext *LCtx,
-QualType type,
-unsigned visitCount);
+  DefinedOrUnknownSVal
+  conjureSymbolVal(const void *symbolTag, const Expr *expr,
+   const CFGBlock::ConstCFGElementRef elemRef,
+   const LocationContext *LCtx, unsigned count);
+  DefinedOrUnknownSVal
+  conjureSymbolVal(const void *symbolTag,
+   const CFGBlock::ConstCFGElementRef elemRef,
+   const LocationContext *LCtx, QualType type, unsigned count);
+  DefinedOrUnknownSVal
+  conjureSymbolVal(const CFGBlock::ConstCFGElementRef elemRef,
+   const LocationContext *LCtx, QualType type,
+   unsigned visitCount);
 
   /// Conjure a symbol representing heap allocated memory region.
-  ///
-  /// Note, the expression should represent a location.
-  DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
-   const LocationContext *LCtx,
-   unsigned Count);
-
-  /// Conjure a symbol representing heap allocated memory region.
-  ///
-  /// Note, now, the expression *doesn't* need to represent a location.
-  /// But the type need to!
-  DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
-   const LocationContext *LCtx,
-   QualType type, unsigned Count);
+  DefinedSVal
+  getConjuredHeapSymbolVal(const CFGBlock::ConstCFGElementRef elemRef,

fangyi-zhou wrote:

Same as above.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -533,18 +538,12 @@ class SymbolManager {
   template 
   const SymExprT *acquire(Args &&...args);
 
-  const SymbolConjured *conjureSymbol(const Stmt *E,
-  const LocationContext *LCtx, QualType T,
-  unsigned VisitCount,
-  const void *SymbolTag = nullptr) {
-return acquire(E, LCtx, T, VisitCount, SymbolTag);
-  }
+  const SymbolConjured *
+  conjureSymbol(const CFGBlock::ConstCFGElementRef ElemRef,

fangyi-zhou wrote:

Same as above.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -1515,7 +1515,8 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, 
const CallEvent &Call,
   // conjure a return value for later.
   if (lastElement.isUnknown())
 lastElement = C.getSValBuilder().conjureSymbolVal(
-nullptr, Call.getOriginExpr(), LCtx, C.blockCount());
+nullptr, Call.getOriginExpr(), C.getCFGElementRef(), LCtx,

fangyi-zhou wrote:

I don't know what's the correct one to pass and don't have a way to check 
reliably since I don't understand the static analysis code. I don't understand 
your intention in this comment, do you mean I should pass the CFGElementRef to 
the Call or not?

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -198,32 +191,24 @@ class SValBuilder {
   /// The advantage of symbols derived/built from other symbols is that we
   /// preserve the relation between related(or even equivalent) expressions, so
   /// conjured symbols should be used sparingly.
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
-const Expr *expr,
-const LocationContext *LCtx,
-unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Stmt *S,
-const LocationContext *LCtx,
-QualType type, unsigned count);
-  DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
-const LocationContext *LCtx,
-QualType type,
-unsigned visitCount);
+  DefinedOrUnknownSVal
+  conjureSymbolVal(const void *symbolTag, const Expr *expr,
+   const CFGBlock::ConstCFGElementRef elemRef,

fangyi-zhou wrote:

If you look at the implementation code, there's some special treatment wrt the 
type of the expression

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -1376,8 +1379,8 @@ StoreRef RegionStoreManager::invalidateRegions(
   }
 
   RegionBindingsRef B = getRegionBindings(store);
-  InvalidateRegionsWorker W(*this, StateMgr, B, S, Count, LCtx, IS, ITraits,
-Invalidated, GlobalsFilter);
+  InvalidateRegionsWorker W(*this, StateMgr, B, Call->getCFGElementRef(), 
Count,

fangyi-zhou wrote:

Are you referring to this instance that I should pass the refernece to the 
statement instead of the call? I think I misunderstood this comment so I 
changed the references to not use the one from the call in all places.

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


[clang] [Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured (PR #128251)

2025-02-23 Thread Fangyi Zhou via cfe-commits


@@ -151,10 +151,10 @@ SValBuilder::getRegionValueSymbolVal(const 
TypedValueRegion *region) {
   return nonloc::SymbolVal(sym);
 }
 
-DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,

fangyi-zhou wrote:

This overload would have been removed, but its behaviour is not entirely the 
same as obtaining the type from the expression directly. (See the check for 
`isGLValue`). Without complicating the refactor in this PR I decided to leave 
it as is, and add a new parameter for the CFG Element Ref

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


[clang] [clang] Improve module out of date error message (PR #128103)

2025-02-23 Thread Chuanqi Xu via cfe-commits

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


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


[clang] [ubsan] Remove -fsanitizer=vptr from -fsanitizer=undefined (PR #121115)

2025-02-23 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka updated 
https://github.com/llvm/llvm-project/pull/121115

>From bca319184733b4bad1eb6b83aaac18a75be40b8c Mon Sep 17 00:00:00 2001
From: Vitaly Buka 
Date: Wed, 25 Dec 2024 14:22:10 -0800
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
 =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4

[skip ci]
---
 clang/test/Driver/sanitizer-ld.c | 303 ++-
 1 file changed, 174 insertions(+), 129 deletions(-)

diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index 8f2f7a5997ab4..0c36da1773c9f 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -1,14 +1,17 @@
 // Test sanitizers ld flags.
 
+// RUN: export FILECHECK_OPTS="--implicit-check-not=\"/libclang_rt\""
+
 // RUN: %clang -### %s 2>&1 \
 // RUN: --target=i386-unknown-linux -fuse-ld=ld -fsanitize=address \
 // RUN: -resource-dir=%S/Inputs/resource_dir \
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX %s
 //
-// CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld"
 // CHECK-ASAN-LINUX-NOT: "-lc"
-// CHECK-ASAN-LINUX: libclang_rt.asan.a"
+// CHECK-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan_static.a" 
"--no-whole-archive"
+// CHECK-ASAN-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan.a" 
"--no-whole-archive"
 // CHECK-ASAN-LINUX-NOT: "--export-dynamic"
 // CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms"
 // CHECK-ASAN-LINUX-NOT: "--export-dynamic"
@@ -23,17 +26,16 @@
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-LINUX %s
 //
-// CHECK-ASAN-NO-LINK-RUNTIME-LINUX-NOT: libclang_rt.asan_static-x86_64
-// CHECK-ASAN-NO-LINK-RUNTIME-LINUX-NOT: libclang_rt.asan-x86_64
+// CHECK-ASAN-NO-LINK-RUNTIME-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld"
 
-// RUN: %clang -fsanitize=address -fno-sanitize-link-runtime -### %s 2>&1 \
+// RUN: %clang -fsanitize=address -fsanitize-link-runtime -### %s 2>&1 \
 // RUN: --target=arm64e-apple-macosx -fuse-ld=ld \
 // RUN: -resource-dir=%S/Inputs/resource_dir \
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-NO-LINK-RUNTIME-DARWIN %s
 //
-// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN-NOT: libclang_rt.asan_static
-// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN-NOT: libclang_rt.asan
+// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN: /libclang_rt.asan_osx_dynamic.dylib
+// CHECK-ASAN-NO-LINK-RUNTIME-DARWIN: /libclang_rt.osx.a
 
 // RUN: %clang -fsanitize=address -### %s 2>&1 \
 // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
@@ -41,8 +43,9 @@
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-EXECUTABLE-LINUX %s
 //
-// CHECK-ASAN-EXECUTABLE-LINUX: libclang_rt.asan_static
-// CHECK-ASAN-EXECUTABLE-LINUX: libclang_rt.asan
+// CHECK-ASAN-EXECUTABLE-LINUX: "--whole-archive" 
"{{.*}}libclang_rt.asan_static.a" "--no-whole-archive"
+// CHECK-ASAN-EXECUTABLE-LINUX: "--whole-archive" "{{.*}}libclang_rt.asan.a" 
"--no-whole-archive"
+// CHECK-ASAN-EXECUTABLE-LINUX: "--dynamic-list={{.*}}libclang_rt.asan.a.syms"
 
 // RUN: %clang -fsanitize=address -shared -### %s 2>&1  \
 // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
@@ -51,7 +54,6 @@
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-SHARED-LINUX %s
 //
 // CHECK-ASAN-SHARED-LINUX: libclang_rt.asan_static
-// CHECK-ASAN-SHARED-LINUX-NOT: libclang_rt.asan
 
 // RUN: %clang -### %s 2>&1 \
 // RUN: --target=i386-unknown-linux -fuse-ld=ld -fsanitize=address 
-shared-libsan \
@@ -72,11 +74,11 @@
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
 //
-// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld"
 // CHECK-SHARED-ASAN-LINUX-NOT: "-lc"
-// CHECK-SHARED-ASAN-LINUX-NOT: libclang_rt.asan.a"
 // CHECK-SHARED-ASAN-LINUX: libclang_rt.asan.so"
 // CHECK-SHARED-ASAN-LINUX: "--whole-archive" 
"{{.*}}libclang_rt.asan-preinit.a" "--no-whole-archive"
+// CHECK-SHARED-ASAN-LINUX: "--whole-archive" 
"{{.*}}libclang_rt.asan_static.a" "--no-whole-archive"
 // CHECK-SHARED-ASAN-LINUX-NOT: "-lpthread"
 // CHECK-SHARED-ASAN-LINUX-NOT: "-lrt"
 // CHECK-SHARED-ASAN-LINUX-NOT: "-ldl"
@@ -90,11 +92,10 @@
 // RUN: --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
 //
-// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld"
 // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lc"
-// CHECK-DSO-SHARED-ASAN-LINUX-NOT: libclang_rt.asan.a"
-// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "libclang_rt

[clang] [ubsan] Remove -fsanitizer=vptr from -fsanitizer=undefined (PR #121115)

2025-02-23 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

@AaronBallman @zygoloid
Looks like we agree on 
https://discourse.llvm.org/t/rfc-remove-vptr-from-undefined/83830
So I'd  like to merge this patch this week.

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


  1   2   >