[clang] 1542601 - [clang][Interp] Handle non-complex operands in complex bin ops

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T09:08:50+01:00
New Revision: 15426017bda54fb8d9a62cb887edae754e8b7733

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

LOG: [clang][Interp] Handle non-complex operands in complex bin ops

Either LHS or RHS might be non-complex, but not both.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index eb5a1b536b7798..49ba8e95f17995 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -660,19 +660,16 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
   return false;
   }
 
+  // Both LHS and RHS might _not_ be of complex type, but one of them
+  // needs to be.
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
-  PrimType LHSElemT = this->classifyComplexElementType(LHS->getType());
-  PrimType RHSElemT = this->classifyComplexElementType(RHS->getType());
 
-  unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
-  unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
+  PrimType ResultElemT = this->classifyComplexElementType(E->getType());
   unsigned ResultOffset = ~0u;
-  if (!this->DiscardResult)
+  if (!DiscardResult)
 ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
 
-  assert(LHSElemT == RHSElemT);
-
   // Save result pointer in ResultOffset
   if (!this->DiscardResult) {
 if (!this->emitDupPtr(E))
@@ -682,16 +679,64 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
   }
 
   // Evaluate LHS and save value to LHSOffset.
-  if (!this->visit(LHS))
-return false;
-  if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
-return false;
+  bool LHSIsComplex;
+  unsigned LHSOffset;
+  if (LHS->getType()->isAnyComplexType()) {
+LHSIsComplex = true;
+LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
+if (!this->visit(LHS))
+  return false;
+if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
+  return false;
+  } else {
+LHSIsComplex = false;
+PrimType LHST = classifyPrim(LHS->getType());
+LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
+if (!this->visit(LHS))
+  return false;
+if (!this->emitSetLocal(LHST, LHSOffset, E))
+  return false;
+  }
 
   // Same with RHS.
-  if (!this->visit(RHS))
-return false;
-  if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
-return false;
+  bool RHSIsComplex;
+  unsigned RHSOffset;
+  if (RHS->getType()->isAnyComplexType()) {
+RHSIsComplex = true;
+RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
+if (!this->visit(RHS))
+  return false;
+if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
+  return false;
+  } else {
+RHSIsComplex = false;
+PrimType RHST = classifyPrim(RHS->getType());
+RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
+if (!this->visit(RHS))
+  return false;
+if (!this->emitSetLocal(RHST, RHSOffset, E))
+  return false;
+  }
+
+  // For both LHS and RHS, either load the value from the complex pointer, or
+  // directly from the local variable. For index 1 (i.e. the imaginary part),
+  // just load 0 and do the operation anyway.
+  auto loadComplexValue = [this](bool IsComplex, unsigned ElemIndex,
+ unsigned Offset, const Expr *E) -> bool {
+if (IsComplex) {
+  if (!this->emitGetLocal(PT_Ptr, Offset, E))
+return false;
+  if (!this->emitConstUint8(ElemIndex, E))
+return false;
+  if (!this->emitArrayElemPtrPopUint8(E))
+return false;
+  return this->emitLoadPop(classifyComplexElementType(E->getType()), E);
+}
+if (ElemIndex == 0)
+  return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
+return this->visitZeroInitializer(classifyPrim(E->getType()), E->getType(),
+  E);
+  };
 
   // Now we can get pointers to the LHS and RHS from the offsets above.
   BinaryOperatorKind Op = E->getOpcode();
@@ -702,41 +747,29 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
 return false;
 }
 
-if (!this->emitGetLocal(PT_Ptr, LHSOffset, E))
-  return false;
-if (!this->emitConstUint8(ElemIndex, E))
-  return false;
-if (!this->emitArrayElemPtrPopUint8(E))
-  return false;
-if (!this->emitLoadPop(LHSElemT, E))
+if (!loadComplexValue(LHSIsComplex, ElemIndex, LHSOffset, LHS))
   return false;
 
-if (!this->emitGetLocal(PT_Ptr, RHSOffset, E))
-  return false;
-if (!this->emitConstUint8(

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

https://github.com/anematode created 
https://github.com/llvm/llvm-project/pull/82966

Will resolve https://github.com/llvm/llvm-project/issues/66059 . GCC's behavior 
in the case of inlining 
(https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) is that a caller's 
return/frame address may be returned, if the function in question gets inlined. 
Their docs encourage the function to be marked noinline. Therefore, it would be 
courteous to produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.

Marking this as draft because it's not fully ready, and I'd like to see whether 
this is a welcome change.

>From ef4c372a4d9364e6457c88a940c9af8666de0b74 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Mon, 26 Feb 2024 00:01:27 -0800
Subject: [PATCH] Add noinline check for __builtin_frame_address and
 __builtin_return_address

Resolves https://github.com/llvm/llvm-project/issues/66059 . GCC's behavior in 
the case of inlining (https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) 
is that a caller's return/frame address may be returned, if the function in 
question gets inlined. Their docs encourage the function to be marked noinline. 
Therefore, produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 +++
 clang/lib/Sema/SemaChecking.cpp   | 29 +
 clang/test/Sema/builtin-returnaddress.c   | 32 +++
 3 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..8f1cc611203694 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2029,6 +2029,10 @@ def warn_frame_address : Warning<
   "calling '%0' with a nonzero argument is unsafe">,
   InGroup, DefaultIgnore;
 
+def warn_frame_address_missing_noinline: Warning<
+  "calling '%0' in function not marked __attribute__((noinline)) may return a 
caller's %1 address">
+  InGroup, DefaultIgnore;
+
 def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
   "%select{anonymous struct|union}0 member %1 with a non-trivial "
   "%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7fa295ebd94044..1861f7dace3c6e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2733,13 +2733,28 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 // return/frame address.
 Expr::EvalResult Result;
 if (!TheCall->getArg(0)->isValueDependent() &&
-TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
-Result.Val.getInt() != 0)
-  Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
-  << ((BuiltinID == Builtin::BI__builtin_return_address)
-  ? "__builtin_return_address"
-  : "__builtin_frame_address")
-  << TheCall->getSourceRange();
+TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
+  const char *BuiltinName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+   ? "__builtin_return_address"
+   : "__builtin_frame_address";
+
+  if (Result.Val.getInt() != 0) {
+Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+<< BuiltinName << TheCall->getSourceRange();
+  }
+
+  // Check if enclosing function is marked noinline
+  if (const FunctionDecl *FD = dyn_cast(CurContext)) {
+if (!FD->hasAttr() && !FD->isMain()) {
+  const char *ShortName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+  ? "return" : "frame";
+  Diag(TheCall->getBeginLoc(), 
diag::warn_frame_address_missing_noinline)
+  << BuiltinName << ShortName << TheCall->getSourceRange();
+}
+  }
+}
 break;
   }
 
diff --git a/clang/test/Sema/builtin-returnaddress.c 
b/clang/test/Sema/builtin-returnaddress.c
index 16d2a517ac12f2..feb5a2ae05def7 100644
--- a/clang/test/Sema/builtin-returnaddress.c
+++ b/clang/test/Sema/builtin-returnaddress.c
@@ -2,24 +2,32 @@
 // RUN: %clang_cc1 -fsyntax-only -Wmost -verify %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wframe-address -verify %s
 
-void* a(unsigned x) {
+__attribute__((noinline)) void* a(unsigned x) {
 return __builtin_return_address(0);
 }
 
-void* b(unsigned x) {
+__attribute__((noinline)) void* b(unsigned x) {
 return __builtin_return_address(1); // expected-warning{{calling 
'__builtin_return_address' with a nonzero argument is unsafe}}
 }
 
-void* c(unsigned x) {
+__attribute__((noinline)) void* c(unsigned x) {
 return __builtin_frame_address(0);
 }
 
-void* d(unsigned x) {
+__attribute__((

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 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 47aee8b56d65e2bac5c7128424ff06134e454d83 
ef4c372a4d9364e6457c88a940c9af8666de0b74 -- clang/lib/Sema/SemaChecking.cpp 
clang/test/Sema/builtin-returnaddress.c
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 1861f7dace..cc8ba44f60 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2736,8 +2736,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
   const char *BuiltinName =
   (BuiltinID == Builtin::BI__builtin_return_address)
-   ? "__builtin_return_address"
-   : "__builtin_frame_address";
+  ? "__builtin_return_address"
+  : "__builtin_frame_address";
 
   if (Result.Val.getInt() != 0) {
 Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
@@ -2748,9 +2748,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
   if (const FunctionDecl *FD = dyn_cast(CurContext)) {
 if (!FD->hasAttr() && !FD->isMain()) {
   const char *ShortName =
-  (BuiltinID == Builtin::BI__builtin_return_address)
-  ? "return" : "frame";
-  Diag(TheCall->getBeginLoc(), 
diag::warn_frame_address_missing_noinline)
+  (BuiltinID == Builtin::BI__builtin_return_address) ? "return"
+ : "frame";
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_frame_address_missing_noinline)
   << BuiltinName << ShortName << TheCall->getSourceRange();
 }
   }

``




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


[clang] [llvm] [llvm-ar][Archive] Use getDefaultTargetTriple instead of host triple for the fallback archive format. (PR #82888)

2024-02-26 Thread James Henderson via cfe-commits

https://github.com/jh7370 commented:

I think the new behaviour makes more sense to me than the old one, thanks, but 
I think it should be documented both in the release notes and the llvm-ar 
Command Guide document.

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


[clang-tools-extra] [clang-tidy] bugprone-unused-return-value config now supports regexes (PR #82952)

2024-02-26 Thread Piotr Zegar via cfe-commits

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

LGTM, but update also check documentation, simply put there default config so 
user could easily copy it change, and add new functions. And mention that this 
support regexp.

https://github.com/llvm/llvm-project/pull/82952
___
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 support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/82617

>From b2b98e9594b224f471f88924b8b060bee06de483 Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Wed, 21 Feb 2024 09:15:22 +
Subject: [PATCH] [clang-tidy] Add support for determining constness of more
 expressions.

This uses a more systematic approach for determining whcich `DeclRefExpr`s 
mutate
the underlying object: Instead of using a few matchers, we walk up the
AST until we find a parent that we can prove cannot change the
underlying object.

This allows us to handle most address taking and dereference, bindings
to value and const& variables, and track constness of pointee
(see changes in DeclRefExprUtilsTest.cpp).

This allows supporting more patterns in 
`performance-unnecessary-copy-initialization`.

Those two patterns are relatively common:

```
const auto e = (*vector_ptr)[i]
```

and

```
const auto e = vector_ptr->at(i);
```

In our codebase, we have around 25% additional findings from
`performance-unnecessary-copy-initialization` with this change.
I did not see any additional false positives.
---
 .../UnnecessaryCopyInitialization.cpp |  27 +-
 .../clang-tidy/utils/DeclRefExprUtils.cpp | 212 +++---
 .../clang-tidy/utils/DeclRefExprUtils.h   |  33 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../unnecessary-copy-initialization.cpp   |  27 +-
 .../clang-tidy/DeclRefExprUtilsTest.cpp   | 274 +++---
 6 files changed, 396 insertions(+), 183 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index dfe12c5b6007da..9beb185cba929d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -86,16 +86,22 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
isConstRefReturningMethodCall,
   const auto MethodDecl =
   cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
   .bind(MethodDeclId);
-  const auto ReceiverExpr = declRefExpr(to(varDecl().bind(ObjectArgId)));
+  const auto ReceiverExpr =
+  ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
+  const auto OnExpr = anyOf(
+  // Direct reference to `*this`: `a.f()` or `a->f()`.
+  ReceiverExpr,
+  // Access through dereference, typically used for `operator[]`: 
`(*a)[3]`.
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ReceiverExpr)));
   const auto ReceiverType =
   hasCanonicalType(recordType(hasDeclaration(namedDecl(
   unless(matchers::matchesAnyListedName(ExcludedContainerTypes));
 
-  return expr(anyOf(
-  cxxMemberCallExpr(callee(MethodDecl), on(ReceiverExpr),
-thisPointerType(ReceiverType)),
-  cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, ReceiverExpr),
-  hasArgument(0, hasType(ReceiverType);
+  return expr(
+  anyOf(cxxMemberCallExpr(callee(MethodDecl), on(OnExpr),
+  thisPointerType(ReceiverType)),
+cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, OnExpr),
+hasArgument(0, hasType(ReceiverType);
 }
 
 AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
@@ -136,10 +142,11 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
 static bool isInitializingVariableImmutable(
 const VarDecl &InitializingVar, const Stmt &BlockStmt, ASTContext &Context,
 const std::vector &ExcludedContainerTypes) {
-  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
+  QualType T = InitializingVar.getType().getCanonicalType();
+  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context,
+ T->isPointerType() ? 1 : 0))
 return false;
 
-  QualType T = InitializingVar.getType().getCanonicalType();
   // The variable is a value type and we know it is only used as const. Safe
   // to reference it and avoid the copy.
   if (!isa(T))
@@ -273,7 +280,9 @@ void UnnecessaryCopyInitialization::check(
   VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID();
   const bool IsVarUnused = isVariableUnused(NewVar, BlockStmt, 
*Result.Context);
   const bool IsVarOnlyUsedAsConst =
-  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context);
+  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context,
+// `NewVar` is always of non-pointer type.
+0);
   const CheckContext Context{
   NewVar,   BlockStmt,   VarDeclStmt, *Result.Context,
   IssueFix, IsVarUnused, IsVarOnlyUsedAsConst};
diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp 
b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
index 2d73179150e8b8..663691c519b8e9 100644
--- a/clang-tools-extra/clan

[clang-tools-extra] [clang-tidy] bugprone-unused-return-value config now supports regexes (PR #82952)

2024-02-26 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL edited 
https://github.com/llvm/llvm-project/pull/82952
___
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 support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/82617

>From b2b98e9594b224f471f88924b8b060bee06de483 Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Wed, 21 Feb 2024 09:15:22 +
Subject: [PATCH 1/2] [clang-tidy] Add support for determining constness of
 more expressions.

This uses a more systematic approach for determining whcich `DeclRefExpr`s 
mutate
the underlying object: Instead of using a few matchers, we walk up the
AST until we find a parent that we can prove cannot change the
underlying object.

This allows us to handle most address taking and dereference, bindings
to value and const& variables, and track constness of pointee
(see changes in DeclRefExprUtilsTest.cpp).

This allows supporting more patterns in 
`performance-unnecessary-copy-initialization`.

Those two patterns are relatively common:

```
const auto e = (*vector_ptr)[i]
```

and

```
const auto e = vector_ptr->at(i);
```

In our codebase, we have around 25% additional findings from
`performance-unnecessary-copy-initialization` with this change.
I did not see any additional false positives.
---
 .../UnnecessaryCopyInitialization.cpp |  27 +-
 .../clang-tidy/utils/DeclRefExprUtils.cpp | 212 +++---
 .../clang-tidy/utils/DeclRefExprUtils.h   |  33 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../unnecessary-copy-initialization.cpp   |  27 +-
 .../clang-tidy/DeclRefExprUtilsTest.cpp   | 274 +++---
 6 files changed, 396 insertions(+), 183 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index dfe12c5b6007da..9beb185cba929d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -86,16 +86,22 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
isConstRefReturningMethodCall,
   const auto MethodDecl =
   cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
   .bind(MethodDeclId);
-  const auto ReceiverExpr = declRefExpr(to(varDecl().bind(ObjectArgId)));
+  const auto ReceiverExpr =
+  ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
+  const auto OnExpr = anyOf(
+  // Direct reference to `*this`: `a.f()` or `a->f()`.
+  ReceiverExpr,
+  // Access through dereference, typically used for `operator[]`: 
`(*a)[3]`.
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ReceiverExpr)));
   const auto ReceiverType =
   hasCanonicalType(recordType(hasDeclaration(namedDecl(
   unless(matchers::matchesAnyListedName(ExcludedContainerTypes));
 
-  return expr(anyOf(
-  cxxMemberCallExpr(callee(MethodDecl), on(ReceiverExpr),
-thisPointerType(ReceiverType)),
-  cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, ReceiverExpr),
-  hasArgument(0, hasType(ReceiverType);
+  return expr(
+  anyOf(cxxMemberCallExpr(callee(MethodDecl), on(OnExpr),
+  thisPointerType(ReceiverType)),
+cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, OnExpr),
+hasArgument(0, hasType(ReceiverType);
 }
 
 AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
@@ -136,10 +142,11 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
 static bool isInitializingVariableImmutable(
 const VarDecl &InitializingVar, const Stmt &BlockStmt, ASTContext &Context,
 const std::vector &ExcludedContainerTypes) {
-  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
+  QualType T = InitializingVar.getType().getCanonicalType();
+  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context,
+ T->isPointerType() ? 1 : 0))
 return false;
 
-  QualType T = InitializingVar.getType().getCanonicalType();
   // The variable is a value type and we know it is only used as const. Safe
   // to reference it and avoid the copy.
   if (!isa(T))
@@ -273,7 +280,9 @@ void UnnecessaryCopyInitialization::check(
   VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID();
   const bool IsVarUnused = isVariableUnused(NewVar, BlockStmt, 
*Result.Context);
   const bool IsVarOnlyUsedAsConst =
-  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context);
+  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context,
+// `NewVar` is always of non-pointer type.
+0);
   const CheckContext Context{
   NewVar,   BlockStmt,   VarDeclStmt, *Result.Context,
   IssueFix, IsVarUnused, IsVarOnlyUsedAsConst};
diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp 
b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
index 2d73179150e8b8..663691c519b8e9 100644
--- a/clang-tools-extra/

[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)

2024-02-26 Thread Qiu Chaofan via cfe-commits

https://github.com/ecnelises created 
https://github.com/llvm/llvm-project/pull/82968

These builtins are already there in Clang, however current codegen may produce 
suboptimal results due to their complex behavior. Implement them as intrinsics 
to ensure expected instructions are emitted.

>From a06fa5e18313ad50019d50006e34a6b8249d95cd Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Mon, 26 Feb 2024 16:32:28 +0800
Subject: [PATCH] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm

These builtins are already there in Clang, however current codegen may
produce suboptimal results due to their complex behavior. Implement them
as intrinsics to ensure expected instructions are emitted.
---
 clang/lib/CodeGen/CGBuiltin.cpp   |  29 ++---
 .../PowerPC/builtins-ppc-xlcompat-rotate.c|  24 ++--
 llvm/include/llvm/IR/IntrinsicsPowerPC.td |  12 ++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   |  52 
 llvm/test/CodeGen/PowerPC/rldimi.ll   |  15 +++
 llvm/test/CodeGen/PowerPC/rlwimi.ll   | 123 --
 llvm/test/CodeGen/PowerPC/rlwinm.ll   | 108 ++-
 7 files changed, 259 insertions(+), 104 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..5d55be6e9e99df 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -17080,37 +17080,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
 }
 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
   }
-  // Rotate and insert under mask operation.
-  // __rldimi(rs, is, shift, mask)
-  // (rotl64(rs, shift) & mask) | (is & ~mask)
-  // __rlwimi(rs, is, shift, mask)
-  // (rotl(rs, shift) & mask) | (is & ~mask)
   case PPC::BI__builtin_ppc_rldimi:
   case PPC::BI__builtin_ppc_rlwimi: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Op1 = EmitScalarExpr(E->getArg(1));
 Value *Op2 = EmitScalarExpr(E->getArg(2));
 Value *Op3 = EmitScalarExpr(E->getArg(3));
-llvm::Type *Ty = Op0->getType();
-Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
-if (BuiltinID == PPC::BI__builtin_ppc_rldimi)
-  Op2 = Builder.CreateZExt(Op2, Int64Ty);
-Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
-Value *X = Builder.CreateAnd(Shift, Op3);
-Value *Y = Builder.CreateAnd(Op1, Builder.CreateNot(Op3));
-return Builder.CreateOr(X, Y);
-  }
-  // Rotate and insert under mask operation.
-  // __rlwnm(rs, shift, mask)
-  // rotl(rs, shift) & mask
+return Builder.CreateCall(
+CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
+ ? Intrinsic::ppc_rldimi
+ : Intrinsic::ppc_rlwimi),
+{Op0, Op1, Op2, Op3});
+  }
   case PPC::BI__builtin_ppc_rlwnm: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Op1 = EmitScalarExpr(E->getArg(1));
 Value *Op2 = EmitScalarExpr(E->getArg(2));
-llvm::Type *Ty = Op0->getType();
-Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
-Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op1});
-return Builder.CreateAnd(Shift, Op2);
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_rlwnm),
+  {Op0, Op1, Op2});
   }
   case PPC::BI__builtin_ppc_poppar4:
   case PPC::BI__builtin_ppc_poppar8: {
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c 
b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
index d96bfb4621421e..b218547c00d931 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
@@ -16,11 +16,8 @@ void test_builtin_ppc_rldimi() {
   // CHECK:   %res = alloca i64, align 8
   // CHECK-NEXT:  [[RA:%[0-9]+]] = load i64, ptr @ull, align 8
   // CHECK-NEXT:  [[RB:%[0-9]+]] = load i64, ptr @ull, align 8
-  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 
[[RA]], i64 63)
-  // CHECK-NEXT:  [[RD:%[0-9]+]] = and i64 [[RC]], 72057593769492480
-  // CHECK-NEXT:  [[RE:%[0-9]+]] = and i64 [[RB]], -72057593769492481
-  // CHECK-NEXT:  [[RF:%[0-9]+]] = or i64 [[RD]], [[RE]]
-  // CHECK-NEXT:  store i64 [[RF]], ptr %res, align 8
+  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 
[[RB]], i32 63, i64 72057593769492480)
+  // CHECK-NEXT:  store i64 [[RC]], ptr %res, align 8
   // CHECK-NEXT:  ret void
 
   /*shift = 63, mask = 0x00FFF000 = 72057593769492480, ~mask = 
0xFF000FFF = -72057593769492481*/
@@ -32,11 +29,8 @@ void test_builtin_ppc_rlwimi() {
   // CHECK:   %res = alloca i32, align 4
   // CHECK-NEXT:  [[RA:%[0-9]+]] = load i32, ptr @ui, align 4
   // CHECK-NEXT:  [[RB:%[0-9]+]] = load i32, ptr @ui, align 4
-  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 
[[RA]], i32 31)
-  // CHECK-NEXT:  [[RD:%[0-9]+]] = and i32 [[RC]], 16776960
-  // CHECK-NEXT:  [[RE:%[0-9]+]] = and i32 [[RB]], -16

[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)

2024-02-26 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-backend-powerpc

Author: Qiu Chaofan (ecnelises)


Changes

These builtins are already there in Clang, however current codegen may produce 
suboptimal results due to their complex behavior. Implement them as intrinsics 
to ensure expected instructions are emitted.

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


7 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+8-21) 
- (modified) clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c (+8-16) 
- (modified) llvm/include/llvm/IR/IntrinsicsPowerPC.td (+12) 
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+52) 
- (modified) llvm/test/CodeGen/PowerPC/rldimi.ll (+15) 
- (modified) llvm/test/CodeGen/PowerPC/rlwimi.ll (+85-38) 
- (modified) llvm/test/CodeGen/PowerPC/rlwinm.ll (+79-29) 


``diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 734eb5a035ca49..5d55be6e9e99df 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -17080,37 +17080,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
 }
 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
   }
-  // Rotate and insert under mask operation.
-  // __rldimi(rs, is, shift, mask)
-  // (rotl64(rs, shift) & mask) | (is & ~mask)
-  // __rlwimi(rs, is, shift, mask)
-  // (rotl(rs, shift) & mask) | (is & ~mask)
   case PPC::BI__builtin_ppc_rldimi:
   case PPC::BI__builtin_ppc_rlwimi: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Op1 = EmitScalarExpr(E->getArg(1));
 Value *Op2 = EmitScalarExpr(E->getArg(2));
 Value *Op3 = EmitScalarExpr(E->getArg(3));
-llvm::Type *Ty = Op0->getType();
-Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
-if (BuiltinID == PPC::BI__builtin_ppc_rldimi)
-  Op2 = Builder.CreateZExt(Op2, Int64Ty);
-Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
-Value *X = Builder.CreateAnd(Shift, Op3);
-Value *Y = Builder.CreateAnd(Op1, Builder.CreateNot(Op3));
-return Builder.CreateOr(X, Y);
-  }
-  // Rotate and insert under mask operation.
-  // __rlwnm(rs, shift, mask)
-  // rotl(rs, shift) & mask
+return Builder.CreateCall(
+CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
+ ? Intrinsic::ppc_rldimi
+ : Intrinsic::ppc_rlwimi),
+{Op0, Op1, Op2, Op3});
+  }
   case PPC::BI__builtin_ppc_rlwnm: {
 Value *Op0 = EmitScalarExpr(E->getArg(0));
 Value *Op1 = EmitScalarExpr(E->getArg(1));
 Value *Op2 = EmitScalarExpr(E->getArg(2));
-llvm::Type *Ty = Op0->getType();
-Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
-Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op1});
-return Builder.CreateAnd(Shift, Op2);
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_rlwnm),
+  {Op0, Op1, Op2});
   }
   case PPC::BI__builtin_ppc_poppar4:
   case PPC::BI__builtin_ppc_poppar8: {
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c 
b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
index d96bfb4621421e..b218547c00d931 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c
@@ -16,11 +16,8 @@ void test_builtin_ppc_rldimi() {
   // CHECK:   %res = alloca i64, align 8
   // CHECK-NEXT:  [[RA:%[0-9]+]] = load i64, ptr @ull, align 8
   // CHECK-NEXT:  [[RB:%[0-9]+]] = load i64, ptr @ull, align 8
-  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 
[[RA]], i64 63)
-  // CHECK-NEXT:  [[RD:%[0-9]+]] = and i64 [[RC]], 72057593769492480
-  // CHECK-NEXT:  [[RE:%[0-9]+]] = and i64 [[RB]], -72057593769492481
-  // CHECK-NEXT:  [[RF:%[0-9]+]] = or i64 [[RD]], [[RE]]
-  // CHECK-NEXT:  store i64 [[RF]], ptr %res, align 8
+  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 
[[RB]], i32 63, i64 72057593769492480)
+  // CHECK-NEXT:  store i64 [[RC]], ptr %res, align 8
   // CHECK-NEXT:  ret void
 
   /*shift = 63, mask = 0x00FFF000 = 72057593769492480, ~mask = 
0xFF000FFF = -72057593769492481*/
@@ -32,11 +29,8 @@ void test_builtin_ppc_rlwimi() {
   // CHECK:   %res = alloca i32, align 4
   // CHECK-NEXT:  [[RA:%[0-9]+]] = load i32, ptr @ui, align 4
   // CHECK-NEXT:  [[RB:%[0-9]+]] = load i32, ptr @ui, align 4
-  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 
[[RA]], i32 31)
-  // CHECK-NEXT:  [[RD:%[0-9]+]] = and i32 [[RC]], 16776960
-  // CHECK-NEXT:  [[RE:%[0-9]+]] = and i32 [[RB]], -16776961
-  // CHECK-NEXT:  [[RF:%[0-9]+]] = or i32 [[RD]], [[RE]]
-  // CHECK-NEXT:  store i32 [[RF]], ptr %res, align 4
+  // CHECK-NEXT:  [[RC:%[0-9]+]] = call i32 @llvm.ppc.rlwimi(i32 [[RA]], i32 
[[RB]], i32 31, i32 16776960)
+  // CHECK-NEXT:  store i32 [[RC]], ptr %res

[clang-tools-extra] [clang-tidy] Add support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/82617

>From b2b98e9594b224f471f88924b8b060bee06de483 Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Wed, 21 Feb 2024 09:15:22 +
Subject: [PATCH 1/3] [clang-tidy] Add support for determining constness of
 more expressions.

This uses a more systematic approach for determining whcich `DeclRefExpr`s 
mutate
the underlying object: Instead of using a few matchers, we walk up the
AST until we find a parent that we can prove cannot change the
underlying object.

This allows us to handle most address taking and dereference, bindings
to value and const& variables, and track constness of pointee
(see changes in DeclRefExprUtilsTest.cpp).

This allows supporting more patterns in 
`performance-unnecessary-copy-initialization`.

Those two patterns are relatively common:

```
const auto e = (*vector_ptr)[i]
```

and

```
const auto e = vector_ptr->at(i);
```

In our codebase, we have around 25% additional findings from
`performance-unnecessary-copy-initialization` with this change.
I did not see any additional false positives.
---
 .../UnnecessaryCopyInitialization.cpp |  27 +-
 .../clang-tidy/utils/DeclRefExprUtils.cpp | 212 +++---
 .../clang-tidy/utils/DeclRefExprUtils.h   |  33 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../unnecessary-copy-initialization.cpp   |  27 +-
 .../clang-tidy/DeclRefExprUtilsTest.cpp   | 274 +++---
 6 files changed, 396 insertions(+), 183 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index dfe12c5b6007da..9beb185cba929d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -86,16 +86,22 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
isConstRefReturningMethodCall,
   const auto MethodDecl =
   cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
   .bind(MethodDeclId);
-  const auto ReceiverExpr = declRefExpr(to(varDecl().bind(ObjectArgId)));
+  const auto ReceiverExpr =
+  ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
+  const auto OnExpr = anyOf(
+  // Direct reference to `*this`: `a.f()` or `a->f()`.
+  ReceiverExpr,
+  // Access through dereference, typically used for `operator[]`: 
`(*a)[3]`.
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ReceiverExpr)));
   const auto ReceiverType =
   hasCanonicalType(recordType(hasDeclaration(namedDecl(
   unless(matchers::matchesAnyListedName(ExcludedContainerTypes));
 
-  return expr(anyOf(
-  cxxMemberCallExpr(callee(MethodDecl), on(ReceiverExpr),
-thisPointerType(ReceiverType)),
-  cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, ReceiverExpr),
-  hasArgument(0, hasType(ReceiverType);
+  return expr(
+  anyOf(cxxMemberCallExpr(callee(MethodDecl), on(OnExpr),
+  thisPointerType(ReceiverType)),
+cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, OnExpr),
+hasArgument(0, hasType(ReceiverType);
 }
 
 AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
@@ -136,10 +142,11 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
 static bool isInitializingVariableImmutable(
 const VarDecl &InitializingVar, const Stmt &BlockStmt, ASTContext &Context,
 const std::vector &ExcludedContainerTypes) {
-  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
+  QualType T = InitializingVar.getType().getCanonicalType();
+  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context,
+ T->isPointerType() ? 1 : 0))
 return false;
 
-  QualType T = InitializingVar.getType().getCanonicalType();
   // The variable is a value type and we know it is only used as const. Safe
   // to reference it and avoid the copy.
   if (!isa(T))
@@ -273,7 +280,9 @@ void UnnecessaryCopyInitialization::check(
   VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID();
   const bool IsVarUnused = isVariableUnused(NewVar, BlockStmt, 
*Result.Context);
   const bool IsVarOnlyUsedAsConst =
-  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context);
+  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context,
+// `NewVar` is always of non-pointer type.
+0);
   const CheckContext Context{
   NewVar,   BlockStmt,   VarDeclStmt, *Result.Context,
   IssueFix, IsVarUnused, IsVarOnlyUsedAsConst};
diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp 
b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
index 2d73179150e8b8..663691c519b8e9 100644
--- a/clang-tools-extra/

[clang] [AArch64][SME2] Refactor arm_sme.td into multiclasses (PR #78169)

2024-02-26 Thread Matthew Devereau via cfe-commits

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


[clang-tools-extra] [llvm] [clang-tidy] Add support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/82617

>From 9b93c8bf0614e64352de8e210adf6ff316c0133e Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Mon, 19 Feb 2024 14:58:27 +
Subject: [PATCH 1/5] [llvm-exegesis][NFC] Refactor all `ValidationEvent` info
 in a single table.

All data is derived from a single table rather than being spread out
over an enum, a table and the main entry point.
---
 llvm/include/llvm/Target/TargetPfmCounters.td |  1 +
 .../llvm-exegesis/lib/BenchmarkResult.cpp | 49 +--
 .../tools/llvm-exegesis/lib/BenchmarkResult.h | 15 +
 llvm/tools/llvm-exegesis/lib/CMakeLists.txt   |  1 +
 .../lib/LatencyBenchmarkRunner.cpp|  4 +-
 llvm/tools/llvm-exegesis/lib/Target.h |  1 +
 .../llvm-exegesis/lib/ValidationEvent.cpp | 53 
 .../tools/llvm-exegesis/lib/ValidationEvent.h | 60 +++
 llvm/tools/llvm-exegesis/llvm-exegesis.cpp| 20 +--
 9 files changed, 124 insertions(+), 80 deletions(-)
 create mode 100644 llvm/tools/llvm-exegesis/lib/ValidationEvent.cpp
 create mode 100644 llvm/tools/llvm-exegesis/lib/ValidationEvent.h

diff --git a/llvm/include/llvm/Target/TargetPfmCounters.td 
b/llvm/include/llvm/Target/TargetPfmCounters.td
index 8c4d5f50c63a24..cfe432a992b71f 100644
--- a/llvm/include/llvm/Target/TargetPfmCounters.td
+++ b/llvm/include/llvm/Target/TargetPfmCounters.td
@@ -35,6 +35,7 @@ class ValidationEvent  {
   int EventNumber = event_number;
 }
 
+// TableGen names for events defined in `llvm::exegesis::ValidationEvent`.
 def InstructionRetired  : ValidationEvent<0>;
 def L1DCacheLoadMiss : ValidationEvent<1>;
 def L1DCacheStoreMiss : ValidationEvent<2>;
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp 
b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 189add6464173f..f84ebd2a4e68ef 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -9,6 +9,7 @@
 #include "BenchmarkResult.h"
 #include "BenchmarkRunner.h"
 #include "Error.h"
+#include "ValidationEvent.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringRef.h"
@@ -198,7 +199,7 @@ struct 
CustomMappingTraits> {
   static void inputOne(IO &Io, StringRef KeyStr,
std::map &VI) {
 Expected Key =
-exegesis::stringToValidationEvent(KeyStr);
+exegesis::getValidationEventByName(KeyStr);
 if (!Key) {
   Io.setError("Key is not a valid validation event");
   return;
@@ -208,7 +209,7 @@ struct 
CustomMappingTraits> {
 
   static void output(IO &Io, std::map &VI) 
{
 for (auto &IndividualVI : VI) {
-  Io.mapRequired(exegesis::validationEventToString(IndividualVI.first),
+  Io.mapRequired(exegesis::getValidationEventName(IndividualVI.first),
  IndividualVI.second);
 }
   }
@@ -441,49 +442,5 @@ bool operator==(const BenchmarkMeasure &A, const 
BenchmarkMeasure &B) {
  std::tie(B.Key, B.PerInstructionValue, B.PerSnippetValue);
 }
 
-const char *validationEventToString(ValidationEvent VE) {
-  switch (VE) {
-  case exegesis::ValidationEvent::InstructionRetired:
-return "instructions-retired";
-  case exegesis::ValidationEvent::L1DCacheLoadMiss:
-return "l1d-cache-load-misses";
-  case exegesis::ValidationEvent::L1DCacheStoreMiss:
-return "l1d-cache-store-misses";
-  case exegesis::ValidationEvent::L1ICacheLoadMiss:
-return "l1i-cache-load-misses";
-  case exegesis::ValidationEvent::DataTLBLoadMiss:
-return "data-tlb-load-misses";
-  case exegesis::ValidationEvent::DataTLBStoreMiss:
-return "data-tlb-store-misses";
-  case exegesis::ValidationEvent::InstructionTLBLoadMiss:
-return "instruction-tlb-load-misses";
-  case exegesis::ValidationEvent::BranchPredictionMiss:
-return "branch-prediction-misses";
-  }
-  llvm_unreachable("Unhandled exegesis::ValidationEvent enum");
-}
-
-Expected stringToValidationEvent(StringRef Input) {
-  if (Input == "instructions-retired")
-return exegesis::ValidationEvent::InstructionRetired;
-  else if (Input == "l1d-cache-load-misses")
-return exegesis::ValidationEvent::L1DCacheLoadMiss;
-  else if (Input == "l1d-cache-store-misses")
-return exegesis::ValidationEvent::L1DCacheStoreMiss;
-  else if (Input == "l1i-cache-load-misses")
-return exegesis::ValidationEvent::L1ICacheLoadMiss;
-  else if (Input == "data-tlb-load-misses")
-return exegesis::ValidationEvent::DataTLBLoadMiss;
-  else if (Input == "data-tlb-store-misses")
-return exegesis::ValidationEvent::DataTLBStoreMiss;
-  else if (Input == "instruction-tlb-load-misses")
-return exegesis::ValidationEvent::InstructionTLBLoadMiss;
-  else if (Input == "branch-prediction-misses")
-return exegesis::ValidationEvent::BranchPredictionMiss;
-  else
-return make_error("Invalid validation event string",
-   errc::invalid_argumen

[clang-tools-extra] [llvm] [clang-tidy] Add support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

legrosbuffle wrote:

Thanks all. Comments addressed.

> Overall looking fine, but this check need to be run on bigger code-base to 
> verify if there are no false positives or crashes.

Sorry, this was not very clear. By "our codebase" I meant the whole of Google 
code :) This also ran on numerous third party repos.



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


[clang] 56b63e0 - [clang][Interp] Get <=> value info from weak result

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T09:52:38+01:00
New Revision: 56b63e0886ba369a53df5e1d429cde2e4a2d4a34

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

LOG: [clang][Interp] Get <=> value info from weak result

This is also what the current interpreter does and a couple of
test cases expect that.

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h
clang/test/SemaCXX/compare-modules-cxx2a.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 7994550cc7b97e..aecad1598ad2b1 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -808,7 +808,8 @@ bool CMP3(InterpState &S, CodePtr OpPC, const 
ComparisonCategoryInfo *CmpInfo) {
   }
 
   assert(CmpInfo);
-  const auto *CmpValueInfo = CmpInfo->getValueInfo(CmpResult);
+  const auto *CmpValueInfo =
+  CmpInfo->getValueInfo(CmpInfo->makeWeakResult(CmpResult));
   assert(CmpValueInfo);
   assert(CmpValueInfo->hasValidIntValue());
   const APSInt &IntValue = CmpValueInfo->getIntValue();

diff  --git a/clang/test/SemaCXX/compare-modules-cxx2a.cpp 
b/clang/test/SemaCXX/compare-modules-cxx2a.cpp
index 470464427efd9c..19093b89f60cf7 100644
--- a/clang/test/SemaCXX/compare-modules-cxx2a.cpp
+++ b/clang/test/SemaCXX/compare-modules-cxx2a.cpp
@@ -2,6 +2,7 @@
 // RUN: mkdir -p %t
 
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -fcxx-exceptions -verify 
-std=c++2a -fmodules -fmodules-cache-path=%t.mcp -I%S/Inputs %s 
-fno-modules-error-recovery -fmodule-map-file=%S/Inputs/compare.modulemap
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fcxx-exceptions -verify 
-std=c++2a -fmodules -fmodules-cache-path=%t.mcp -I%S/Inputs %s 
-fno-modules-error-recovery -fmodule-map-file=%S/Inputs/compare.modulemap 
-fexperimental-new-constant-interpreter
 
 struct CC { CC(...); };
 



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


[clang-tools-extra] 94ca854 - [clang-tidy] Add support for determining constness of more expressions. (#82617)

2024-02-26 Thread via cfe-commits

Author: Clement Courbet
Date: 2024-02-26T09:55:07+01:00
New Revision: 94ca854d3c874322b1d4b5606c5762adcd3b8e05

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

LOG: [clang-tidy] Add support for determining constness of more expressions. 
(#82617)

This uses a more systematic approach for determining whcich
`DeclRefExpr`s mutate the underlying object: Instead of using a few
matchers, we walk up the AST until we find a parent that we can prove
cannot change the underlying object.

This allows us to handle most address taking and dereference, bindings
to value and const& variables, and track constness of pointee (see
changes in DeclRefExprUtilsTest.cpp).

This allows supporting more patterns in
`performance-unnecessary-copy-initialization`.

Those two patterns are relatively common:

```
const auto e = (*vector_ptr)[i]
```

and

```
const auto e = vector_ptr->at(i);
```

In our codebase, we have around 25% additional findings from
`performance-unnecessary-copy-initialization` with this change. I did
not see any additional false positives.

Added: 


Modified: 
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.h
clang-tools-extra/docs/ReleaseNotes.rst

clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp
clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index dfe12c5b6007da..9beb185cba929d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -86,16 +86,22 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
isConstRefReturningMethodCall,
   const auto MethodDecl =
   cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
   .bind(MethodDeclId);
-  const auto ReceiverExpr = declRefExpr(to(varDecl().bind(ObjectArgId)));
+  const auto ReceiverExpr =
+  ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
+  const auto OnExpr = anyOf(
+  // Direct reference to `*this`: `a.f()` or `a->f()`.
+  ReceiverExpr,
+  // Access through dereference, typically used for `operator[]`: 
`(*a)[3]`.
+  unaryOperator(hasOperatorName("*"), hasUnaryOperand(ReceiverExpr)));
   const auto ReceiverType =
   hasCanonicalType(recordType(hasDeclaration(namedDecl(
   unless(matchers::matchesAnyListedName(ExcludedContainerTypes));
 
-  return expr(anyOf(
-  cxxMemberCallExpr(callee(MethodDecl), on(ReceiverExpr),
-thisPointerType(ReceiverType)),
-  cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, ReceiverExpr),
-  hasArgument(0, hasType(ReceiverType);
+  return expr(
+  anyOf(cxxMemberCallExpr(callee(MethodDecl), on(OnExpr),
+  thisPointerType(ReceiverType)),
+cxxOperatorCallExpr(callee(MethodDecl), hasArgument(0, OnExpr),
+hasArgument(0, hasType(ReceiverType);
 }
 
 AST_MATCHER_FUNCTION(StatementMatcher, isConstRefReturningFunctionCall) {
@@ -136,10 +142,11 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
 static bool isInitializingVariableImmutable(
 const VarDecl &InitializingVar, const Stmt &BlockStmt, ASTContext &Context,
 const std::vector &ExcludedContainerTypes) {
-  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context))
+  QualType T = InitializingVar.getType().getCanonicalType();
+  if (!isOnlyUsedAsConst(InitializingVar, BlockStmt, Context,
+ T->isPointerType() ? 1 : 0))
 return false;
 
-  QualType T = InitializingVar.getType().getCanonicalType();
   // The variable is a value type and we know it is only used as const. Safe
   // to reference it and avoid the copy.
   if (!isa(T))
@@ -273,7 +280,9 @@ void UnnecessaryCopyInitialization::check(
   VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID();
   const bool IsVarUnused = isVariableUnused(NewVar, BlockStmt, 
*Result.Context);
   const bool IsVarOnlyUsedAsConst =
-  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context);
+  isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context,
+// `NewVar` is always of non-pointer type.
+0);
   const CheckContext Context{
   NewVar,   BlockStmt,   VarDeclStmt, *Result.Context,
   IssueFix, IsVarUnused, IsVarOnlyUsedAsConst};

diff  --git a/clan

[clang-tools-extra] [llvm] [clang-tidy] Add support for determining constness of more expressions. (PR #82617)

2024-02-26 Thread Clement Courbet via cfe-commits

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


[clang] [clang][dataflow] Factor out built-in boolean model into an explicit module. (PR #82950)

2024-02-26 Thread via cfe-commits

martinboehme wrote:

> Draft to demo how we can pull out the boolean model. Let's discuss specifics 
> of namings, location, etc.

Not sure -- do you mean let's wordsmith names now, or do you mean we should 
discuss naming and location, but that should happen after we've talked about 
the general approach?

> The purpose of this refactoring is to enable us to compare the performance of 
> different boolean models. In particular, we're interested in investigating a 
> very simple semantic domain of just the booleans (and Top).

Can you expand on how we would swap in a different boolean model?

*  Just put `#ifdef`s in the various functions in `bool_model`?

*  Provide different namespaces containing different boolean models, then in 
`namespace bool_model`, do `using namespace my_desired_bool_model`?

*  Something else?

I would favour a model that's as simple as possible -- I don't think we want to 
use template parameters, for example -- and what you have here looks like it's 
intended to be simple. I'm just not sure exactly where this is intended to go?

> In the process, the PR drastically simplifies the handling of terminators. 
> This cleanup can be pulled out into its own PR, to precede the refactoring 
> work.

I like the cleanup, and I think pulling it out into a separate patch is a good 
idea because a) it's unrelated to the rest of this patch, and b) it can land 
today, without further discussion needed (IMO).

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits

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


[clang] Revert "[clang][dataflow] Correctly handle `InitListExpr` of union type." (PR #82856)

2024-02-26 Thread via cfe-commits

martinboehme wrote:

Sorry about the breakage. Will re-land soon with a test for this case and a fix.

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


[clang] cb2dd02 - [clang][NFC] constify or staticify some CGRecordLowering fns (#82874)

2024-02-26 Thread via cfe-commits

Author: Nathan Sidwell
Date: 2024-02-26T04:44:03-05:00
New Revision: cb2dd0282cf2f5dfc58d5a060dd2aa73c3b4c08e

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

LOG: [clang][NFC] constify or staticify some CGRecordLowering fns (#82874)

Some CGRecordLowering functions either do not need the object or do not mutate 
it.  Thus marking static or const as appropriate.

Added: 


Modified: 
clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 868ef810f3c4e8..7822903b89ce47 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -95,7 +95,7 @@ struct CGRecordLowering {
   CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D, bool Packed);
   // Short helper routines.
   /// Constructs a MemberInfo instance from an offset and llvm::Type *.
-  MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
+  static MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
 return MemberInfo(Offset, MemberInfo::Field, Data);
   }
 
@@ -104,7 +104,7 @@ struct CGRecordLowering {
   /// fields of the same formal type.  We want to emit a layout with
   /// these discrete storage units instead of combining them into a
   /// continuous run.
-  bool isDiscreteBitFieldABI() {
+  bool isDiscreteBitFieldABI() const {
 return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
D->isMsStruct(Context);
   }
@@ -121,22 +121,22 @@ struct CGRecordLowering {
   /// other bases, which complicates layout in specific ways.
   ///
   /// Note specifically that the ms_struct attribute doesn't change this.
-  bool isOverlappingVBaseABI() {
+  bool isOverlappingVBaseABI() const {
 return !Context.getTargetInfo().getCXXABI().isMicrosoft();
   }
 
   /// Wraps llvm::Type::getIntNTy with some implicit arguments.
-  llvm::Type *getIntNType(uint64_t NumBits) {
+  llvm::Type *getIntNType(uint64_t NumBits) const {
 unsigned AlignedBits = llvm::alignTo(NumBits, Context.getCharWidth());
 return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
   }
   /// Get the LLVM type sized as one character unit.
-  llvm::Type *getCharType() {
+  llvm::Type *getCharType() const {
 return llvm::Type::getIntNTy(Types.getLLVMContext(),
  Context.getCharWidth());
   }
   /// Gets an llvm type of size NumChars and alignment 1.
-  llvm::Type *getByteArrayType(CharUnits NumChars) {
+  llvm::Type *getByteArrayType(CharUnits NumChars) const {
 assert(!NumChars.isZero() && "Empty byte arrays aren't allowed.");
 llvm::Type *Type = getCharType();
 return NumChars == CharUnits::One() ? Type :
@@ -144,7 +144,7 @@ struct CGRecordLowering {
   }
   /// Gets the storage type for a field decl and handles storage
   /// for itanium bitfields that are smaller than their declared type.
-  llvm::Type *getStorageType(const FieldDecl *FD) {
+  llvm::Type *getStorageType(const FieldDecl *FD) const {
 llvm::Type *Type = Types.ConvertTypeForMem(FD->getType());
 if (!FD->isBitField()) return Type;
 if (isDiscreteBitFieldABI()) return Type;
@@ -152,29 +152,29 @@ struct CGRecordLowering {
  (unsigned)Context.toBits(getSize(Type;
   }
   /// Gets the llvm Basesubobject type from a CXXRecordDecl.
-  llvm::Type *getStorageType(const CXXRecordDecl *RD) {
+  llvm::Type *getStorageType(const CXXRecordDecl *RD) const {
 return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
   }
-  CharUnits bitsToCharUnits(uint64_t BitOffset) {
+  CharUnits bitsToCharUnits(uint64_t BitOffset) const {
 return Context.toCharUnitsFromBits(BitOffset);
   }
-  CharUnits getSize(llvm::Type *Type) {
+  CharUnits getSize(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getTypeAllocSize(Type));
   }
-  CharUnits getAlignment(llvm::Type *Type) {
+  CharUnits getAlignment(llvm::Type *Type) const {
 return CharUnits::fromQuantity(DataLayout.getABITypeAlign(Type));
   }
-  bool isZeroInitializable(const FieldDecl *FD) {
+  bool isZeroInitializable(const FieldDecl *FD) const {
 return Types.isZeroInitializable(FD->getType());
   }
-  bool isZeroInitializable(const RecordDecl *RD) {
+  bool isZeroInitializable(const RecordDecl *RD) const {
 return Types.isZeroInitializable(RD);
   }
   void appendPaddingBytes(CharUnits Size) {
 if (!Size.isZero())
   FieldTypes.push_back(getByteArrayType(Size));
   }
-  uint64_t getFieldBitOffset(const FieldDecl *FD) {
+  uint64_t getFieldBitOffset(const FieldDecl *FD) const {
 return Layout.getFieldOffset(FD->getFieldIndex());
   }
   // Layout routines.



_

[clang] [clang][NFC] constify or staticify some CGRecordLowering fns (PR #82874)

2024-02-26 Thread Nathan Sidwell via cfe-commits

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


[clang] [Driver] Improve error when a compiler-rt library is not found (PR #81037)

2024-02-26 Thread Tobias Hieta via cfe-commits

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

This seems good to me, it worked in my internal test as I expected it!

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


[clang] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker (PR #82977)

2024-02-26 Thread via cfe-commits

https://github.com/Discookie created 
https://github.com/llvm/llvm-project/pull/82977

This checker reports cases where an array of polymorphic objects are deleted as 
their base class.
Deleting an array where the array's static type is different from its dynamic 
type is undefined.

Similar in structure to `alpha.cplusplus.ArrayDelete`.

This checker corresponds to the SEI Cert rule [CTR56-CPP: Do not use pointer 
arithmetic on polymorphic 
objects](https://wiki.sei.cmu.edu/confluence/display/cplusplus/CTR56-CPP.+Do+not+use+pointer+arithmetic+on+polymorphic+objects).

>From 0318d05d4c6f4792287084fe90c23cd064a09d17 Mon Sep 17 00:00:00 2001
From: Viktor 
Date: Thu, 22 Feb 2024 09:28:04 +
Subject: [PATCH] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker

---
 clang/docs/analyzer/checkers.rst  |  33 
 .../clang/StaticAnalyzer/Checkers/Checkers.td |   5 +
 .../StaticAnalyzer/Checkers/CMakeLists.txt|   1 +
 .../Checkers/PolymorphicPtrArithmetic.cpp | 180 ++
 .../Analysis/PolymorphicPtrArithmetic.cpp | 141 ++
 5 files changed, 360 insertions(+)
 create mode 100644 
clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
 create mode 100644 clang/test/Analysis/PolymorphicPtrArithmetic.cpp

diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 510629d8a2d480..5d000dbc03181d 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -581,6 +581,39 @@ store combinations of flag values:
 
 Projects that use this pattern should not enable this optin checker.
 
+.. _optin-cplusplus-PolymorphicPtrArithmetic:
+
+optin.cplusplus.PolymorphicPtrArithmetic (C++)
+""
+
+This checker reports pointer arithmetic operations on arrays of polymorphic
+objects, where the array has the type of its base class.
+Deleting an array where the array's static type is different from its dynamic
+type is undefined.
+
+This checker corresponds to the CERT rule `CTR56-CPP: Do not use pointer 
arithmetic on polymorphic objects 
`_.
+
+.. code-block:: cpp
+
+ class Base {
+ public:
+   int member = 0;
+   virtual ~Base() {}
+ };
+ class Derived : public Base {}
+
+ Base *create() {
+   Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
+   return x;
+ }
+
+ void foo() {
+   Base *x = create();
+   (x + 3)->member += 1; // warn: Doing pointer arithmetic with 'Derived' 
objects as their base class 'Base' is undefined
+   x[3].member += 1;  // warn: Doing pointer arithmetic with 'Derived' objects 
as their base class 'Base' is undefined
+   delete[] static_cast(x);
+ }
+
 .. _optin-cplusplus-UninitializedObject:
 
 optin.cplusplus.UninitializedObject (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..85ffe6f42cf40e 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -706,6 +706,11 @@ def PureVirtualCallChecker : Checker<"PureVirtualCall">,
 
 let ParentPackage = CplusplusOptIn in {
 
+def PolymorphicPtrArithmeticChecker : Checker<"PolymorphicPtrArithmetic">,
+  HelpText<"Reports doing pointer arithmetic on arrays of polymorphic objects "
+   "with the type of their base class">,
+  Documentation;
+
 def UninitializedObjectChecker: Checker<"UninitializedObject">,
   HelpText<"Reports uninitialized fields after object construction">,
   CheckerOptions<[
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..a29b36a04cf064 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   ContainerModeling.cpp
   ConversionChecker.cpp
   CXXDeleteChecker.cpp
+  PolymorphicPtrArithmetic.cpp
   CXXSelfAssignmentChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp 
b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
new file mode 100644
index 00..1e8dfff74738d5
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
@@ -0,0 +1,180 @@
+//=== PolymorphicPtrArithmetic.cpp --*- 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
+//
+//===--===//
+//
+// This checker reports pointer arithmetic operations on arrays of
+// polymorphic objects, where the array has

[clang] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker (PR #82977)

2024-02-26 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

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

Author: Discookie (Discookie)


Changes

This checker reports cases where an array of polymorphic objects are deleted as 
their base class.
Deleting an array where the array's static type is different from its dynamic 
type is undefined.

Similar in structure to `alpha.cplusplus.ArrayDelete`.

This checker corresponds to the SEI Cert rule [CTR56-CPP: Do not use pointer 
arithmetic on polymorphic 
objects](https://wiki.sei.cmu.edu/confluence/display/cplusplus/CTR56-CPP.+Do+not+use+pointer+arithmetic+on+polymorphic+objects).

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


5 Files Affected:

- (modified) clang/docs/analyzer/checkers.rst (+33) 
- (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+5) 
- (modified) clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt (+1) 
- (added) clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp (+180) 
- (added) clang/test/Analysis/PolymorphicPtrArithmetic.cpp (+141) 


``diff
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 510629d8a2d480..5d000dbc03181d 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -581,6 +581,39 @@ store combinations of flag values:
 
 Projects that use this pattern should not enable this optin checker.
 
+.. _optin-cplusplus-PolymorphicPtrArithmetic:
+
+optin.cplusplus.PolymorphicPtrArithmetic (C++)
+""
+
+This checker reports pointer arithmetic operations on arrays of polymorphic
+objects, where the array has the type of its base class.
+Deleting an array where the array's static type is different from its dynamic
+type is undefined.
+
+This checker corresponds to the CERT rule `CTR56-CPP: Do not use pointer 
arithmetic on polymorphic objects 
`_.
+
+.. code-block:: cpp
+
+ class Base {
+ public:
+   int member = 0;
+   virtual ~Base() {}
+ };
+ class Derived : public Base {}
+
+ Base *create() {
+   Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
+   return x;
+ }
+
+ void foo() {
+   Base *x = create();
+   (x + 3)->member += 1; // warn: Doing pointer arithmetic with 'Derived' 
objects as their base class 'Base' is undefined
+   x[3].member += 1;  // warn: Doing pointer arithmetic with 'Derived' objects 
as their base class 'Base' is undefined
+   delete[] static_cast(x);
+ }
+
 .. _optin-cplusplus-UninitializedObject:
 
 optin.cplusplus.UninitializedObject (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..85ffe6f42cf40e 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -706,6 +706,11 @@ def PureVirtualCallChecker : Checker<"PureVirtualCall">,
 
 let ParentPackage = CplusplusOptIn in {
 
+def PolymorphicPtrArithmeticChecker : Checker<"PolymorphicPtrArithmetic">,
+  HelpText<"Reports doing pointer arithmetic on arrays of polymorphic objects "
+   "with the type of their base class">,
+  Documentation;
+
 def UninitializedObjectChecker: Checker<"UninitializedObject">,
   HelpText<"Reports uninitialized fields after object construction">,
   CheckerOptions<[
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..a29b36a04cf064 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   ContainerModeling.cpp
   ConversionChecker.cpp
   CXXDeleteChecker.cpp
+  PolymorphicPtrArithmetic.cpp
   CXXSelfAssignmentChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp 
b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
new file mode 100644
index 00..1e8dfff74738d5
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
@@ -0,0 +1,180 @@
+//=== PolymorphicPtrArithmetic.cpp --*- 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
+//
+//===--===//
+//
+// This checker reports pointer arithmetic operations on arrays of
+// polymorphic objects, where the array has the type of its base class.
+// Corresponds to the CTR56-CPP. Do not use pointer arithmetic on
+// polymorphic objects
+//
+//===--===//
+

[clang] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker (PR #82977)

2024-02-26 Thread via cfe-commits

https://github.com/Discookie updated 
https://github.com/llvm/llvm-project/pull/82977

>From 1454b5bb4fad03b043c25a64c8c4f4495e17a316 Mon Sep 17 00:00:00 2001
From: Viktor 
Date: Mon, 26 Feb 2024 10:06:01 +
Subject: [PATCH] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker

---
 clang/docs/analyzer/checkers.rst  |  33 
 .../clang/StaticAnalyzer/Checkers/Checkers.td |   5 +
 .../StaticAnalyzer/Checkers/CMakeLists.txt|   1 +
 .../Checkers/PolymorphicPtrArithmetic.cpp | 178 ++
 .../Analysis/PolymorphicPtrArithmetic.cpp | 141 ++
 5 files changed, 358 insertions(+)
 create mode 100644 
clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
 create mode 100644 clang/test/Analysis/PolymorphicPtrArithmetic.cpp

diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 510629d8a2d480..5d000dbc03181d 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -581,6 +581,39 @@ store combinations of flag values:
 
 Projects that use this pattern should not enable this optin checker.
 
+.. _optin-cplusplus-PolymorphicPtrArithmetic:
+
+optin.cplusplus.PolymorphicPtrArithmetic (C++)
+""
+
+This checker reports pointer arithmetic operations on arrays of polymorphic
+objects, where the array has the type of its base class.
+Deleting an array where the array's static type is different from its dynamic
+type is undefined.
+
+This checker corresponds to the CERT rule `CTR56-CPP: Do not use pointer 
arithmetic on polymorphic objects 
`_.
+
+.. code-block:: cpp
+
+ class Base {
+ public:
+   int member = 0;
+   virtual ~Base() {}
+ };
+ class Derived : public Base {}
+
+ Base *create() {
+   Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
+   return x;
+ }
+
+ void foo() {
+   Base *x = create();
+   (x + 3)->member += 1; // warn: Doing pointer arithmetic with 'Derived' 
objects as their base class 'Base' is undefined
+   x[3].member += 1;  // warn: Doing pointer arithmetic with 'Derived' objects 
as their base class 'Base' is undefined
+   delete[] static_cast(x);
+ }
+
 .. _optin-cplusplus-UninitializedObject:
 
 optin.cplusplus.UninitializedObject (C++)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index e7774e5a9392d2..85ffe6f42cf40e 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -706,6 +706,11 @@ def PureVirtualCallChecker : Checker<"PureVirtualCall">,
 
 let ParentPackage = CplusplusOptIn in {
 
+def PolymorphicPtrArithmeticChecker : Checker<"PolymorphicPtrArithmetic">,
+  HelpText<"Reports doing pointer arithmetic on arrays of polymorphic objects "
+   "with the type of their base class">,
+  Documentation;
+
 def UninitializedObjectChecker: Checker<"UninitializedObject">,
   HelpText<"Reports uninitialized fields after object construction">,
   CheckerOptions<[
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 4443ffd0929388..a29b36a04cf064 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   ContainerModeling.cpp
   ConversionChecker.cpp
   CXXDeleteChecker.cpp
+  PolymorphicPtrArithmetic.cpp
   CXXSelfAssignmentChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp 
b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
new file mode 100644
index 00..dfa71e1cfd2ef7
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/PolymorphicPtrArithmetic.cpp
@@ -0,0 +1,178 @@
+//=== PolymorphicPtrArithmetic.cpp --*- 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
+//
+//===--===//
+//
+// This checker reports pointer arithmetic operations on arrays of
+// polymorphic objects, where the array has the type of its base class.
+// Corresponds to the CTR56-CPP. Do not use pointer arithmetic on
+// polymorphic objects
+//
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "cla

[clang] [Driver] Improve error when a compiler-rt library is not found (PR #81037)

2024-02-26 Thread Martin Storsjö via cfe-commits

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

LGTM, thanks.

In principle, we're just trading surprises in one case into surprises in 
another case, but I guess this case is the one with more non-obvious details 
(and this can be argued is the future direction we should be heading towards, 
even if I'm not personally a huge fan of it), so it seems reasonable and 
valuable.

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


[clang] [TBAA] Skip all bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 Thread Florian Hahn via cfe-commits

https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/82922

>From 556fcefed9645aa0a0a965ff8f22d8accdf9eefc Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Sun, 25 Feb 2024 13:23:17 +
Subject: [PATCH 1/2] [TBAA] Skip all bitfields when generating !tbaa.struct
 metadata.

At the moment, clang generates what I believe are incorrect !tbaa.struct
fields for named bitfields. At the moment, the base type size is used
for named bifields (e.g. sizeof(int)) instead of the bifield width per
field. This results in overalpping fields in !tbaa.struct metadata.

This causes incorrect results when extracting individual copied fields
from !tbaa.struct as in added in dc85719d5.

This patch fixes that by skipping all bitfields, not only unnamed ones
(note that CollectFields has a TODO to support bitfields). As bitfields
specify their widths in bits, while !tbaa metadata uses bytes for sizes
and offsets, I don't think we would be able to generate correct metadata
for them in general.

If this understanding is correct, I can also extend the verifier to
check that !tbaa.struct fields aren't overlapping.

Fixes https://github.com/llvm/llvm-project/issues/82586
---
 clang/lib/CodeGen/CodeGenTBAA.cpp  | 2 +-
 clang/test/CodeGen/tbaa-struct.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index dc288bc3f6157a..43a1aee3d73823 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -298,7 +298,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
 unsigned idx = 0;
 for (RecordDecl::field_iterator i = RD->field_begin(),
  e = RD->field_end(); i != e; ++i, ++idx) {
-  if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
+  if ((*i)->isZeroSize(Context) || (*i)->isBitField())
 continue;
   uint64_t Offset = BaseOffset +
 Layout.getFieldOffset(idx) / Context.getCharWidth();
diff --git a/clang/test/CodeGen/tbaa-struct.cpp 
b/clang/test/CodeGen/tbaa-struct.cpp
index ff5521fcf3f604..17c9d6bf6a7260 100644
--- a/clang/test/CodeGen/tbaa-struct.cpp
+++ b/clang/test/CodeGen/tbaa-struct.cpp
@@ -130,7 +130,7 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) {
 // CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, 
i64 8, !{{.*}}}
 // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, 
[[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]}
 // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, 
[[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]}
-// CHECK-OLD: [[TS6]] = !{i64 0, i64 4, [[TAG_INT]], i64 1, i64 4, 
[[TAG_INT]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]}
+// CHECK-OLD: [[TS6]] = !{i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, 
[[TAG_DOUBLE:!.+]]}
 // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0}
 // CHECK-OLD  [[DOUBLE]] = !{!"double", [[CHAR]], i64 0}
 

>From 32be3b7d944fc5da50add4b6fea551ba6c9d428c Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Mon, 26 Feb 2024 10:19:57 +
Subject: [PATCH 2/2] WIP use CGBitFieldInfo.

---
 clang/lib/CodeGen/CodeGenModule.cpp |  2 +-
 clang/lib/CodeGen/CodeGenTBAA.cpp   | 33 +++--
 clang/lib/CodeGen/CodeGenTBAA.h |  4 +++-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 95e457bef28ed3..ed8db055723024 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -397,7 +397,7 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
   if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
   (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
-TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(),
+TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, 
getLangOpts(),
getCXXABI().getMangleContext()));
 
   // If debug info or coverage generation is enabled, create the CGDebugInfo
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 43a1aee3d73823..6a453bb1144582 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -14,6 +14,8 @@
 //
 
//===--===//
 
+#include "CGRecordLayout.h"
+#include "CodeGenTypes.h"
 #include "CodeGenTBAA.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -29,10 +31,10 @@
 using namespace clang;
 using namespace CodeGen;
 
-CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module 
&M,
  const CodeGenOptions &CGO,
  const LangOptions &Features, MangleContext &MContext)
-  : Contex

[clang] [TBAA] Skip all bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 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 8c5e9cf737138aba22a4a8f64ef2c5efc80dd7f9 
32be3b7d944fc5da50add4b6fea551ba6c9d428c -- clang/lib/CodeGen/CodeGenModule.cpp 
clang/lib/CodeGen/CodeGenTBAA.cpp clang/lib/CodeGen/CodeGenTBAA.h 
clang/test/CodeGen/tbaa-struct.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index ed8db05572..11b407e2b1 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -397,8 +397,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
   if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
   (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
-TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, 
getLangOpts(),
-   getCXXABI().getMangleContext()));
+TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts,
+   getLangOpts(), getCXXABI().getMangleContext()));
 
   // If debug info or coverage generation is enabled, create the CGDebugInfo
   // object.
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 6a453bb114..5793e0df33 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -14,9 +14,9 @@
 //
 
//===--===//
 
+#include "CodeGenTBAA.h"
 #include "CGRecordLayout.h"
 #include "CodeGenTypes.h"
-#include "CodeGenTBAA.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/Mangle.h"
@@ -31,13 +31,12 @@
 using namespace clang;
 using namespace CodeGen;
 
-CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module 
&M,
- const CodeGenOptions &CGO,
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes,
+ llvm::Module &M, const CodeGenOptions &CGO,
  const LangOptions &Features, MangleContext &MContext)
-  : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
-Features(Features), MContext(MContext), MDHelper(M.getContext()),
-Root(nullptr), Char(nullptr)
-{}
+: Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
+  Features(Features), MContext(MContext), MDHelper(M.getContext()),
+  Root(nullptr), Char(nullptr) {}
 
 CodeGenTBAA::~CodeGenTBAA() {
 }
@@ -316,17 +315,18 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
   j++;
 }
 uint64_t Offset = BaseOffset;
-uint64_t Size = llvm::divideCeil(CurrentBitFieldSize , 8);
+uint64_t Size = llvm::divideCeil(CurrentBitFieldSize, 8);
 llvm::MDNode *TBAAType = getChar();
-llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, 
Size));
-Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, 
TBAATag));
+llvm::MDNode *TBAATag =
+getAccessTagInfo(TBAAAccessInfo(TBAAType, Size));
+Fields.push_back(
+llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
 i = std::prev(j);
   } else {
 if (!CollectFields(Offset, FieldQTy, Fields,
MayAlias || TypeHasMayAlias(FieldQTy)))
   return false;
-
-}
+  }
 }
 return true;
   }
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index 7e315c285b..aa6da2731a 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -29,7 +29,7 @@ namespace clang {
   class Type;
 
 namespace CodeGen {
-  class CodeGenTypes;
+class CodeGenTypes;
 
 // TBAAAccessKind - A kind of TBAA memory access descriptor.
 enum class TBAAAccessKind : unsigned {
@@ -169,8 +169,9 @@ class CodeGenTBAA {
   llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
 
 public:
-  CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const 
CodeGenOptions &CGO,
-  const LangOptions &Features, MangleContext &MContext);
+  CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M,
+  const CodeGenOptions &CGO, const LangOptions &Features,
+  MangleContext &MContext);
   ~CodeGenTBAA();
 
   /// getTypeInfo - Get metadata used to describe accesses to objects of the

``




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


[clang] [clang] Refactor target attribute mangling. (PR #81893)

2024-02-26 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea updated 
https://github.com/llvm/llvm-project/pull/81893

>From 20734a17b90e4b425aa86f152777301cda810e63 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Thu, 15 Feb 2024 15:53:51 +
Subject: [PATCH] [clang] Refactor target attribute mangling.

Before this patch all of the 'target', 'target_version' and 'target_clones'
attributes were sharing a common mangling logic across different targets.
However we would like to differenciate this logic, therefore I have moved
the default path to ABIInfo and provided overrides for AArch64. This
way we can resolve feature aliases without affecting the name mangling
The PR #80540 demonstrates a motivating case.
---
 clang/lib/CodeGen/ABIInfo.cpp |  51 
 clang/lib/CodeGen/ABIInfo.h   |   8 ++
 clang/lib/CodeGen/CodeGenModule.cpp   | 111 --
 clang/lib/CodeGen/Targets/AArch64.cpp |  34 
 4 files changed, 109 insertions(+), 95 deletions(-)

diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp
index 1b56cf7c596d06..7eb0b2e31159b9 100644
--- a/clang/lib/CodeGen/ABIInfo.cpp
+++ b/clang/lib/CodeGen/ABIInfo.cpp
@@ -184,6 +184,57 @@ ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType 
Ty,
   /*ByVal*/ false, Realign);
 }
 
+std::string ABIInfo::getManglingSuffixFromAttr(TargetAttr *Attr) const {
+  if (Attr->isDefaultVersion())
+return {};
+
+  return getManglingSuffixFromStr(Attr->getFeaturesStr());
+}
+
+std::string ABIInfo::getManglingSuffixFromAttr(TargetVersionAttr *Attr) const {
+  return getManglingSuffixFromStr(Attr->getNamesStr());
+}
+
+std::string ABIInfo::getManglingSuffixFromAttr(TargetClonesAttr *Attr,
+   unsigned Index) const {
+  std::string Suffix = getManglingSuffixFromStr(Attr->getFeatureStr(Index));
+  Suffix.append("." + Twine(Attr->getMangledIndex(Index)).str());
+  return Suffix;
+}
+
+std::string ABIInfo::getManglingSuffixFromStr(StringRef AttrStr) const {
+  if (AttrStr == "default")
+return ".default";
+
+  std::string ManglingSuffix(".");
+  const TargetInfo &TI = CGT.getTarget();
+  ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
+
+  llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
+// Multiversioning doesn't allow "no-${feature}", so we can
+// only have "+" prefixes here.
+assert(LHS.starts_with("+") && RHS.starts_with("+") &&
+   "Features should always have a prefix.");
+return TI.multiVersionSortPriority(LHS.substr(1)) >
+   TI.multiVersionSortPriority(RHS.substr(1));
+  });
+
+  bool IsFirst = true;
+  if (!Info.CPU.empty()) {
+IsFirst = false;
+ManglingSuffix.append(Twine("arch_", Info.CPU).str());
+  }
+
+  for (StringRef Feat : Info.Features) {
+if (!IsFirst)
+  ManglingSuffix.append("_");
+IsFirst = false;
+ManglingSuffix.append(Feat.substr(1).str());
+  }
+
+  return ManglingSuffix;
+}
+
 // Pin the vtable to this file.
 SwiftABIInfo::~SwiftABIInfo() = default;
 
diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h
index b9a5ef6e436693..56b4a89d2507f1 100644
--- a/clang/lib/CodeGen/ABIInfo.h
+++ b/clang/lib/CodeGen/ABIInfo.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
 #define LLVM_CLANG_LIB_CODEGEN_ABIINFO_H
 
+#include "clang/AST/Attr.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/Type.h"
 #include "llvm/IR/CallingConv.h"
@@ -111,6 +112,13 @@ class ABIInfo {
 
   CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty,
bool Realign = false) const;
+
+  virtual std::string getManglingSuffixFromAttr(TargetAttr *Attr) const;
+  virtual std::string getManglingSuffixFromAttr(TargetVersionAttr *Attr) const;
+  virtual std::string getManglingSuffixFromAttr(TargetClonesAttr *Attr,
+unsigned VersionIndex) const;
+
+  virtual std::string getManglingSuffixFromStr(StringRef AttrStr) const;
 };
 
 /// Target specific hooks for defining how a type should be passed or returned
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 95e457bef28ed3..e9bbc2706a693c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1726,59 +1726,6 @@ static void AppendCPUSpecificCPUDispatchMangling(const 
CodeGenModule &CGM,
 Out << ".resolver";
 }
 
-static void AppendTargetVersionMangling(const CodeGenModule &CGM,
-const TargetVersionAttr *Attr,
-raw_ostream &Out) {
-  if (Attr->isDefaultVersion()) {
-Out << ".default";
-return;
-  }
-  Out << "._";
-  const TargetInfo &TI = CGM.getTarget();
-  llvm::SmallVector Feats;
-  Attr->getFeatures(Feats);
-  llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) 
{
-return TI.multiVersionSortPriori

[clang-tools-extra] [clang-tidy] Improved modernize-use-using by fixing a false-negative (PR #82947)

2024-02-26 Thread Félix-Antoine Constantin via cfe-commits

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


[clang] a5ccf85 - [clang][Interp] Not all RVO call expressions are initializing

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T11:40:58+01:00
New Revision: a5ccf8522b96c56fc6bda54cf68a64c5d65b75cb

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

LOG: [clang][Interp] Not all RVO call expressions are initializing

We do not necessarily prepare storage for the return value when
we are returning a complex value.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 49ba8e95f17995..b5402ec8caaec6 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2703,7 +2703,14 @@ bool ByteCodeExprGen::VisitCallExpr(const 
CallExpr *E) {
   return false;
   }
 } else {
-  assert(Initializing);
+  // We need the result. Prepare a pointer to return or
+  // dup the current one.
+  if (!Initializing) {
+if (std::optional LocalIndex = allocateLocal(E)) {
+  if (!this->emitGetPtrLocal(*LocalIndex, E))
+return false;
+}
+  }
   if (!this->emitDupPtr(E))
 return false;
 }

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index 2b65ccf9946e70..b6091d90867a01 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -124,6 +124,12 @@ void func(void) {
   result = arr * ii;
 }
 
+constexpr _Complex float getComplexFloat() {
+  return {1,2};
+}
+static_assert(__real(getComplexFloat()) == 1, "");
+static_assert(__imag(getComplexFloat()) == 2, "");
+
 namespace CastToBool {
   constexpr _Complex int F = {0, 1};
   static_assert(F, "");



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


[clang] [clang] Refactor target attribute mangling. (PR #81893)

2024-02-26 Thread Alexandros Lamprineas via cfe-commits

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


[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-26 Thread via cfe-commits

https://github.com/martinboehme created 
https://github.com/llvm/llvm-project/pull/82986

This fixes a crash introduced by https://github.com/llvm/llvm-project/pull/82348
but also adds additional handling to make sure that we treat empty initializer
lists for both unions and structs/classes correctly (see tests added in this
patch).

>From a48dc2e9a481ba5ed5d801a59c1dbc23fe0092d1 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Mon, 26 Feb 2024 11:41:08 +
Subject: [PATCH] [clang][dataflow] Correctly treat empty initializer lists for
 unions.

This fixes a crash introduced by https://github.com/llvm/llvm-project/pull/82348
but also adds additional handling to make sure that we treat empty initializer
lists for both unions and structs/classes correctly (see tests added in this
patch).
---
 .../FlowSensitive/DataflowEnvironment.cpp |  7 +-
 clang/lib/Analysis/FlowSensitive/Transfer.cpp | 15 +++-
 .../Analysis/FlowSensitive/TransferTest.cpp   | 68 ++-
 3 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 0cfc26ea952cda..fd7b06efcc7861 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -983,7 +983,7 @@ StorageLocation &Environment::createObjectInternal(const 
ValueDecl *D,
   }
 
   Value *Val = nullptr;
-  if (InitExpr)
+  if (InitExpr) {
 // In the (few) cases where an expression is intentionally
 // "uninterpreted", `InitExpr` is not associated with a value.  There are
 // two ways to handle this situation: propagate the status, so that
@@ -998,6 +998,11 @@ StorageLocation &Environment::createObjectInternal(const 
ValueDecl *D,
 // default value (assuming we don't update the environment API to return
 // references).
 Val = getValue(*InitExpr);
+
+if (!Val && isa(InitExpr) &&
+InitExpr->getType()->isPointerType())
+  Val = 
&getOrCreateNullPointerValue(InitExpr->getType()->getPointeeType());
+  }
   if (!Val)
 Val = createValue(Ty);
 
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp 
b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index cd1f04e53cff68..d73965806a533f 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -685,9 +685,22 @@ class TransferVisitor : public 
ConstStmtVisitor {
 
 // `S->inits()` contains all the initializer expressions, including the
 // ones for direct base classes.
-auto Inits = S->inits();
+ArrayRef Inits = S->inits();
 size_t InitIdx = 0;
 
+// Unions initialized with an empty initializer list need special 
treatment.
+// For structs/classes initialized with an empty initializer list, Clang
+// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for 
unions,
+// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
+std::optional ImplicitValueInitForUnion;
+SmallVector InitsForUnion;
+if (S->getType()->isUnionType() && Inits.empty()) {
+  assert(FieldsForInit.size() == 1);
+  ImplicitValueInitForUnion.emplace(FieldsForInit.front()->getType());
+  InitsForUnion.push_back(&*ImplicitValueInitForUnion);
+  Inits = InitsForUnion;
+}
+
 // Initialize base classes.
 if (auto* R = S->getType()->getAsCXXRecordDecl()) {
   assert(FieldsForInit.size() + R->getNumBases() == Inits.size());
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index e7d74581865a32..2eb9a37f289426 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2393,8 +2393,72 @@ TEST(TransferTest, InitListExprAsUnion) {
 auto &FLoc = getFieldLoc(
 *Env.getThisPointeeStorageLocation(), "F", ASTCtx);
 auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
-ASSERT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
-ASSERT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForUnion) {
+  // This is a crash repro.
+  std::string Code = R"cc(
+class target {
+  union {
+int *a;
+bool *b;
+  } F;
+
+ public:
+  constexpr target() : F{} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
+};
+  )cc";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTC

[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (martinboehme)


Changes

This fixes a crash introduced by https://github.com/llvm/llvm-project/pull/82348
but also adds additional handling to make sure that we treat empty initializer
lists for both unions and structs/classes correctly (see tests added in this
patch).

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


3 Files Affected:

- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+6-1) 
- (modified) clang/lib/Analysis/FlowSensitive/Transfer.cpp (+14-1) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+66-2) 


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 0cfc26ea952cda..fd7b06efcc7861 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -983,7 +983,7 @@ StorageLocation &Environment::createObjectInternal(const 
ValueDecl *D,
   }
 
   Value *Val = nullptr;
-  if (InitExpr)
+  if (InitExpr) {
 // In the (few) cases where an expression is intentionally
 // "uninterpreted", `InitExpr` is not associated with a value.  There are
 // two ways to handle this situation: propagate the status, so that
@@ -998,6 +998,11 @@ StorageLocation &Environment::createObjectInternal(const 
ValueDecl *D,
 // default value (assuming we don't update the environment API to return
 // references).
 Val = getValue(*InitExpr);
+
+if (!Val && isa(InitExpr) &&
+InitExpr->getType()->isPointerType())
+  Val = 
&getOrCreateNullPointerValue(InitExpr->getType()->getPointeeType());
+  }
   if (!Val)
 Val = createValue(Ty);
 
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp 
b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index cd1f04e53cff68..d73965806a533f 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -685,9 +685,22 @@ class TransferVisitor : public 
ConstStmtVisitor {
 
 // `S->inits()` contains all the initializer expressions, including the
 // ones for direct base classes.
-auto Inits = S->inits();
+ArrayRef Inits = S->inits();
 size_t InitIdx = 0;
 
+// Unions initialized with an empty initializer list need special 
treatment.
+// For structs/classes initialized with an empty initializer list, Clang
+// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for 
unions,
+// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
+std::optional ImplicitValueInitForUnion;
+SmallVector InitsForUnion;
+if (S->getType()->isUnionType() && Inits.empty()) {
+  assert(FieldsForInit.size() == 1);
+  ImplicitValueInitForUnion.emplace(FieldsForInit.front()->getType());
+  InitsForUnion.push_back(&*ImplicitValueInitForUnion);
+  Inits = InitsForUnion;
+}
+
 // Initialize base classes.
 if (auto* R = S->getType()->getAsCXXRecordDecl()) {
   assert(FieldsForInit.size() + R->getNumBases() == Inits.size());
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index e7d74581865a32..2eb9a37f289426 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2393,8 +2393,72 @@ TEST(TransferTest, InitListExprAsUnion) {
 auto &FLoc = getFieldLoc(
 *Env.getThisPointeeStorageLocation(), "F", ASTCtx);
 auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
-ASSERT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
-ASSERT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForUnion) {
+  // This is a crash repro.
+  std::string Code = R"cc(
+class target {
+  union {
+int *a;
+bool *b;
+  } F;
+
+ public:
+  constexpr target() : F{} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
+};
+  )cc";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForStruct) {
+  std::string Code = R"cc(
+class target {
+  struct {
+int *a;
+bool *b;
+  

[clang] Revert "[clang][dataflow] Correctly handle `InitListExpr` of union type." (PR #82856)

2024-02-26 Thread via cfe-commits

martinboehme wrote:

I see you haven't merged this revert yet.

Alternatively, here's a fix-forward, if you're prepared to go with that:

https://github.com/llvm/llvm-project/pull/82986

Otherwise, do of course merge the revert, and I'll reland with the fix-forward 
incorporated.

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


[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)

2024-02-26 Thread via cfe-commits

https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82673

>From e0b1af2589f2bbb12e57ac72d6280cf6545c93ae Mon Sep 17 00:00:00 2001
From: AMS21 
Date: Thu, 22 Feb 2024 19:24:43 +0100
Subject: [PATCH] [clang-tidy] Let `bugprone-use-after-move` also handle calls
 to `std::forward`

Fixes #82023
---
 .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 57 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 ++
 .../checks/bugprone/use-after-move.rst| 12 
 .../checkers/bugprone/use-after-move.cpp  | 37 
 4 files changed, 95 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
index c5b6b541096ca9..b91ad0f1822955 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -330,7 +330,8 @@ void UseAfterMoveFinder::getReinits(
 traverse(TK_AsIs, DeclRefMatcher),
 unless(parmVarDecl(hasType(
 references(qualType(isConstQualified())),
-unless(callee(functionDecl(hasName("::std::move")))
+unless(callee(functionDecl(
+hasAnyName("::std::move", "::std::forward")))
   .bind("reinit");
 
   Stmts->clear();
@@ -359,24 +360,46 @@ void UseAfterMoveFinder::getReinits(
   }
 }
 
+enum class MoveType {
+  Move,// std::move
+  Forward, // std::forward
+};
+
+static MoveType determineMoveType(const FunctionDecl *FuncDecl) {
+  if (FuncDecl->getName() == "move")
+return MoveType::Move;
+  if (FuncDecl->getName() == "forward")
+return MoveType::Forward;
+
+  llvm_unreachable("Invalid move type");
+}
+
 static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg,
const UseAfterMove &Use, ClangTidyCheck *Check,
-   ASTContext *Context) {
-  SourceLocation UseLoc = Use.DeclRef->getExprLoc();
-  SourceLocation MoveLoc = MovingCall->getExprLoc();
+   ASTContext *Context, MoveType Type) {
+  const SourceLocation UseLoc = Use.DeclRef->getExprLoc();
+  const SourceLocation MoveLoc = MovingCall->getExprLoc();
+
+  const bool IsMove = (Type == MoveType::Move);
 
-  Check->diag(UseLoc, "'%0' used after it was moved")
-  << MoveArg->getDecl()->getName();
-  Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note);
+  Check->diag(UseLoc, "'%0' used after it was %select{forwarded|moved}1")
+  << MoveArg->getDecl()->getName() << IsMove;
+  Check->diag(MoveLoc, "%select{forward|move}0 occurred here",
+  DiagnosticIDs::Note)
+  << IsMove;
   if (Use.EvaluationOrderUndefined) {
-Check->diag(UseLoc,
-"the use and move are unsequenced, i.e. there is no guarantee "
-"about the order in which they are evaluated",
-DiagnosticIDs::Note);
+Check->diag(
+UseLoc,
+"the use and %select{forward|move}0 are unsequenced, i.e. "
+"there is no guarantee about the order in which they are evaluated",
+DiagnosticIDs::Note)
+<< IsMove;
   } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) {
 Check->diag(UseLoc,
-"the use happens in a later loop iteration than the move",
-DiagnosticIDs::Note);
+"the use happens in a later loop iteration than the "
+"%select{forward|move}0",
+DiagnosticIDs::Note)
+<< IsMove;
   }
 }
 
@@ -388,7 +411,9 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder 
*Finder) {
   auto TryEmplaceMatcher =
   cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace";
   auto CallMoveMatcher =
-  callExpr(argumentCountIs(1), 
callee(functionDecl(hasName("::std::move"))),
+  callExpr(argumentCountIs(1),
+   callee(functionDecl(hasAnyName("::std::move", "::std::forward"))
+  .bind("move-decl")),
hasArgument(0, declRefExpr().bind("arg")),
unless(inDecltypeOrTemplateArg()),
unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"),
@@ -436,6 +461,7 @@ void UseAfterMoveCheck::check(const 
MatchFinder::MatchResult &Result) {
   const auto *CallMove = Result.Nodes.getNodeAs("call-move");
   const auto *MovingCall = Result.Nodes.getNodeAs("moving-call");
   const auto *Arg = Result.Nodes.getNodeAs("arg");
+  const auto *MoveDecl = Result.Nodes.getNodeAs("move-decl");
 
   if (!MovingCall || !MovingCall->getExprLoc().isValid())
 MovingCall = CallMove;
@@ -470,7 +496,8 @@ void UseAfterMoveCheck::check(const 
MatchFinder::MatchResult &Result) {
 UseAfterMoveFinder Finder(Result.Context);
 UseAfterMove Use;
 if (Finder.find(CodeBlock, MovingCall, Arg->getDecl(), &Use))
-  e

[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)

2024-02-26 Thread via cfe-commits

AMS21 wrote:

Rebased and implemented review suggestions

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


[clang] [clang][Sema] Simplify err_init_conversion_failed diagnostic message for const variables (PR #82109)

2024-02-26 Thread Artem Tyurin via cfe-commits

agentcooper wrote:

@cjdb Hey Christopher, I'm curious to hear your thoughts on this change.

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


[clang] [llvm] [LLVM][TypeSize] Remove default constructor. (PR #82810)

2024-02-26 Thread Paul Walker via cfe-commits

https://github.com/paulwalker-arm updated 
https://github.com/llvm/llvm-project/pull/82810

>From a4c46459564bd8a8e5ca2a56fa643f866b7e869a Mon Sep 17 00:00:00 2001
From: Paul Walker 
Date: Fri, 23 Feb 2024 18:26:10 +
Subject: [PATCH] [LLVM][TypeSize] Remove default constructor.

---
 clang/lib/CodeGen/CGCall.cpp| 15 ++-
 llvm/include/llvm/Support/TypeSize.h|  2 --
 llvm/unittests/Support/TypeSizeTest.cpp |  1 -
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d05cf1c6e1814e..0d86fcf544d0fd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3221,12 +3221,10 @@ void CodeGenFunction::EmitFunctionProlog(const 
CGFunctionInfo &FI,
 
   llvm::StructType *STy =
   dyn_cast(ArgI.getCoerceToType());
-  llvm::TypeSize StructSize;
-  llvm::TypeSize PtrElementSize;
   if (ArgI.isDirect() && !ArgI.getCanBeFlattened() && STy &&
   STy->getNumElements() > 1) {
-StructSize = CGM.getDataLayout().getTypeAllocSize(STy);
-PtrElementSize =
+llvm::TypeSize StructSize = CGM.getDataLayout().getTypeAllocSize(STy);
+llvm::TypeSize PtrElementSize =
 CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(Ty));
 if (STy->containsHomogeneousScalableVectorTypes()) {
   assert(StructSize == PtrElementSize &&
@@ -5310,12 +5308,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
 
   llvm::StructType *STy =
   dyn_cast(ArgInfo.getCoerceToType());
-  llvm::Type *SrcTy = ConvertTypeForMem(I->Ty);
-  llvm::TypeSize SrcTypeSize;
-  llvm::TypeSize DstTypeSize;
   if (STy && ArgInfo.isDirect() && !ArgInfo.getCanBeFlattened()) {
-SrcTypeSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
-DstTypeSize = CGM.getDataLayout().getTypeAllocSize(STy);
+llvm::Type *SrcTy = ConvertTypeForMem(I->Ty);
+llvm::TypeSize SrcTypeSize =
+CGM.getDataLayout().getTypeAllocSize(SrcTy);
+llvm::TypeSize DstTypeSize = CGM.getDataLayout().getTypeAllocSize(STy);
 if (STy->containsHomogeneousScalableVectorTypes()) {
   assert(SrcTypeSize == DstTypeSize &&
  "Only allow non-fractional movement of structure with "
diff --git a/llvm/include/llvm/Support/TypeSize.h 
b/llvm/include/llvm/Support/TypeSize.h
index 1b793b0eccf3c7..68dbe1ea3062ab 100644
--- a/llvm/include/llvm/Support/TypeSize.h
+++ b/llvm/include/llvm/Support/TypeSize.h
@@ -321,8 +321,6 @@ class TypeSize : public 
details::FixedOrScalableQuantity {
   : FixedOrScalableQuantity(V) {}
 
 public:
-  constexpr TypeSize() : FixedOrScalableQuantity(0, false) {}
-
   constexpr TypeSize(ScalarTy Quantity, bool Scalable)
   : FixedOrScalableQuantity(Quantity, Scalable) {}
 
diff --git a/llvm/unittests/Support/TypeSizeTest.cpp 
b/llvm/unittests/Support/TypeSizeTest.cpp
index 34fe376989e7ba..b02b7e60095359 100644
--- a/llvm/unittests/Support/TypeSizeTest.cpp
+++ b/llvm/unittests/Support/TypeSizeTest.cpp
@@ -81,7 +81,6 @@ static_assert(INT64_C(2) * TSFixed32 == 
TypeSize::getFixed(64));
 static_assert(UINT64_C(2) * TSFixed32 == TypeSize::getFixed(64));
 static_assert(alignTo(TypeSize::getFixed(7), 8) == TypeSize::getFixed(8));
 
-static_assert(TypeSize() == TypeSize::getFixed(0));
 static_assert(TypeSize::getZero() == TypeSize::getFixed(0));
 static_assert(TypeSize::getZero() != TypeSize::getScalable(0));
 static_assert(TypeSize::getFixed(0) != TypeSize::getScalable(0));

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


[clang] af97139 - [clang][Interp] Handle missing Lambda field initializer

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T13:16:35+01:00
New Revision: af971396a9c77a57eb66fcb7eac3f671a7084680

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

LOG: [clang][Interp] Handle missing Lambda field initializer

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/SemaCXX/cxx1z-lambda-star-this.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index b5402ec8caaec6..e96afb1078cc79 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1731,6 +1731,9 @@ bool ByteCodeExprGen::VisitLambdaExpr(const 
LambdaExpr *E) {
 const Expr *Init = *CaptureInitIt;
 ++CaptureInitIt;
 
+if (!Init)
+  continue;
+
 if (std::optional T = classify(Init)) {
   if (!this->visit(Init))
 return false;

diff  --git a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp 
b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
index 95bc32b603ddf0..45b78139d0b018 100644
--- a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
+++ b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
@@ -3,6 +3,11 @@
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions 
%s -DMS_EXTENSIONS
 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING
 
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -emit-llvm-only 
%s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions 
%s -DMS_EXTENSIONS -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING -fexperimental-new-constant-interpreter
+
 template 
 constexpr bool is_same = false;
 template 



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


[clang] clang serialization unittests: fix some leaks (PR #82773)

2024-02-26 Thread Krasimir Georgiev via cfe-commits

https://github.com/krasimirgg updated 
https://github.com/llvm/llvm-project/pull/82773

>From 43f8b15fa3e5465f1939d0359ff5dcfc83ed1717 Mon Sep 17 00:00:00 2001
From: Krasimir Georgiev 
Date: Fri, 23 Feb 2024 15:11:51 +
Subject: [PATCH 1/2] clang serialization unittests: fix some leaks

No functional changes intended.

Fixes some leaks found by running under asan with --gtest_repeat=2.
---
 .../Serialization/ModuleCacheTest.cpp  | 18 ++
 .../Serialization/VarDeclConstantInitTest.cpp  |  1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp 
b/clang/unittests/Serialization/ModuleCacheTest.cpp
index c3e347ffec660c..76aeee60f5a435 100644
--- a/clang/unittests/Serialization/ModuleCacheTest.cpp
+++ b/clang/unittests/Serialization/ModuleCacheTest.cpp
@@ -88,6 +88,16 @@ class ModuleCacheTest : public ::testing::Test {
 }
 )cpp");
   }
+ 
+  std::unique_ptr createInvocationAndEnableFree(
+  ArrayRef Args, CreateInvocationOptions Opts) {
+std::unique_ptr Invocation =
+createInvocation(Args, Opts);
+if (Invocation)
+  Invocation->getFrontendOpts().DisableFree = false;
+
+return Invocation;
+  }
 };
 
 TEST_F(ModuleCacheTest, CachedModuleNewPath) {
@@ -106,7 +116,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) {
 MCPArg.c_str(), "-working-directory", TestDir.c_str(),
 "test.m"};
   std::shared_ptr Invocation =
-  createInvocation(Args, CIOpts);
+  createInvocationAndEnableFree(Args, CIOpts);
   ASSERT_TRUE(Invocation);
   CompilerInstance Instance;
   Instance.setDiagnostics(Diags.get());
@@ -129,7 +139,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) {
  "-Fframeworks",  MCPArg.c_str(), "-working-directory",
  TestDir.c_str(), "test.m"};
   std::shared_ptr Invocation2 =
-  createInvocation(Args2, CIOpts);
+  createInvocationAndEnableFree(Args2, CIOpts);
   ASSERT_TRUE(Invocation2);
   CompilerInstance Instance2(Instance.getPCHContainerOperations(),
  &Instance.getModuleCache());
@@ -156,7 +166,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) {
 MCPArg.c_str(), "-working-directory", TestDir.c_str(),
 "test.m"};
   std::shared_ptr Invocation =
-  createInvocation(Args, CIOpts);
+  createInvocationAndEnableFree(Args, CIOpts);
   ASSERT_TRUE(Invocation);
   CompilerInstance Instance;
   Instance.setDiagnostics(Diags.get());
@@ -173,7 +183,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) {
   TestDir.c_str(), "-Xclang",  "-fallow-pcm-with-compiler-errors",
   "test.m"};
   std::shared_ptr Invocation2 =
-  createInvocation(Args2, CIOpts);
+  createInvocationAndEnableFree(Args2, CIOpts);
   ASSERT_TRUE(Invocation2);
   CompilerInstance Instance2(Instance.getPCHContainerOperations(),
  &Instance.getModuleCache());
diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp 
b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
index 86ae929e7f17e4..7efa1c1d64a964 100644
--- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
+++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
@@ -103,6 +103,7 @@ export namespace Fibonacci
   std::shared_ptr Invocation =
   createInvocation(Args, CIOpts);
   ASSERT_TRUE(Invocation);
+  Invocation->getFrontendOpts().DisableFree = false;
 
   CompilerInstance Instance;
   Instance.setDiagnostics(Diags.get());

>From 4ab1858f489d9222ce114bf8a351ac1e8012ec00 Mon Sep 17 00:00:00 2001
From: Krasimir Georgiev 
Date: Fri, 23 Feb 2024 15:20:32 +
Subject: [PATCH 2/2] reformat

---
 clang/unittests/Serialization/ModuleCacheTest.cpp | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp 
b/clang/unittests/Serialization/ModuleCacheTest.cpp
index 76aeee60f5a435..a7ca98549b4125 100644
--- a/clang/unittests/Serialization/ModuleCacheTest.cpp
+++ b/clang/unittests/Serialization/ModuleCacheTest.cpp
@@ -88,9 +88,10 @@ class ModuleCacheTest : public ::testing::Test {
 }
 )cpp");
   }
- 
-  std::unique_ptr createInvocationAndEnableFree(
-  ArrayRef Args, CreateInvocationOptions Opts) {
+
+  std::unique_ptr
+  createInvocationAndEnableFree(ArrayRef Args,
+CreateInvocationOptions Opts) {
 std::unique_ptr Invocation =
 createInvocation(Args, Opts);
 if (Invocation)

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


[clang] f290c00 - [TBAA] Add additional bitfield tests.

2024-02-26 Thread Florian Hahn via cfe-commits

Author: Florian Hahn
Date: 2024-02-26T12:36:00Z
New Revision: f290c000d87bfc72a31b151dffa2d190596ebe91

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

LOG: [TBAA] Add additional bitfield tests.

Additional test for https://github.com/llvm/llvm-project/pull/82922/.

Added: 


Modified: 
clang/test/CodeGen/tbaa-struct.cpp

Removed: 




diff  --git a/clang/test/CodeGen/tbaa-struct.cpp 
b/clang/test/CodeGen/tbaa-struct.cpp
index ff5521fcf3f604..e25fbc1a778103 100644
--- a/clang/test/CodeGen/tbaa-struct.cpp
+++ b/clang/test/CodeGen/tbaa-struct.cpp
@@ -109,8 +109,6 @@ struct NamedBitfields {
double f3;
 };
 
-NamedBitfields g;
-
 void copy8(NamedBitfields *a1, NamedBitfields *a2) {
 // CHECK-LABEL: _Z5copy8P14NamedBitfieldsS0_
 // CHECK:   tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 
dereferenceable(16) %a1, ptr noundef nonnull align 8 dereferenceable(16) %a2, 
i64 16, i1 false),
@@ -119,6 +117,23 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) {
   *a1 = *a2;
 }
 
+struct NamedBitfields2 {
+  char a, b, c;
+   signed f0 : 3;
+   unsigned f1 : 4;
+   char f2 : 7;
+   double f3;
+   unsigned f4 : 4;
+};
+
+void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) {
+// CHECK-LABEL: _Z5copy9P15NamedBitfields2S0_
+// CHECK:   tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 
dereferenceable(24) %a1, ptr noundef nonnull align 8 dereferenceable(24) %a2, 
i64 24, i1 false),
+// CHECK-OLD-SAME: !tbaa.struct [[TS7:!.*]]
+// CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields2:!.+]], !tbaa.struct
+  *a1 = *a2;
+}
+
 // CHECK-OLD: [[TS]] = !{i64 0, i64 2, !{{.*}}, i64 4, i64 4, !{{.*}}, i64 8, 
i64 1, !{{.*}}, i64 12, i64 4, !{{.*}}}
 // CHECK-OLD: [[CHAR:!.*]] = !{!"omnipotent char", !{{.*}}}
 // CHECK-OLD: [[TAG_INT:!.*]] = !{[[INT:!.*]], [[INT]], i64 0}
@@ -133,6 +148,7 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) {
 // CHECK-OLD: [[TS6]] = !{i64 0, i64 4, [[TAG_INT]], i64 1, i64 4, 
[[TAG_INT]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]}
 // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0}
 // CHECK-OLD  [[DOUBLE]] = !{!"double", [[CHAR]], i64 0}
+// CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, 
[[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 4, [[TAG_INT]], i64 3, i64 
4, [[TAG_INT]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 
16, i64 4, [[TAG_INT]]}
 
 // CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"}
 // CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0}
@@ -150,3 +166,5 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) {
 // CHECK-NEW-DAG: [[TAG_NamedBitfields]] = !{[[TYPE_NamedBitfields:!.+]], 
[[TYPE_NamedBitfields]], i64 0, i64 16}
 // CHECK-NEW-DAG: [[TYPE_NamedBitfields]] = !{[[TYPE_char]], i64 16, 
!"_ZTS14NamedBitfields", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 1, i64 
4, [[TYPE_char]], i64 2, i64 1, [[TYPE_double:!.+]], i64 8, i64 8}
 // CHECK-NEW-DAG: [[TYPE_double]] = !{[[TYPE_char]], i64 8, !"double"}
+// CHECK-NEW-DAG: [[TAG_NamedBitfields2]] = !{[[TYPE_NamedBitfields2:!.+]], 
[[TYPE_NamedBitfields2]], i64 0, i64 24}
+// CHECK-NEW-DAG: [[TYPE_NamedBitfields2]] = !{[[TYPE_char]], i64 24, 
!"_ZTS15NamedBitfields2", [[TYPE_char]], i64 0, i64 1, [[TYPE_char]], i64 1, 
i64 1, [[TYPE_char]], i64 2, i64 1, [[TYPE_int]], i64 3, i64 4, [[TYPE_int]], 
i64 3, i64 4, [[TYPE_char]], i64 4, i64 1, [[TYPE_double]], i64 8, i64 8, 
[[TYPE_int]], i64 16, i64 4}



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


[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,1014 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum IsActive_t : bool { IsNotActive, IsActive };
+enum IsReplacement_t : bool { IsNotReplacement, IsReplacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::IsActive),
+IsReplacement(Replacement == IsReplacement_t::IsReplacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isMultiLevelPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  QualType Type;
+
+  // Nullability for a function/method appertains to the retain type.
+  if (auto Function = dyn_cast(D))
+Type = Function->getReturnType();
+  else if (auto Method = dyn_cast(D))
+Type = Method->getReturnType();
+  else if (auto Value = dyn_cast(D))
+Type = Value->getType();
+  else if (auto Property = dyn_cast(D))
+Type = Property->getType();
+  else
+return;
+
+  // Check the nullability specifier on this type.
+  QualType OrigType = Type;
+  S.CheckImplicitNullabilityTypeSpecifier(Type, Nullability, D->getLocation(),
+  isa(D),
+  /*overrideExisting=*/true);
+  if (Type.getTypePtr() == OrigType.getTypePtr())
+return;
+
+  if (auto Function = dyn_cast(D)) {
+const FunctionType *FnType = Function->getType()->castAs();
+if (const FunctionProtoType *Proto = dyn_cast(FnType))
+  Function->setType(S.Context.getFunctionType(Type, Proto->getParamTypes(),
+  Proto->getExtProtoInfo()));
+else
+  Function->setType(
+  S.Context.getFunctionNoProtoType(Type, FnType->getExtInfo()));
+  } else if (auto Method = dyn_cast(D)) {
+Method->setReturnType(Type);
+
+// Make it a context-sensitive keyword if we can.
+if (!isMultiLevelPointerType(Type))
+  Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+  Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+
+  } else if (auto Value = dyn_cast(D)) {
+Value->setType(Type);
+
+// Make it a context-sensitive keyword if we can.
+if (auto Parm = dyn_cast(D)) {
+  if (Parm->isObjCMethodParameter() && !isMultiLevelPointerType(Type))
+Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+}
+  } else if (auto Property = dyn_cast(D)) {
+Property->setType(Type, Property->getTypeSourceInfo());
+
+// Make it a property attribute if we can.
+if (!isMultiLevelPointerType(Type))
+  Property->setPropertyAttributes(
+  ObjCPropertyAttribute::kind_null_resettable);
+
+  } else
+llvm_unreachable("cannot handle nullability here");
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef CopyString(ASTContext &Ctx, StringRef String) {
+  void *mem = Ctx.Allocate(String.size(), alignof(char));
+  memcpy(mem, String.data(), String.size());
+  return StringRef(static_cast(mem), String.size());
+}
+
+static AttributeCommonInfo getDummyAttrInfo() {
+  return AttributeCommonInfo(SourceRange(),
+ AttributeCommonInfo::UnknownAttribute,
+ {AttributeCommonInfo::AS_GNU,
+  /*Spelling*/ 0, /*IsAlignas*/ false,
+  /*IsRegularKeywordAttribute*/ false});
+}
+
+namespace {
+template  struct AttrKindFor {};
+
+#define ATTR(X)   

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits

https://github.com/egorzhdan updated 
https://github.com/llvm/llvm-project/pull/78445

>From 806fe5abaeec7ad7d75d0be026bb42808d15bc41 Mon Sep 17 00:00:00 2001
From: Egor Zhdan 
Date: Wed, 17 Jan 2024 13:41:25 +
Subject: [PATCH] [APINotes] Upstream Sema logic to apply API Notes to decls

This upstreams more of the Clang API Notes functionality that is currently 
implemented in the Apple fork: 
https://github.com/apple/llvm-project/tree/next/clang/lib/APINotes
---
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/Sema/Sema.h   |   6 +
 clang/lib/Sema/CMakeLists.txt |   1 +
 clang/lib/Sema/SemaAPINotes.cpp   | 988 ++
 clang/lib/Sema/SemaDecl.cpp   |   4 +
 clang/lib/Sema/SemaDeclAttr.cpp   |   3 +
 clang/lib/Sema/SemaDeclCXX.cpp|   6 +-
 clang/lib/Sema/SemaDeclObjC.cpp   |   4 +
 clang/lib/Sema/SemaObjCProperty.cpp   |   5 +
 clang/lib/Sema/SemaTemplate.cpp   |   7 +
 10 files changed, 1030 insertions(+), 1 deletion(-)
 create mode 100644 clang/lib/Sema/SemaAPINotes.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ebda201361fb07..887d6120f48d2c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10760,6 +10760,13 @@ def warn_imp_cast_drops_unaligned : Warning<
 
 } // end of sema category
 
+let CategoryName = "API Notes Issue" in {
+
+def err_incompatible_replacement_type : Error<
+  "API notes replacement type %0 has a different size from original type %1">;
+
+} // end of API Notes category
+
 let CategoryName = "OpenMP Issue" in {
 // OpenMP support.
 def err_omp_expected_var_arg : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fcccac10f4733a..77749372b7fb65 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4883,6 +4883,12 @@ class Sema final {
   bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
 bool SkipArgCountCheck = false);
 
+  /// Map any API notes provided for this declaration to attributes on the
+  /// declaration.
+  ///
+  /// Triggered by declaration-attribute processing.
+  void ProcessAPINotes(Decl *D);
+
   /// Determine if type T is a valid subject for a nonnull and similar
   /// attributes. By default, we look through references (the behavior used by
   /// nonnull), but if the second parameter is true, then we treat a reference
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 862f9d4ffb825d..e8bff07ced0cfa 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangSema
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
+  SemaAPINotes.cpp
   SemaAvailability.cpp
   SemaCXXScopeSpec.cpp
   SemaCast.cpp
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 00..836c633e9d2042
--- /dev/null
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,988 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsSubstitution_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsSubstitution_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsSubstitution_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNull

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };

egorzhdan wrote:

`State` seems a bit too generic of a name to me, and these are still `bool`s so 
they won't get more cases. I renamed `IsReplacement_t` to `IsSubstitution_t`, 
but I would prefer to leave `IsActive_t` as is.

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


[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsReplacement_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  auto IsUnmodified = [&](Decl *D, QualType QT,
+  NullabilityKind Nullability) -> bool {
+QualType Original = QT;
+S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
+isa(D),
+/*OverrideExisting=*/true);
+return QT.getTypePtr() == Original.getTypePtr();
+  };
+
+  if (auto Function = dyn_cast(D)) {
+if (!IsUnmodified(D, Function->getReturnType(), Nullability)) {

egorzhdan wrote:

Agreed, done.

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


[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsReplacement_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  auto IsUnmodified = [&](Decl *D, QualType QT,
+  NullabilityKind Nullability) -> bool {
+QualType Original = QT;
+S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
+isa(D),
+/*OverrideExisting=*/true);
+return QT.getTypePtr() == Original.getTypePtr();
+  };
+
+  if (auto Function = dyn_cast(D)) {
+if (!IsUnmodified(D, Function->getReturnType(), Nullability)) {
+  QualType FnType = Function->getType();
+  Function->setType(FnType);
+}
+  } else if (auto Method = dyn_cast(D)) {
+QualType Type = Method->getReturnType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Method->setReturnType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (!isIndirectPointerType(Type))
+Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+}
+  } else if (auto Value = dyn_cast(D)) {
+QualType Type = Value->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Value->setType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (auto Parm = dyn_cast(D)) {
+if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
+  Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+  Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+  }
+}
+  } else if (auto Property = dyn_cast(D)) {
+QualType Type = Property->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Property->setType(Type, Property->getTypeSourceInfo());
+
+  // Make it a property attribute if we can.
+  if (!isIndirectPointerType(Type))
+Property->setPropertyAttributes(
+ObjCPropertyAttribute::kind_null_resettable);
+}
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String) {
+  void *mem = Ctx.Allocate(String.size(), alignof(char *));
+  memcpy(mem, String.data(), String.size());
+  return StringRef(static_cast(mem), String.size());
+}
+
+static AttributeCommonInfo getPlaceholderAttrInfo() {
+  return AttributeCommonInfo(SourceRange(),
+ AttributeCommonInfo::UnknownAttribute,
+ {AttributeCommonInfo::AS_GNU,
+  /*Spelling*/ 0, /*IsAlignas*/ false,
+  /*IsRegularKeywordAttribute*/ false});
+}
+
+namespace {
+template  struct AttrKindFor {};
+
+#define ATTR(X)
\
+  template <> struct AttrKindFor {
\
+static const attr::Kind value = attr::X;   
\
+  };
+#include "clang/Basic/AttrList.inc"
+
+/// Handle an attribute introduced by API notes.
+///
+/// \param IsAddition Whether we shoul

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsReplacement_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  auto IsUnmodified = [&](Decl *D, QualType QT,
+  NullabilityKind Nullability) -> bool {
+QualType Original = QT;
+S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
+isa(D),
+/*OverrideExisting=*/true);
+return QT.getTypePtr() == Original.getTypePtr();
+  };
+
+  if (auto Function = dyn_cast(D)) {
+if (!IsUnmodified(D, Function->getReturnType(), Nullability)) {
+  QualType FnType = Function->getType();
+  Function->setType(FnType);
+}
+  } else if (auto Method = dyn_cast(D)) {
+QualType Type = Method->getReturnType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Method->setReturnType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (!isIndirectPointerType(Type))
+Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+}
+  } else if (auto Value = dyn_cast(D)) {
+QualType Type = Value->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Value->setType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (auto Parm = dyn_cast(D)) {
+if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
+  Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+  Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+  }
+}
+  } else if (auto Property = dyn_cast(D)) {
+QualType Type = Property->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Property->setType(Type, Property->getTypeSourceInfo());
+
+  // Make it a property attribute if we can.
+  if (!isIndirectPointerType(Type))
+Property->setPropertyAttributes(
+ObjCPropertyAttribute::kind_null_resettable);
+}
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String) {
+  void *mem = Ctx.Allocate(String.size(), alignof(char *));
+  memcpy(mem, String.data(), String.size());
+  return StringRef(static_cast(mem), String.size());
+}
+
+static AttributeCommonInfo getPlaceholderAttrInfo() {
+  return AttributeCommonInfo(SourceRange(),
+ AttributeCommonInfo::UnknownAttribute,
+ {AttributeCommonInfo::AS_GNU,
+  /*Spelling*/ 0, /*IsAlignas*/ false,
+  /*IsRegularKeywordAttribute*/ false});
+}
+
+namespace {
+template  struct AttrKindFor {};
+
+#define ATTR(X)
\
+  template <> struct AttrKindFor {
\
+static const attr::Kind value = attr::X;   
\
+  };
+#include "clang/Basic/AttrList.inc"
+
+/// Handle an attribute introduced by API notes.
+///
+/// \param IsAddition Whether we shoul

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsReplacement_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  auto IsUnmodified = [&](Decl *D, QualType QT,
+  NullabilityKind Nullability) -> bool {
+QualType Original = QT;
+S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
+isa(D),
+/*OverrideExisting=*/true);
+return QT.getTypePtr() == Original.getTypePtr();
+  };
+
+  if (auto Function = dyn_cast(D)) {
+if (!IsUnmodified(D, Function->getReturnType(), Nullability)) {
+  QualType FnType = Function->getType();
+  Function->setType(FnType);
+}
+  } else if (auto Method = dyn_cast(D)) {
+QualType Type = Method->getReturnType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Method->setReturnType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (!isIndirectPointerType(Type))
+Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+}
+  } else if (auto Value = dyn_cast(D)) {
+QualType Type = Value->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Value->setType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (auto Parm = dyn_cast(D)) {
+if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
+  Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+  Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+  }
+}
+  } else if (auto Property = dyn_cast(D)) {
+QualType Type = Property->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Property->setType(Type, Property->getTypeSourceInfo());
+
+  // Make it a property attribute if we can.
+  if (!isIndirectPointerType(Type))
+Property->setPropertyAttributes(
+ObjCPropertyAttribute::kind_null_resettable);
+}
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String) {
+  void *mem = Ctx.Allocate(String.size(), alignof(char *));
+  memcpy(mem, String.data(), String.size());
+  return StringRef(static_cast(mem), String.size());
+}
+
+static AttributeCommonInfo getPlaceholderAttrInfo() {
+  return AttributeCommonInfo(SourceRange(),
+ AttributeCommonInfo::UnknownAttribute,
+ {AttributeCommonInfo::AS_GNU,
+  /*Spelling*/ 0, /*IsAlignas*/ false,
+  /*IsRegularKeywordAttribute*/ false});
+}
+
+namespace {
+template  struct AttrKindFor {};
+
+#define ATTR(X)
\
+  template <> struct AttrKindFor {
\
+static const attr::Kind value = attr::X;   
\
+  };
+#include "clang/Basic/AttrList.inc"
+
+/// Handle an attribute introduced by API notes.
+///
+/// \param IsAddition Whether we shoul

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits


@@ -0,0 +1,989 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsReplacement_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsReplacement_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsReplacement_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
+ VersionedInfoMetadata Metadata) {
+  if (!Metadata.IsActive)
+return;
+
+  auto IsUnmodified = [&](Decl *D, QualType QT,
+  NullabilityKind Nullability) -> bool {
+QualType Original = QT;
+S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
+isa(D),
+/*OverrideExisting=*/true);
+return QT.getTypePtr() == Original.getTypePtr();
+  };
+
+  if (auto Function = dyn_cast(D)) {
+if (!IsUnmodified(D, Function->getReturnType(), Nullability)) {
+  QualType FnType = Function->getType();
+  Function->setType(FnType);
+}
+  } else if (auto Method = dyn_cast(D)) {
+QualType Type = Method->getReturnType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Method->setReturnType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (!isIndirectPointerType(Type))
+Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+}
+  } else if (auto Value = dyn_cast(D)) {
+QualType Type = Value->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Value->setType(Type);
+
+  // Make it a context-sensitive keyword if we can.
+  if (auto Parm = dyn_cast(D)) {
+if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
+  Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
+  Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
+  }
+}
+  } else if (auto Property = dyn_cast(D)) {
+QualType Type = Property->getType();
+if (!IsUnmodified(D, Type, Nullability)) {
+  Property->setType(Type, Property->getTypeSourceInfo());
+
+  // Make it a property attribute if we can.
+  if (!isIndirectPointerType(Type))
+Property->setPropertyAttributes(
+ObjCPropertyAttribute::kind_null_resettable);
+}
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef ASTAllocateString(ASTContext &Ctx, StringRef String) {
+  void *mem = Ctx.Allocate(String.size(), alignof(char *));
+  memcpy(mem, String.data(), String.size());
+  return StringRef(static_cast(mem), String.size());
+}
+
+static AttributeCommonInfo getPlaceholderAttrInfo() {
+  return AttributeCommonInfo(SourceRange(),
+ AttributeCommonInfo::UnknownAttribute,
+ {AttributeCommonInfo::AS_GNU,
+  /*Spelling*/ 0, /*IsAlignas*/ false,
+  /*IsRegularKeywordAttribute*/ false});
+}
+
+namespace {
+template  struct AttrKindFor {};
+
+#define ATTR(X)
\
+  template <> struct AttrKindFor {
\
+static const attr::Kind value = attr::X;   
\
+  };
+#include "clang/Basic/AttrList.inc"
+
+/// Handle an attribute introduced by API notes.
+///
+/// \param IsAddition Whether we shoul

[clang] 58aa995 - [clang][Interp][NFC] Fix comment typo

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T13:56:37+01:00
New Revision: 58aa995baf66fffb1284ecb289dc9f02c70de4fa

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

LOG: [clang][Interp][NFC] Fix comment typo

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index aecad1598ad2b1..2b36a05e1af96a 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1048,7 +1048,7 @@ bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I) 
{
 
 /// 1) Converts the value on top of the stack to an APValue
 /// 2) Sets that APValue on \Temp
-/// 3) Initialized global with index \I with that
+/// 3) Initializes global with index \I with that
 template ::T>
 bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I,
 const LifetimeExtendedTemporaryDecl *Temp) {



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


[clang] a35599b - [clang][Interp] Implement a few _is_lock_free builtins

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T13:56:37+01:00
New Revision: a35599b9ae5e7ad924b78c65f6348e0b711bad5d

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

LOG: [clang][Interp] Implement a few _is_lock_free builtins

Implementation looks similar to the one in the current interpreter.
Except for three static assertions, test/Sema/atomic-ops.c works.

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/Context.cpp 
b/clang/lib/AST/Interp/Context.cpp
index 578dc44fe4f8d4..b09019f3e65b79 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -160,7 +160,7 @@ std::optional Context::classify(QualType T) const 
{
   if (T->isReferenceType() || T->isPointerType())
 return PT_Ptr;
 
-  if (const auto *AT = dyn_cast(T))
+  if (const auto *AT = T->getAs())
 return classify(AT->getValueType());
 
   if (const auto *DT = dyn_cast(T))

diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 401af580e1aaf6..2fb076d7793a8d 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -887,6 +887,73 @@ static bool interp__builtin_bswap(InterpState &S, CodePtr 
OpPC,
   return true;
 }
 
+/// bool __atomic_always_lock_free(size_t, void const volatile*)
+/// bool __atomic_is_lock_free(size_t, void const volatile*)
+/// bool __c11_atomic_is_lock_free(size_t)
+static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+  unsigned BuiltinOp = Func->getBuiltinID();
+
+  PrimType ValT = *S.getContext().classify(Call->getArg(0));
+  unsigned SizeValOffset = 0;
+  if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
+SizeValOffset = align(primSize(ValT)) + align(primSize(PT_Ptr));
+  const APSInt &SizeVal = peekToAPSInt(S.Stk, ValT, SizeValOffset);
+
+  auto returnBool = [&S](bool Value) -> bool {
+S.Stk.push(Value);
+return true;
+  };
+
+  // For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power
+  // of two less than or equal to the maximum inline atomic width, we know it
+  // is lock-free.  If the size isn't a power of two, or greater than the
+  // maximum alignment where we promote atomics, we know it is not lock-free
+  // (at least not in the sense of atomic_is_lock_free).  Otherwise,
+  // the answer can only be determined at runtime; for example, 16-byte
+  // atomics have lock-free implementations on some, but not all,
+  // x86-64 processors.
+
+  // Check power-of-two.
+  CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
+  if (Size.isPowerOfTwo()) {
+// Check against inlining width.
+unsigned InlineWidthBits =
+S.getCtx().getTargetInfo().getMaxAtomicInlineWidth();
+if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) {
+
+  // OK, we will inline appropriately-aligned operations of this size,
+  // and _Atomic(T) is appropriately-aligned.
+  if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
+  Size == CharUnits::One())
+return returnBool(true);
+
+  // Same for null pointers.
+  assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
+  const Pointer &Ptr = S.Stk.peek();
+  if (Ptr.isZero())
+return returnBool(true);
+
+  QualType PointeeType = Call->getArg(1)
+ ->IgnoreImpCasts()
+ ->getType()
+ ->castAs()
+ ->getPointeeType();
+  // OK, we will inline operations on this object.
+  if (!PointeeType->isIncompleteType() &&
+  S.getCtx().getTypeAlignInChars(PointeeType) >= Size)
+return returnBool(true);
+}
+  }
+
+  if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
+return returnBool(false);
+
+  return false;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -1186,6 +1253,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const Function *F,
   return false;
 break;
 
+  case Builtin::BI__atomic_always_lock_free:
+  case Builtin::BI__atomic_is_lock_free:
+  case Builtin::BI__c11_atomic_is_lock_free:
+if (!interp__builtin_atomic_lock_free(S, OpPC, Frame, F, Call))
+  return false;
+break;
+
   default:
 return false;
   }

diff  --git a/clang/test/AST/Interp/atomic.c b/clang/test/

[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits

https://github.com/chapuni commented:

TODO:

* Version bump in file formats (wip)
* Update documents

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits


@@ -973,9 +970,11 @@ void InstrLowerer::lowerMCDCTestVectorBitmapUpdate(
   auto *MCDCCondBitmapAddr = Update->getMCDCCondBitmapAddr();
   auto *BitmapAddr = getBitmapAddress(Update);
 
-  // Load Temp Val.
+  // Load Temp Val + BitmapIdx.
   //  %mcdc.temp = load i32, ptr %mcdc.addr, align 4
-  auto *Temp = Builder.CreateLoad(Int32Ty, MCDCCondBitmapAddr, "mcdc.temp");
+  auto *Temp = Builder.CreateAdd(
+  Builder.CreateLoad(Int32Ty, MCDCCondBitmapAddr, "mcdc.temp"),
+  Update->getBitmapIndex());

chapuni wrote:

`tvupdate`'s Index points to the bit index in the bitmap.

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits


@@ -1201,19 +1197,22 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy 
&Builder, const Expr *S,
   // Extract the ID of the condition we are setting in the bitmap.
   const auto &Branch = BranchStateIter->second;
   assert(Branch.ID >= 0 && "Condition has no ID!");
+  assert(Branch.DecisionStmt);
 
-  auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
+  // Cancel the emission if the Decision is erased after the allocation.
+  const auto DecisionIter =
+  RegionMCDCState->DecisionByStmt.find(Branch.DecisionStmt);
+  if (DecisionIter == RegionMCDCState->DecisionByStmt.end())
+return;
 
-  // Emit intrinsic that updates a dedicated temporary value on the stack after
-  // a condition is evaluated. After the set of conditions has been updated,
-  // the resulting value is used to update the boolean expression's bitmap.
-  llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
-  Builder.getInt64(FunctionHash),
-  Builder.getInt32(Branch.ID),
-  MCDCCondBitmapAddr.getPointer(), Val};
-  Builder.CreateCall(
-  CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update),
-  Args);
+  const auto &TVIdxs = DecisionIter->second.Indices[Branch.ID];
+
+  auto *CurTV = Builder.CreateLoad(MCDCCondBitmapAddr,
+   "mcdc." + Twine(Branch.ID + 1) + ".cur");
+  auto *NewTV = Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[true]));
+  NewTV = Builder.CreateSelect(
+  Val, NewTV, Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[false])));
+  Builder.CreateStore(NewTV, MCDCCondBitmapAddr);

chapuni wrote:

I don't use the intrinsic.

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


[clang] [TBAA] Skip all bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 Thread Florian Hahn via cfe-commits

https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/82922

>From 556fcefed9645aa0a0a965ff8f22d8accdf9eefc Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Sun, 25 Feb 2024 13:23:17 +
Subject: [PATCH 1/5] [TBAA] Skip all bitfields when generating !tbaa.struct
 metadata.

At the moment, clang generates what I believe are incorrect !tbaa.struct
fields for named bitfields. At the moment, the base type size is used
for named bifields (e.g. sizeof(int)) instead of the bifield width per
field. This results in overalpping fields in !tbaa.struct metadata.

This causes incorrect results when extracting individual copied fields
from !tbaa.struct as in added in dc85719d5.

This patch fixes that by skipping all bitfields, not only unnamed ones
(note that CollectFields has a TODO to support bitfields). As bitfields
specify their widths in bits, while !tbaa metadata uses bytes for sizes
and offsets, I don't think we would be able to generate correct metadata
for them in general.

If this understanding is correct, I can also extend the verifier to
check that !tbaa.struct fields aren't overlapping.

Fixes https://github.com/llvm/llvm-project/issues/82586
---
 clang/lib/CodeGen/CodeGenTBAA.cpp  | 2 +-
 clang/test/CodeGen/tbaa-struct.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index dc288bc3f6157a..43a1aee3d73823 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -298,7 +298,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
 unsigned idx = 0;
 for (RecordDecl::field_iterator i = RD->field_begin(),
  e = RD->field_end(); i != e; ++i, ++idx) {
-  if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
+  if ((*i)->isZeroSize(Context) || (*i)->isBitField())
 continue;
   uint64_t Offset = BaseOffset +
 Layout.getFieldOffset(idx) / Context.getCharWidth();
diff --git a/clang/test/CodeGen/tbaa-struct.cpp 
b/clang/test/CodeGen/tbaa-struct.cpp
index ff5521fcf3f604..17c9d6bf6a7260 100644
--- a/clang/test/CodeGen/tbaa-struct.cpp
+++ b/clang/test/CodeGen/tbaa-struct.cpp
@@ -130,7 +130,7 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) {
 // CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, 
i64 8, !{{.*}}}
 // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, 
[[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]}
 // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, 
[[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]}
-// CHECK-OLD: [[TS6]] = !{i64 0, i64 4, [[TAG_INT]], i64 1, i64 4, 
[[TAG_INT]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]}
+// CHECK-OLD: [[TS6]] = !{i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, 
[[TAG_DOUBLE:!.+]]}
 // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0}
 // CHECK-OLD  [[DOUBLE]] = !{!"double", [[CHAR]], i64 0}
 

>From 32be3b7d944fc5da50add4b6fea551ba6c9d428c Mon Sep 17 00:00:00 2001
From: Florian Hahn 
Date: Mon, 26 Feb 2024 10:19:57 +
Subject: [PATCH 2/5] WIP use CGBitFieldInfo.

---
 clang/lib/CodeGen/CodeGenModule.cpp |  2 +-
 clang/lib/CodeGen/CodeGenTBAA.cpp   | 33 +++--
 clang/lib/CodeGen/CodeGenTBAA.h |  4 +++-
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 95e457bef28ed3..ed8db055723024 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -397,7 +397,7 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
   if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
   (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
-TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(),
+TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, 
getLangOpts(),
getCXXABI().getMangleContext()));
 
   // If debug info or coverage generation is enabled, create the CGDebugInfo
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 43a1aee3d73823..6a453bb1144582 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -14,6 +14,8 @@
 //
 
//===--===//
 
+#include "CGRecordLayout.h"
+#include "CodeGenTypes.h"
 #include "CodeGenTBAA.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -29,10 +31,10 @@
 using namespace clang;
 using namespace CodeGen;
 
-CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module 
&M,
  const CodeGenOptions &CGO,
  const LangOptions &Features, MangleContext &MContext)
-  : Contex

[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 Thread Florian Hahn via cfe-commits

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


[clang] [clang][analyzer] StreamChecker: Add more APIs, invalidate fscanf args (PR #82476)

2024-02-26 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource updated 
https://github.com/llvm/llvm-project/pull/82476

From a21881d82fe3674b344d4a3807e9d2590c98ce93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20=C3=81lvarez=20Ayll=C3=B3n?=
 
Date: Tue, 14 Nov 2023 09:28:45 +0100
Subject: [PATCH 1/4] [clang][analyzer] StreamChecker: add more APIs,
 invalidate fscanf args

1. Model getc, vfscanf, putc, vfprintf.
2. fscanf invalidates all arguments after the format string.
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp |  39 +-
 ...ystem-header-simulator-for-simple-stream.h |   2 +-
 .../system-header-simulator-for-valist.h  |   4 +
 .../Analysis/Inputs/system-header-simulator.h |   3 +
 clang/test/Analysis/stream.c  | 128 ++
 5 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index a070f451694a3b..7938a0d30a91a3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -21,6 +21,8 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
 #include 
 #include 
 
@@ -171,7 +173,7 @@ using FnCheck = std::function;
 
 using ArgNoTy = unsigned int;
-static const ArgNoTy ArgNone = std::numeric_limits::max();
+const ArgNoTy ArgNone = std::numeric_limits::max();
 
 struct FnDescription {
   FnCheck PreFn;
@@ -179,6 +181,26 @@ struct FnDescription {
   ArgNoTy StreamArgNo;
 };
 
+[[nodiscard]] ProgramStateRef
+escapeArgsAfterIndex(ProgramStateRef State, CheckerContext &C,
+ const CallEvent &Call, unsigned FirstEscapingArgIndex) {
+  const auto *CE = Call.getOriginExpr();
+  assert(CE);
+
+  if (Call.getNumArgs() <= FirstEscapingArgIndex)
+return State;
+
+  SmallVector EscapingArgs;
+  EscapingArgs.reserve(Call.getNumArgs() - FirstEscapingArgIndex);
+  for (auto EscArgIdx :
+   llvm::seq(FirstEscapingArgIndex, Call.getNumArgs()))
+EscapingArgs.push_back(Call.getArgSVal(EscArgIdx));
+  State = State->invalidateRegions(EscapingArgs, CE, C.blockCount(),
+   C.getLocationContext(),
+   /*CausesPointerEscape=*/false);
+  return State;
+}
+
 /// Get the value of the stream argument out of the passed call event.
 /// The call should contain a function that is described by Desc.
 SVal getStreamArg(const FnDescription *Desc, const CallEvent &Call) {
@@ -396,6 +418,18 @@ class StreamChecker : public Checker FnTestDescriptions = {
@@ -997,6 +1031,9 @@ void StreamChecker::evalFscanf(const FnDescription *Desc, 
const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
+  // The pointers passed to fscanf escape and get invalidated.
+  State = escapeArgsAfterIndex(State, C, Call, /*FirstEscapingArgIndex=*/2);
+
   // Add the success state.
   // In this context "success" means there is not an EOF or other read error
   // before any item is matched in 'fscanf'. But there may be match failure,
diff --git 
a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
index 098a2208fecbe9..c26d3582149120 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
@@ -5,7 +5,7 @@
 // suppressed.
 #pragma clang system_header
 
-typedef struct __sFILE {
+typedef struct _FILE {
   unsigned char *_p;
 } FILE;
 FILE *fopen(const char *restrict, const char *restrict) __asm("_" "fopen" );
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
index 7299b61353d460..87688bd8b312f4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
@@ -10,6 +10,8 @@
 #define restrict /*restrict*/
 #endif
 
+typedef struct _FILE FILE;
+
 typedef __builtin_va_list va_list;
 
 #define va_start(ap, param) __builtin_va_start(ap, param)
@@ -21,6 +23,8 @@ int vprintf (const char *restrict format, va_list arg);
 
 int vsprintf (char *restrict s, const char *restrict format, va_list arg);
 
+int vfscanf(FILE *stream, const char *format, va_list ap);
+
 int some_library_function(int n, va_list arg);
 
 // No warning from system header.
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index 15986984802c0e..8fd51449ecc0a4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -73,6 +73,9 @@ int ferror(FILE *stream);

[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 Thread Florian Hahn via cfe-commits

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


[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)

2024-02-26 Thread NAKAMURA Takumi via cfe-commits

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


[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)

2024-02-26 Thread Florian Hahn via cfe-commits

fhahn wrote:

> This seems like it messes up the metadata in a different way: we have no 
> representation of the bitfield at all, so it looks like it's padding.
> 
> I think we want to treat multiple adjacent bitfields as a single "field". So 
> NamedBitfields from the testcase would have three fields in the LLVM TBAA 
> data: one "field" containing both bitfields, followed by a field for the 
> char, followed by a field for the double. You should be able to use 
> CGBitFieldInfo for this, I think?

Thanks, updated the patch as suggested.

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


[clang] [clang][analyzer] StreamChecker: Model getc, vfscanf, putc, vfprintf (PR #82476)

2024-02-26 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource edited 
https://github.com/llvm/llvm-project/pull/82476
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][NFC] Prefer usings over typedefs (PR #82920)

2024-02-26 Thread via cfe-commits

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

Personally I feel that the `typedef`s are also OK, but if you prefer `using`, 
then feel free to switch to using it. (In this particular case I'd agree that 
the `using` is a bit nicer because it doesn't need the column alignment.)

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


[clang] [clang][NFC] Trim license header comments to 81 characters (PR #82919)

2024-02-26 Thread via cfe-commits

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


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


[clang] [clang] Support `__is_trivially_copyable(int()&)==false` (PR #81298)

2024-02-26 Thread Amirreza Ashouri via cfe-commits

https://github.com/AMP999 updated 
https://github.com/llvm/llvm-project/pull/81298

>From d59c262b31937fdd2b907ec11d7f08e4a385007c Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Fri, 9 Feb 2024 21:55:03 +0330
Subject: [PATCH 1/5] [clang] Support `__is_trivially_copyable(int()&)==false`

IMHO it would be productive to make a similar change for `typeid`,
in `ParseCXXTypeid`, in order to improve Clang's error message for
https://godbolt.org/z/oKKWxeYra
But that might be better done by adding a new DeclaratorContext
specifically for TypeidArg, instead of pretending that the argument
to `typeid` is a template argument, because I don't know what else
that change might affect.

Fixes https://github.com/llvm/llvm-project/issues/77585
---
 clang/lib/Parse/ParseExprCXX.cpp | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..746a8b2286ac4c 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3899,7 +3899,9 @@ ExprResult Parser::ParseTypeTrait() {
   SmallVector Args;
   do {
 // Parse the next type.
-TypeResult Ty = ParseTypeName();
+TypeResult Ty = ParseTypeName(nullptr, getLangOpts().CPlusPlus
+   ? DeclaratorContext::TemplateArg
+   : DeclaratorContext::TypeName);
 if (Ty.isInvalid()) {
   Parens.skipToEnd();
   return ExprError();
@@ -3941,7 +3943,7 @@ ExprResult Parser::ParseArrayTypeTrait() {
   if (T.expectAndConsume())
 return ExprError();
 
-  TypeResult Ty = ParseTypeName();
+  TypeResult Ty = ParseTypeName(nullptr, DeclaratorContext::TemplateArg);
   if (Ty.isInvalid()) {
 SkipUntil(tok::comma, StopAtSemi);
 SkipUntil(tok::r_paren, StopAtSemi);

>From 4c58f4f351a17cf4bf3c9d0ccfa118d0fe3a52de Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Sun, 11 Feb 2024 20:35:04 +0330
Subject: [PATCH 2/5] [clang] Fix the failing test in #81298

---
 clang/test/Sema/static-assert.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c
index 4e9e6b7ee558bd..7e1ce135cbd995 100644
--- a/clang/test/Sema/static-assert.c
+++ b/clang/test/Sema/static-assert.c
@@ -57,7 +57,7 @@ UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // 
ext-warning 3 {{'_Static_
 typedef UNION(char, short) U3; // expected-error {{static assertion failed due 
to requirement 'sizeof(char) == sizeof(short)': type size mismatch}} \
// expected-note{{evaluates to '1 == 2'}} \
// ext-warning 3 {{'_Static_assert' is a C11 
extension}}
-typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \
+typedef UNION(float, 0.5f) U4; // expected-error-re type name requires a 
specifier or qualifier|expected a type \
// ext-warning 3 {{'_Static_assert' is a C11 
extension}}
 
 // After defining the assert macro in MS-compatibility mode, we should

>From 03c2cfb73fc291ecfc5318077b295a6e38cd9869 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Mon, 12 Feb 2024 23:47:33 +0330
Subject: [PATCH 3/5] Add a release note.

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

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 32440ee64e3ebe..0beb10af709804 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -217,6 +217,8 @@ Bug Fixes to C++ Support
   Fixes (`#80971 ICE when explicit object parameter be a function parameter 
pack`)
 - Fixed a bug where abbreviated function templates would append their invented 
template parameters to
   an empty template parameter lists.
+- Fix parsing of abominable function types inside type traits. 
+  Fixes (`#77585 `_)
 
 Bug Fixes to AST Handling
 ^

>From 0de0aa09fb5f45fcde688d988377582b9257b6b8 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri 
Date: Tue, 13 Feb 2024 01:19:27 +0330
Subject: [PATCH 4/5] Remove trailing white space in ReleaseNotes.rst.

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

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0beb10af709804..55f3faea365a07 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -217,7 +217,7 @@ Bug Fixes to C++ Support
   Fixes (`#80971 ICE when explicit object parameter be a function parameter 
pack`)
 - Fixed a bug where abbreviated function templates would append their invented 
template parameters to
   an empty template parameter lists.
-- Fix parsing of abominable function types inside type traits. 
+- Fix parsing of abominable function types inside type traits.
   Fixes (`#77585 `_)
 
 Bug Fixes to AST Handling

>

[clang] 96e536e - [clang][NFC] Prefer usings over typedefs (#82920)

2024-02-26 Thread via cfe-commits

Author: Balazs Benics
Date: 2024-02-26T14:08:16+01:00
New Revision: 96e536ecf5e6202089ee10ca81c38fbce70851d7

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

LOG: [clang][NFC] Prefer usings over typedefs (#82920)

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowValues.h

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
index 2248bcdf3a512f..8e88f9c4d9c2df 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -45,12 +45,12 @@ class DataflowValues {
   
//======//
 
 public:
-  typedef typename ValueTypes::ValTy   ValTy;
-  typedef typename ValueTypes::AnalysisDataTy  AnalysisDataTy;
-  typedef _AnalysisDirTag  AnalysisDirTag;
-  typedef llvm::DenseMap  EdgeDataMapTy;
-  typedef llvm::DenseMap   BlockDataMapTy;
-  typedef llvm::DenseMap   StmtDataMapTy;
+  using ValTy = typename ValueTypes::ValTy;
+  using AnalysisDataTy = typename ValueTypes::AnalysisDataTy;
+  using AnalysisDirTag = _AnalysisDirTag;
+  using EdgeDataMapTy = llvm::DenseMap;
+  using BlockDataMapTy = llvm::DenseMap;
+  using StmtDataMapTy = llvm::DenseMap;
 
   
//======//
   // Predicates.



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


[clang] [clang][NFC] Prefer usings over typedefs (PR #82920)

2024-02-26 Thread Balazs Benics via cfe-commits

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


[clang] c4e9463 - Revert "[clang][dataflow] Correctly handle `InitListExpr` of union type." (#82856)

2024-02-26 Thread via cfe-commits

Author: Samira Bazuzi
Date: 2024-02-26T14:23:46+01:00
New Revision: c4e94633e8a48ee33115d5d3161ee142fc1c9700

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

LOG: Revert "[clang][dataflow] Correctly handle `InitListExpr` of union type." 
(#82856)

Reverts llvm/llvm-project#82348, which caused crashes when analyzing
empty InitListExprs for unions, e.g.

```cc
union U {
  double double_value;
  int int_value;
};

void target() {
  U value;
  value = {};
}
```

Co-authored-by: Samira Bazuzi 

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupport.h
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index b3dc940705f870..0aecc749bf415c 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -753,12 +753,9 @@ RecordStorageLocation *getImplicitObjectLocation(const 
CXXMemberCallExpr &MCE,
 RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
  const Environment &Env);
 
-/// Returns the fields of a `RecordDecl` that are initialized by an
-/// `InitListExpr`, in the order in which they appear in
-/// `InitListExpr::inits()`.
-/// `Init->getType()` must be a record type.
-std::vector
-getFieldsForInitListExpr(const InitListExpr *InitList);
+/// Returns the fields of `RD` that are initialized by an `InitListExpr`, in 
the
+/// order in which they appear in `InitListExpr::inits()`.
+std::vector getFieldsForInitListExpr(const RecordDecl *RD);
 
 /// Associates a new `RecordValue` with `Loc` and returns the new value.
 RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 0cfc26ea952cda..d487944ce92111 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -361,8 +361,8 @@ getFieldsGlobalsAndFuncs(const Stmt &S, FieldSet &Fields,
 if (const auto *FD = dyn_cast(VD))
   Fields.insert(FD);
   } else if (auto *InitList = dyn_cast(&S)) {
-if (InitList->getType()->isRecordType())
-  for (const auto *FD : getFieldsForInitListExpr(InitList))
+if (RecordDecl *RD = InitList->getType()->getAsRecordDecl())
+  for (const auto *FD : getFieldsForInitListExpr(RD))
 Fields.insert(FD);
   }
 }
@@ -1104,22 +1104,12 @@ RecordStorageLocation *getBaseObjectLocation(const 
MemberExpr &ME,
   return Env.get(*Base);
 }
 
-std::vector
-getFieldsForInitListExpr(const InitListExpr *InitList) {
-  const RecordDecl *RD = InitList->getType()->getAsRecordDecl();
-  assert(RD != nullptr);
-
-  std::vector Fields;
-
-  if (InitList->getType()->isUnionType()) {
-Fields.push_back(InitList->getInitializedFieldInUnion());
-return Fields;
-  }
-
+std::vector getFieldsForInitListExpr(const RecordDecl *RD) {
   // Unnamed bitfields are only used for padding and do not appear in
   // `InitListExpr`'s inits. However, those fields do appear in `RecordDecl`'s
   // field list, and we thus need to remove them before mapping inits to
   // fields to avoid mapping inits to the wrongs fields.
+  std::vector Fields;
   llvm::copy_if(
   RD->fields(), std::back_inserter(Fields),
   [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });

diff  --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp 
b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index cd1f04e53cff68..fe13e919bddcd8 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -663,7 +663,14 @@ class TransferVisitor : public 
ConstStmtVisitor {
   void VisitInitListExpr(const InitListExpr *S) {
 QualType Type = S->getType();
 
-if (!Type->isRecordType()) {
+if (Type->isUnionType()) {
+  // FIXME: Initialize unions properly.
+  if (auto *Val = Env.createValue(Type))
+Env.setValue(*S, *Val);
+  return;
+}
+
+if (!Type->isStructureOrClassType()) {
   // Until array initialization is implemented, we don't need to care about
   // cases where `getNumInits() > 1`.
   if (S->getNumInits() == 1)
@@ -681,9 +688,10 @@ class TransferVisitor : public 
ConstStmtVisitor {
 llvm::DenseMap FieldLocs;
 
 // This only contains the direct fields for the given type.
- 

[clang] Revert "[clang][dataflow] Correctly handle `InitListExpr` of union type." (PR #82856)

2024-02-26 Thread via cfe-commits

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


[clang] [flang] [llvm] [Docs] Allow building man pages without myst_parser (PR #82402)

2024-02-26 Thread Aaron Ballman via cfe-commits

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

LGTM aside from the formatting issue @mgorny mentioned.

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


[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Krystian Stasiowski via cfe-commits

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

>From 3966e98d9eb6c04faf8a7fd0c4de804964437595 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 20 Feb 2024 14:03:50 -0500
Subject: [PATCH] [Clang][Sema] Defer instantiation of exception specification
 until after partial ordering when determining primary template

---
 clang/lib/Sema/SemaTemplate.cpp   | 34 +
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 14 +++
 clang/test/CXX/except/except.spec/p13.cpp | 38 +++
 .../SemaTemplate/class-template-noexcept.cpp  | 14 +--
 4 files changed, 79 insertions(+), 21 deletions(-)
 create mode 100644 clang/test/CXX/except/except.spec/p13.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7d3d665194add1..de09a56cf59502 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -9707,6 +9707,40 @@ bool Sema::CheckFunctionTemplateSpecialization(
   // Ignore access information;  it doesn't figure into redeclaration checking.
   FunctionDecl *Specialization = cast(*Result);
 
+  // C++23 [except.spec]p13:
+  //   An exception specification is considered to be needed when:
+  //   - [...]
+  //   - the exception specification is compared to that of another declaration
+  // (e.g., an explicit specialization or an overriding virtual function);
+  //   - [...]
+  //
+  //  The exception specification of a defaulted function is evaluated as
+  //  described above only when needed; similarly, the noexcept-specifier of a
+  //  specialization of a function template or member function of a class
+  //  template is instantiated only when needed.
+  //
+  // The standard doesn't specify what the "comparison with another 
declaration"
+  // entails, nor the exact circumstances in which it occurs. Moreover, it does
+  // not state which properties of an explicit specialization must match the
+  // primary template.
+  //
+  // We assume that an explicit specialization must correspond with (per
+  // [basic.scope.scope]p4) and declare the same entity as (per [basic.link]p8)
+  // the declaration produced by substitution into the function template.
+  //
+  // Since the determination whether two function declarations correspond does
+  // not consider exception specification, we only need to instantiate it once
+  // we determine the primary template when comparing types per
+  // [basic.link]p11.1.
+  auto *SpecializationFPT =
+  Specialization->getType()->castAs();
+  // If the function has a dependent exception specification, resolve it after
+  // we have selected the primary template so we can check whether it matches.
+  if (getLangOpts().CPlusPlus17 &&
+  isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
+  !ResolveExceptionSpec(FD->getLocation(), SpecializationFPT))
+return true;
+
   FunctionTemplateSpecializationInfo *SpecInfo
 = Specialization->getTemplateSpecializationInfo();
   assert(SpecInfo && "Function template specialization info missing?");
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 47cc22310c4eec..563491f76f5478 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4632,11 +4632,9 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
Info.getLocation()))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
 
-  // If the function has a dependent exception specification, resolve it now,
-  // so we can check that the exception specification matches.
   auto *SpecializationFPT =
   Specialization->getType()->castAs();
-  if (getLangOpts().CPlusPlus17 &&
+  if (IsAddressOfFunction && getLangOpts().CPlusPlus17 &&
   isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
   !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
@@ -4662,11 +4660,11 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
   // specialization with respect to arguments of compatible pointer to function
   // types, template argument deduction fails.
   if (!ArgFunctionType.isNull()) {
-if (IsAddressOfFunction
-? !isSameOrCompatibleFunctionType(
-  Context.getCanonicalType(SpecializationType),
-  Context.getCanonicalType(ArgFunctionType))
-: !Context.hasSameType(SpecializationType, ArgFunctionType)) {
+if (IsAddressOfFunction ? !isSameOrCompatibleFunctionType(
+  Context.getCanonicalType(SpecializationType),
+  Context.getCanonicalType(ArgFunctionType))
+: 
!Context.hasSameFunctionTypeIgnoringExceptionSpec(
+  SpecializationType, ArgFunctionType)) {
   I

[clang] [clang] remove (clang::)ast_matchers:: namespace from AST matcher args for docs (PR #81437)

2024-02-26 Thread Aaron Ballman via cfe-commits

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

LGTM!

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


[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Krystian Stasiowski via cfe-commits

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

>From e669903ec50ef0fb1297f150e3a4eb6837db1b53 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 20 Feb 2024 14:03:50 -0500
Subject: [PATCH] [Clang][Sema] Defer instantiation of exception specification
 until after partial ordering when determining primary template

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/lib/Sema/SemaTemplate.cpp   | 34 +
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 14 +++
 clang/test/CXX/except/except.spec/p13.cpp | 38 +++
 .../SemaTemplate/class-template-noexcept.cpp  | 14 +--
 5 files changed, 81 insertions(+), 21 deletions(-)
 create mode 100644 clang/test/CXX/except/except.spec/p13.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 529dd783ab7382..9e67bbb7895040 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -281,6 +281,8 @@ Bug Fixes to C++ Support
   a requires-clause lie at the same depth as those of the surrounding lambda. 
This,
   in turn, results in the wrong template argument substitution during 
constraint checking.
   (`#78524 `_)
+- Clang no longer instantiates the exception specification of discarded 
candidate function
+  templates when determining the primary template of an explicit 
specialization.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7d3d665194add1..de09a56cf59502 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -9707,6 +9707,40 @@ bool Sema::CheckFunctionTemplateSpecialization(
   // Ignore access information;  it doesn't figure into redeclaration checking.
   FunctionDecl *Specialization = cast(*Result);
 
+  // C++23 [except.spec]p13:
+  //   An exception specification is considered to be needed when:
+  //   - [...]
+  //   - the exception specification is compared to that of another declaration
+  // (e.g., an explicit specialization or an overriding virtual function);
+  //   - [...]
+  //
+  //  The exception specification of a defaulted function is evaluated as
+  //  described above only when needed; similarly, the noexcept-specifier of a
+  //  specialization of a function template or member function of a class
+  //  template is instantiated only when needed.
+  //
+  // The standard doesn't specify what the "comparison with another 
declaration"
+  // entails, nor the exact circumstances in which it occurs. Moreover, it does
+  // not state which properties of an explicit specialization must match the
+  // primary template.
+  //
+  // We assume that an explicit specialization must correspond with (per
+  // [basic.scope.scope]p4) and declare the same entity as (per [basic.link]p8)
+  // the declaration produced by substitution into the function template.
+  //
+  // Since the determination whether two function declarations correspond does
+  // not consider exception specification, we only need to instantiate it once
+  // we determine the primary template when comparing types per
+  // [basic.link]p11.1.
+  auto *SpecializationFPT =
+  Specialization->getType()->castAs();
+  // If the function has a dependent exception specification, resolve it after
+  // we have selected the primary template so we can check whether it matches.
+  if (getLangOpts().CPlusPlus17 &&
+  isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
+  !ResolveExceptionSpec(FD->getLocation(), SpecializationFPT))
+return true;
+
   FunctionTemplateSpecializationInfo *SpecInfo
 = Specialization->getTemplateSpecializationInfo();
   assert(SpecInfo && "Function template specialization info missing?");
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 47cc22310c4eec..563491f76f5478 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4632,11 +4632,9 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
Info.getLocation()))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
 
-  // If the function has a dependent exception specification, resolve it now,
-  // so we can check that the exception specification matches.
   auto *SpecializationFPT =
   Specialization->getType()->castAs();
-  if (getLangOpts().CPlusPlus17 &&
+  if (IsAddressOfFunction && getLangOpts().CPlusPlus17 &&
   isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
   !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
@@ -4662,11 +4660,11 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
   // specialization with respect to arguments of compatible pointer to fu

[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

@erichkeane Added release note, relevant standardese quote, and some exposition.

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


[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-26 Thread Yitzhak Mandelbaum via cfe-commits

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


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


[clang] 046682e - [clang-format] Add AlignConsecutiveTableGenCondOperatorColons option. (#82878)

2024-02-26 Thread via cfe-commits

Author: Hirofumi Nakamura
Date: 2024-02-26T22:50:51+09:00
New Revision: 046682ef88a254443e8620bfd48b35bfa0a83809

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

LOG: [clang-format] Add AlignConsecutiveTableGenCondOperatorColons option. 
(#82878)

To align colons inside TableGen !cond operators.

Added: 


Modified: 
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/WhitespaceManager.cpp
clang/lib/Format/WhitespaceManager.h
clang/unittests/Format/FormatTestTableGen.cpp

Removed: 




diff  --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 6515b166001910..d509bb80767979 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -955,6 +955,146 @@ the configuration (without a prefix: ``Auto``).
   }
 
 
+.. _AlignConsecutiveTableGenCondOperatorColons:
+
+**AlignConsecutiveTableGenCondOperatorColons** (``AlignConsecutiveStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ 
`
+  Style of aligning consecutive TableGen cond operator colons.
+  Align the colons of cases inside !cond operators.
+
+  .. code-block:: c++
+
+!cond(!eq(size, 1) : 1,
+  !eq(size, 16): 1,
+  true : 0)
+
+  Nested configuration flags:
+
+  Alignment options.
+
+  They can also be read as a whole for compatibility. The choices are:
+  - None
+  - Consecutive
+  - AcrossEmptyLines
+  - AcrossComments
+  - AcrossEmptyLinesAndComments
+
+  For example, to align across empty lines and not across comments, either
+  of these work.
+
+  .. code-block:: c++
+
+AlignConsecutiveMacros: AcrossEmptyLines
+
+AlignConsecutiveMacros:
+  Enabled: true
+  AcrossEmptyLines: true
+  AcrossComments: false
+
+  * ``bool Enabled`` Whether aligning is enabled.
+
+.. code-block:: c++
+
+  #define SHORT_NAME   42
+  #define LONGER_NAME  0x007f
+  #define EVEN_LONGER_NAME (2)
+  #define foo(x)   (x * x)
+  #define bar(y, z)(y + z)
+
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int  : 1;
+  int b: 12;
+  int ccc  : 8;
+
+  int  = 12;
+  float   b = 23;
+  std::string ccc;
+
+  * ``bool AcrossEmptyLines`` Whether to align across empty lines.
+
+.. code-block:: c++
+
+  true:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d= 3;
+
+  false:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d = 3;
+
+  * ``bool AcrossComments`` Whether to align across comments.
+
+.. code-block:: c++
+
+  true:
+  int d= 3;
+  /* A comment. */
+  double e = 4;
+
+  false:
+  int d = 3;
+  /* A comment. */
+  double e = 4;
+
+  * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``.  Whether 
compound assignments
+like ``+=`` are aligned along with ``=``.
+
+.. code-block:: c++
+
+  true:
+  a   &= 2;
+  bbb  = 2;
+
+  false:
+  a &= 2;
+  bbb = 2;
+
+  * ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. 
Whether function pointers are
+aligned.
+
+.. code-block:: c++
+
+  true:
+  unsigned i;
+  int &r;
+  int *p;
+  int  (*f)();
+
+  false:
+  unsigned i;
+  int &r;
+  int *p;
+  int (*f)();
+
+  * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
+operators are left-padded to the same length as long ones in order to
+put all assignment operators to the right of the left hand side.
+
+.. code-block:: c++
+
+  true:
+  a   >>= 2;
+  bbb   = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+  false:
+  a >>= 2;
+  bbb = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+
 .. _AlignEscapedNewlines:
 
 **AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) 
:versionbadge:`clang-format 5` :ref:`¶ `

diff  --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 47923e06d2c2d1..449ce9e53be147 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -414,6 +414,16 @@ struct FormatStyle {
   /// \version 17
   ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;
 
+  /// Style of aligning consecutive TableGen cond operator colons.
+  /// Align the colons of cases inside !cond operators.
+  /// \code
+  ///   !cond(!eq(size, 1) : 1,
+  /// !eq(size, 16): 1,
+  /// true : 0)
+  /// \endcode
+  /// \version 19
+  AlignConsecutiveSty

[clang] [clang-format] Add AlignConsecutiveTableGenCondOperatorColons option. (PR #82878)

2024-02-26 Thread Hirofumi Nakamura via cfe-commits

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


[clang] [clang-format] Add AlignConsecutiveTableGenCondOperatorColons option. (PR #82878)

2024-02-26 Thread Hirofumi Nakamura via cfe-commits

hnakamura5 wrote:

Thank you!

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


[clang] 440b174 - [APINotes] Upstream Sema logic to apply API Notes to decls

2024-02-26 Thread via cfe-commits

Author: Egor Zhdan
Date: 2024-02-26T13:52:27Z
New Revision: 440b1743ee0c8bfb7bf0c4b503bde5ab9af88dc0

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

LOG: [APINotes] Upstream Sema logic to apply API Notes to decls

This upstreams more of the Clang API Notes functionality that is
currently implemented in the Apple fork:
https://github.com/apple/llvm-project/tree/next/clang/lib/APINotes

This was extracted from a larger PR:
https://github.com/llvm/llvm-project/pull/73017

Added: 
clang/lib/Sema/SemaAPINotes.cpp

Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/CMakeLists.txt
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaDeclObjC.cpp
clang/lib/Sema/SemaObjCProperty.cpp
clang/lib/Sema/SemaTemplate.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..dad1764ad4f861 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10760,6 +10760,13 @@ def warn_imp_cast_drops_unaligned : Warning<
 
 } // end of sema category
 
+let CategoryName = "API Notes Issue" in {
+
+def err_incompatible_replacement_type : Error<
+  "API notes replacement type %0 has a 
diff erent size from original type %1">;
+
+} // end of API Notes category
+
 let CategoryName = "OpenMP Issue" in {
 // OpenMP support.
 def err_omp_expected_var_arg : Error<

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e457694e4625db..c966a99c51968b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4883,6 +4883,12 @@ class Sema final {
   bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
 bool SkipArgCountCheck = false);
 
+  /// Map any API notes provided for this declaration to attributes on the
+  /// declaration.
+  ///
+  /// Triggered by declaration-attribute processing.
+  void ProcessAPINotes(Decl *D);
+
   /// Determine if type T is a valid subject for a nonnull and similar
   /// attributes. By default, we look through references (the behavior used by
   /// nonnull), but if the second parameter is true, then we treat a reference

diff  --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index 862f9d4ffb825d..e8bff07ced0cfa 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangSema
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
+  SemaAPINotes.cpp
   SemaAvailability.cpp
   SemaCXXScopeSpec.cpp
   SemaCast.cpp

diff  --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 00..836c633e9d2042
--- /dev/null
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,988 @@
+//===--- SemaAPINotes.cpp - API Notes Handling 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===--===//
+
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+
+namespace {
+enum class IsActive_t : bool { Inactive, Active };
+enum class IsSubstitution_t : bool { Original, Replacement };
+
+struct VersionedInfoMetadata {
+  /// An empty version refers to unversioned metadata.
+  VersionTuple Version;
+  unsigned IsActive : 1;
+  unsigned IsReplacement : 1;
+
+  VersionedInfoMetadata(VersionTuple Version, IsActive_t Active,
+IsSubstitution_t Replacement)
+  : Version(Version), IsActive(Active == IsActive_t::Active),
+IsReplacement(Replacement == IsSubstitution_t::Replacement) {}
+};
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isIndirectPointerType(QualType Type) {
+  QualType Pointee = Type->getPointeeType();
+  if (Pointee.isNull())
+return false;
+
+  return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() ||
+ Pointee->isMemberPointerType();
+}
+
+/// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *D, N

[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)

2024-02-26 Thread Egor Zhdan via cfe-commits

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


[clang] [llvm] [llvm-ar][Archive] Use getDefaultTargetTriple instead of host triple for the fallback archive format. (PR #82888)

2024-02-26 Thread via cfe-commits

gbreynoo wrote:

Thanks @cjacek, LGTM once James' comment has been covered.

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


[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Krystian Stasiowski via cfe-commits

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

>From 06fe8f513866684b70b044524eba9ece9d2701c0 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Tue, 20 Feb 2024 14:03:50 -0500
Subject: [PATCH] [Clang][Sema] Defer instantiation of exception specification
 until after partial ordering when determining primary template

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/lib/Sema/SemaTemplate.cpp   | 34 +
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 14 ++--
 clang/test/CXX/except/except.spec/p13.cpp | 74 +++
 .../SemaTemplate/class-template-noexcept.cpp  | 14 +---
 5 files changed, 117 insertions(+), 21 deletions(-)
 create mode 100644 clang/test/CXX/except/except.spec/p13.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 529dd783ab7382..9e67bbb7895040 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -281,6 +281,8 @@ Bug Fixes to C++ Support
   a requires-clause lie at the same depth as those of the surrounding lambda. 
This,
   in turn, results in the wrong template argument substitution during 
constraint checking.
   (`#78524 `_)
+- Clang no longer instantiates the exception specification of discarded 
candidate function
+  templates when determining the primary template of an explicit 
specialization.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7d3d665194add1..de09a56cf59502 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -9707,6 +9707,40 @@ bool Sema::CheckFunctionTemplateSpecialization(
   // Ignore access information;  it doesn't figure into redeclaration checking.
   FunctionDecl *Specialization = cast(*Result);
 
+  // C++23 [except.spec]p13:
+  //   An exception specification is considered to be needed when:
+  //   - [...]
+  //   - the exception specification is compared to that of another declaration
+  // (e.g., an explicit specialization or an overriding virtual function);
+  //   - [...]
+  //
+  //  The exception specification of a defaulted function is evaluated as
+  //  described above only when needed; similarly, the noexcept-specifier of a
+  //  specialization of a function template or member function of a class
+  //  template is instantiated only when needed.
+  //
+  // The standard doesn't specify what the "comparison with another 
declaration"
+  // entails, nor the exact circumstances in which it occurs. Moreover, it does
+  // not state which properties of an explicit specialization must match the
+  // primary template.
+  //
+  // We assume that an explicit specialization must correspond with (per
+  // [basic.scope.scope]p4) and declare the same entity as (per [basic.link]p8)
+  // the declaration produced by substitution into the function template.
+  //
+  // Since the determination whether two function declarations correspond does
+  // not consider exception specification, we only need to instantiate it once
+  // we determine the primary template when comparing types per
+  // [basic.link]p11.1.
+  auto *SpecializationFPT =
+  Specialization->getType()->castAs();
+  // If the function has a dependent exception specification, resolve it after
+  // we have selected the primary template so we can check whether it matches.
+  if (getLangOpts().CPlusPlus17 &&
+  isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
+  !ResolveExceptionSpec(FD->getLocation(), SpecializationFPT))
+return true;
+
   FunctionTemplateSpecializationInfo *SpecInfo
 = Specialization->getTemplateSpecializationInfo();
   assert(SpecInfo && "Function template specialization info missing?");
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 47cc22310c4eec..563491f76f5478 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4632,11 +4632,9 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
Info.getLocation()))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
 
-  // If the function has a dependent exception specification, resolve it now,
-  // so we can check that the exception specification matches.
   auto *SpecializationFPT =
   Specialization->getType()->castAs();
-  if (getLangOpts().CPlusPlus17 &&
+  if (IsAddressOfFunction && getLangOpts().CPlusPlus17 &&
   isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) &&
   !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT))
 return TemplateDeductionResult::MiscellaneousDeductionFailure;
@@ -4662,11 +4660,11 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
   // specialization with respect to arguments of compatible pointer to function
   // 

[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Krystian Stasiowski via cfe-commits

sdkrystian wrote:

Also added a couple more tests since the diagnostics currently depend on 
whether instantiation occurs. 

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


[clang] 668cd1c - [OpenACC] Implement 'return' branch-out of Compute Construct (#82814)

2024-02-26 Thread via cfe-commits

Author: Erich Keane
Date: 2024-02-26T06:04:38-08:00
New Revision: 668cd1ca15a8b9c60a87e5244db9c97b3ba2e624

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

LOG: [OpenACC] Implement 'return' branch-out of Compute Construct (#82814)

Like with 'break'/'continue', returning out of a compute construct is
ill-formed, so this implements the diagnostic. However, unlike the
OpenMP implementation of this same diagnostic, OpenACC doesn't have a
concept of 'capture region', so this is implemented as just checking the
'scope'.

Added: 
clang/test/SemaOpenACC/no-branch-in-out.cpp

Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Scope.h
clang/lib/Sema/SemaStmt.cpp
clang/test/SemaOpenACC/no-branch-in-out.c

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dad1764ad4f861..57784a4ba2e388 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12210,6 +12210,7 @@ def warn_acc_clause_unimplemented
 def err_acc_construct_appertainment
 : Error<"OpenACC construct '%0' cannot be used here; it can only "
 "be used in a statement context">;
-def err_acc_branch_in_out
-: Error<"invalid branch %select{out of|into}0 OpenACC Compute Construct">;
+def err_acc_branch_in_out_compute_construct
+: Error<"invalid %select{branch|return}0 %select{out of|into}1 OpenACC "
+"Compute Construct">;
 } // end of sema component.

diff  --git a/clang/include/clang/Sema/Scope.h 
b/clang/include/clang/Sema/Scope.h
index e7f166fe3461fd..b6b5a1f3479a25 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -521,6 +521,19 @@ class Scope {
 return getFlags() & Scope::OpenACCComputeConstructScope;
   }
 
+  bool isInOpenACCComputeConstructScope() const {
+for (const Scope *S = this; S; S = S->getParent()) {
+  if (S->getFlags() & Scope::OpenACCComputeConstructScope)
+return true;
+  else if (S->getFlags() &
+   (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
+Scope::TemplateParamScope | Scope::FunctionPrototypeScope |
+Scope::AtCatchScope | Scope::ObjCMethodScope))
+return false;
+}
+return false;
+  }
+
   /// Determine whether this scope is a while/do/for statement, which can have
   /// continue statements embedded into it.
   bool isContinueScope() const {

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index fcad09a63662ba..0a5c2b23a90c8e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3361,8 +3361,9 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope 
*CurScope) {
   // of a compute construct counts as 'branching out of' the compute construct,
   // so diagnose here.
   if (S->isOpenACCComputeConstructScope())
-return StmtError(Diag(ContinueLoc, diag::err_acc_branch_in_out)
- << /*out of */ 0);
+return StmtError(
+Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
+<< /*branch*/ 0 << /*out of */ 0);
 
   CheckJumpOutOfSEHFinally(*this, ContinueLoc, *S);
 
@@ -3390,8 +3391,9 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope 
*CurScope) {
   if (S->isOpenACCComputeConstructScope() ||
   (S->isLoopScope() && S->getParent() &&
S->getParent()->isOpenACCComputeConstructScope()))
-return StmtError(Diag(BreakLoc, diag::err_acc_branch_in_out)
- << /*out of */ 0);
+return StmtError(
+Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
+<< /*branch*/ 0 << /*out of */ 0);
 
   CheckJumpOutOfSEHFinally(*this, BreakLoc, *S);
 
@@ -3947,6 +3949,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr 
*RetValExp,
   RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true);
   if (RetVal.isInvalid())
 return StmtError();
+
+  if (getCurScope()->isInOpenACCComputeConstructScope())
+return StmtError(
+Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
+<< /*return*/ 1 << /*out of */ 0);
+
   StmtResult R =
   BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true);
   if (R.isInvalid() || ExprEvalContexts.back().isDiscardedStatementContext())

diff  --git a/clang/test/SemaOpenACC/no-branch-in-out.c 
b/clang/test/SemaOpenACC/no-branch-in-out.c
index 33a171f1b68d51..f8fb40a1ca8f72 100644
--- a/clang/test/SemaOpenACC/no-branch-in-out.c
+++ b/clang/test/SemaOpenACC/no-branch-in-out.c
@@ -93,3 +93,23 @@ void BreakContinue() {
 
 }
 
+void Return() {
+#pragma acc parallel
+  {
+return;// expected-error{{invalid return out of OpenACC Compute Con

[clang] [OpenACC] Implement 'return' branch-out of Compute Construct (PR #82814)

2024-02-26 Thread Erich Keane via cfe-commits

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


[clang] [clang][analyzer] StreamChecker: Model getc, vfscanf, putc, vfprintf (PR #82476)

2024-02-26 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource updated 
https://github.com/llvm/llvm-project/pull/82476

From a21881d82fe3674b344d4a3807e9d2590c98ce93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20=C3=81lvarez=20Ayll=C3=B3n?=
 
Date: Tue, 14 Nov 2023 09:28:45 +0100
Subject: [PATCH 1/5] [clang][analyzer] StreamChecker: add more APIs,
 invalidate fscanf args

1. Model getc, vfscanf, putc, vfprintf.
2. fscanf invalidates all arguments after the format string.
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp |  39 +-
 ...ystem-header-simulator-for-simple-stream.h |   2 +-
 .../system-header-simulator-for-valist.h  |   4 +
 .../Analysis/Inputs/system-header-simulator.h |   3 +
 clang/test/Analysis/stream.c  | 128 ++
 5 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index a070f451694a3b..7938a0d30a91a3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -21,6 +21,8 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
 #include 
 #include 
 
@@ -171,7 +173,7 @@ using FnCheck = std::function;
 
 using ArgNoTy = unsigned int;
-static const ArgNoTy ArgNone = std::numeric_limits::max();
+const ArgNoTy ArgNone = std::numeric_limits::max();
 
 struct FnDescription {
   FnCheck PreFn;
@@ -179,6 +181,26 @@ struct FnDescription {
   ArgNoTy StreamArgNo;
 };
 
+[[nodiscard]] ProgramStateRef
+escapeArgsAfterIndex(ProgramStateRef State, CheckerContext &C,
+ const CallEvent &Call, unsigned FirstEscapingArgIndex) {
+  const auto *CE = Call.getOriginExpr();
+  assert(CE);
+
+  if (Call.getNumArgs() <= FirstEscapingArgIndex)
+return State;
+
+  SmallVector EscapingArgs;
+  EscapingArgs.reserve(Call.getNumArgs() - FirstEscapingArgIndex);
+  for (auto EscArgIdx :
+   llvm::seq(FirstEscapingArgIndex, Call.getNumArgs()))
+EscapingArgs.push_back(Call.getArgSVal(EscArgIdx));
+  State = State->invalidateRegions(EscapingArgs, CE, C.blockCount(),
+   C.getLocationContext(),
+   /*CausesPointerEscape=*/false);
+  return State;
+}
+
 /// Get the value of the stream argument out of the passed call event.
 /// The call should contain a function that is described by Desc.
 SVal getStreamArg(const FnDescription *Desc, const CallEvent &Call) {
@@ -396,6 +418,18 @@ class StreamChecker : public Checker FnTestDescriptions = {
@@ -997,6 +1031,9 @@ void StreamChecker::evalFscanf(const FnDescription *Desc, 
const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
+  // The pointers passed to fscanf escape and get invalidated.
+  State = escapeArgsAfterIndex(State, C, Call, /*FirstEscapingArgIndex=*/2);
+
   // Add the success state.
   // In this context "success" means there is not an EOF or other read error
   // before any item is matched in 'fscanf'. But there may be match failure,
diff --git 
a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
index 098a2208fecbe9..c26d3582149120 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
@@ -5,7 +5,7 @@
 // suppressed.
 #pragma clang system_header
 
-typedef struct __sFILE {
+typedef struct _FILE {
   unsigned char *_p;
 } FILE;
 FILE *fopen(const char *restrict, const char *restrict) __asm("_" "fopen" );
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
index 7299b61353d460..87688bd8b312f4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
@@ -10,6 +10,8 @@
 #define restrict /*restrict*/
 #endif
 
+typedef struct _FILE FILE;
+
 typedef __builtin_va_list va_list;
 
 #define va_start(ap, param) __builtin_va_start(ap, param)
@@ -21,6 +23,8 @@ int vprintf (const char *restrict format, va_list arg);
 
 int vsprintf (char *restrict s, const char *restrict format, va_list arg);
 
+int vfscanf(FILE *stream, const char *format, va_list ap);
+
 int some_library_function(int n, va_list arg);
 
 // No warning from system header.
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index 15986984802c0e..8fd51449ecc0a4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -73,6 +73,9 @@ int ferror(FILE *stream);

[clang] 7c52d0c - [clang][Interp] Try to atomic.c on Mac

2024-02-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-26T15:07:58+01:00
New Revision: 7c52d0c98187b55d2f513122c21daf49d88169a6

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

LOG: [clang][Interp] Try to atomic.c on Mac

This test was broken on MacOS, see the discussion in
https://github.com/llvm/llvm-project/commit/a35599b9ae5e7ad924b78c65f6348e0b711bad5d

Added: 


Modified: 
clang/test/AST/Interp/atomic.c

Removed: 




diff  --git a/clang/test/AST/Interp/atomic.c b/clang/test/AST/Interp/atomic.c
index 316e8d5bf35167..c5fd9ab2229341 100644
--- a/clang/test/AST/Interp/atomic.c
+++ b/clang/test/AST/Interp/atomic.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fgnuc-version=4.2.1 
-fexperimental-new-constant-interpreter -verify=both,expected %s
-// RUN: %clang_cc1 -fgnuc-version=4.2.1 -verify=both,ref %s
+// RUN: %clang_cc1 -fgnuc-version=4.2.1 -triple=i686-linux-gnu -ffreestanding 
-fexperimental-new-constant-interpreter -verify=both,expected %s
+// RUN: %clang_cc1 -fgnuc-version=4.2.1 -triple=i686-linux-gnu -ffreestanding 
-verify=both,ref %s
 
 /// FIXME: Copied from test/Sema/atomic-expr.c.
 /// this expression seems to be rejected for weird reasons,



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


[clang] [clang][analyzer] StreamChecker: Model getc, vfscanf, putc, vfprintf (PR #82476)

2024-02-26 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource updated 
https://github.com/llvm/llvm-project/pull/82476

From a21881d82fe3674b344d4a3807e9d2590c98ce93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20=C3=81lvarez=20Ayll=C3=B3n?=
 
Date: Tue, 14 Nov 2023 09:28:45 +0100
Subject: [PATCH 1/5] [clang][analyzer] StreamChecker: add more APIs,
 invalidate fscanf args

1. Model getc, vfscanf, putc, vfprintf.
2. fscanf invalidates all arguments after the format string.
---
 .../StaticAnalyzer/Checkers/StreamChecker.cpp |  39 +-
 ...ystem-header-simulator-for-simple-stream.h |   2 +-
 .../system-header-simulator-for-valist.h  |   4 +
 .../Analysis/Inputs/system-header-simulator.h |   3 +
 clang/test/Analysis/stream.c  | 128 ++
 5 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index a070f451694a3b..7938a0d30a91a3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -21,6 +21,8 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
 #include 
 #include 
 
@@ -171,7 +173,7 @@ using FnCheck = std::function;
 
 using ArgNoTy = unsigned int;
-static const ArgNoTy ArgNone = std::numeric_limits::max();
+const ArgNoTy ArgNone = std::numeric_limits::max();
 
 struct FnDescription {
   FnCheck PreFn;
@@ -179,6 +181,26 @@ struct FnDescription {
   ArgNoTy StreamArgNo;
 };
 
+[[nodiscard]] ProgramStateRef
+escapeArgsAfterIndex(ProgramStateRef State, CheckerContext &C,
+ const CallEvent &Call, unsigned FirstEscapingArgIndex) {
+  const auto *CE = Call.getOriginExpr();
+  assert(CE);
+
+  if (Call.getNumArgs() <= FirstEscapingArgIndex)
+return State;
+
+  SmallVector EscapingArgs;
+  EscapingArgs.reserve(Call.getNumArgs() - FirstEscapingArgIndex);
+  for (auto EscArgIdx :
+   llvm::seq(FirstEscapingArgIndex, Call.getNumArgs()))
+EscapingArgs.push_back(Call.getArgSVal(EscArgIdx));
+  State = State->invalidateRegions(EscapingArgs, CE, C.blockCount(),
+   C.getLocationContext(),
+   /*CausesPointerEscape=*/false);
+  return State;
+}
+
 /// Get the value of the stream argument out of the passed call event.
 /// The call should contain a function that is described by Desc.
 SVal getStreamArg(const FnDescription *Desc, const CallEvent &Call) {
@@ -396,6 +418,18 @@ class StreamChecker : public Checker FnTestDescriptions = {
@@ -997,6 +1031,9 @@ void StreamChecker::evalFscanf(const FnDescription *Desc, 
const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
+  // The pointers passed to fscanf escape and get invalidated.
+  State = escapeArgsAfterIndex(State, C, Call, /*FirstEscapingArgIndex=*/2);
+
   // Add the success state.
   // In this context "success" means there is not an EOF or other read error
   // before any item is matched in 'fscanf'. But there may be match failure,
diff --git 
a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
index 098a2208fecbe9..c26d3582149120 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-simple-stream.h
@@ -5,7 +5,7 @@
 // suppressed.
 #pragma clang system_header
 
-typedef struct __sFILE {
+typedef struct _FILE {
   unsigned char *_p;
 } FILE;
 FILE *fopen(const char *restrict, const char *restrict) __asm("_" "fopen" );
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h 
b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
index 7299b61353d460..87688bd8b312f4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-for-valist.h
@@ -10,6 +10,8 @@
 #define restrict /*restrict*/
 #endif
 
+typedef struct _FILE FILE;
+
 typedef __builtin_va_list va_list;
 
 #define va_start(ap, param) __builtin_va_start(ap, param)
@@ -21,6 +23,8 @@ int vprintf (const char *restrict format, va_list arg);
 
 int vsprintf (char *restrict s, const char *restrict format, va_list arg);
 
+int vfscanf(FILE *stream, const char *format, va_list ap);
+
 int some_library_function(int n, va_list arg);
 
 // No warning from system header.
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index 15986984802c0e..8fd51449ecc0a4 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -73,6 +73,9 @@ int ferror(FILE *stream);

[clang] [clang][analyzer] StreamChecker: Model getc, vfscanf, putc, vfprintf (PR #82476)

2024-02-26 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource edited 
https://github.com/llvm/llvm-project/pull/82476
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Defer instantiation of exception specification until after partial ordering when determining primary template (PR #82417)

2024-02-26 Thread Erich Keane via cfe-commits

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


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


[clang] [clang-format] Add AlignConsecutiveTableGenDefinitions option. (PR #83008)

2024-02-26 Thread Hirofumi Nakamura via cfe-commits

https://github.com/hnakamura5 created 
https://github.com/llvm/llvm-project/pull/83008

To align TableGen consecutive definitions.

>From 4d22f709eff00b38cce6e9f4087bea14d04424fd Mon Sep 17 00:00:00 2001
From: hnakamura5 
Date: Mon, 26 Feb 2024 23:17:55 +0900
Subject: [PATCH 1/2] [clang-format] Add AlignConsecutiveTableGenDefinitions
 option to align TableGen consecutive definitions.

---
 clang/docs/ClangFormatStyleOptions.rst| 140 ++
 clang/include/clang/Format/Format.h   |  12 ++
 clang/lib/Format/Format.cpp   |   3 +
 clang/lib/Format/WhitespaceManager.cpp|   9 +-
 clang/lib/Format/WhitespaceManager.h  |   3 +
 clang/unittests/Format/FormatTestTableGen.cpp |  14 ++
 6 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index d509bb80767979..7be66df3aec61d 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1095,6 +1095,146 @@ the configuration (without a prefix: ``Auto``).
   bbb >>= 2;
 
 
+.. _AlignConsecutiveTableGenDefinitionsColons:
+
+**AlignConsecutiveTableGenDefinitionsColons** (``AlignConsecutiveStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ 
`
+  Style of aligning consecutive TableGen definition colons.
+  This aligns the inheritance colons of consecutive definitions.
+
+  .. code-block:: c++
+
+def Def   : Parent {}
+def DefDef: Parent {}
+def DefDefDef : Parent {}
+
+  Nested configuration flags:
+
+  Alignment options.
+
+  They can also be read as a whole for compatibility. The choices are:
+  - None
+  - Consecutive
+  - AcrossEmptyLines
+  - AcrossComments
+  - AcrossEmptyLinesAndComments
+
+  For example, to align across empty lines and not across comments, either
+  of these work.
+
+  .. code-block:: c++
+
+AlignConsecutiveMacros: AcrossEmptyLines
+
+AlignConsecutiveMacros:
+  Enabled: true
+  AcrossEmptyLines: true
+  AcrossComments: false
+
+  * ``bool Enabled`` Whether aligning is enabled.
+
+.. code-block:: c++
+
+  #define SHORT_NAME   42
+  #define LONGER_NAME  0x007f
+  #define EVEN_LONGER_NAME (2)
+  #define foo(x)   (x * x)
+  #define bar(y, z)(y + z)
+
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int  : 1;
+  int b: 12;
+  int ccc  : 8;
+
+  int  = 12;
+  float   b = 23;
+  std::string ccc;
+
+  * ``bool AcrossEmptyLines`` Whether to align across empty lines.
+
+.. code-block:: c++
+
+  true:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d= 3;
+
+  false:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d = 3;
+
+  * ``bool AcrossComments`` Whether to align across comments.
+
+.. code-block:: c++
+
+  true:
+  int d= 3;
+  /* A comment. */
+  double e = 4;
+
+  false:
+  int d = 3;
+  /* A comment. */
+  double e = 4;
+
+  * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``.  Whether 
compound assignments
+like ``+=`` are aligned along with ``=``.
+
+.. code-block:: c++
+
+  true:
+  a   &= 2;
+  bbb  = 2;
+
+  false:
+  a &= 2;
+  bbb = 2;
+
+  * ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. 
Whether function pointers are
+aligned.
+
+.. code-block:: c++
+
+  true:
+  unsigned i;
+  int &r;
+  int *p;
+  int  (*f)();
+
+  false:
+  unsigned i;
+  int &r;
+  int *p;
+  int (*f)();
+
+  * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
+operators are left-padded to the same length as long ones in order to
+put all assignment operators to the right of the left hand side.
+
+.. code-block:: c++
+
+  true:
+  a   >>= 2;
+  bbb   = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+  false:
+  a >>= 2;
+  bbb = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+
 .. _AlignEscapedNewlines:
 
 **AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) 
:versionbadge:`clang-format 5` :ref:`¶ `
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 449ce9e53be147..1b66d6b9fc6ced 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -424,6 +424,16 @@ struct FormatStyle {
   /// \version 19
   AlignConsecutiveStyle AlignConsecutiveTableGenCondOperatorColons;
 
+  /// Style of aligning consecutive TableGen definition colons.
+  /// This aligns the inheritance colons of consecutive definitions.
+  /// \code
+  ///   def Def   : Parent {}
+  ///   def DefDef: Parent {}
+  ///   def DefDefDef : Parent {}
+  /// \endcode
+  /// \version 19
+  Alig

[clang] [clang-format] Add AlignConsecutiveTableGenDefinitions option. (PR #83008)

2024-02-26 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-format

@llvm/pr-subscribers-clang

Author: Hirofumi Nakamura (hnakamura5)


Changes

To align TableGen consecutive definitions.

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


6 Files Affected:

- (modified) clang/docs/ClangFormatStyleOptions.rst (+140) 
- (modified) clang/include/clang/Format/Format.h (+12) 
- (modified) clang/lib/Format/Format.cpp (+3) 
- (modified) clang/lib/Format/WhitespaceManager.cpp (+8-1) 
- (modified) clang/lib/Format/WhitespaceManager.h (+3) 
- (modified) clang/unittests/Format/FormatTestTableGen.cpp (+14) 


``diff
diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index d509bb80767979..df399a229d8d4f 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1095,6 +1095,146 @@ the configuration (without a prefix: ``Auto``).
   bbb >>= 2;
 
 
+.. _AlignConsecutiveTableGenDefinitionColons:
+
+**AlignConsecutiveTableGenDefinitionColons** (``AlignConsecutiveStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ 
`
+  Style of aligning consecutive TableGen definition colons.
+  This aligns the inheritance colons of consecutive definitions.
+
+  .. code-block:: c++
+
+def Def   : Parent {}
+def DefDef: Parent {}
+def DefDefDef : Parent {}
+
+  Nested configuration flags:
+
+  Alignment options.
+
+  They can also be read as a whole for compatibility. The choices are:
+  - None
+  - Consecutive
+  - AcrossEmptyLines
+  - AcrossComments
+  - AcrossEmptyLinesAndComments
+
+  For example, to align across empty lines and not across comments, either
+  of these work.
+
+  .. code-block:: c++
+
+AlignConsecutiveMacros: AcrossEmptyLines
+
+AlignConsecutiveMacros:
+  Enabled: true
+  AcrossEmptyLines: true
+  AcrossComments: false
+
+  * ``bool Enabled`` Whether aligning is enabled.
+
+.. code-block:: c++
+
+  #define SHORT_NAME   42
+  #define LONGER_NAME  0x007f
+  #define EVEN_LONGER_NAME (2)
+  #define foo(x)   (x * x)
+  #define bar(y, z)(y + z)
+
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int  : 1;
+  int b: 12;
+  int ccc  : 8;
+
+  int  = 12;
+  float   b = 23;
+  std::string ccc;
+
+  * ``bool AcrossEmptyLines`` Whether to align across empty lines.
+
+.. code-block:: c++
+
+  true:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d= 3;
+
+  false:
+  int a= 1;
+  int somelongname = 2;
+  double c = 3;
+
+  int d = 3;
+
+  * ``bool AcrossComments`` Whether to align across comments.
+
+.. code-block:: c++
+
+  true:
+  int d= 3;
+  /* A comment. */
+  double e = 4;
+
+  false:
+  int d = 3;
+  /* A comment. */
+  double e = 4;
+
+  * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``.  Whether 
compound assignments
+like ``+=`` are aligned along with ``=``.
+
+.. code-block:: c++
+
+  true:
+  a   &= 2;
+  bbb  = 2;
+
+  false:
+  a &= 2;
+  bbb = 2;
+
+  * ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. 
Whether function pointers are
+aligned.
+
+.. code-block:: c++
+
+  true:
+  unsigned i;
+  int &r;
+  int *p;
+  int  (*f)();
+
+  false:
+  unsigned i;
+  int &r;
+  int *p;
+  int (*f)();
+
+  * ``bool PadOperators`` Only for ``AlignConsecutiveAssignments``.  Whether 
short assignment
+operators are left-padded to the same length as long ones in order to
+put all assignment operators to the right of the left hand side.
+
+.. code-block:: c++
+
+  true:
+  a   >>= 2;
+  bbb   = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+  false:
+  a >>= 2;
+  bbb = 2;
+
+  a = 2;
+  bbb >>= 2;
+
+
 .. _AlignEscapedNewlines:
 
 **AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``) 
:versionbadge:`clang-format 5` :ref:`¶ `
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 449ce9e53be147..613f1fd168465d 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -424,6 +424,16 @@ struct FormatStyle {
   /// \version 19
   AlignConsecutiveStyle AlignConsecutiveTableGenCondOperatorColons;
 
+  /// Style of aligning consecutive TableGen definition colons.
+  /// This aligns the inheritance colons of consecutive definitions.
+  /// \code
+  ///   def Def   : Parent {}
+  ///   def DefDef: Parent {}
+  ///   def DefDefDef : Parent {}
+  /// \endcode
+  /// \version 19
+  AlignConsecutiveStyle AlignConsecutiveTableGenDefinitionColons;
+
   /// Different styles for aligning escaped newlines.
   enum EscapedNewlineAlignmentStyle : int8_t {
 

[clang] [HIP] fix host min/max in header (PR #82956)

2024-02-26 Thread Yaxun Liu via cfe-commits


@@ -1306,14 +1306,50 @@ float min(float __x, float __y) { return 
__builtin_fminf(__x, __y); }
 __DEVICE__
 double min(double __x, double __y) { return __builtin_fmin(__x, __y); }
 
+// Define host min/max functions.
+
 #if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
-__host__ inline static int min(int __arg1, int __arg2) {
-  return __arg1 < __arg2 ? __arg1 : __arg2;
-}
 
-__host__ inline static int max(int __arg1, int __arg2) {
-  return __arg1 > __arg2 ? __arg1 : __arg2;
-}
+#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
+#define DEFINE_MIN_MAX_FUNCTIONS(type1, type2) \
+static inline auto min(const type1 __a, const type2 __b) \
+  -> typename std::remove_reference::type { \
+  return (__a < __b) ? __a : __b; \
+} \
+static inline auto max(const type1 __a, const type2 __b) \
+  -> typename std::remove_reference __b ? __a : __b)>::type { \
+  return (__a > __b) ? __a : __b; \
+}
+
+// Define min and max functions for same type comparisons
+DEFINE_MIN_MAX_FUNCTIONS(int, int)

yxsamliu wrote:

sorry I was wrong about the reference.

The issue with the template approach is that it has subtle differences 
regarding overloading resolution compared with CUDA, which could lead to 
incompatibility.

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


[clang] [HIP] fix host min/max in header (PR #82956)

2024-02-26 Thread Yaxun Liu via cfe-commits

https://github.com/yxsamliu updated 
https://github.com/llvm/llvm-project/pull/82956

>From aa50cadf0baf84ea38379fd3276f306a27164007 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" 
Date: Sun, 25 Feb 2024 11:13:40 -0500
Subject: [PATCH] [HIP] fix host min/max in header

CUDA defines min/max functions for host in global namespace.
HIP header needs to define them too to be compatible.
Currently only min/max(int, int) is defined. This causes
wrong result for arguments that are out of range for int.
This patch defines host min/max functions to be compatible
with CUDA.

Fixes: SWDEV-446564
Change-Id: I73363b534db3aa9ac34ee2a136e582b3f71d5dd1
---
 clang/lib/Headers/__clang_hip_math.h | 60 ++--
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Headers/__clang_hip_math.h 
b/clang/lib/Headers/__clang_hip_math.h
index 11e1e7d032586f..8e048ab0d383aa 100644
--- a/clang/lib/Headers/__clang_hip_math.h
+++ b/clang/lib/Headers/__clang_hip_math.h
@@ -1306,14 +1306,66 @@ float min(float __x, float __y) { return 
__builtin_fminf(__x, __y); }
 __DEVICE__
 double min(double __x, double __y) { return __builtin_fmin(__x, __y); }
 
+// Define host min/max functions.
+
 #if !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
-__host__ inline static int min(int __arg1, int __arg2) {
-  return __arg1 < __arg2 ? __arg1 : __arg2;
+
+#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
+#pragma push_macro("DEFINE_MIN_MAX_FUNCTIONS")
+#define DEFINE_MIN_MAX_FUNCTIONS(ret_type, type1, type2)   
\
+  static inline ret_type min(const type1 __a, const type2 __b) {   
\
+return (__a < __b) ? __a : __b;
\
+  }
\
+  static inline ret_type max(const type1 __a, const type2 __b) {   
\
+return (__a > __b) ? __a : __b;
\
+  }
+
+// Define min and max functions for same type comparisons
+DEFINE_MIN_MAX_FUNCTIONS(int, int, int)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, unsigned int)
+DEFINE_MIN_MAX_FUNCTIONS(long, long, long)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, unsigned long)
+DEFINE_MIN_MAX_FUNCTIONS(long long, long long, long long)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long,
+ unsigned long long)
+
+// Define min and max functions for all mixed type comparisons
+DEFINE_MIN_MAX_FUNCTIONS(unsigned int, int, unsigned int)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned int, unsigned int, int)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long, long, unsigned long)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long, unsigned long, long)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, long long, unsigned long long)
+DEFINE_MIN_MAX_FUNCTIONS(unsigned long long, unsigned long long, long long)
+
+// Floating-point comparisons using built-in functions
+static inline float min(float const __a, float const __b) {
+  return __builtin_fminf(__a, __b);
+}
+static inline double min(double const __a, double const __b) {
+  return __builtin_fmin(__a, __b);
+}
+static inline double min(float const __a, double const __b) {
+  return __builtin_fmin(__a, __b);
+}
+static inline double min(double const __a, float const __b) {
+  return __builtin_fmin(__a, __b);
 }
 
-__host__ inline static int max(int __arg1, int __arg2) {
-  return __arg1 > __arg2 ? __arg1 : __arg2;
+static inline float max(float const __a, float const __b) {
+  return __builtin_fmaxf(__a, __b);
+}
+static inline double max(double const __a, double const __b) {
+  return __builtin_fmax(__a, __b);
+}
+static inline double max(float const __a, double const __b) {
+  return __builtin_fmax(__a, __b);
 }
+static inline double max(double const __a, float const __b) {
+  return __builtin_fmax(__a, __b);
+}
+
+#pragma pop_macro("DEFINE_MIN_MAX_FUNCTIONS")
+
 #endif // !defined(__HIPCC_RTC__) && !defined(__OPENMP_AMDGCN__)
 #endif
 

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


[clang] Reapply "[Clang][Sema] Diagnose function/variable templates that shadow their own template parameters (#78274)" (PR #79683)

2024-02-26 Thread Krystian Stasiowski via cfe-commits


@@ -885,16 +885,19 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation 
PointOfInstantiation,
 /// that the template parameter 'PrevDecl' is being shadowed by a new
 /// declaration at location Loc. Returns true to indicate that this is
 /// an error, and false otherwise.
-void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) 
{
+void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl,
+   bool IssueWarning) {

sdkrystian wrote:

@AaronBallman should I still wait for @cor3ntin to reply?

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-26 Thread Erich Keane via cfe-commits

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-26 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

Clang is mostly good, needs an entry in `ReleaseNotes.rst`.  Also, a Clang 
'codegen' test for templates (see the example I gave you!) would be helpful as 
well.

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


  1   2   3   4   5   >