[clang] 89071f3 - [clang] Drop unaligned from calls to readNext (NFC) (#88842)

2024-04-16 Thread via cfe-commits

Author: Kazu Hirata
Date: 2024-04-16T00:09:41-07:00
New Revision: 89071f35599ac58cde99923a376d6b75c0d49e4b

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

LOG: [clang] Drop unaligned from calls to readNext (NFC) (#88842)

Now readNext defaults to unaligned accesses.  This patch drops
unaligned to improve readability.

Added: 


Modified: 
clang/lib/APINotes/APINotesReader.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/GlobalModuleIndex.cpp
clang/lib/Serialization/MultiOnDiskHashTable.h

Removed: 




diff  --git a/clang/lib/APINotes/APINotesReader.cpp 
b/clang/lib/APINotes/APINotesReader.cpp
index fbbe9c32ce1258..dfc3beb6fa13ee 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -30,23 +30,20 @@ namespace {
 llvm::VersionTuple ReadVersionTuple(const uint8_t *&Data) {
   uint8_t NumVersions = (*Data++) & 0x03;
 
-  unsigned Major =
-  endian::readNext(Data);
+  unsigned Major = endian::readNext(Data);
   if (NumVersions == 0)
 return llvm::VersionTuple(Major);
 
-  unsigned Minor =
-  endian::readNext(Data);
+  unsigned Minor = endian::readNext(Data);
   if (NumVersions == 1)
 return llvm::VersionTuple(Major, Minor);
 
   unsigned Subminor =
-  endian::readNext(Data);
+  endian::readNext(Data);
   if (NumVersions == 2)
 return llvm::VersionTuple(Major, Minor, Subminor);
 
-  unsigned Build =
-  endian::readNext(Data);
+  unsigned Build = endian::readNext(Data);
   return llvm::VersionTuple(Major, Minor, Subminor, Build);
 }
 
@@ -71,16 +68,16 @@ class VersionedTableInfo {
 
   static std::pair ReadKeyDataLength(const uint8_t *&Data) 
{
 unsigned KeyLength =
-endian::readNext(Data);
+endian::readNext(Data);
 unsigned DataLength =
-endian::readNext(Data);
+endian::readNext(Data);
 return {KeyLength, DataLength};
   }
 
   static data_type ReadData(internal_key_type Key, const uint8_t *Data,
 unsigned Length) {
 unsigned NumElements =
-endian::readNext(Data);
+endian::readNext(Data);
 data_type Result;
 Result.reserve(NumElements);
 for (unsigned i = 0; i != NumElements; ++i) {
@@ -105,14 +102,14 @@ void ReadCommonEntityInfo(const uint8_t *&Data, 
CommonEntityInfo &Info) {
 Info.setSwiftPrivate(static_cast((UnavailableBits >> 3) & 0x01));
 
   unsigned MsgLength =
-  endian::readNext(Data);
+  endian::readNext(Data);
   Info.UnavailableMsg =
   std::string(reinterpret_cast(Data),
   reinterpret_cast(Data) + MsgLength);
   Data += MsgLength;
 
   unsigned SwiftNameLength =
-  endian::readNext(Data);
+  endian::readNext(Data);
   Info.SwiftName =
   std::string(reinterpret_cast(Data),
   reinterpret_cast(Data) + SwiftNameLength);
@@ -124,7 +121,7 @@ void ReadCommonTypeInfo(const uint8_t *&Data, 
CommonTypeInfo &Info) {
   ReadCommonEntityInfo(Data, Info);
 
   unsigned SwiftBridgeLength =
-  endian::readNext(Data);
+  endian::readNext(Data);
   if (SwiftBridgeLength > 0) {
 Info.setSwiftBridge(std::string(reinterpret_cast(Data),
 SwiftBridgeLength - 1));
@@ -132,7 +129,7 @@ void ReadCommonTypeInfo(const uint8_t *&Data, 
CommonTypeInfo &Info) {
   }
 
   unsigned ErrorDomainLength =
-  endian::readNext(Data);
+  endian::readNext(Data);
   if (ErrorDomainLength > 0) {
 Info.setNSErrorDomain(std::optional(std::string(
 reinterpret_cast(Data), ErrorDomainLength - 1)));
@@ -163,9 +160,9 @@ class IdentifierTableInfo {
 
   static std::pair ReadKeyDataLength(const uint8_t *&Data) 
{
 unsigned KeyLength =
-endian::readNext(Data);
+endian::readNext(Data);
 unsigned DataLength =
-endian::readNext(Data);
+endian::readNext(Data);
 return {KeyLength, DataLength};
   }
 
@@ -175,8 +172,7 @@ class IdentifierTableInfo {
 
   static data_type ReadData(internal_key_type key, const uint8_t *Data,
 unsigned Length) {
-return endian::readNext(
-Data);
+return endian::readNext(Data);
   }
 };
 
@@ -203,26 +199,24 @@ class ObjCContextIDTableInfo {
 
   static std::pair ReadKeyDataLength(const uint8_t *&Data) 
{
 unsigned KeyLength =
-endian::readNext(Data);
+endian::readNext(Data);
 unsigned DataLength =
-endian::readNext(Data);
+endian::readNext(Data);
 return {KeyLength, DataLength};
   }
 
   static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
 auto ParentCtxID =
-endian::readNext(Data);
+endian::readNext(Data);
 auto ContextKind =
-endian::readNext(Data);
-auto NameID =
-e

[clang] [clang] Drop unaligned from calls to readNext (NFC) (PR #88842)

2024-04-16 Thread Kazu Hirata via cfe-commits

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


[clang] [Driver] Ensure ToolChain::LibraryPaths is not empty for non-Darwin (PR #87866)

2024-04-16 Thread antoine moynault via cfe-commits

antmox wrote:

Hello @MaskRay @bazuzi,
Looks like one of the commit ([Driver] Ensure ToolChain::LibraryPaths is not 
empty for non-Darwin) broke the clang-arm64-windows-msvc-2stage bot here:
https://lab.llvm.org/buildbot/#/builders/120/builds/6489
Old compiler-rt lib seems still used 
"--dependent-lib=clang_rt.builtins-aarch64.lib"

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+///   * `ParenExpr` - The CFG takes the operator precedence into account, but
+///   otherwise omits the node afterwards.
+///
+///   * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+///   destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+/// 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);
+
+// A collection of several types of declarations, all referenced from the same
+// function.
+struct ReferencedDecls {
+  // Fields includes non-static data members.
+  FieldSet Fields;
+  // Globals includes all variables with global storage, notably including
+  // static data members and static variables declared within a function.

martinboehme wrote:

```suggestion
  // All variables with static storage duration, notably including static 
member variables and static
  // variables declared within a function.
```

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits




martinboehme wrote:

Can you add this file to clang/docs/tools/clang-formatted-files.txt?

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+///   * `ParenExpr` - The CFG takes the operator precedence into account, but
+///   otherwise omits the node afterwards.
+///
+///   * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+///   destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+/// 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);
+
+// A collection of several types of declarations, all referenced from the same
+// function.
+struct ReferencedDecls {
+  // Fields includes non-static data members.
+  FieldSet Fields;
+  // Globals includes all variables with global storage, notably including
+  // static data members and static variables declared within a function.
+  llvm::DenseSet Globals;
+  // Functions includes free functions and member functions which are
+  // referenced, but not necessarily called.
+  llvm::DenseSet Functions;
+};
+
+/// Collects and returns fields, global variables and functions that are
+/// declared in or referenced from `FD`.
+ReferencedDecls getReferencedDecls(const FunctionDecl &FD);
+} // namespace dataflow

martinboehme wrote:

```suggestion
ReferencedDecls getReferencedDecls(const FunctionDecl &FD);

} // namespace dataflow
```

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+///   * `ParenExpr` - The CFG takes the operator precedence into account, but
+///   otherwise omits the node afterwards.
+///
+///   * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+///   destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+/// 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);
+
+// A collection of several types of declarations, all referenced from the same
+// function.
+struct ReferencedDecls {
+  // Fields includes non-static data members.

martinboehme wrote:

```suggestion
  /// Non-static member variables.
```

*  Make this a Doxygen comment (three slashes)
*  No need to repeat the name of the declaration you're documenting
*  "includes" could be interpreted as "in addition to something else, includes 
non-static data members", so just dropping it.
*  Standard C++ terminology is "member variables"

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+///   * `ParenExpr` - The CFG takes the operator precedence into account, but
+///   otherwise omits the node afterwards.
+///
+///   * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+///   destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+/// 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);
+
+// A collection of several types of declarations, all referenced from the same
+// function.
+struct ReferencedDecls {
+  // Fields includes non-static data members.
+  FieldSet Fields;
+  // Globals includes all variables with global storage, notably including
+  // static data members and static variables declared within a function.
+  llvm::DenseSet Globals;
+  // Functions includes free functions and member functions which are
+  // referenced, but not necessarily called.

martinboehme wrote:

```suggestion
  // Free functions and member functions which are referenced (but not 
necessarily called).
```

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,214 @@
+//===-- ASTOps.h ---*- C++ -*-===//

martinboehme wrote:

```suggestion
//===-- ASTOps.cpp -*- C++ -*-===//
```

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,214 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/ASTOps.h"
+#include "clang/AST/ComputeDependence.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include 
+#include 
+#include 
+
+#define DEBUG_TYPE "dataflow"
+
+namespace clang::dataflow {
+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;
+  }
+
+  // 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.
+  llvm::copy_if(
+  RD->fields(), std::back_inserter(Fields),
+  [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
+  return Fields;
+}
+
+static void insertIfGlobal(const Decl &D,
+   llvm::DenseSet &Vars) {
+  if (auto *V = dyn_cast(&D))
+if (V->hasGlobalStorage())
+  Vars.insert(V);
+}
+
+static void insertIfFunction(const Decl &D,
+ llvm::DenseSet &Funcs) {
+  if (auto *FD = dyn_cast(&D))
+Funcs.insert(FD);
+}
+
+static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
+  // Use getCalleeDecl instead of getMethodDecl in order to handle
+  // pointer-to-member calls.
+  const auto *MethodDecl = dyn_cast_or_null(C.getCalleeDecl());
+  if (!MethodDecl)
+return nullptr;
+  auto *Body = dyn_cast_or_null(MethodDecl->getBody());
+  if (!Body || Body->size() != 1)
+return nullptr;
+  if (auto *RS = dyn_cast(*Body->body_begin()))
+if (auto *Return = RS->getRetValue())
+  return dyn_cast(Return->IgnoreParenImpCasts());
+  return nullptr;
+}
+
+static void getReferencedDecls(const Decl &D, FieldSet &Fields,
+   llvm::DenseSet &Vars,
+   llvm::DenseSet &Funcs) {
+  insertIfGlobal(D, Vars);
+  insertIfFunction(D, Funcs);
+  if (const auto *Decomp = dyn_cast(&D))
+for (const auto *B : Decomp->bindings())
+  if (auto *ME = dyn_cast_or_null(B->getBinding()))
+// FIXME: should we be using `E->getFoundDecl()`?
+if (const auto *FD = dyn_cast(ME->getMemberDecl()))
+  Fields.insert(FD);
+}
+
+/// Traverses `S` and inserts into `Fields`, `Vars` and `Funcs` any fields,
+/// global variables and functions that are declared in or referenced from
+/// sub-statements.
+static void getReferencedDecls(const Stmt &S, FieldSet &Fields,

martinboehme wrote:

Again, suggest a `ReferencedDecls` parameter. This would also make the multiple 
recursive calls less verbose.

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits

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

Thanks for the cleanup!

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits




martinboehme wrote:

Can you add this file to clang/docs/tools/clang-formatted-files.txt?

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -648,36 +563,13 @@ void Environment::initialize() {
 void Environment::initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl) {
   assert(FuncDecl->doesThisDeclarationHaveABody());
 
-  FieldSet Fields;
-  llvm::DenseSet Vars;
-  llvm::DenseSet Funcs;
-
-  // Look for global variable and field references in the
-  // constructor-initializers.
-  if (const auto *CtorDecl = dyn_cast(FuncDecl)) {
-for (const auto *Init : CtorDecl->inits()) {
-  if (Init->isMemberInitializer()) {
-Fields.insert(Init->getMember());
-  } else if (Init->isIndirectMemberInitializer()) {
-for (const auto *I : Init->getIndirectMember()->chain())
-  Fields.insert(cast(I));
-  }
-  const Expr *E = Init->getInit();
-  assert(E != nullptr);
-  getFieldsGlobalsAndFuncs(*E, Fields, Vars, Funcs);
-}
-// Add all fields mentioned in default member initializers.
-for (const FieldDecl *F : CtorDecl->getParent()->fields())
-  if (const auto *I = F->getInClassInitializer())
-  getFieldsGlobalsAndFuncs(*I, Fields, Vars, Funcs);
-  }
-  getFieldsGlobalsAndFuncs(*FuncDecl->getBody(), Fields, Vars, Funcs);
+  ReferencedDecls FGF = getReferencedDecls(*FuncDecl);

martinboehme wrote:

```suggestion
  ReferencedDecls Referenced = getReferencedDecls(*FuncDecl);
```

(Now that the struct is called `ReferencedDecls`, it's not clear why the 
variable should be called `FGF`.)

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -66,6 +66,35 @@ inline bool recordsEqual(const RecordStorageLocation &Loc1,
   return recordsEqual(Loc1, Env, Loc2, Env);
 }
 
+/// Helper class for initialization of a record with an `InitListExpr`.
+/// `InitListExpr::inits()` contains the initializers for both the base classes
+/// and the fields of the record; this helper class separates these out into 
two
+/// different lists. In addition, it deals with special cases associated with
+/// unions.
+class RecordInitListHelper {
+public:
+  // `InitList` must have record type.
+  RecordInitListHelper(const InitListExpr *InitList);
+
+  // Base classes with their associated initializer expressions.
+  ArrayRef> base_inits() const {
+return BaseInits;
+  }
+
+  // Fields with their associated initializer expressions.
+  ArrayRef> field_inits() const {
+return FieldInits;
+  }
+
+private:
+  SmallVector> BaseInits;
+  SmallVector> FieldInits;
+
+  // We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a
+  // member variable because we store a pointer to it in `FieldInits`.
+  std::optional ImplicitValueInitForUnion;
+};
+

martinboehme wrote:

I think this would fit better in ASTOps.h as well.

The intent of RecordOps.h is to contain functions that operate on our 
representation of record objects, i.e. `RecordStorageLocation`s. 
`RecordInitListHelper`, on the other hand, is just a more convenient way of 
accessing the initializers in an `InitListExpr` and so seems a better fit in 
ASTOps.h. (Note also that the closely related `getFieldsForInitListExpr()` 
already lives there.)

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,214 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#include "clang/Analysis/FlowSensitive/ASTOps.h"
+#include "clang/AST/ComputeDependence.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include 
+#include 
+#include 
+
+#define DEBUG_TYPE "dataflow"
+
+namespace clang::dataflow {
+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;
+  }
+
+  // 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.
+  llvm::copy_if(
+  RD->fields(), std::back_inserter(Fields),
+  [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
+  return Fields;
+}
+
+static void insertIfGlobal(const Decl &D,
+   llvm::DenseSet &Vars) {
+  if (auto *V = dyn_cast(&D))
+if (V->hasGlobalStorage())
+  Vars.insert(V);
+}
+
+static void insertIfFunction(const Decl &D,
+ llvm::DenseSet &Funcs) {
+  if (auto *FD = dyn_cast(&D))
+Funcs.insert(FD);
+}
+
+static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
+  // Use getCalleeDecl instead of getMethodDecl in order to handle
+  // pointer-to-member calls.
+  const auto *MethodDecl = dyn_cast_or_null(C.getCalleeDecl());
+  if (!MethodDecl)
+return nullptr;
+  auto *Body = dyn_cast_or_null(MethodDecl->getBody());
+  if (!Body || Body->size() != 1)
+return nullptr;
+  if (auto *RS = dyn_cast(*Body->body_begin()))
+if (auto *Return = RS->getRetValue())
+  return dyn_cast(Return->IgnoreParenImpCasts());
+  return nullptr;
+}
+
+static void getReferencedDecls(const Decl &D, FieldSet &Fields,
+   llvm::DenseSet &Vars,
+   llvm::DenseSet &Funcs) {

martinboehme wrote:

Suggest a `ReferencedDecls` parameter instead of passing `Fields`, `Vars`, and 
`Funcs` separately.

```suggestion
static void getReferencedDecls(const Decl &D, ReferencedDecls &Referenced) {
```

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to

martinboehme wrote:

```suggestion
namespace dataflow {

/// Skip past nodes that the CFG does not emit. These nodes are invisible to
```

This is the usual style in the project. (Otherwise, the namespace looks as if 
it belongs more closely to the following function than that function belongs to 
the others.)

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


[clang] [clang][dataflow] Expose getReferencedDecls and relocate free functions. (PR #88754)

2024-04-16 Thread via cfe-commits


@@ -0,0 +1,75 @@
+//===-- ASTOps.h ---*- 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
+//
+//===--===//
+//
+//  Operations on AST nodes that are used in flow-sensitive analysis.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+///   * `ParenExpr` - The CFG takes the operator precedence into account, but
+///   otherwise omits the node afterwards.
+///
+///   * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+///   destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+/// 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);
+
+// A collection of several types of declarations, all referenced from the same
+// function.
+struct ReferencedDecls {
+  // Fields includes non-static data members.
+  FieldSet Fields;
+  // Globals includes all variables with global storage, notably including
+  // static data members and static variables declared within a function.
+  llvm::DenseSet Globals;
+  // Functions includes free functions and member functions which are
+  // referenced, but not necessarily called.
+  llvm::DenseSet Functions;
+};
+
+/// Collects and returns fields, global variables and functions that are
+/// declared in or referenced from `FD`.

martinboehme wrote:

```suggestion
/// Returns declarations that are declared in or referenced from `FD`.
```

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


[clang] [X86][test] Added extra cet tests (PR #88736)

2024-04-16 Thread Isha Agarwal via cfe-commits


@@ -2,12 +2,20 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
 // FULL: #define __CET__ 3
 // CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
 
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}
+// CFPROTNONE-NOT: cf-protection-branch

iagarwa wrote:

done in latest patch

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


[clang] [X86][test] Added extra cet tests (PR #88736)

2024-04-16 Thread Isha Agarwal via cfe-commits

https://github.com/iagarwa updated 
https://github.com/llvm/llvm-project/pull/88736

>From 821c61fb4905b491176e00ea9ed322aad04c98e3 Mon Sep 17 00:00:00 2001
From: Isha Agarwal 
Date: Mon, 15 Apr 2024 06:22:34 -0700
Subject: [PATCH 1/2] [X86][test] Added extra cet tests

Updated cet test to:
-Check different modules based on different cet options
-Added negative tests also

Signed-off-by: Isha Agarwal 
---
 clang/test/CodeGen/X86/x86-cf-protection.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/clang/test/CodeGen/X86/x86-cf-protection.c 
b/clang/test/CodeGen/X86/x86-cf-protection.c
index ba63b9e17c6f63..abc6ed63d61289 100644
--- a/clang/test/CodeGen/X86/x86-cf-protection.c
+++ b/clang/test/CodeGen/X86/x86-cf-protection.c
@@ -2,6 +2,10 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
@@ -9,5 +13,9 @@
 // CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
 
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}
+// CFPROTNONE-NOT: cf-protection-branch
+// NOTCET-NOT: #define __CET__
 
 void foo() {}

>From ac2078274b367896aef6840d04e24a72012cf0ba Mon Sep 17 00:00:00 2001
From: Isha Agarwal 
Date: Mon, 15 Apr 2024 21:09:54 -0700
Subject: [PATCH 2/2] Address comments

---
 clang/test/CodeGen/X86/x86-cf-protection.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/test/CodeGen/X86/x86-cf-protection.c 
b/clang/test/CodeGen/X86/x86-cf-protection.c
index abc6ed63d61289..02aee868936b40 100644
--- a/clang/test/CodeGen/X86/x86-cf-protection.c
+++ b/clang/test/CodeGen/X86/x86-cf-protection.c
@@ -1,21 +1,22 @@
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=return %s | 
FileCheck %s --check-prefix=RETURN
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=branch %s | 
FileCheck %s --check-prefix=BRANCH
 // RUN: %clang_cc1 -E -triple i386 -dM -o - -fcf-protection=full %s   | 
FileCheck %s --check-prefix=FULL
+// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 // RUN: not %clang_cc1 -emit-llvm-only -triple i386 -target-cpu pentium-mmx 
-fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=NOCFPROT
-// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROT
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=return %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTR
+// RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=branch %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTB
 // RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=full %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTF
 // RUN: %clang_cc1 -triple=x86_64 -o - -fcf-protection=none %s -emit-llvm | 
FileCheck %s --check-prefix=CFPROTNONE
-// RUN: %clang_cc1 -E -triple=x86_64 -dM -o - -fcf-protection=none %s | 
FileCheck %s --check-prefix=NOTCET
 
 // RETURN: #define __CET__ 2
 // BRANCH: #define __CET__ 1
 // FULL: #define __CET__ 3
-// CFPROT: !{i32 8, !"cf-protection-branch", i32 1}
-
+// NOTCET-NOT: #define __CET__
 // NOCFPROT: error: option 'cf-protection=branch' cannot be specified on this 
target
+// CFPROTR: !{i32 8, !"cf-protection-return", i32 1}
+// CFPROTB: !{i32 8, !"cf-protection-branch", i32 1}
 // CFPROTF: !{i32 8, !"cf-protection-return", i32 1}
 // CFPROTF-NEXT: !{i32 8, !"cf-protection-branch", i32 1}
-// CFPROTNONE-NOT: cf-protection-branch
-// NOTCET-NOT: #define __CET__
+// CFPROTNONE-NOT: cf-protection-
 
 void foo() {}

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


[clang] d26dd58 - [StmtProfile] Don't profile the body of lambda expressions

2024-04-16 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-04-16T15:41:26+08:00
New Revision: d26dd58ca5b59032eb371b8f51d9134acdd8d3ad

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

LOG: [StmtProfile] Don't profile the body of lambda expressions

Close https://github.com/llvm/llvm-project/issues/87609

We tried to profile the body of the lambda expressions in
https://reviews.llvm.org/D153957. But as the original comments show,
it is indeed dangerous. After we tried to skip calculating the ODR
hash values recently, we have fall into this trap twice.

So in this patch, I choose to not profile the body of the lambda
expression. The signature of the lambda is still profiled.

Added: 
clang/test/Modules/hashing-decls-in-exprs-from-gmf-2.cppm

Modified: 
clang/include/clang/AST/DeclBase.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/Decl.cpp
clang/lib/AST/DeclBase.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterDecl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 2194d268fa86f0..1079993f496945 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -672,16 +672,6 @@ class alignas(8) Decl {
   /// Whether this declaration comes from explicit global module.
   bool isFromExplicitGlobalModule() const;
 
-  /// Check if we should skip checking ODRHash for declaration \param D.
-  ///
-  /// The existing ODRHash mechanism seems to be not stable enough and
-  /// the false positive ODR violation reports are annoying and we rarely see
-  /// true ODR violation reports. Also we learned that MSVC disabled ODR checks
-  /// for declarations in GMF. So we try to disable ODR checks in the GMF to
-  /// get better user experiences before we make the ODR violation checks 
stable
-  /// enough.
-  bool shouldSkipCheckingODR() const;
-
   /// Return true if this declaration has an attribute which acts as
   /// definition of the entity, such as 'alias' or 'ifunc'.
   bool hasDefiningAttr() const;

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index e3fde887f99cb7..43ee06c524b3a0 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2457,6 +2457,12 @@ class BitsUnpacker {
   uint32_t Value;
   uint32_t CurrentBitsIndex = ~0;
 };
+
+inline bool shouldSkipCheckingODR(const Decl *D) {
+  return D->getASTContext().getLangOpts().SkipODRCheckInGMF &&
+ D->isFromExplicitGlobalModule();
+}
+
 } // namespace clang
 
 #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 2b2d5a2663a18b..33b6f8611f2162 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4534,7 +4534,7 @@ unsigned FunctionDecl::getODRHash() {
   }
 
   class ODRHash Hash;
-  Hash.AddFunctionDecl(this, /*SkipBody=*/shouldSkipCheckingODR());
+  Hash.AddFunctionDecl(this);
   setHasODRHash(true);
   ODRHash = Hash.CalculateHash();
   return ODRHash;

diff  --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 66a727d9dd0c39..434926324c96ca 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1106,11 +1106,6 @@ bool Decl::isFromExplicitGlobalModule() const {
   return getOwningModule() && getOwningModule()->isExplicitGlobalModule();
 }
 
-bool Decl::shouldSkipCheckingODR() const {
-  return getASTContext().getLangOpts().SkipODRCheckInGMF &&
- isFromExplicitGlobalModule();
-}
-
 static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
 static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
 

diff  --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index d2aac1e640380f..789e4634bd293b 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2071,13 +2071,31 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
   }
 
   CXXRecordDecl *Lambda = S->getLambdaClass();
-  ID.AddInteger(Lambda->getODRHash());
-
   for (const auto &Capture : Lambda->captures()) {
 ID.AddInteger(Capture.getCaptureKind());
 if (Capture.capturesVariable())
   VisitDecl(Capture.getCapturedVar());
   }
+
+  // Profiling the body of the lambda may be dangerous during deserialization.
+  // So we'd like only to profile the signature here.
+  ODRHash Hasher;
+  // FIXME: We can't get the operator call easily by
+  // `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
+  // So we have to do something raw here.
+  for (auto *SubDecl : Lambda->decls()) {
+FunctionD

[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)

2024-04-16 Thread via cfe-commits


@@ -4429,6 +4434,284 @@ class FunctionNoProtoType : public FunctionType, public 
llvm::FoldingSetNode {
   }
 };
 
+// 
--
+
+class Decl;
+class CXXMethodDecl;
+class FunctionTypeEffectsRef;
+class FunctionTypeEffectSet;
+
+/*
+  TODO: Idea about how to move most of the FunctionEffect business out of
+  Type.h, thus removing these forward declarations.
+
+  - Keep FunctionEffect itself here but make it more minimal. Don't define 
flags
+  or any behaviors, just the Kind and an accessor.
+  - Keep FunctionEffectCondExpr here.
+  - Make FunctionProtoType and ExtProtoInfo use only ArrayRef
+  and ArrayRef.
+  - Somewhere in Sema, define ExtFunctionEffect, which holds a FunctionEffect
+and has all the behavior-related methods.
+  - There too, define the containers. FunctionTypeEffectsRef can have a
+  constructor or factory method that initializes itself from a
+  FunctionProtoType.
+*/

Sirraide wrote:

A few things that came to mind:
> Keep FunctionEffect itself here but make it more minimal. Don't define flags
  or any behaviors, just the Kind and an accessor.

I mean, keeping the flags here seems fine. The function effects are part of the 
type, so this (or a different header if it gets too long that is then included 
here) being where all of the effect-related things are declared makes sense.

> Keep FunctionEffectCondExpr here.

I don’t particularly like the name of this class because it ending with `Expr` 
suggests that it’s a new kind of expression, which it really isn’t; I’d maybe 
rename it to `FunctionEffectCondition` or sth.

> Somewhere in Sema, define ExtFunctionEffect, which holds a FunctionEffect
  and has all the behavior-related methods.

One thing to keep in mind is that Clang is divided into separate libraries; 
Sema is one of them, and so is the AST library, which is where types live. If 
the `ExtFunctionEffect` would end up being part of the `FunctionProtoType`, 
then it ought to be in the AST library. (I haven’t had the time to look at the 
changes yet; this is just me commenting on this comment here.)

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #83124)

2024-04-16 Thread via cfe-commits

https://github.com/mahtohappy updated 
https://github.com/llvm/llvm-project/pull/83124

>From 517134e20bafba3509531cdd884d617df4d8d86f Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Tue, 27 Feb 2024 03:13:51 -0800
Subject: [PATCH] [Clang][Sema] placement new initializes typedef array with
 correct size

---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/TreeTransform.h| 14 -
 .../instantiate-new-placement-size.cpp| 20 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/instantiate-new-placement-size.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 515dffa28df186..1e4a35ab432d1d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -285,6 +285,8 @@ Bug Fixes to C++ Support
   templates when determining the primary template of an explicit 
specialization.
 - Fixed a crash in Microsoft compatibility mode where unqualified dependent 
base class
   lookup searches the bases of an incomplete class.
+- placement new initializes typedef array with correct size
+  (`#41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7389a48fe56fcc..0cda78650fcc83 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12669,6 +12669,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12730,7 +12743,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
new file mode 100644
index 00..7a29d3dee8491e
--- /dev/null
+++ b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
+// Issue no: 41441
+#include 
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TArray();
+}
+
+int main()
+{
+f();
+f();
+}

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


[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)

2024-04-16 Thread via cfe-commits

Sirraide wrote:

> I think the code to do this could live in the effect set if it were under 
> Sema (as I just described)

Seeing as the effect set is part of the type, at least the parts that are 
stored in the `FunctionProtoType` can’t be in Sema and have to stay in the AST 
library.

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


[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)

2024-04-16 Thread via cfe-commits


@@ -4429,6 +4434,284 @@ class FunctionNoProtoType : public FunctionType, public 
llvm::FoldingSetNode {
   }
 };
 
+// 
--
+
+class Decl;
+class CXXMethodDecl;
+class FunctionTypeEffectsRef;
+class FunctionTypeEffectSet;
+
+/*
+  TODO: Idea about how to move most of the FunctionEffect business out of
+  Type.h, thus removing these forward declarations.
+
+  - Keep FunctionEffect itself here but make it more minimal. Don't define 
flags
+  or any behaviors, just the Kind and an accessor.
+  - Keep FunctionEffectCondExpr here.
+  - Make FunctionProtoType and ExtProtoInfo use only ArrayRef
+  and ArrayRef.
+  - Somewhere in Sema, define ExtFunctionEffect, which holds a FunctionEffect
+and has all the behavior-related methods.
+  - There too, define the containers. FunctionTypeEffectsRef can have a
+  constructor or factory method that initializes itself from a
+  FunctionProtoType.
+*/
+
+/// Represents an abstract function effect, using just an enumeration 
describing
+/// its kind.
+class FunctionEffect {
+public:
+  /// Identifies the particular effect.
+  enum class Kind : uint8_t {
+None,
+NonBlocking,
+NonAllocating,
+  };
+
+  /// Flags describing some behaviors of the effect.
+  using Flags = unsigned;
+  enum FlagBit : Flags {
+// Can verification inspect callees' implementations? (e.g. nonblocking:
+// yes, tcb+types: no)
+FE_InferrableOnCallees = 0x1,
+
+// Language constructs which effects can diagnose as disallowed.
+FE_ExcludeThrow = 0x2,
+FE_ExcludeCatch = 0x4,
+FE_ExcludeObjCMessageSend = 0x8,
+FE_ExcludeStaticLocalVars = 0x10,
+FE_ExcludeThreadLocalVars = 0x20
+  };
+
+  /// Describes the result of effects differing between a base class's virtual
+  /// method and an overriding method in a subclass.
+  enum class OverrideResult {
+Ignore,
+Warn,
+Merge // Base method's effects are merged with those of the override.
+  };
+
+private:
+  Kind FKind = Kind::None;
+
+  // Expansion: for hypothetical TCB+types, there could be one Kind for TCB,
+  // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would
+  // be considered for uniqueness.
+
+public:
+  FunctionEffect() = default;
+
+  explicit FunctionEffect(Kind K) : FKind(K) {}
+
+  /// The kind of the effect.
+  Kind kind() const { return FKind; }
+
+  /// Flags describing some behaviors of the effect.
+  Flags flags() const {
+switch (FKind) {
+case Kind::NonBlocking:
+  return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+ FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars |
+ FE_ExcludeThreadLocalVars;
+case Kind::NonAllocating:
+  // Same as NonBlocking, except without FE_ExcludeStaticLocalVars
+  return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+ FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars;
+case Kind::None:
+  break;
+}
+llvm_unreachable("unknown effect kind");
+  }
+
+  /// The description printed in diagnostics, e.g. 'nonblocking'.
+  StringRef name() const;
+
+  /// Return true if adding or removing the effect as part of a type conversion
+  /// should generate a diagnostic.
+  bool shouldDiagnoseConversion(bool Adding, QualType OldType,
+const FunctionTypeEffectsRef &OldFX,
+QualType NewType,
+const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if adding or removing the effect in a redeclaration should
+  /// generate a diagnostic.
+  bool shouldDiagnoseRedeclaration(bool Adding, const FunctionDecl 
&OldFunction,
+   const FunctionTypeEffectsRef &OldFX,
+   const FunctionDecl &NewFunction,
+   const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if adding or removing the effect in a C++ virtual method
+  /// override should generate a diagnostic.
+  OverrideResult
+  shouldDiagnoseMethodOverride(bool Adding, const CXXMethodDecl &OldMethod,
+   const FunctionTypeEffectsRef &OldFX,
+   const CXXMethodDecl &NewMethod,
+   const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if the effect is allowed to be inferred on the callee,
+  /// which is either a FunctionDecl or BlockDecl.
+  /// This is only used if the effect has FE_InferrableOnCallees flag set.
+  /// Example: This allows nonblocking(false) to prevent inference for the
+  /// function.
+  bool canInferOnFunction(const Decl &Callee) const;
+
+  // Return false for success. When true is returned for a direct call, then 
the
+  // FE_InferrableOnCallees flag may trigger inference rather than an immediate
+  // diagnostic. Caller should be assumed to have the effect (it may not hav

[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)

2024-04-16 Thread via cfe-commits


@@ -4429,6 +4434,284 @@ class FunctionNoProtoType : public FunctionType, public 
llvm::FoldingSetNode {
   }
 };
 
+// 
--
+
+class Decl;
+class CXXMethodDecl;
+class FunctionTypeEffectsRef;
+class FunctionTypeEffectSet;
+
+/*
+  TODO: Idea about how to move most of the FunctionEffect business out of
+  Type.h, thus removing these forward declarations.
+
+  - Keep FunctionEffect itself here but make it more minimal. Don't define 
flags
+  or any behaviors, just the Kind and an accessor.
+  - Keep FunctionEffectCondExpr here.
+  - Make FunctionProtoType and ExtProtoInfo use only ArrayRef
+  and ArrayRef.
+  - Somewhere in Sema, define ExtFunctionEffect, which holds a FunctionEffect
+and has all the behavior-related methods.
+  - There too, define the containers. FunctionTypeEffectsRef can have a
+  constructor or factory method that initializes itself from a
+  FunctionProtoType.
+*/
+
+/// Represents an abstract function effect, using just an enumeration 
describing
+/// its kind.
+class FunctionEffect {
+public:
+  /// Identifies the particular effect.
+  enum class Kind : uint8_t {
+None,
+NonBlocking,
+NonAllocating,
+  };
+
+  /// Flags describing some behaviors of the effect.
+  using Flags = unsigned;
+  enum FlagBit : Flags {
+// Can verification inspect callees' implementations? (e.g. nonblocking:
+// yes, tcb+types: no)
+FE_InferrableOnCallees = 0x1,
+
+// Language constructs which effects can diagnose as disallowed.
+FE_ExcludeThrow = 0x2,
+FE_ExcludeCatch = 0x4,
+FE_ExcludeObjCMessageSend = 0x8,
+FE_ExcludeStaticLocalVars = 0x10,
+FE_ExcludeThreadLocalVars = 0x20
+  };
+
+  /// Describes the result of effects differing between a base class's virtual
+  /// method and an overriding method in a subclass.
+  enum class OverrideResult {
+Ignore,
+Warn,
+Merge // Base method's effects are merged with those of the override.
+  };
+
+private:
+  Kind FKind = Kind::None;
+
+  // Expansion: for hypothetical TCB+types, there could be one Kind for TCB,
+  // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would
+  // be considered for uniqueness.
+
+public:
+  FunctionEffect() = default;
+
+  explicit FunctionEffect(Kind K) : FKind(K) {}
+
+  /// The kind of the effect.
+  Kind kind() const { return FKind; }
+
+  /// Flags describing some behaviors of the effect.
+  Flags flags() const {
+switch (FKind) {
+case Kind::NonBlocking:
+  return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+ FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars |
+ FE_ExcludeThreadLocalVars;
+case Kind::NonAllocating:
+  // Same as NonBlocking, except without FE_ExcludeStaticLocalVars
+  return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+ FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars;
+case Kind::None:
+  break;
+}
+llvm_unreachable("unknown effect kind");
+  }
+
+  /// The description printed in diagnostics, e.g. 'nonblocking'.
+  StringRef name() const;
+
+  /// Return true if adding or removing the effect as part of a type conversion
+  /// should generate a diagnostic.
+  bool shouldDiagnoseConversion(bool Adding, QualType OldType,
+const FunctionTypeEffectsRef &OldFX,
+QualType NewType,
+const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if adding or removing the effect in a redeclaration should
+  /// generate a diagnostic.
+  bool shouldDiagnoseRedeclaration(bool Adding, const FunctionDecl 
&OldFunction,
+   const FunctionTypeEffectsRef &OldFX,
+   const FunctionDecl &NewFunction,
+   const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if adding or removing the effect in a C++ virtual method
+  /// override should generate a diagnostic.
+  OverrideResult
+  shouldDiagnoseMethodOverride(bool Adding, const CXXMethodDecl &OldMethod,
+   const FunctionTypeEffectsRef &OldFX,
+   const CXXMethodDecl &NewMethod,
+   const FunctionTypeEffectsRef &NewFX) const;
+
+  /// Return true if the effect is allowed to be inferred on the callee,
+  /// which is either a FunctionDecl or BlockDecl.
+  /// This is only used if the effect has FE_InferrableOnCallees flag set.
+  /// Example: This allows nonblocking(false) to prevent inference for the
+  /// function.
+  bool canInferOnFunction(const Decl &Callee) const;
+
+  // Return false for success. When true is returned for a direct call, then 
the
+  // FE_InferrableOnCallees flag may trigger inference rather than an immediate
+  // diagnostic. Caller should be assumed to have the effect (it may not hav

[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)

2024-04-16 Thread Orlando Cazalet-Hyams via cfe-commits


@@ -5361,7 +5383,56 @@ static bool IsReconstitutableType(QualType QT) {
   return T.Reconstitutable;
 }
 
-std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const {
+bool CGDebugInfo::HasReconstitutableArgs(
+ArrayRef Args) const {
+  return llvm::all_of(Args, [&](const TemplateArgument &TA) {
+switch (TA.getKind()) {
+case TemplateArgument::Template:
+  // Easy to reconstitute - the value of the parameter in the debug
+  // info is the string name of the template. (so the template name
+  // itself won't benefit from any name rebuilding, but that's a
+  // representational limitation - maybe DWARF could be
+  // changed/improved to use some more structural representation)

OCHyams wrote:

👍 Promoted the sentence out of parens.

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


[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)

2024-04-16 Thread Orlando Cazalet-Hyams via cfe-commits


@@ -4584,6 +4584,32 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, 
const llvm::Triple &T,
 }
   }
 
+  // Emit DW_TAG_template_alias for template aliases? True by default for SCE.
+  const auto *DebugTemplateAlias = Args.getLastArg(
+  options::OPT_gtemplate_alias, options::OPT_gno_template_alias);
+  bool UseDebugTemplateAlias =
+  DebuggerTuning == llvm::DebuggerKind::SCE && RequestedDWARFVersion >= 5;
+  if (DebugTemplateAlias &&
+  checkDebugInfoOption(DebugTemplateAlias, Args, D, TC)) {
+const auto &Opt = DebugTemplateAlias->getOption();
+UseDebugTemplateAlias = Opt.matches(options::OPT_gtemplate_alias);
+  }
+  if (UseDebugTemplateAlias) {
+// DW_TAG_template_alias is a DWARFv5 feature. Warn if we can't use it.
+if (DebugTemplateAlias && RequestedDWARFVersion < 5)
+  D.Diag(diag::warn_drv_dwarf_feature_requires_version)
+  << DebugTemplateAlias->getAsString(Args) << 5
+  << RequestedDWARFVersion;
+else if (DebugTemplateAlias && EffectiveDWARFVersion < 5)
+  // The toolchain has reduced allowed dwarf version, so we can't enable
+  // -gtemplate-alias.
+  D.Diag(diag::warn_drv_dwarf_version_limited_by_target)
+  << DebugTemplateAlias->getAsString(Args) << TC.getTripleString() << 5
+  << EffectiveDWARFVersion;
+else
+  CmdArgs.push_back("-gtemplate-alias");
+  }

OCHyams wrote:

Done

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


[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)

2024-04-16 Thread Orlando Cazalet-Hyams via cfe-commits


@@ -465,3 +465,15 @@
 // MANGLED_TEMP_NAMES: error: unknown argument 
'-gsimple-template-names=mangled'; did you mean '-Xclang 
-gsimple-template-names=mangled'
 // RUN: %clang -### -target x86_64 -c -g %s 2>&1 | FileCheck 
--check-prefix=FULL_TEMP_NAMES 
--implicit-check-not=debug-forward-template-params %s
 // FULL_TEMP_NAMES-NOT: -gsimple-template-names
+
+ Test -g[no-]template-alias (enabled by default with SCE debugger tuning). 
Requires DWARFv5.
+// RUN: %clang -### -target x86_64 -c -gdwarf-5 -gsce %s 2>&1 | FileCheck %s 
--check-prefixes=TEMPLATE-ALIAS

OCHyams wrote:

This gave `clang: error: unknown argument '--target'; did you mean '-target'?`

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


[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)

2024-04-16 Thread Orlando Cazalet-Hyams via cfe-commits


@@ -1,4 +1,4 @@
-// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -ggdb -std=c++11 -S -emit-llvm %s -o - | FileCheck %s

OCHyams wrote:

Agreed, done

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


[clang] Fix UPCAddressofArraySubscriptGadget::getClaimedVarUseSites() (PR #88406)

2024-04-16 Thread via cfe-commits

juanvazquez wrote:

Ping

A gentle ping in case there is something missing on my side to get this merged. 
It's my first time contributing to LLVM. Thanks!

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


[clang] Fix missing dtor in function calls accepting trivial ABI structs (PR #88751)

2024-04-16 Thread Utkarsh Saxena via cfe-commits

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


[clang-tools-extra] [clangd] Propagate context into stdlib indexing thread (PR #87611)

2024-04-16 Thread kadir çetinkaya via cfe-commits

https://github.com/kadircet updated 
https://github.com/llvm/llvm-project/pull/87611

From cd8993935f5c5ff8a46d2741ef8c76348ab8e868 Mon Sep 17 00:00:00 2001
From: Kadir Cetinkaya 
Date: Thu, 4 Apr 2024 10:57:44 +0200
Subject: [PATCH] [clangd] Propagate context into stdlib indexing thread

Some FS implementations rely on snapshots available in the context.
---
 clang-tools-extra/clangd/ClangdServer.cpp | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 5790273d625ef1..23fe6db57fa790 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -30,6 +30,7 @@
 #include "refactor/Rename.h"
 #include "refactor/Tweak.h"
 #include "support/Cancellation.h"
+#include "support/Context.h"
 #include "support/Logger.h"
 #include "support/MemoryTree.h"
 #include "support/ThreadsafeFS.h"
@@ -112,7 +113,12 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
  // Index outlives TUScheduler (declared first)
  FIndex(FIndex),
  // shared_ptr extends lifetime
- Stdlib(Stdlib)]() mutable {
+ Stdlib(Stdlib),
+ // We have some FS implementations that rely on infomration in
+ // the context.
+ Ctx(Context::current().clone())]() mutable {
+  // Make sure we install the context into current thread.
+  WithContext C(std::move(Ctx));
   clang::noteBottomOfStack();
   IndexFileIn IF;
   IF.Symbols = indexStandardLibrary(std::move(CI), Loc, *TFS);

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


[clang-tools-extra] [clangd] Propagate context into stdlib indexing thread (PR #87611)

2024-04-16 Thread kadir çetinkaya via cfe-commits

https://github.com/kadircet updated 
https://github.com/llvm/llvm-project/pull/87611

From a5cc9640c05ad06bff6ec28c958669df4b7e8214 Mon Sep 17 00:00:00 2001
From: Kadir Cetinkaya 
Date: Thu, 4 Apr 2024 10:57:44 +0200
Subject: [PATCH] [clangd] Propagate context into stdlib indexing thread

Some FS implementations rely on snapshots available in the context.
---
 clang-tools-extra/clangd/ClangdServer.cpp | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 5790273d625ef1..1c4c2a79b5c051 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -30,6 +30,7 @@
 #include "refactor/Rename.h"
 #include "refactor/Tweak.h"
 #include "support/Cancellation.h"
+#include "support/Context.h"
 #include "support/Logger.h"
 #include "support/MemoryTree.h"
 #include "support/ThreadsafeFS.h"
@@ -112,7 +113,12 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
  // Index outlives TUScheduler (declared first)
  FIndex(FIndex),
  // shared_ptr extends lifetime
- Stdlib(Stdlib)]() mutable {
+ Stdlib(Stdlib),
+ // We have some FS implementations that rely on information in
+ // the context.
+ Ctx(Context::current().clone())]() mutable {
+  // Make sure we install the context into current thread.
+  WithContext C(std::move(Ctx));
   clang::noteBottomOfStack();
   IndexFileIn IF;
   IF.Symbols = indexStandardLibrary(std::move(CI), Loc, *TFS);

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits


@@ -370,4 +370,7 @@ def warn_missing_symbol_graph_dir : Warning<
   "Missing symbol graph output directory, defaulting to working directory">,
   InGroup;
 
+def err_ast_action_on_unparsable_source : Error<
+  "can not apply ast actions to LLVM IR file '%0'">, 

Sirraide wrote:

```suggestion
  "can not apply AST actions to LLVM IR file '%0'">, 
```

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits

https://github.com/Sirraide commented:

Not too familiar w/ the driver, but this looks fine to me except for two minor 
things.

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits


@@ -370,4 +370,7 @@ def warn_missing_symbol_graph_dir : Warning<
   "Missing symbol graph output directory, defaulting to working directory">,
   InGroup;
 
+def err_ast_action_on_unparsable_source : Error<

Sirraide wrote:

nit: Maybe a different name for this would be better? It’s not really 
‘unparseable’, seeing as we can parse LLVM IR just fine; it’s just not C++. 

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits

Sirraide wrote:

> I'm not sure if this diagnostic information makes sense, do you have any 
> suggestions?

If passing a specific command-line to Clang causes it to assert, then I’d say 
issuing a diagnostic instead is better, yeah (if this assert was only reachable 
by using Clang as a library then it’d be a different matter imo), so I think it 
does make sense, yeah.

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread via cfe-commits

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


[clang] [Clang] Diagnose apply AST consume actions on LLVM IR (PR #88602)

2024-04-16 Thread Timm Baeder via cfe-commits


@@ -370,4 +370,7 @@ def warn_missing_symbol_graph_dir : Warning<
   "Missing symbol graph output directory, defaulting to working directory">,
   InGroup;
 
+def err_ast_action_on_unparsable_source : Error<
+  "can not apply ast actions to LLVM IR file '%0'">, 

tbaederr wrote:

```suggestion
  "cannot apply ast actions to LLVM IR file '%0'">, 
```

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


[clang] [Driver] Ensure ToolChain::LibraryPaths is not empty for non-Darwin (PR #87866)

2024-04-16 Thread YunQiang Su via cfe-commits

wzssyqa wrote:

See: https://github.com/llvm/llvm-project/pull/87866
Can you have a try to add an extra option
```
-resource-dir=%S/Inputs/resource_dir
```

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


[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread Tobias Hieta via cfe-commits

https://github.com/tru created https://github.com/llvm/llvm-project/pull/88857

Previously the trivial_abi was ignored for records when targetting the 
microsoft abi, the MSVC rules where always enforced to ensure compatibility 
with MSVC. This commit changes it to be closer to the itanium abi when a record 
is marked with the trivial_abi attribute.

Fixes #87993

>From 22f627cac7b2ea08a5569bb25d9c1d054b3a7cae Mon Sep 17 00:00:00 2001
From: Tobias Hieta 
Date: Tue, 16 Apr 2024 09:38:53 +0200
Subject: [PATCH] [clang] Handle trivial_abi attribute for Microsoft ABI.

Previously the trivial_abi was ignored for records when targetting
the microsoft abi, the MSVC rules where always enforced to ensure
compatibility with MSVC. This commit changes it to be closer to
the itanium abi when a record is marked with the trivial_abi attribute.

Fixes #87993
---
 clang/docs/ReleaseNotes.rst|  4 
 clang/lib/CodeGen/MicrosoftCXXABI.cpp  |  5 +
 clang/test/CodeGenCXX/trivial_abi_msvc.cpp | 21 +
 3 files changed, 30 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/trivial_abi_msvc.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76701dc723b6c3..c5241403711726 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -63,6 +63,10 @@ ABI Changes in This Version
   MSVC uses a different mangling for these objects, compatibility is not 
affected.
   (#GH85423).
 
+- The attribute ``trivial_abi`` now works when targetting the Microsoft ABI. 
Marking
+  a struct with this attribute will now cause clang to emit ABI similar to the 
Itanium
+  ABI. This is not compatible with the Microsoft ABI. (#GH87993).
+
 AST Dumping Potentially Breaking Changes
 
 
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d38a26940a3cb6..b930913badcd3f 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1105,6 +1105,11 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl 
GD) const {
 
 static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
  CodeGenModule &CGM) {
+  // If the record is marked with the trivial_abi attribute, we don't
+  // have to conform to the standard MSVC ABI.
+  if (RD->hasAttr())
+return true;
+
   // On AArch64, HVAs that can be passed in registers can also be returned
   // in registers. (Note this is using the MSVC definition of an HVA; see
   // isPermittedToBeHomogeneousAggregate().)
diff --git a/clang/test/CodeGenCXX/trivial_abi_msvc.cpp 
b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
new file mode 100644
index 00..8826a8224c6671
--- /dev/null
+++ b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull 
align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr 
%retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+

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


[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Tobias Hieta (tru)


Changes

Previously the trivial_abi was ignored for records when targetting the 
microsoft abi, the MSVC rules where always enforced to ensure compatibility 
with MSVC. This commit changes it to be closer to the itanium abi when a record 
is marked with the trivial_abi attribute.

Fixes #87993

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+4) 
- (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+5) 
- (added) clang/test/CodeGenCXX/trivial_abi_msvc.cpp (+21) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76701dc723b6c3..c5241403711726 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -63,6 +63,10 @@ ABI Changes in This Version
   MSVC uses a different mangling for these objects, compatibility is not 
affected.
   (#GH85423).
 
+- The attribute ``trivial_abi`` now works when targetting the Microsoft ABI. 
Marking
+  a struct with this attribute will now cause clang to emit ABI similar to the 
Itanium
+  ABI. This is not compatible with the Microsoft ABI. (#GH87993).
+
 AST Dumping Potentially Breaking Changes
 
 
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d38a26940a3cb6..b930913badcd3f 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1105,6 +1105,11 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl 
GD) const {
 
 static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
  CodeGenModule &CGM) {
+  // If the record is marked with the trivial_abi attribute, we don't
+  // have to conform to the standard MSVC ABI.
+  if (RD->hasAttr())
+return true;
+
   // On AArch64, HVAs that can be passed in registers can also be returned
   // in registers. (Note this is using the MSVC definition of an HVA; see
   // isPermittedToBeHomogeneousAggregate().)
diff --git a/clang/test/CodeGenCXX/trivial_abi_msvc.cpp 
b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
new file mode 100644
index 00..8826a8224c6671
--- /dev/null
+++ b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull 
align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr 
%retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+

``




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


[clang] d6d84b5 - [analyzer] Handle builtin functions in MallocChecker (#88416)

2024-04-16 Thread via cfe-commits

Author: NagyDonat
Date: 2024-04-16T10:41:26+02:00
New Revision: d6d84b5d1448e4f2e24b467a0abcf42fe9d543e9

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

LOG: [analyzer] Handle builtin functions in MallocChecker (#88416)

This commit ensures that the `CallDescription`s in `MallocChecker` are
matched with the mode `CDM::CLibrary`, so:
- they don't match methods or functions within user-defined namespaces;
- they also match builtin variants of these functions (if any), so the
checker can model `__builtin_alloca()` like `alloca()`.

This change fixes https://github.com/llvm/llvm-project/issues/81597. New
tests were added to verify that `std::malloc` and `std::free` (from
``) are modeled, but a method that's named e.g. `free` isn't
confused with the memory release function.

The responsibility for modeling `__builtin_alloca` and
`__builtin_alloca_with_align` was moved from `BuiltinFunctionChecker` to
`MallocChecker`, to avoid buggy interactions between the checkers and
ensure that the builtin and non-builtin variants are handled by exactly
the same logic.

This change might be a step backwards for the users who don't have
`unix.Malloc` enabled; but I suspect that `__builtin_alloca()` is so
rare that it would be a waste of time to implement backwards
compatibility for them.

There were several test files that relied on `__builtin_alloca()` calls
to get an `AllocaRegion`, these were modified to enable `unix.Malloc`.
One of these files (cxx-uninitialized-object-ptr-ref.cpp) had some tests
that relied on the fact that `malloc()` was treated as a "black box" in
them, these were updated to use `calloc()` (to get initialized memory)
and `free()` (to avoid memory leak reports).

While I was developing this change, I found a very suspicious assert in
`MallocChecker`. As it isn't blocking the goals of this commit, I just
marked it with a FIXME, but I'll try to investigate and fix it in a
follow-up change.

Added: 
clang/test/Analysis/malloc-std-namespace.cpp

Modified: 
clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
clang/test/Analysis/Inputs/system-header-simulator-cxx.h
clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
clang/test/Analysis/exercise-ps.c
clang/test/Analysis/explain-svals.cpp
clang/test/Analysis/malloc.c
clang/test/Analysis/malloc.cpp
clang/test/Analysis/stack-addr-ps.c
clang/test/Analysis/stackaddrleak.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 01e46fa8591c07..1a75d7b52ad6e9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -6,7 +6,11 @@
 //
 
//===--===//
 //
-// This checker evaluates clang builtin functions.
+// This checker evaluates "standalone" clang builtin functions that are not
+// just special-cased variants of well-known non-builtin functions.
+// Builtin functions like __builtin_memcpy and __builtin_alloca should be
+// evaluated by the same checker that handles their non-builtin variant to
+// ensure that the two variants are handled consistently.
 //
 
//===--===//
 
@@ -80,25 +84,6 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call,
 return true;
   }
 
-  case Builtin::BI__builtin_alloca_with_align:
-  case Builtin::BI__builtin_alloca: {
-SValBuilder &SVB = C.getSValBuilder();
-const loc::MemRegionVal R =
-SVB.getAllocaRegionVal(CE, C.getLocationContext(), C.blockCount());
-
-// Set the extent of the region in bytes. This enables us to use the SVal
-// of the argument directly. If we saved the extent in bits, it'd be more
-// 
diff icult to reason about values like symbol*8.
-auto Size = Call.getArgSVal(0);
-if (auto DefSize = Size.getAs()) {
-  // This `getAs()` is mostly paranoia, because core.CallAndMessage reports
-  // undefined function arguments (unless it's disabled somehow).
-  state = setDynamicExtent(state, R.getRegion(), *DefSize, SVB);
-}
-C.addTransition(state->BindExpr(CE, LCtx, R));
-return true;
-  }
-
   case Builtin::BI__builtin_dynamic_object_size:
   case Builtin::BI__builtin_object_size:
   case Builtin::BI__builtin_constant_p: {

diff  --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 88fb42b6625aa4..11651fd491f743 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -40

[clang] [analyzer] Handle builtin functions in MallocChecker (PR #88416)

2024-04-16 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy ,NagyDonat
 
Message-ID:
In-Reply-To: 


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


[clang] [llvm] [ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (PR #85863)

2024-04-16 Thread Harald van Dijk via cfe-commits


@@ -645,7 +645,7 @@ LazyValueInfoImpl::solveBlockValueImpl(Value *Val, 
BasicBlock *BB) {
   // instruction is placed, even if it could legally be hoisted much higher.
   // That is unfortunate.
   PointerType *PT = dyn_cast(BBI->getType());
-  if (PT && isKnownNonZero(BBI, DL))
+  if (PT && isKnownNonZero(BBI, /*Depth=*/0, DL))

hvdijk wrote:

Thanks, I had been slightly optimistic that this was just going to be a few 
days, but it sounds like it's going to be longer. In that case I will check 
what is easiest for us (which might be to submit that LLVM change ourselves).

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


[clang] 5a46123 - Fix missing dtor in function calls accepting trivial ABI structs (#88751)

2024-04-16 Thread via cfe-commits

Author: Utkarsh Saxena
Date: 2024-04-16T11:01:03+02:00
New Revision: 5a46123ddf62900d3dc73330f699c73038645198

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

LOG: Fix missing dtor in function calls accepting trivial ABI structs (#88751)

Fixes https://github.com/llvm/llvm-project/issues/88478

Promoting the `EHCleanup` to `NormalAndEHCleanup` in `EmitCallArgs`
surfaced another bug with deactivation of normal cleanups. Here we
missed emitting CPP scope ends for deactivated normal cleanups. This
patch also fixes that bug.

We missed emitting CPP scope ends because we remove the `fallthrough`
(clears the insertion point) before deactivating normal cleanups. This
is to make the emitted "normal" cleanup code unreachable. But we still
need to emit CPP scope ends in the original basic block even for a
deactivated normal cleanup.
(This worked correctly before we did not remove `fallthrough` for
`EHCleanup`s).

Added: 


Modified: 
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGCleanup.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7a0bc6fa77b889..0c860a3ccbd2f0 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4694,11 +4694,11 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 AggValueSlot Slot = args.isUsingInAlloca()
 ? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
 
-bool DestroyedInCallee = true, NeedsEHCleanup = true;
+bool DestroyedInCallee = true, NeedsCleanup = true;
 if (const auto *RD = type->getAsCXXRecordDecl())
   DestroyedInCallee = RD->hasNonTrivialDestructor();
 else
-  NeedsEHCleanup = needsEHCleanup(type.isDestructedType());
+  NeedsCleanup = type.isDestructedType();
 
 if (DestroyedInCallee)
   Slot.setExternallyDestructed();
@@ -4707,14 +4707,15 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 RValue RV = Slot.asRValue();
 args.add(RV, type);
 
-if (DestroyedInCallee && NeedsEHCleanup) {
+if (DestroyedInCallee && NeedsCleanup) {
   // Create a no-op GEP between the placeholder and the cleanup so we can
   // RAUW it successfully.  It also serves as a marker of the first
   // instruction where the cleanup is active.
-  pushFullExprCleanup(EHCleanup, Slot.getAddress(),
-  type);
+  pushFullExprCleanup(NormalAndEHCleanup,
+  Slot.getAddress(), type);
   // This unreachable is a temporary marker which will be removed later.
-  llvm::Instruction *IsActive = Builder.CreateUnreachable();
+  llvm::Instruction *IsActive =
+  Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
   args.addArgCleanupDeactivation(EHStack.stable_begin(), IsActive);
 }
 return;

diff  --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index 5bf48bc22a5495..8683f19d9da28e 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -634,12 +634,19 @@ static void destroyOptimisticNormalEntry(CodeGenFunction 
&CGF,
 /// Pops a cleanup block.  If the block includes a normal cleanup, the
 /// current insertion point is threaded through the cleanup, as are
 /// any branch fixups on the cleanup.
-void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
+void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
+  bool ForDeactivation) {
   assert(!EHStack.empty() && "cleanup stack is empty!");
   assert(isa(*EHStack.begin()) && "top not a cleanup!");
   EHCleanupScope &Scope = cast(*EHStack.begin());
   assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
 
+  // If we are deactivating a normal cleanup, we need to pretend that the
+  // fallthrough is unreachable. We restore this IP before returning.
+  CGBuilderTy::InsertPoint NormalDeactivateOrigIP;
+  if (ForDeactivation && (Scope.isNormalCleanup() || !getLangOpts().EHAsynch)) 
{
+NormalDeactivateOrigIP = Builder.saveAndClearIP();
+  }
   // Remember activation information.
   bool IsActive = Scope.isActive();
   Address NormalActiveFlag =
@@ -729,6 +736,8 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough) {
 EHStack.popCleanup(); // safe because there are no fixups
 assert(EHStack.getNumBranchFixups() == 0 ||
EHStack.hasNormalCleanups());
+if (NormalDeactivateOrigIP.isSet())
+  Builder.restoreIP(NormalDeactivateOrigIP);
 return;
   }
 
@@ -765,9 +774,16 @@ void CodeGenFunction::PopCleanupBlock(bool 
Fallth

[clang] Fix missing dtor in function calls accepting trivial ABI structs (PR #88751)

2024-04-16 Thread Utkarsh Saxena via cfe-commits

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #83124)

2024-04-16 Thread via cfe-commits

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


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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #83124)

2024-04-16 Thread via cfe-commits


@@ -285,6 +285,8 @@ Bug Fixes to C++ Support
   templates when determining the primary template of an explicit 
specialization.
 - Fixed a crash in Microsoft compatibility mode where unqualified dependent 
base class
   lookup searches the bases of an incomplete class.
+- placement new initializes typedef array with correct size
+  (`#41441 `_)

cor3ntin wrote:

```suggestion
  (#GH41441)
```

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


[clang] 9141e1c - [clang][Interp] Gracefully handle bitcasts to non-primitive types

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T11:08:30+02:00
New Revision: 9141e1c24f87e5735bc4178a018eba4bdf2750aa

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

LOG: [clang][Interp] Gracefully handle bitcasts to non-primitive types

We were calling classfiyPrim() instead of classify().

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 01ec31e4077f70..5866228663dca2 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -262,7 +262,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
   return this->discard(SubExpr);
 
 std::optional FromT = classify(SubExpr->getType());
-std::optional ToT = classifyPrim(CE->getType());
+std::optional ToT = classify(CE->getType());
 if (!FromT || !ToT)
   return false;
 

diff  --git a/clang/test/AST/Interp/vectors.cpp 
b/clang/test/AST/Interp/vectors.cpp
index 8afef3c897bff7..fb5787a9eda9a9 100644
--- a/clang/test/AST/Interp/vectors.cpp
+++ b/clang/test/AST/Interp/vectors.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter 
-verify=expected,both %s
 // RUN: %clang_cc1 -verify=ref,both %s
 
-// both-no-diagnostics
+// ref-no-diagnostics
 
 typedef int __attribute__((vector_size(16))) VI4;
 constexpr VI4 A = {1,2,3,4};
@@ -20,3 +20,9 @@ namespace Vector {
   }
   constexpr auto v2 = g(4);
 }
+
+/// FIXME: We need to support BitCasts between vector types.
+namespace {
+  typedef float __attribute__((vector_size(16))) VI42;
+  constexpr VI42 A2 = A; // expected-error {{must be initialized by a constant 
expression}}
+}



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


[clang] 485d556 - [clang][Interp][NFC] Add Block::dump()

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T11:15:11+02:00
New Revision: 485d556d8c23b54da952e75c3cadc9db3050fd9e

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

LOG: [clang][Interp][NFC] Add Block::dump()

Added: 


Modified: 
clang/lib/AST/Interp/Disasm.cpp
clang/lib/AST/Interp/InterpBlock.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index 022b394e58e643..ebc4e4f195ba62 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -264,3 +264,19 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, 
unsigned Indentation,
 ++I;
   }
 }
+
+LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const {
+  {
+ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_BLUE, true});
+OS << "Block " << (void *)this << "\n";
+  }
+  unsigned NPointers = 0;
+  for (const Pointer *P = Pointers; P; P = P->Next) {
+++NPointers;
+  }
+  OS << "  Pointers: " << NPointers << "\n";
+  OS << "  Dead: " << IsDead << "\n";
+  OS << "  Static: " << IsStatic << "\n";
+  OS << "  Extern: " << IsExtern << "\n";
+  OS << "  Initialized: " << IsInitialized << "\n";
+}

diff  --git a/clang/lib/AST/Interp/InterpBlock.h 
b/clang/lib/AST/Interp/InterpBlock.h
index 9db82567d2d5d6..6d5856fbd4ea19 100644
--- a/clang/lib/AST/Interp/InterpBlock.h
+++ b/clang/lib/AST/Interp/InterpBlock.h
@@ -118,6 +118,9 @@ class Block final {
 IsInitialized = false;
   }
 
+  void dump() const { dump(llvm::errs()); }
+  void dump(llvm::raw_ostream &OS) const;
+
 protected:
   friend class Pointer;
   friend class DeadBlock;



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


[clang] 58b49ce - [clang][Interp] Support __builtin_vectorelements

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T11:21:41+02:00
New Revision: 58b49cef1d772a922a433fd4a42e41db3f18d34b

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

LOG: [clang][Interp] Support __builtin_vectorelements

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 5866228663dca2..93059edc4622f8 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1251,6 +1251,15 @@ bool 
ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr(
 return this->emitConst(Size.getQuantity(), E);
   }
 
+  if (Kind == UETT_VectorElements) {
+if (const auto *VT = E->getTypeOfArgument()->getAs())
+  return this->emitConst(VT->getNumElements(), E);
+
+// FIXME: Apparently we need to catch the fact that a sizeless vector type
+// has been passed and diagnose that (at run time).
+assert(E->getTypeOfArgument()->isSizelessVectorType());
+  }
+
   return false;
 }
 

diff  --git a/clang/test/AST/Interp/vectors.cpp 
b/clang/test/AST/Interp/vectors.cpp
index fb5787a9eda9a9..6c5d916f51f563 100644
--- a/clang/test/AST/Interp/vectors.cpp
+++ b/clang/test/AST/Interp/vectors.cpp
@@ -13,12 +13,14 @@ namespace Vector {
 return VI4 { n * 3, n + 4, n - 5, n / 6 };
   }
   constexpr auto v1 = f(10);
+  static_assert(__builtin_vectorelements(v1) == (16 / sizeof(int)), "");
 
   typedef double __attribute__((vector_size(32))) VD4;
   constexpr VD4 g(int n) {
 return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 };
   }
   constexpr auto v2 = g(4);
+  static_assert(__builtin_vectorelements(v2) == (32 / sizeof(double)), "");
 }
 
 /// FIXME: We need to support BitCasts between vector types.



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


[clang] ca4cf97 - [clang][Interp][NFC] Fix Pointer::isZero() for block pointers

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T11:45:03+02:00
New Revision: ca4cf973279a3991248056a73bcb2bac8b37d035

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

LOG: [clang][Interp][NFC] Fix Pointer::isZero() for block pointers

We don't need to consider the offset here anymore since we now
have proper integral pointers.

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index fcd00aac62f93e..b4475577b74625 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -241,13 +241,10 @@ class Pointer {
 
   /// Checks if the pointer is null.
   bool isZero() const {
-if (Offset != 0)
-  return false;
-
 if (isBlockPointer())
   return asBlockPointer().Pointee == nullptr;
 assert(isIntegralPointer());
-return asIntPointer().Value == 0;
+return asIntPointer().Value == 0 && Offset == 0;
   }
   /// Checks if the pointer is live.
   bool isLive() const {



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


[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-16 Thread via cfe-commits

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

See also discussion in #88726.


>From 3da6980d1957c19bdb821c6059c032b1e1c55863 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 16 Apr 2024 09:52:35 +
Subject: [PATCH] [clang][dataflow] Refactor `PropagateResultObject()` with a
 switch statement.

See also discussion in #88726.
---
 .../FlowSensitive/DataflowEnvironment.cpp | 128 ++
 1 file changed, 71 insertions(+), 57 deletions(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..86b42b12c93e94 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -500,72 +500,86 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 
 ResultObjectMap[E] = Loc;
 
-// The following AST node kinds are "original initializers": They are the
-// lowest-level AST node that initializes a given object, and nothing
-// below them can initialize the same object (or part of it).
-if (isa(E) || isa(E) || isa(E) ||
-isa(E) || isa(E) ||
-isa(E)) {
-  return;
-}
-if (auto *Op = dyn_cast(E);
-Op && Op->getOpcode() == BO_Cmp) {
-  // Builtin `<=>` returns a `std::strong_ordering` object.
-  return;
-}
-
-if (auto *InitList = dyn_cast(E)) {
-  if (!InitList->isSemanticForm())
+switch(E->getStmtClass()) {
+  // The following AST node kinds are "original initializers": They are the
+  // lowest-level AST node that initializes a given object, and nothing
+  // below them can initialize the same object (or part of it).
+  case Stmt::CXXConstructExprClass:
+  case Stmt::CallExprClass:
+  case Stmt::LambdaExprClass:
+  case Stmt::CXXDefaultArgExprClass:
+  case Stmt::CXXDefaultInitExprClass:
+  case Stmt::CXXStdInitializerListExprClass:
+return;
+  case Stmt::BinaryOperatorClass: {
+auto *Op = cast(E);
+if (Op->getOpcode() == BO_Cmp) {
+  // Builtin `<=>` returns a `std::strong_ordering` object. We
+  // consider this to be an "original" initializer too (see above).
+  return;
+}
+if (Op->isCommaOp()) {
+  PropagateResultObject(Op->getRHS(), Loc);
+  return;
+}
+// We don't expect any other binary operators to produce a record
+// prvalue, so if we get here, we've hit some case we don't know
+// about.
+assert(false);
 return;
-  if (InitList->isTransparent()) {
-PropagateResultObject(InitList->getInit(0), Loc);
+  }
+  case Stmt::BinaryConditionalOperatorClass:
+  case Stmt::ConditionalOperatorClass: {
+auto *Cond = cast(E);
+PropagateResultObject(Cond->getTrueExpr(), Loc);
+PropagateResultObject(Cond->getFalseExpr(), Loc);
 return;
   }
+  case Stmt::InitListExprClass: {
+auto *InitList = cast(E);
+if (!InitList->isSemanticForm())
+  return;
+if (InitList->isTransparent()) {
+  PropagateResultObject(InitList->getInit(0), Loc);
+  return;
+}
 
-  RecordInitListHelper InitListHelper(InitList);
+RecordInitListHelper InitListHelper(InitList);
 
-  for (auto [Base, Init] : InitListHelper.base_inits()) {
-assert(Base->getType().getCanonicalType() ==
-   Init->getType().getCanonicalType());
+for (auto [Base, Init] : InitListHelper.base_inits()) {
+  assert(Base->getType().getCanonicalType() ==
+ Init->getType().getCanonicalType());
 
-// Storage location for the base class is the same as that of the
-// derived class because we "flatten" the object hierarchy and put all
-// fields in `RecordStorageLocation` of the derived class.
-PropagateResultObject(Init, Loc);
-  }
+  // Storage location for the base class is the same as that of the
+  // derived class because we "flatten" the object hierarchy and put 
all
+  // fields in `RecordStorageLocation` of the derived class.
+  PropagateResultObject(Init, Loc);
+}
 
-  for (auto [Field, Init] : InitListHelper.field_inits()) {
-// Fields of non-record type are handled in
-// `TransferVisitor::VisitInitListExpr()`.
-if (!Field->getType()->isRecordType())
-  continue;
-PropagateResultObject(
-Init, cast(Loc->getChild(*Field)));
+for (auto [Field, Init] : InitListHelper.field_inits()) {
+  // Fields of non-record type are handled in
+  // `TransferVisitor::VisitInitListExpr()`.
+  if (!Field->getType()->isRecordType())
+continue;
+  PropagateResultObject(
+  Init, cast(Loc->getChild(*Field)));
+}
+return;
+ 

[clang] [clang][dataflow] Fix result object location for builtin `<=>`. (PR #88726)

2024-04-16 Thread via cfe-commits


@@ -508,6 +508,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 isa(E)) {
   return;
 }
+if (auto *Op = dyn_cast(E);

martinboehme wrote:

See https://github.com/llvm/llvm-project/pull/88865 for the PR that refactors 
this into a switch statement -- let's continue discussion there.

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


[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-16 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 3c6f91e5b671321c95259dabecdbdfe4a6d69ce1 
3da6980d1957c19bdb821c6059c032b1e1c55863 -- 
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 86b42b12c9..7ef6b9d1df 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -500,85 +500,85 @@ public:
 
 ResultObjectMap[E] = Loc;
 
-switch(E->getStmtClass()) {
-  // The following AST node kinds are "original initializers": They are the
-  // lowest-level AST node that initializes a given object, and nothing
-  // below them can initialize the same object (or part of it).
-  case Stmt::CXXConstructExprClass:
-  case Stmt::CallExprClass:
-  case Stmt::LambdaExprClass:
-  case Stmt::CXXDefaultArgExprClass:
-  case Stmt::CXXDefaultInitExprClass:
-  case Stmt::CXXStdInitializerListExprClass:
+switch (E->getStmtClass()) {
+// The following AST node kinds are "original initializers": They are the
+// lowest-level AST node that initializes a given object, and nothing
+// below them can initialize the same object (or part of it).
+case Stmt::CXXConstructExprClass:
+case Stmt::CallExprClass:
+case Stmt::LambdaExprClass:
+case Stmt::CXXDefaultArgExprClass:
+case Stmt::CXXDefaultInitExprClass:
+case Stmt::CXXStdInitializerListExprClass:
+  return;
+case Stmt::BinaryOperatorClass: {
+  auto *Op = cast(E);
+  if (Op->getOpcode() == BO_Cmp) {
+// Builtin `<=>` returns a `std::strong_ordering` object. We
+// consider this to be an "original" initializer too (see above).
 return;
-  case Stmt::BinaryOperatorClass: {
-auto *Op = cast(E);
-if (Op->getOpcode() == BO_Cmp) {
-  // Builtin `<=>` returns a `std::strong_ordering` object. We
-  // consider this to be an "original" initializer too (see above).
-  return;
-}
-if (Op->isCommaOp()) {
-  PropagateResultObject(Op->getRHS(), Loc);
-  return;
-}
-// We don't expect any other binary operators to produce a record
-// prvalue, so if we get here, we've hit some case we don't know
-// about.
-assert(false);
+  }
+  if (Op->isCommaOp()) {
+PropagateResultObject(Op->getRHS(), Loc);
 return;
   }
-  case Stmt::BinaryConditionalOperatorClass:
-  case Stmt::ConditionalOperatorClass: {
-auto *Cond = cast(E);
-PropagateResultObject(Cond->getTrueExpr(), Loc);
-PropagateResultObject(Cond->getFalseExpr(), Loc);
+  // We don't expect any other binary operators to produce a record
+  // prvalue, so if we get here, we've hit some case we don't know
+  // about.
+  assert(false);
+  return;
+}
+case Stmt::BinaryConditionalOperatorClass:
+case Stmt::ConditionalOperatorClass: {
+  auto *Cond = cast(E);
+  PropagateResultObject(Cond->getTrueExpr(), Loc);
+  PropagateResultObject(Cond->getFalseExpr(), Loc);
+  return;
+}
+case Stmt::InitListExprClass: {
+  auto *InitList = cast(E);
+  if (!InitList->isSemanticForm())
+return;
+  if (InitList->isTransparent()) {
+PropagateResultObject(InitList->getInit(0), Loc);
 return;
   }
-  case Stmt::InitListExprClass: {
-auto *InitList = cast(E);
-if (!InitList->isSemanticForm())
-  return;
-if (InitList->isTransparent()) {
-  PropagateResultObject(InitList->getInit(0), Loc);
-  return;
-}
 
-RecordInitListHelper InitListHelper(InitList);
+  RecordInitListHelper InitListHelper(InitList);
 
-for (auto [Base, Init] : InitListHelper.base_inits()) {
-  assert(Base->getType().getCanonicalType() ==
- Init->getType().getCanonicalType());
+  for (auto [Base, Init] : InitListHelper.base_inits()) {
+assert(Base->getType().getCanonicalType() ==
+   Init->getType().getCanonicalType());
 
-  // Storage location for the base class is the same as that of the
-  // derived class because we "flatten" the object hierarchy and put 
all
-  // fields in `RecordStorageLocation` of the derived class.
-  PropagateResultObject(Init, Loc);
-}
-
-for (auto [Field, Init] : InitListHelper.field_inits()) {
-  // Fields of non-record type are handled in
-  // `TransferVisitor::VisitInitListExpr()`.
-  if (!Field->getType()->isRecordType())
-continue;
-

[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-16 Thread via cfe-commits

martinboehme wrote:

Here's a draft that shows what `PropagateResultObject()` looks like when 
refactored using a switch statement.

I'm not sure if this is an improvement or not. I do see how this makes the case 
distinction clearer -- OTOH, we have one more level of indentation now (though 
that doesn't really hurt formatting), and there's duplication between the 
switch cases and the casts, for example:

```cxx
  case Stmt::BinaryOperatorClass: {
auto *Op = cast(E);
```

Would appreciate opinions.

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


[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread Reid Kleckner via cfe-commits


@@ -63,6 +63,10 @@ ABI Changes in This Version
   MSVC uses a different mangling for these objects, compatibility is not 
affected.
   (#GH85423).
 
+- The attribute ``trivial_abi`` now works when targetting the Microsoft ABI. 
Marking

rnk wrote:

It's overly broad to say it "works", and I suggest narrowing the scope of the 
release note. For example, there is a [major known 
issue](https://github.com/llvm/llvm-project/issues/69394) with 
`__is_trivially_relocatable`, which I think means that `trivial_abi` won't work 
the way people want it to in containers. Maybe try:
> Records carrying the ``trivial_abi`` attribute are now returned directly in 
> registers in more cases when using the Microsoft ABI. It is not possible to 
> pass ``trivial_abi`` records between MSVC and Clang, so there is no ABI 
> compatibility requirement. This is an ABI break with old versions of Clang. 
> (#GH87993) 

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


[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread Reid Kleckner via cfe-commits


@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull 
align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr 
%retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+

rnk wrote:

For completeness, please add the instance and static method return cases, since 
those are indirect for other reasons. For me, it's sufficient to check the 
function prototype, both of which should have an sret pointer:
https://godbolt.org/z/fn7vrGrKh

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


[clang] 31424be - [clang][Interp][NFC] Compare std::optionals directly

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T12:09:49+02:00
New Revision: 31424be3aef4290dd84065b9371fcd0c5014e097

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

LOG: [clang][Interp][NFC] Compare std::optionals directly

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 93059edc4622f8..4a7b40440770e3 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1624,7 +1624,7 @@ bool 
ByteCodeExprGen::VisitCompoundAssignOperator(
 return false;
   if (!this->emitLoad(*LT, E))
 return false;
-  if (*LT != *LHSComputationT) {
+  if (LT != LHSComputationT) {
 if (!this->emitCast(*LT, *LHSComputationT, E))
   return false;
   }
@@ -1680,7 +1680,7 @@ bool 
ByteCodeExprGen::VisitCompoundAssignOperator(
   }
 
   // And now cast from LHSComputationT to ResultT.
-  if (*ResultT != *LHSComputationT) {
+  if (ResultT != LHSComputationT) {
 if (!this->emitCast(*LHSComputationT, *ResultT, E))
   return false;
   }



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


[clang] a831c54 - [clang][Interp] Avoid calling invalid functions

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T12:09:49+02:00
New Revision: a831c54357c2bb7b8b457ccea22836c23e8b8625

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

LOG: [clang][Interp] Avoid calling invalid functions

Check if the non-null function pointer is even valid before calling
the function.

Added: 


Modified: 
clang/lib/AST/Interp/FunctionPointer.h
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/functions.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/FunctionPointer.h 
b/clang/lib/AST/Interp/FunctionPointer.h
index c2ea295b82bdf5..fc3d7a4214a72b 100644
--- a/clang/lib/AST/Interp/FunctionPointer.h
+++ b/clang/lib/AST/Interp/FunctionPointer.h
@@ -32,6 +32,7 @@ class FunctionPointer final {
 
   const Function *getFunction() const { return Func; }
   bool isZero() const { return !Func; }
+  bool isValid() const { return Valid; }
   bool isWeak() const {
 if (!Func || !Valid)
   return false;

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 4182254357eb9a..dd0bacd73acb10 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2236,6 +2236,10 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, 
uint32_t ArgSize,
 << const_cast(E) << E->getSourceRange();
 return false;
   }
+
+  if (!FuncPtr.isValid())
+return false;
+
   assert(F);
 
   // Check argument nullability state.

diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 4fb3c816000ab8..f9bb5d53634e0b 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -584,9 +584,20 @@ namespace VariadicOperator {
 namespace WeakCompare {
   [[gnu::weak]]void weak_method();
   static_assert(weak_method != nullptr, ""); // both-error {{not an integral 
constant expression}} \
- // both-note {{comparison against 
address of weak declaration '&weak_method' can only be performed at runtim}}
+ // both-note {{comparison against 
address of weak declaration '&weak_method' can only be performed at runtim}}
 
   constexpr auto A = &weak_method;
   static_assert(A != nullptr, ""); // both-error {{not an integral constant 
expression}} \
-   // both-note {{comparison against address of 
weak declaration '&weak_method' can only be performed at runtim}}
+   // both-note {{comparison against address 
of weak declaration '&weak_method' can only be performed at runtim}}
+}
+
+namespace FromIntegral {
+#if __cplusplus >= 202002L
+  typedef double (*DoubleFn)();
+  int a[(int)DoubleFn((void*)-1)()]; // both-error {{not allowed at file 
scope}} \
+// both-warning {{variable length arrays}}
+  int b[(int)DoubleFn((void*)(-1 + 1))()]; // both-error {{not allowed at file 
scope}} \
+   // expected-note {{evaluates to a 
null function pointer}} \
+   // both-warning {{variable length 
arrays}}
+#endif
 }



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


[clang] b0194d2 - [SEH] Ignore async exception flag when the environment is not MSVC (#88101)

2024-04-16 Thread via cfe-commits

Author: Phoebe Wang
Date: 2024-04-16T18:19:50+08:00
New Revision: b0194d2894db49d7cf4d36aed87952c3e0c6a390

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

LOG: [SEH] Ignore async exception flag when the environment is not MSVC (#88101)

Fixes #62449

Added: 
clang/test/Driver/windows-seh-async-verify.cpp

Modified: 
clang/lib/Driver/ToolChains/Clang.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 6d52eced104296..096ed14f957046 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -346,11 +346,14 @@ static bool addExceptionArgs(const ArgList &Args, 
types::ID InputType,
   bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
  false);
 
-  bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
-  options::OPT_fno_async_exceptions, false);
-  if (EHa) {
-CmdArgs.push_back("-fasync-exceptions");
-EH = true;
+  // Async exceptions are Windows MSVC only.
+  if (Triple.isWindowsMSVCEnvironment()) {
+bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
+options::OPT_fno_async_exceptions, false);
+if (EHa) {
+  CmdArgs.push_back("-fasync-exceptions");
+  EH = true;
+}
   }
 
   // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
@@ -8102,7 +8105,8 @@ struct EHFlags {
 ///  The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
 /// - c: Assume that extern "C" functions are implicitly nounwind.
 /// The default is /EHs-c-, meaning cleanups are disabled.
-static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
+static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args,
+   bool isWindowsMSVC) {
   EHFlags EH;
 
   std::vector EHArgs =
@@ -8112,8 +8116,15 @@ static EHFlags parseClangCLEHFlags(const Driver &D, 
const ArgList &Args) {
   switch (EHVal[I]) {
   case 'a':
 EH.Asynch = maybeConsumeDash(EHVal, I);
-if (EH.Asynch)
+if (EH.Asynch) {
+  // Async exceptions are Windows MSVC only.
+  if (!isWindowsMSVC) {
+EH.Asynch = false;
+D.Diag(clang::diag::warn_drv_unused_argument) << "/EHa" << EHVal;
+continue;
+  }
   EH.Synch = false;
+}
 continue;
   case 'c':
 EH.NoUnwindC = maybeConsumeDash(EHVal, I);
@@ -8177,7 +8188,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID 
InputType,
 
   const Driver &D = getToolChain().getDriver();
 
-  EHFlags EH = parseClangCLEHFlags(D, Args);
+  bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
+  EHFlags EH = parseClangCLEHFlags(D, Args, IsWindowsMSVC);
   if (!isNVPTX && (EH.Synch || EH.Asynch)) {
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");

diff  --git a/clang/test/Driver/windows-seh-async-verify.cpp 
b/clang/test/Driver/windows-seh-async-verify.cpp
new file mode 100644
index 00..5fda6a77dba049
--- /dev/null
+++ b/clang/test/Driver/windows-seh-async-verify.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang --target=x86_64-pc-windows -fasync-exceptions -fsyntax-only %s 
-### 2>&1 | FileCheck %s
+// RUN: %clang_cl --target=x86_64-pc-windows /EHa -fsyntax-only %s -### 2>&1 | 
FileCheck %s
+// RUN: %clang --target=x86_64-pc-windows-gnu -fasync-exceptions -fsyntax-only 
%s -### 2>&1 | FileCheck %s --check-prefixes=GNU-ALL,GNU
+// RUN: %clang_cl --target=x86_64-pc-windows-gnu /EHa -fsyntax-only %s -### 
2>&1 | FileCheck %s --check-prefixes=GNU-ALL,CL-GNU
+
+// CHECK-NOT: warning
+// GNU: warning: argument unused during compilation: '-fasync-exceptions' 
[-Wunused-command-line-argument]
+// CL-GNU: warning: argument unused during compilation: '/EHa' 
[-Wunused-command-line-argument]
+
+// CHECK: -fasync-exceptions
+// GNU-ALL-NOT: -fasync-exceptions
+struct S {
+union _Un {
+~_Un() {}
+char _Buf[12];
+};
+_Un _un;
+};
+
+struct Embed {
+S v2;
+};
+
+void PR62449() { Embed v{}; }



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


[clang] [SEH] Ignore async exception flag when the environment is not MSVC (PR #88101)

2024-04-16 Thread Phoebe Wang via cfe-commits

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


[clang] c09384e - [clang][Interp] Support MemberExprs pointing to VarDecls

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T12:34:35+02:00
New Revision: c09384e2b419c7b4e4167e0d0295d9018cc6169c

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

LOG: [clang][Interp] Support MemberExprs pointing to VarDecls

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 4a7b40440770e3..a069f3ec27e721 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1267,10 +1267,19 @@ template 
 bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) {
   // 'Base.Member'
   const Expr *Base = E->getBase();
+  const ValueDecl *Member = E->getMemberDecl();
 
   if (DiscardResult)
 return this->discard(Base);
 
+  if (const auto *VD = dyn_cast(Member)) {
+// I am almost confident in saying that a var decl must be static
+// and therefore registered as a global variable. But this will probably
+// turn out to be wrong some time in the future, as always.
+if (auto GlobalIndex = P.getGlobal(VD))
+  return this->emitGetPtrGlobal(*GlobalIndex, E);
+  }
+
   if (Initializing) {
 if (!this->delegate(Base))
   return false;
@@ -1280,8 +1289,6 @@ bool ByteCodeExprGen::VisitMemberExpr(const 
MemberExpr *E) {
   }
 
   // Base above gives us a pointer on the stack.
-  // TODO: Implement non-FieldDecl members.
-  const ValueDecl *Member = E->getMemberDecl();
   if (const auto *FD = dyn_cast(Member)) {
 const RecordDecl *RD = FD->getParent();
 const Record *R = getRecord(RD);

diff  --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index f251497ed70182..2c33fa1bf88432 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1309,3 +1309,11 @@ namespace pr18633 {
 func2();
   }
 }
+
+namespace {
+  struct F {
+static constexpr int Z = 12;
+  };
+  F f;
+  static_assert(f.Z == 12, "");
+}



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


[clang] 1120d8e - [clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (#88455)

2024-04-16 Thread via cfe-commits

Author: Alex Voicu
Date: 2024-04-16T11:37:29+01:00
New Revision: 1120d8e6f799121b611aa23bdc128e40cf9c6c58

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

LOG: [clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (#88455)

Currently neither the SPIR nor the SPIRV targets specify the AS for
globals in their datalayout strings. This is problematic because
CodeGen/LLVM will default to AS0 in this case, which produces Globals
that end up in the private address space for e.g. OCL, HIPSPV or SYCL.
This patch addresses it by completing the datalayout string.

Added: 


Modified: 
clang/lib/Basic/Targets/SPIR.h
clang/test/CodeGen/target-data.c
llvm/lib/IR/AutoUpgrade.cpp
llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp

Removed: 




diff  --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index e25991e3dfe821..9a4a8b501460b6 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -259,7 +259,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public 
SPIRTargetInfo {
 SizeType = TargetInfo::UnsignedInt;
 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
-"v96:128-v192:256-v256:256-v512:512-v1024:1024");
+"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
   }
 
   void getTargetDefines(const LangOptions &Opts,
@@ -276,7 +276,7 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public 
SPIRTargetInfo {
 SizeType = TargetInfo::UnsignedLong;
 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
-"v96:128-v192:256-v256:256-v512:512-v1024:1024");
+"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
   }
 
   void getTargetDefines(const LangOptions &Opts,
@@ -336,7 +336,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public 
BaseSPIRVTargetInfo {
 SizeType = TargetInfo::UnsignedInt;
 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
-"v96:128-v192:256-v256:256-v512:512-v1024:1024");
+"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
   }
 
   void getTargetDefines(const LangOptions &Opts,
@@ -357,7 +357,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public 
BaseSPIRVTargetInfo {
 SizeType = TargetInfo::UnsignedLong;
 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
-"v96:128-v192:256-v256:256-v512:512-v1024:1024");
+"v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
   }
 
   void getTargetDefines(const LangOptions &Opts,

diff  --git a/clang/test/CodeGen/target-data.c 
b/clang/test/CodeGen/target-data.c
index acff367d50eb91..c184f314f68f80 100644
--- a/clang/test/CodeGen/target-data.c
+++ b/clang/test/CodeGen/target-data.c
@@ -251,11 +251,11 @@
 
 // RUN: %clang_cc1 -triple spir-unknown -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=SPIR
-// SPIR: target datalayout = 
"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+// SPIR: target datalayout = 
"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
 
 // RUN: %clang_cc1 -triple spir64-unknown -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=SPIR64
-// SPIR64: target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+// SPIR64: target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
 
 // RUN: %clang_cc1 -triple bpfel -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=BPFEL

diff  --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 2c480fb76ee4de..634b2dd5119e8d 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5341,10 +5341,11 @@ MDNode *llvm::upgradeInstructionLoopAttachment(MDNode 
&N) {
 
 std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) {
   Triple T(TT);
-  // The only data layout upgrades needed for pre-GCN are setting the address
-  // space of globals to 1.
-  if (T.isAMDGPU() && !T.isAMDGCN() && !DL.contains("-G") &&
-  !DL.starts_with("G")) {
+  // The only data layout upgrades needed for pre-GCN, SPIR or SPIRV are 
setting
+  // the address space of globals to 1. This does not apply to SPIRV Logical.
+  if (((T.isAMDGPU() && !T.isAMDGCN()) ||
+   (T.isSPIR() || (T.isSPIRV() && !T.isSPIRVLogical( &&
+  !DL.contains("-G") && !DL.starts_with("G

[clang] [llvm] [clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (PR #88455)

2024-04-16 Thread Alex Voicu via cfe-commits

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


[clang] [llvm] [clang][CodeGen] Add AS for Globals to SPIR & SPIRV datalayouts (PR #88455)

2024-04-16 Thread Alex Voicu via cfe-commits

AlexVlx wrote:

Merged, thanks everyone for the reviews!

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


[clang] [Clang][CodeGen] Start migrating away from assuming the Default AS is 0 (PR #88182)

2024-04-16 Thread Alex Voicu via cfe-commits

https://github.com/AlexVlx updated 
https://github.com/llvm/llvm-project/pull/88182

>From 426e74cabb003eb5dc83adf347a5800d49bc87b7 Mon Sep 17 00:00:00 2001
From: Alex Voicu 
Date: Mon, 18 Mar 2024 11:49:12 +
Subject: [PATCH 1/7] Start migrating away from the embedded assumption that
 the default AS **must** be 0.

---
 clang/lib/CodeGen/CGExprCXX.cpp  |  2 +-
 clang/lib/CodeGen/CodeGenModule.cpp  | 10 ++
 clang/lib/CodeGen/CodeGenTypeCache.h |  2 +-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 2adbef6d55122c..b9c920a81d79c9 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -,7 +,7 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction 
&CGF, const Expr *E,
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
-  llvm::Type *PtrTy = llvm::PointerType::getUnqual(getLLVMContext());
+  llvm::Type *PtrTy = Int8PtrTy;
   LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
 
   auto MaybeASCast = [=](auto &&TypeInfo) {
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ceecff28cbc63..7dd14d32aa2d03 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -364,7 +364,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
   IntPtrTy = llvm::IntegerType::get(LLVMContext,
 C.getTargetInfo().getMaxPointerWidth());
-  Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
+  Int8PtrTy = llvm::PointerType::get(
+  LLVMContext, C.getTargetInfo().getTargetAddressSpace(LangAS::Default));
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
   llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
@@ -4512,9 +4513,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
 IsIncompleteFunction = true;
   }
 
-  llvm::Function *F =
-  llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
- Entry ? StringRef() : MangledName, &getModule());
+  llvm::Function *F = llvm::Function::Create(
+  FTy, llvm::Function::ExternalLinkage,
+  getDataLayout().getProgramAddressSpace(),
+  Entry ? StringRef() : MangledName, &getModule());
 
   // Store the declaration associated with this function so it is potentially
   // updated by further declarations or definitions and emitted at the end.
diff --git a/clang/lib/CodeGen/CodeGenTypeCache.h 
b/clang/lib/CodeGen/CodeGenTypeCache.h
index 083d69214fb3c2..e273ebe3b060f2 100644
--- a/clang/lib/CodeGen/CodeGenTypeCache.h
+++ b/clang/lib/CodeGen/CodeGenTypeCache.h
@@ -51,7 +51,7 @@ struct CodeGenTypeCache {
 llvm::IntegerType *PtrDiffTy;
   };
 
-  /// void*, void** in address space 0
+  /// void*, void** in the target's default address space (often 0)
   union {
 llvm::PointerType *UnqualPtrTy;
 llvm::PointerType *VoidPtrTy;

>From 74ae6f52a5f84f8fc92135df3ff93a4a89b914ed Mon Sep 17 00:00:00 2001
From: Alex Voicu 
Date: Mon, 25 Mar 2024 10:55:22 +0200
Subject: [PATCH 2/7] Make querying the Global AS more robust, add 1 new test
 (WiP).

---
 clang/lib/CodeGen/CodeGenModule.cpp   | 10 ---
 clang/lib/CodeGen/ItaniumCXXABI.cpp   |  4 ++-
 ...x11-with-nonzero-default-address-space.cpp | 29 +++
 3 files changed, 38 insertions(+), 5 deletions(-)
 create mode 100644 
clang/test/CodeGenCXX/typeid-cxx11-with-nonzero-default-address-space.cpp

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 63d54f9b1c0b60..39ccd40bf1adbb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -371,8 +371,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   const llvm::DataLayout &DL = M.getDataLayout();
   AllocaInt8PtrTy =
   llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
-  GlobalsInt8PtrTy =
-  llvm::PointerType::get(LLVMContext, DL.getDefaultGlobalsAddressSpace());
+  GlobalsInt8PtrTy = llvm::PointerType::get(
+  LLVMContext, C.getTargetAddressSpace(GetGlobalVarAddressSpace(nullptr)));
   ConstGlobalsPtrTy = llvm::PointerType::get(
   LLVMContext, C.getTargetAddressSpace(GetGlobalConstantAddressSpace()));
   ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace();
@@ -5018,7 +5018,9 @@ llvm::GlobalVariable 
*CodeGenModule::CreateOrReplaceCXXRuntimeVariable(
 
   // Create a new variable.
   GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
-Linkage, nullptr, Name);
+Linkage, nullptr, Name, nullptr,
+llvm::GlobalValue::NotThreadLocal,
+GlobalsInt8PtrTy->getAddressSpace());
 
   if (OldGV) {
 // Replace occurrences of the old variable if needed.
@@ -5133,7 +5135,7 @@ La

[clang] [clang][dataflow] Refactor `PropagateResultObject()` with a switch statement. (PR #88865)

2024-04-16 Thread via cfe-commits

https://github.com/martinboehme updated 
https://github.com/llvm/llvm-project/pull/88865

>From 440ace1337ed7a06286a4455e3e6e428d14d847d Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 16 Apr 2024 09:52:35 +
Subject: [PATCH] [clang][dataflow] Refactor `PropagateResultObject()` with a
 switch statement.

See also discussion in #88726.
---
 .../FlowSensitive/DataflowEnvironment.cpp | 68 +++
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..7ef6b9d1df5182 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -500,21 +500,43 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 
 ResultObjectMap[E] = Loc;
 
+switch (E->getStmtClass()) {
 // The following AST node kinds are "original initializers": They are the
 // lowest-level AST node that initializes a given object, and nothing
 // below them can initialize the same object (or part of it).
-if (isa(E) || isa(E) || isa(E) ||
-isa(E) || isa(E) ||
-isa(E)) {
+case Stmt::CXXConstructExprClass:
+case Stmt::CallExprClass:
+case Stmt::LambdaExprClass:
+case Stmt::CXXDefaultArgExprClass:
+case Stmt::CXXDefaultInitExprClass:
+case Stmt::CXXStdInitializerListExprClass:
+  return;
+case Stmt::BinaryOperatorClass: {
+  auto *Op = cast(E);
+  if (Op->getOpcode() == BO_Cmp) {
+// Builtin `<=>` returns a `std::strong_ordering` object. We
+// consider this to be an "original" initializer too (see above).
+return;
+  }
+  if (Op->isCommaOp()) {
+PropagateResultObject(Op->getRHS(), Loc);
+return;
+  }
+  // We don't expect any other binary operators to produce a record
+  // prvalue, so if we get here, we've hit some case we don't know
+  // about.
+  assert(false);
   return;
 }
-if (auto *Op = dyn_cast(E);
-Op && Op->getOpcode() == BO_Cmp) {
-  // Builtin `<=>` returns a `std::strong_ordering` object.
+case Stmt::BinaryConditionalOperatorClass:
+case Stmt::ConditionalOperatorClass: {
+  auto *Cond = cast(E);
+  PropagateResultObject(Cond->getTrueExpr(), Loc);
+  PropagateResultObject(Cond->getFalseExpr(), Loc);
   return;
 }
-
-if (auto *InitList = dyn_cast(E)) {
+case Stmt::InitListExprClass: {
+  auto *InitList = cast(E);
   if (!InitList->isSemanticForm())
 return;
   if (InitList->isTransparent()) {
@@ -544,28 +566,20 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
   }
   return;
 }
-
-if (auto *Op = dyn_cast(E); Op && Op->isCommaOp()) {
-  PropagateResultObject(Op->getRHS(), Loc);
+default: {
+  // All other expression nodes that propagate a record prvalue should
+  // have exactly one child.
+  SmallVector Children(E->child_begin(), E->child_end());
+  LLVM_DEBUG({
+if (Children.size() != 1)
+  E->dump();
+  });
+  assert(Children.size() == 1);
+  for (Stmt *S : Children)
+PropagateResultObject(cast(S), Loc);
   return;
 }
-
-if (auto *Cond = dyn_cast(E)) {
-  PropagateResultObject(Cond->getTrueExpr(), Loc);
-  PropagateResultObject(Cond->getFalseExpr(), Loc);
-  return;
 }
-
-// All other expression nodes that propagate a record prvalue should have
-// exactly one child.
-SmallVector Children(E->child_begin(), E->child_end());
-LLVM_DEBUG({
-  if (Children.size() != 1)
-E->dump();
-});
-assert(Children.size() == 1);
-for (Stmt *S : Children)
-  PropagateResultObject(cast(S), Loc);
   }
 
 private:

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


[clang] 32b74ca - [clang][Interp] Load value from MemberExpr if required

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T13:04:28+02:00
New Revision: 32b74ca6e41768c91eee8b8ca26235b110a65deb

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

LOG: [clang][Interp] Load value from MemberExpr if required

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a069f3ec27e721..00c4a9f161304a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1272,12 +1272,23 @@ bool ByteCodeExprGen::VisitMemberExpr(const 
MemberExpr *E) {
   if (DiscardResult)
 return this->discard(Base);
 
+  // MemberExprs are almost always lvalues, in which case we don't need to
+  // do the load. But sometimes they aren't.
+  const auto maybeLoadValue = [&]() -> bool {
+if (E->isGLValue())
+  return true;
+if (std::optional T = classify(E))
+  return this->emitLoadPop(*T, E);
+return false;
+  };
+
   if (const auto *VD = dyn_cast(Member)) {
 // I am almost confident in saying that a var decl must be static
 // and therefore registered as a global variable. But this will probably
 // turn out to be wrong some time in the future, as always.
 if (auto GlobalIndex = P.getGlobal(VD))
-  return this->emitGetPtrGlobal(*GlobalIndex, E);
+  return this->emitGetPtrGlobal(*GlobalIndex, E) && maybeLoadValue();
+return false;
   }
 
   if (Initializing) {
@@ -1295,8 +1306,8 @@ bool ByteCodeExprGen::VisitMemberExpr(const 
MemberExpr *E) {
 const Record::Field *F = R->getField(FD);
 // Leave a pointer to the field on the stack.
 if (F->Decl->getType()->isReferenceType())
-  return this->emitGetFieldPop(PT_Ptr, F->Offset, E);
-return this->emitGetPtrField(F->Offset, E);
+  return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
+return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
   }
 
   return false;

diff  --git a/clang/test/AST/Interp/cxx03.cpp b/clang/test/AST/Interp/cxx03.cpp
index d30cbb2fd7a201..b6aaf0840cfb36 100644
--- a/clang/test/AST/Interp/cxx03.cpp
+++ b/clang/test/AST/Interp/cxx03.cpp
@@ -10,3 +10,17 @@ namespace NonInitializingMemberExpr {

   // both-note {{required by}} \

   // both-note {{subexpression not valid}}
 }
+
+
+namespace NonLValueMemberExpr {
+  struct PODType {
+int value;
+  };
+
+#define ATTR __attribute__((require_constant_initialization))
+  struct TT1 {
+ATTR static const int &subobj_init;
+  };
+
+  const int &TT1::subobj_init = PODType().value;
+}



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


[clang] [clang][dataflow] Support `StmtExpr` in `PropagateResultObject()`. (PR #88872)

2024-04-16 Thread via cfe-commits

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

This patch adds a test that assert-fails without the fix.


>From b2df2208aaee019279afe362ff538e97d59497dd Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 16 Apr 2024 11:03:47 +
Subject: [PATCH] [clang][dataflow] Support `StmtExpr` in
 `PropagateResultObject()`.

This patch adds a test that assert-fails without the fix.
---
 .../FlowSensitive/DataflowEnvironment.cpp |  5 
 .../Analysis/FlowSensitive/TransferTest.cpp   | 26 +++
 2 files changed, 31 insertions(+)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..6974c195d42f6c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -556,6 +556,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
   return;
 }
 
+if (auto *SE = dyn_cast(E)) {
+  PropagateResultObject(cast(SE->getSubStmt()->body_back()), Loc);
+  return;
+}
+
 // All other expression nodes that propagate a record prvalue should have
 // exactly one child.
 SmallVector Children(E->child_begin(), E->child_end());
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..d7a51b009712f6 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForStmtExpr) {
+  std::string Code = R"(
+struct S {};
+void target() {
+  S s = ({ S(); });
+  // [[p]]
+}
+  )";
+  using ast_matchers::cxxConstructExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *Construct = selectFirst(
+"construct", match(cxxConstructExpr().bind("construct"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*Construct),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

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


[clang] [clang][dataflow] Support `StmtExpr` in `PropagateResultObject()`. (PR #88872)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-analysis

Author: None (martinboehme)


Changes

This patch adds a test that assert-fails without the fix.


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


2 Files Affected:

- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+5) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+26) 


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..6974c195d42f6c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -556,6 +556,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
   return;
 }
 
+if (auto *SE = dyn_cast(E)) {
+  PropagateResultObject(cast(SE->getSubStmt()->body_back()), Loc);
+  return;
+}
+
 // All other expression nodes that propagate a record prvalue should have
 // exactly one child.
 SmallVector Children(E->child_begin(), E->child_end());
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..d7a51b009712f6 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForStmtExpr) {
+  std::string Code = R"(
+struct S {};
+void target() {
+  S s = ({ S(); });
+  // [[p]]
+}
+  )";
+  using ast_matchers::cxxConstructExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *Construct = selectFirst(
+"construct", match(cxxConstructExpr().bind("construct"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*Construct),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

``




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


[clang] [clang][dataflow] Support `StmtExpr` in `PropagateResultObject()`. (PR #88872)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (martinboehme)


Changes

This patch adds a test that assert-fails without the fix.


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


2 Files Affected:

- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+5) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+26) 


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..6974c195d42f6c 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -556,6 +556,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
   return;
 }
 
+if (auto *SE = dyn_cast(E)) {
+  PropagateResultObject(cast(SE->getSubStmt()->body_back()), Loc);
+  return;
+}
+
 // All other expression nodes that propagate a record prvalue should have
 // exactly one child.
 SmallVector Children(E->child_begin(), E->child_end());
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..d7a51b009712f6 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForStmtExpr) {
+  std::string Code = R"(
+struct S {};
+void target() {
+  S s = ({ S(); });
+  // [[p]]
+}
+  )";
+  using ast_matchers::cxxConstructExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *Construct = selectFirst(
+"construct", match(cxxConstructExpr().bind("construct"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*Construct),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

``




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


[clang] [llvm] [ValueTracking] Restore isKnownNonZero parameter order. (PR #88873)

2024-04-16 Thread Harald van Dijk via cfe-commits

https://github.com/hvdijk created 
https://github.com/llvm/llvm-project/pull/88873

Prior to #85863, the required parameters of llvm::isKnownNonZero were Value and 
DataLayout. After, they are Value, Depth, and SimplifyQuery, where 
SimplifyQuery is implicitly constructible from DataLayout. The change to move 
Depth before SimplifyQuery needed callers to be updated unnecessarily, and as 
commented in #85863, we actually want Depth to be after SimplifyQuery anyway so 
that it can be defaulted and the caller does not need to specify it.

>From 6763d8cce44be02e9065c9c640736ac85ffcf8a2 Mon Sep 17 00:00:00 2001
From: Harald van Dijk 
Date: Tue, 16 Apr 2024 12:06:31 +0100
Subject: [PATCH] [ValueTracking] Restore isKnownNonZero parameter order.

Prior to #85863, the required parameters of llvm::isKnownNonZero were
Value and DataLayout. After, they are Value, Depth, and SimplifyQuery,
where SimplifyQuery is implicitly constructible from DataLayout. The
change to move Depth before SimplifyQuery needed callers to be updated
unnecessarily, and as commented in #85863, we actually want Depth to be
after SimplifyQuery anyway so that it can be defaulted and the caller
does not need to specify it.
---
 clang/lib/CodeGen/CGCall.cpp  |   3 +-
 llvm/include/llvm/Analysis/ValueTracking.h|   2 +-
 llvm/lib/Analysis/BasicAliasAnalysis.cpp  |   3 +-
 llvm/lib/Analysis/InstructionSimplify.cpp |  25 ++---
 llvm/lib/Analysis/LazyValueInfo.cpp   |   5 +-
 llvm/lib/Analysis/Loads.cpp   |   4 +-
 llvm/lib/Analysis/ScalarEvolution.cpp |   2 +-
 llvm/lib/Analysis/ValueTracking.cpp   | 106 +-
 llvm/lib/CodeGen/CodeGenPrepare.cpp   |   2 +-
 .../Transforms/IPO/AttributorAttributes.cpp   |   2 +-
 llvm/lib/Transforms/IPO/FunctionAttrs.cpp |   2 +-
 .../InstCombine/InstCombineAddSub.cpp |   2 +-
 .../InstCombine/InstCombineAndOrXor.cpp   |   4 +-
 .../InstCombine/InstCombineCalls.cpp  |  11 +-
 .../InstCombine/InstCombineCompares.cpp   |  18 +--
 .../Transforms/InstCombine/InstCombinePHI.cpp |   3 +-
 .../InstCombine/InstructionCombining.cpp  |   2 +-
 .../Instrumentation/MemorySanitizer.cpp   |   4 +-
 .../Utils/PromoteMemoryToRegister.cpp |   2 +-
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp |  20 ++--
 .../Transforms/Vectorize/VectorCombine.cpp|   2 +-
 llvm/unittests/Analysis/ValueTrackingTest.cpp |  13 +--
 22 files changed, 113 insertions(+), 124 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7a0bc6fa77b889..3f5463a9a70e9d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4124,8 +4124,7 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return llvm::isKnownNonZero(Addr.getBasePointer(), /*Depth=*/0,
-  CGF.CGM.getDataLayout());
+  return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h 
b/llvm/include/llvm/Analysis/ValueTracking.h
index 9db0894162afca..e1c41b3b55ccfb 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -124,7 +124,7 @@ bool isOnlyUsedInZeroEqualityComparison(const Instruction 
*CxtI);
 /// specified, perform context-sensitive analysis and return true if the
 /// pointer couldn't possibly be null at the specified instruction.
 /// Supports values with integer or pointer type and vectors of integers.
-bool isKnownNonZero(const Value *V, unsigned Depth, const SimplifyQuery &Q);
+bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth = 
0);
 
 /// Return true if the two given values are negation.
 /// Currently can recoginze Value pair:
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp 
b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index b082dfe8fbd217..16ee2ca49d0ece 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1283,8 +1283,7 @@ AliasResult BasicAAResult::aliasGEP(
 // VarIndex = Scale*V.
 const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
 if (Var.Val.TruncBits == 0 &&
-isKnownNonZero(Var.Val.V, /*Depth=*/0,
-   SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
+isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
   // Check if abs(V*Scale) >= abs(Scale) holds in the presence of
   // potentially wrapping math.
   auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4e6e666922671d..8955de6375dec4 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1586,10 +1586,10 @@ static Value *simplifyUnsignedRang

[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread Tobias Hieta via cfe-commits


@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull 
align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr 
%retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+

tru wrote:

I checked your example there and the instanceMethod is no problem, but I 
noticed that the staticMethod doesn't contain a `sret` return value with this 
patch. Since we are not passing `this` to it - I think this is expected, but 
just want to make sure.

```
; Function Attrs: mustprogress noinline optnone uwtable
define dso_local i64 @"?staticMethod@TrivialInstance@@SA?AUTrivial@@XZ"() #0 
align 2 {
entry:
  %retval = alloca %struct.Trivial, align 8
  %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull align 8 
dereferenceable(8) %retval)
  %coerce.dive = getelementptr inbounds %struct.Trivial, ptr %retval, i32 0, 
i32 0
  %0 = load ptr, ptr %coerce.dive, align 8
  %coerce.val.pi = ptrtoint ptr %0 to i64
  ret i64 %coerce.val.pi
}
```

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


[clang] [Clang][Sema] placement new initializes typedef array with correct size (PR #83124)

2024-04-16 Thread via cfe-commits

https://github.com/mahtohappy updated 
https://github.com/llvm/llvm-project/pull/83124

>From a6fc7dbd5d71c1484d78e518648fb3f0f8e593d2 Mon Sep 17 00:00:00 2001
From: mahtohappy 
Date: Tue, 27 Feb 2024 03:13:51 -0800
Subject: [PATCH] [Clang][Sema] placement new initializes typedef array with
 correct size

---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/TreeTransform.h| 14 -
 .../instantiate-new-placement-size.cpp| 20 +++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/instantiate-new-placement-size.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76701dc723b6c3..255d2cc0440438 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -539,6 +539,8 @@ Bug Fixes to C++ Support
   Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), 
(#GH86398), and (#GH86399).
 - Fix a crash when deducing ``auto`` from an invalid dereference (#GH88329).
 - Fix a crash in requires expression with templated base class member 
function. Fixes (#GH84020).
+- placement new initializes typedef array with correct size
+  (`#GH41441 `_)
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 8c96134af7c8f0..9d15f3eacbb0f4 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12802,6 +12802,19 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 ArraySize = NewArraySize.get();
   }
 
+  // Per C++0x [expr.new]p5, the type being constructed may be a
+  // typedef of an array type.
+  QualType AllocType = AllocTypeInfo->getType();
+  if (ArraySize) {
+if (const ConstantArrayType *Array =
+SemaRef.Context.getAsConstantArrayType(AllocType)) {
+  ArraySize = IntegerLiteral::Create(SemaRef.Context, Array->getSize(),
+ SemaRef.Context.getSizeType(),
+ E->getBeginLoc());
+  AllocType = Array->getElementType();
+}
+  }
+
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   SmallVector PlacementArgs;
@@ -12863,7 +12876,6 @@ TreeTransform::TransformCXXNewExpr(CXXNewExpr 
*E) {
 return E;
   }
 
-  QualType AllocType = AllocTypeInfo->getType();
   if (!ArraySize) {
 // If no array size was specified, but the new expression was
 // instantiated with an array type (e.g., "new T" where T is
diff --git a/clang/test/SemaCXX/instantiate-new-placement-size.cpp 
b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
new file mode 100644
index 00..7a29d3dee8491e
--- /dev/null
+++ b/clang/test/SemaCXX/instantiate-new-placement-size.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -S -fno-discard-value-names -emit-llvm -o - %s | FileCheck %s
+// Issue no: 41441
+#include 
+
+// CHECK: call void @llvm.memset.p0.i64(ptr align 1 %x, i8 0, i64 8, i1 false)
+// CHECK: call void @llvm.memset.p0.i64(ptr align 16 %x, i8 0, i64 32, i1 
false)
+template 
+void f()
+{
+typedef TYPE TArray[8];
+
+TArray x;
+new(&x) TArray();
+}
+
+int main()
+{
+f();
+f();
+}

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


[clang] [llvm] [ValueTracking] Restore isKnownNonZero parameter order. (PR #88873)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Harald van Dijk (hvdijk)


Changes

Prior to #85863, the required parameters of llvm::isKnownNonZero were 
Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where 
SimplifyQuery is implicitly constructible from DataLayout. The change to move 
Depth before SimplifyQuery needed callers to be updated unnecessarily, and as 
commented in #85863, we actually want Depth to be after SimplifyQuery 
anyway so that it can be defaulted and the caller does not need to specify it.

---

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


22 Files Affected:

- (modified) clang/lib/CodeGen/CGCall.cpp (+1-2) 
- (modified) llvm/include/llvm/Analysis/ValueTracking.h (+1-1) 
- (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+1-2) 
- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+12-13) 
- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+2-3) 
- (modified) llvm/lib/Analysis/Loads.cpp (+2-2) 
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+1-1) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+53-53) 
- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+1-1) 
- (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+1-1) 
- (modified) llvm/lib/Transforms/IPO/FunctionAttrs.cpp (+1-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp (+1-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+2-2) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+4-7) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+9-9) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp (+1-2) 
- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+2-2) 
- (modified) llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+10-10) 
- (modified) llvm/lib/Transforms/Vectorize/VectorCombine.cpp (+1-1) 
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+5-8) 


``diff
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7a0bc6fa77b889..3f5463a9a70e9d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4124,8 +4124,7 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return llvm::isKnownNonZero(Addr.getBasePointer(), /*Depth=*/0,
-  CGF.CGM.getDataLayout());
+  return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h 
b/llvm/include/llvm/Analysis/ValueTracking.h
index 9db0894162afca..e1c41b3b55ccfb 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -124,7 +124,7 @@ bool isOnlyUsedInZeroEqualityComparison(const Instruction 
*CxtI);
 /// specified, perform context-sensitive analysis and return true if the
 /// pointer couldn't possibly be null at the specified instruction.
 /// Supports values with integer or pointer type and vectors of integers.
-bool isKnownNonZero(const Value *V, unsigned Depth, const SimplifyQuery &Q);
+bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth = 
0);
 
 /// Return true if the two given values are negation.
 /// Currently can recoginze Value pair:
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp 
b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index b082dfe8fbd217..16ee2ca49d0ece 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1283,8 +1283,7 @@ AliasResult BasicAAResult::aliasGEP(
 // VarIndex = Scale*V.
 const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
 if (Var.Val.TruncBits == 0 &&
-isKnownNonZero(Var.Val.V, /*Depth=*/0,
-   SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
+isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
   // Check if abs(V*Scale) >= abs(Scale) holds in the presence of
   // potentially wrapping math.
   auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4e6e666922671d..8955de6375dec4 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1586,10 +1586,10 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst 
*ZeroICmp,
 if (match(UnsignedICmp,
   m_c_ICmp(UnsignedPred, m_Specific(Y), m_Specific(A {
   if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&
-  EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, /*Depth=*/0, Q))
+  EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, Q))
 re

[clang] [llvm] [ValueTracking] Convert `isKnownNonZero` to use SimplifyQuery (PR #85863)

2024-04-16 Thread Harald van Dijk via cfe-commits


@@ -645,7 +645,7 @@ LazyValueInfoImpl::solveBlockValueImpl(Value *Val, 
BasicBlock *BB) {
   // instruction is placed, even if it could legally be hoisted much higher.
   // That is unfortunate.
   PointerType *PT = dyn_cast(BBI->getType());
-  if (PT && isKnownNonZero(BBI, DL))
+  if (PT && isKnownNonZero(BBI, /*Depth=*/0, DL))

hvdijk wrote:

Created #88873 for it.

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


[clang] [llvm] [ValueTracking] Restore isKnownNonZero parameter order. (PR #88873)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Harald van Dijk (hvdijk)


Changes

Prior to #85863, the required parameters of llvm::isKnownNonZero were 
Value and DataLayout. After, they are Value, Depth, and SimplifyQuery, where 
SimplifyQuery is implicitly constructible from DataLayout. The change to move 
Depth before SimplifyQuery needed callers to be updated unnecessarily, and as 
commented in #85863, we actually want Depth to be after SimplifyQuery 
anyway so that it can be defaulted and the caller does not need to specify it.

---

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


22 Files Affected:

- (modified) clang/lib/CodeGen/CGCall.cpp (+1-2) 
- (modified) llvm/include/llvm/Analysis/ValueTracking.h (+1-1) 
- (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+1-2) 
- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+12-13) 
- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+2-3) 
- (modified) llvm/lib/Analysis/Loads.cpp (+2-2) 
- (modified) llvm/lib/Analysis/ScalarEvolution.cpp (+1-1) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+53-53) 
- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+1-1) 
- (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+1-1) 
- (modified) llvm/lib/Transforms/IPO/FunctionAttrs.cpp (+1-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp (+1-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+2-2) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+4-7) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+9-9) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp (+1-2) 
- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+2-2) 
- (modified) llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+10-10) 
- (modified) llvm/lib/Transforms/Vectorize/VectorCombine.cpp (+1-1) 
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+5-8) 


``diff
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7a0bc6fa77b889..3f5463a9a70e9d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4124,8 +4124,7 @@ static bool isProvablyNull(llvm::Value *addr) {
 }
 
 static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
-  return llvm::isKnownNonZero(Addr.getBasePointer(), /*Depth=*/0,
-  CGF.CGM.getDataLayout());
+  return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
 }
 
 /// Emit the actual writing-back of a writeback.
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h 
b/llvm/include/llvm/Analysis/ValueTracking.h
index 9db0894162afca..e1c41b3b55ccfb 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -124,7 +124,7 @@ bool isOnlyUsedInZeroEqualityComparison(const Instruction 
*CxtI);
 /// specified, perform context-sensitive analysis and return true if the
 /// pointer couldn't possibly be null at the specified instruction.
 /// Supports values with integer or pointer type and vectors of integers.
-bool isKnownNonZero(const Value *V, unsigned Depth, const SimplifyQuery &Q);
+bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth = 
0);
 
 /// Return true if the two given values are negation.
 /// Currently can recoginze Value pair:
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp 
b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index b082dfe8fbd217..16ee2ca49d0ece 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1283,8 +1283,7 @@ AliasResult BasicAAResult::aliasGEP(
 // VarIndex = Scale*V.
 const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
 if (Var.Val.TruncBits == 0 &&
-isKnownNonZero(Var.Val.V, /*Depth=*/0,
-   SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
+isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CxtI))) {
   // Check if abs(V*Scale) >= abs(Scale) holds in the presence of
   // potentially wrapping math.
   auto MultiplyByScaleNoWrap = [](const VariableGEPIndex &Var) {
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp 
b/llvm/lib/Analysis/InstructionSimplify.cpp
index 4e6e666922671d..8955de6375dec4 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1586,10 +1586,10 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst 
*ZeroICmp,
 if (match(UnsignedICmp,
   m_c_ICmp(UnsignedPred, m_Specific(Y), m_Specific(A {
   if (UnsignedPred == ICmpInst::ICMP_UGE && IsAnd &&
-  EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, /*Depth=*/0, Q))
+  EqPred == ICmpInst::ICMP_NE && isKnownNonZero(B, Q))
   

[clang] [clang][dataflow] Treat `BuiltinBitCastExpr` correctly in `PropagateResultObject()`. (PR #88875)

2024-04-16 Thread via cfe-commits

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

This patch includes a test that assert-fails without the fix.


>From c8797bbbdb32d9f153b36b6902f8562af75fb896 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 16 Apr 2024 11:13:00 +
Subject: [PATCH] [clang][dataflow] Treat `BuiltinBitCastExpr` correctly in
 `PropagateResultObject()`.

This patch includes a test that assert-fails without the fix.
---
 .../FlowSensitive/DataflowEnvironment.cpp |  6 -
 .../Analysis/FlowSensitive/TransferTest.cpp   | 26 +++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..90eea420258764 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -505,7 +505,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 // below them can initialize the same object (or part of it).
 if (isa(E) || isa(E) || isa(E) ||
 isa(E) || isa(E) ||
-isa(E)) {
+isa(E) ||
+// We treat `BuiltinBitCastExpr` as an "original initializer" too as
+// it may not even be casting from a record type -- and even if it is,
+// the two objects are in general of unrelated type.
+isa(E)) {
   return;
 }
 if (auto *Op = dyn_cast(E);
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..54744a2762e773 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
+  std::string Code = R"(
+struct S { int i; };
+void target(int i) {
+  S s = __builtin_bit_cast(S, i);
+  // [[p]]
+}
+  )";
+  using ast_matchers::explicitCastExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *BuiltinBitCast = selectFirst(
+"cast", match(explicitCastExpr().bind("cast"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*BuiltinBitCast),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

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


[clang] [clang][dataflow] Treat `BuiltinBitCastExpr` correctly in `PropagateResultObject()`. (PR #88875)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-analysis

Author: None (martinboehme)


Changes

This patch includes a test that assert-fails without the fix.


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


2 Files Affected:

- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+5-1) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+26) 


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..90eea420258764 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -505,7 +505,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 // below them can initialize the same object (or part of it).
 if (isa(E) || isa(E) || isa(E) ||
 isa(E) || isa(E) ||
-isa(E)) {
+isa(E) ||
+// We treat `BuiltinBitCastExpr` as an "original initializer" too as
+// it may not even be casting from a record type -- and even if it is,
+// the two objects are in general of unrelated type.
+isa(E)) {
   return;
 }
 if (auto *Op = dyn_cast(E);
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..54744a2762e773 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
+  std::string Code = R"(
+struct S { int i; };
+void target(int i) {
+  S s = __builtin_bit_cast(S, i);
+  // [[p]]
+}
+  )";
+  using ast_matchers::explicitCastExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *BuiltinBitCast = selectFirst(
+"cast", match(explicitCastExpr().bind("cast"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*BuiltinBitCast),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

``




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


[clang] [clang][dataflow] Treat `BuiltinBitCastExpr` correctly in `PropagateResultObject()`. (PR #88875)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (martinboehme)


Changes

This patch includes a test that assert-fails without the fix.


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


2 Files Affected:

- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+5-1) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+26) 


``diff
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index ee2581143e1141..90eea420258764 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -505,7 +505,11 @@ class ResultObjectVisitor : public 
RecursiveASTVisitor {
 // below them can initialize the same object (or part of it).
 if (isa(E) || isa(E) || isa(E) ||
 isa(E) || isa(E) ||
-isa(E)) {
+isa(E) ||
+// We treat `BuiltinBitCastExpr` as an "original initializer" too as
+// it may not even be casting from a record type -- and even if it is,
+// the two objects are in general of unrelated type.
+isa(E)) {
   return;
 }
 if (auto *Op = dyn_cast(E);
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d8bcc3da4b8b1c..54744a2762e773 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -3182,6 +3182,32 @@ TEST(TransferTest, 
ResultObjectLocationForStdInitializerListExpr) {
   });
 }
 
+TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
+  std::string Code = R"(
+struct S { int i; };
+void target(int i) {
+  S s = __builtin_bit_cast(S, i);
+  // [[p]]
+}
+  )";
+  using ast_matchers::explicitCastExpr;
+  using ast_matchers::match;
+  using ast_matchers::selectFirst;
+  using ast_matchers::traverse;
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto *BuiltinBitCast = selectFirst(
+"cast", match(explicitCastExpr().bind("cast"), ASTCtx));
+
+EXPECT_EQ(&Env.getResultObjectLocation(*BuiltinBitCast),
+  &getLocForDecl(ASTCtx, Env, "s"));
+  });
+}
+
 TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
   std::string Code = R"(
 struct A {

``




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


[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

2024-04-16 Thread Tobias Hieta via cfe-commits

https://github.com/tru updated https://github.com/llvm/llvm-project/pull/88857

>From 08214d87d1a7c83ea25eef3bf18de1568a20a152 Mon Sep 17 00:00:00 2001
From: Tobias Hieta 
Date: Tue, 16 Apr 2024 09:38:53 +0200
Subject: [PATCH] [clang] Handle trivial_abi attribute for Microsoft ABI.

Previously the trivial_abi was ignored for records when targetting
the microsoft abi, the MSVC rules where always enforced to ensure
compatibility with MSVC. This commit changes it to be closer to
the itanium abi when a record is marked with the trivial_abi attribute.

Fixes #87993
---
 clang/docs/ReleaseNotes.rst|  5 
 clang/lib/CodeGen/MicrosoftCXXABI.cpp  |  5 
 clang/test/CodeGenCXX/trivial_abi_msvc.cpp | 31 ++
 3 files changed, 41 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/trivial_abi_msvc.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76701dc723b6c3..2b653e5af6f5ae 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -63,6 +63,11 @@ ABI Changes in This Version
   MSVC uses a different mangling for these objects, compatibility is not 
affected.
   (#GH85423).
 
+- Records carrying the trivial_abi attribute are now returned directly in 
registers
+  in more cases when using the Microsoft ABI. It is not possible to pass 
trivial_abi
+  records between MSVC and Clang, so there is no ABI compatibility 
requirement. This
+  is an ABI break with old versions of Clang. (#GH87993)
+
 AST Dumping Potentially Breaking Changes
 
 
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d38a26940a3cb6..b930913badcd3f 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1105,6 +1105,11 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl 
GD) const {
 
 static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
  CodeGenModule &CGM) {
+  // If the record is marked with the trivial_abi attribute, we don't
+  // have to conform to the standard MSVC ABI.
+  if (RD->hasAttr())
+return true;
+
   // On AArch64, HVAs that can be passed in registers can also be returned
   // in registers. (Note this is using the MSVC definition of an HVA; see
   // isPermittedToBeHomogeneousAggregate().)
diff --git a/clang/test/CodeGenCXX/trivial_abi_msvc.cpp 
b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
new file mode 100644
index 00..0af1d63acd1a5e
--- /dev/null
+++ b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA@XZ"(ptr noundef nonnull 
align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr 
%retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+
+struct TrivialInstance {
+Trivial instanceMethod();
+static Trivial staticMethod();
+};
+
+// We need to make sure that instanceMethod has a sret return value since 
`this` will always go in the register.
+// CHECK-LABEL: define{{.*}} void 
@"?instanceMethod@TrivialInstance@@QEAA?AUTrivial@@XZ"({{.*}} 
sret(%struct.Trivial{{.*}}
+Trivial TrivialInstance::instanceMethod() { return {}; }
+// CHECK-LABEL: define{{.*}} i64 
@"?staticMethod@TrivialInstance@@SA?AUTrivial@@XZ"(
+Trivial TrivialInstance::staticMethod() { return {}; }

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


[libclc] [WIP] Libclc tests (PR #87989)

2024-04-16 Thread Fraser Cormack via cfe-commits

https://github.com/frasercrmck updated 
https://github.com/llvm/llvm-project/pull/87989

>From c53dc3564822f305d09d19dc3b7327b33028fe11 Mon Sep 17 00:00:00 2001
From: Fraser Cormack 
Date: Thu, 4 Apr 2024 17:49:13 +0100
Subject: [PATCH] [libclc] Add initial LIT tests

---
 libclc/CMakeLists.txt  |  4 +++
 libclc/test/CMakeLists.txt | 38 +++
 libclc/test/add_sat.cl |  3 ++
 libclc/test/as_type.cl |  5 ++-
 libclc/test/convert.cl |  5 ++-
 libclc/test/cos.cl |  5 ++-
 libclc/test/cross.cl   |  5 ++-
 libclc/test/fabs.cl|  5 ++-
 libclc/test/get_group_id.cl|  5 ++-
 libclc/test/lit.cfg.py | 57 ++
 libclc/test/lit.site.cfg.py.in | 24 ++
 libclc/test/rsqrt.cl   |  8 +++--
 libclc/test/subsat.cl  | 11 ---
 13 files changed, 163 insertions(+), 12 deletions(-)
 create mode 100644 libclc/test/CMakeLists.txt
 create mode 100644 libclc/test/lit.cfg.py
 create mode 100644 libclc/test/lit.site.cfg.py.in

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 7528228b3b7f9b..ca5e5d1d1755d2 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -411,3 +411,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
 endif()
   endforeach( d )
 endforeach( t )
+
+if( NOT LIBCLC_STANDALONE_BUILD )
+  add_subdirectory( test )
+endif()
diff --git a/libclc/test/CMakeLists.txt b/libclc/test/CMakeLists.txt
new file mode 100644
index 00..796b6a0e1e8544
--- /dev/null
+++ b/libclc/test/CMakeLists.txt
@@ -0,0 +1,38 @@
+set(LIBCLC_TEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+  MAIN_CONFIG
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+)
+
+list(APPEND LIBCLC_TEST_DEPS
+  libclc::clang
+  FileCheck count not
+)
+
+add_custom_target(check-libclc)
+
+foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
+  foreach( d ${${t}_devices} )
+
+get_libclc_device_info(
+  TRIPLE ${t}
+  DEVICE ${d}
+  CPU cpu
+  ARCH_SUFFIX arch_suffix
+  CLANG_TRIPLE clang_triple
+)
+
+add_lit_testsuite(check-libclc-${arch_suffix}
+  "Running libclc ${arch_suffix} regression tests"
+  ${CMAKE_CURRENT_BINARY_DIR}
+  PARAMS "target=${clang_triple}" cpu=${cpu} "builtins=${arch_suffix}.bc"
+  DEPENDS prepare-${arch_suffix}.bc ${LIBCLC_TEST_DEPS}
+)
+
+add_dependencies( check-libclc check-libclc-${arch_suffix} )
+
+  endforeach()
+endforeach()
diff --git a/libclc/test/add_sat.cl b/libclc/test/add_sat.cl
index 45c8567b440397..f23a105ac83386 100644
--- a/libclc/test/add_sat.cl
+++ b/libclc/test/add_sat.cl
@@ -1,3 +1,6 @@
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
 __kernel void foo(__global char *a, __global char *b, __global char *c) {
   *a = add_sat(*b, *c);
 }
diff --git a/libclc/test/as_type.cl b/libclc/test/as_type.cl
index e8fb1228d28d11..729303a53da051 100644
--- a/libclc/test/as_type.cl
+++ b/libclc/test/as_type.cl
@@ -1,3 +1,6 @@
-__kernel void foo(int4 *x, float4 *y) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__global int4 *x, __global float4 *y) {
   *x = as_int4(*y);
 }
diff --git a/libclc/test/convert.cl b/libclc/test/convert.cl
index 928fc326b6a18f..9ea5b192769a26 100644
--- a/libclc/test/convert.cl
+++ b/libclc/test/convert.cl
@@ -1,3 +1,6 @@
-__kernel void foo(int4 *x, float4 *y) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__global int4 *x, __global float4 *y) {
   *x = convert_int4(*y);
 }
diff --git a/libclc/test/cos.cl b/libclc/test/cos.cl
index 4230eb2a0e93c6..21384ba1d73dfd 100644
--- a/libclc/test/cos.cl
+++ b/libclc/test/cos.cl
@@ -1,3 +1,6 @@
-__kernel void foo(float4 *f) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__global float4 *f) {
   *f = cos(*f);
 }
diff --git a/libclc/test/cross.cl b/libclc/test/cross.cl
index 08955cbd9af568..c628a6656c5739 100644
--- a/libclc/test/cross.cl
+++ b/libclc/test/cross.cl
@@ -1,3 +1,6 @@
-__kernel void foo(float4 *f) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__global float4 *f) {
   *f = cross(f[0], f[1]);
 }
diff --git a/libclc/test/fabs.cl b/libclc/test/fabs.cl
index 91d42c466676fd..27881304224567 100644
--- a/libclc/test/fabs.cl
+++ b/libclc/test/fabs.cl
@@ -1,3 +1,6 @@
-__kernel void foo(float *f) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__global float *f) {
   *f = fabs(*f);
 }
diff --git a/libclc/test/get_group_id.cl b/libclc/test/get_group_id.cl
index 43725cda802710..cd4d114b59ed16 100644
--- a/libclc/test/get_group_id.cl
+++ b/libclc/test/get_group_id.cl
@@ -1,3 +1,6 @@
-__kernel void foo(int *i) {
+// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
+
+// CHECK: foo
+__kernel void foo(__glo

[clang] 09e7d75 - [clang][Interp] Don't add 'in call to' diagnostics for builtin frames

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T13:29:41+02:00
New Revision: 09e7d7585cf881fb598eb56738579b84d027318c

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

LOG: [clang][Interp] Don't add 'in call to' diagnostics for builtin frames

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.cpp
clang/lib/AST/Interp/State.cpp
clang/test/AST/Interp/builtin-functions.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.cpp 
b/clang/lib/AST/Interp/InterpFrame.cpp
index 12e2e6ff9155b9..ba957546473e98 100644
--- a/clang/lib/AST/Interp/InterpFrame.cpp
+++ b/clang/lib/AST/Interp/InterpFrame.cpp
@@ -152,6 +152,13 @@ void print(llvm::raw_ostream &OS, const Pointer &P, 
ASTContext &Ctx,
 }
 
 void InterpFrame::describe(llvm::raw_ostream &OS) const {
+  // We create frames for builtin functions as well, but we can't reliably
+  // diagnose them. The 'in call to' diagnostics for them add no value to the
+  // user _and_ it doesn't generally work since the argument types don't always
+  // match the function prototype. Just ignore them.
+  if (const auto *F = getFunction(); F && F->isBuiltin())
+return;
+
   const FunctionDecl *F = getCallee();
   if (const auto *M = dyn_cast(F);
   M && M->isInstance() && !isa(F)) {

diff  --git a/clang/lib/AST/Interp/State.cpp b/clang/lib/AST/Interp/State.cpp
index 47fbf5145cd4e4..0d9dadec4b9581 100644
--- a/clang/lib/AST/Interp/State.cpp
+++ b/clang/lib/AST/Interp/State.cpp
@@ -155,7 +155,8 @@ void State::addCallStack(unsigned Limit) {
 SmallString<128> Buffer;
 llvm::raw_svector_ostream Out(Buffer);
 F->describe(Out);
-addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
-<< Out.str() << CallRange;
+if (!Buffer.empty())
+  addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
+  << Out.str() << CallRange;
   }
 }

diff  --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index a7adc92d3714fa..1a29a664d7ce54 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -24,16 +24,13 @@ namespace strcmp {
   static_assert(__builtin_strcmp("abab", "abab\0banana") == 0, "");
   static_assert(__builtin_strcmp("abab\0banana", "abab\0canada") == 0, "");
   static_assert(__builtin_strcmp(0, "abab") == 0, ""); // both-error {{not an 
integral constant}} \
-   // both-note 
{{dereferenced null}} \
-   // expected-note {{in 
call to}}
+   // both-note 
{{dereferenced null}}
   static_assert(__builtin_strcmp("abab", 0) == 0, ""); // both-error {{not an 
integral constant}} \
-   // both-note 
{{dereferenced null}} \
-   // expected-note {{in 
call to}}
+   // both-note 
{{dereferenced null}}
 
   static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar) == -1, "");
   static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar + 6) == 0, ""); // 
both-error {{not an integral constant}} \
-// 
both-note {{dereferenced one-past-the-end}} \
-// 
expected-note {{in call to}}
+// 
both-note {{dereferenced one-past-the-end}}
 
   /// Used to assert because we're passing a dummy pointer to
   /// __builtin_strcmp() when evaluating the return statement.
@@ -72,14 +69,11 @@ constexpr const char *a = "foo\0quux";
   static_assert(check(c), "");
 
   constexpr int over1 = __builtin_strlen(a + 9); // both-error {{constant 
expression}} \
- // both-note 
{{one-past-the-end}} \
- // expected-note {{in call 
to}}
+ // both-note 
{{one-past-the-end}}
   constexpr int over2 = __builtin_strlen(b + 9); // both-error {{constant 
expression}} \
- // both-note 
{{one-past-the-end}} \
- // expected-note {{in call 
to}}
+ // both-note 
{{one-past-the-end}}
   constexpr int over3 = __builtin_strlen(c + 9); // both-error {{constant 
expression}} \
- // both-note 
{{one-past-the-end}} \
- // expected-note {{in call 
to}}
+ 

[clang] a8de3ee - [clang][Interp][NFC] Fix some build warnings

2024-04-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-04-16T13:29:41+02:00
New Revision: a8de3ee8994023ea7669397587f8118ae5bba9c9

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

LOG: [clang][Interp][NFC] Fix some build warnings

Fixes:
/buildbot/worker/arc-folder/llvm-project/clang/lib/AST/Interp/Disasm.cpp:143:25:
 warning: cast from type 'const clang::interp::Block*' to type 'void*' casts 
away qualifiers [-Wcast-qual]
/buildbot/worker/arc-folder/llvm-project/clang/lib/AST/Interp/Disasm.cpp:271:23:
 warning: cast from type 'const clang::interp::Block*' to type 'void*' casts 
away qualifiers [-Wcast-qual]

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index ebc4e4f195ba62..d127f33223e802 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -140,7 +140,7 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) 
const {
 const Descriptor *Desc = G->block()->getDescriptor();
 Pointer GP = getPtrGlobal(GI);
 
-OS << GI << ": " << (void *)G->block() << " ";
+OS << GI << ": " << (const void *)G->block() << " ";
 {
   ColorScope SC(OS, true,
 GP.isInitialized()
@@ -268,7 +268,7 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, 
unsigned Indentation,
 LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const {
   {
 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_BLUE, true});
-OS << "Block " << (void *)this << "\n";
+OS << "Block " << (const void *)this << "\n";
   }
   unsigned NPointers = 0;
   for (const Pointer *P = Pointers; P; P = P->Next) {



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


[clang] [analyzer] Use explicit call description mode (easy cases) (PR #88879)

2024-04-16 Thread via cfe-commits

https://github.com/NagyDonat created 
https://github.com/llvm/llvm-project/pull/88879

This commit explicitly specifies the matching mode (C library function, any 
non-method function, or C++ method) for the `CallDescription`s constructed in 
various checkers where this transition was easy and straightforward.

This change won't cause major functional changes, but isn't NFC because it 
ensures that e.g. call descriptions for a non-method function won't 
accidentally match a method that has the same name.

Separate commits will perform (or have already performed) this change in other 
checkers. My goal is to ensure that the call description mode is always 
explicitly specified and eliminate (or strongly restrict) the vague "may be 
either a method or a simple function" mode that's the current default.

>From 7305bb3aa8b05fc4bbe1bc3b44bb185dc0a647cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Tue, 16 Apr 2024 13:19:56 +0200
Subject: [PATCH] [analyzer] Use explicit call description mode (easy cases)

This commit explicitly specifies the matching mode (C library function,
any non-method function, or C++ method) for the `CallDescription`s
constructed in various checkers where this transition was easy and
straightforward.

This change won't cause major functional changes, but isn't NFC because
it ensures that e.g. call descriptions for a non-method function won't
accidentally match a method that has the same name.

Separate commits will perform (or have already performed) this change in
other checkers. My goal is to ensure that the call description mode is
always explicitly specified and eliminate (or strongly restrict) the
vague "may be either a method or a simple function" mode that's the
current default.
---
 .../Checkers/CastValueChecker.cpp  | 18 +-
 .../StaticAnalyzer/Checkers/ChrootChecker.cpp  |  3 ++-
 .../Checkers/ErrnoTesterChecker.cpp| 12 +++-
 .../Checkers/MmapWriteExecChecker.cpp  |  5 ++---
 .../Checkers/StdVariantChecker.cpp | 10 ++
 .../StaticAnalyzer/Checkers/StringChecker.cpp  |  2 +-
 .../Checkers/cert/PutenvWithAutoChecker.cpp|  2 +-
 7 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
index f02d20d45678b3..c7479d74eafc33 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -56,23 +56,23 @@ class CastValueChecker : public Checker {
 
 private:
   // These are known in the LLVM project. The pairs are in the following form:
-  // {{{namespace, call}, argument-count}, {callback, kind}}
+  // {{match-mode, {namespace, call}, argument-count}, {callback, kind}}
   const CallDescriptionMap> CDM = {
-  {{{"llvm", "cast"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "cast"}, 1},
{&CastValueChecker::evalCast, CallKind::Function}},
-  {{{"llvm", "dyn_cast"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "dyn_cast"}, 1},
{&CastValueChecker::evalDynCast, CallKind::Function}},
-  {{{"llvm", "cast_or_null"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "cast_or_null"}, 1},
{&CastValueChecker::evalCastOrNull, CallKind::Function}},
-  {{{"llvm", "dyn_cast_or_null"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "dyn_cast_or_null"}, 1},
{&CastValueChecker::evalDynCastOrNull, CallKind::Function}},
-  {{{"clang", "castAs"}, 0},
+  {{CDM::CXXMethod, {"clang", "castAs"}, 0},
{&CastValueChecker::evalCastAs, CallKind::Method}},
-  {{{"clang", "getAs"}, 0},
+  {{CDM::CXXMethod, {"clang", "getAs"}, 0},
{&CastValueChecker::evalGetAs, CallKind::Method}},
-  {{{"llvm", "isa"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "isa"}, 1},
{&CastValueChecker::evalIsa, CallKind::InstanceOf}},
-  {{{"llvm", "isa_and_nonnull"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "isa_and_nonnull"}, 1},
{&CastValueChecker::evalIsaAndNonNull, CallKind::InstanceOf}}};
 
   void evalCast(const CallEvent &Call, DefinedOrUnknownSVal DV,
diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index be7be15022d360..3a0a01c23de03e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -43,7 +43,8 @@ class ChrootChecker : public Checker {
   // This bug refers to possibly break out of a chroot() jail.
   const BugType BT_BreakJail{this, "Break out of jail"};
 
-  const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1};
+  const CallDescription Chroot{CDM::CLibrary, {"chroot"}, 1},
+  Chdir{CDM::CLibrary, {"chdir"}, 1};
 
 public:
   ChrootChecker() {}
diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
index c46ebee0c94ff4..6076a6bc789737 100644
--- a/cla

[clang] [analyzer] Use explicit call description mode (easy cases) (PR #88879)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




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

Author: None (NagyDonat)


Changes

This commit explicitly specifies the matching mode (C library function, any 
non-method function, or C++ method) for the `CallDescription`s constructed in 
various checkers where this transition was easy and straightforward.

This change won't cause major functional changes, but isn't NFC because it 
ensures that e.g. call descriptions for a non-method function won't 
accidentally match a method that has the same name.

Separate commits will perform (or have already performed) this change in other 
checkers. My goal is to ensure that the call description mode is always 
explicitly specified and eliminate (or strongly restrict) the vague "may be 
either a method or a simple function" mode that's the current default.

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


7 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp (+9-9) 
- (modified) clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp (+2-1) 
- (modified) clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp (+7-5) 
- (modified) clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp (+2-3) 
- (modified) clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp (+6-4) 
- (modified) clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp (+1-1) 
- (modified) clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp 
(+1-1) 


``diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
index f02d20d45678b3..c7479d74eafc33 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -56,23 +56,23 @@ class CastValueChecker : public Checker {
 
 private:
   // These are known in the LLVM project. The pairs are in the following form:
-  // {{{namespace, call}, argument-count}, {callback, kind}}
+  // {{match-mode, {namespace, call}, argument-count}, {callback, kind}}
   const CallDescriptionMap> CDM = {
-  {{{"llvm", "cast"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "cast"}, 1},
{&CastValueChecker::evalCast, CallKind::Function}},
-  {{{"llvm", "dyn_cast"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "dyn_cast"}, 1},
{&CastValueChecker::evalDynCast, CallKind::Function}},
-  {{{"llvm", "cast_or_null"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "cast_or_null"}, 1},
{&CastValueChecker::evalCastOrNull, CallKind::Function}},
-  {{{"llvm", "dyn_cast_or_null"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "dyn_cast_or_null"}, 1},
{&CastValueChecker::evalDynCastOrNull, CallKind::Function}},
-  {{{"clang", "castAs"}, 0},
+  {{CDM::CXXMethod, {"clang", "castAs"}, 0},
{&CastValueChecker::evalCastAs, CallKind::Method}},
-  {{{"clang", "getAs"}, 0},
+  {{CDM::CXXMethod, {"clang", "getAs"}, 0},
{&CastValueChecker::evalGetAs, CallKind::Method}},
-  {{{"llvm", "isa"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "isa"}, 1},
{&CastValueChecker::evalIsa, CallKind::InstanceOf}},
-  {{{"llvm", "isa_and_nonnull"}, 1},
+  {{CDM::SimpleFunc, {"llvm", "isa_and_nonnull"}, 1},
{&CastValueChecker::evalIsaAndNonNull, CallKind::InstanceOf}}};
 
   void evalCast(const CallEvent &Call, DefinedOrUnknownSVal DV,
diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index be7be15022d360..3a0a01c23de03e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -43,7 +43,8 @@ class ChrootChecker : public Checker {
   // This bug refers to possibly break out of a chroot() jail.
   const BugType BT_BreakJail{this, "Break out of jail"};
 
-  const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1};
+  const CallDescription Chroot{CDM::CLibrary, {"chroot"}, 1},
+  Chdir{CDM::CLibrary, {"chdir"}, 1};
 
 public:
   ChrootChecker() {}
diff --git a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
index c46ebee0c94ff4..6076a6bc789737 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ErrnoTesterChecker.cpp
@@ -70,13 +70,15 @@ class ErrnoTesterChecker : public Checker {
 
   using EvalFn = std::function;
   const CallDescriptionMap TestCalls{
-  {{{"ErrnoTesterChecker_setErrno"}, 1}, 
&ErrnoTesterChecker::evalSetErrno},
-  {{{"ErrnoTesterChecker_getErrno"}, 0}, 
&ErrnoTesterChecker::evalGetErrno},
-  {{{"ErrnoTesterChecker_setErrnoIfError"}, 0},
+  {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrno"}, 1},
+   &ErrnoTesterChecker::evalSetErrno},
+  {{CDM::SimpleFunc, {"ErrnoTesterChecker_getErrno"}, 0},
+   &ErrnoTesterChecker::evalGetErrno},
+  {{CDM::SimpleFunc, {"ErrnoTesterChecker_setErrnoIfError"}, 0},
   

[clang] 71b9f66 - [clang][Index] Use canonical function parameter types in USRs (#68222)

2024-04-16 Thread via cfe-commits

Author: Krystian Stasiowski
Date: 2024-04-16T07:34:27-04:00
New Revision: 71b9f6648222771470473431bc8ef2a2c25e872c

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

LOG: [clang][Index] Use canonical function parameter types in USRs (#68222)

This is necessary to ensure that functions declared in different
translation units whose parameter types only differ in top-level
cv-qualification generate the same USR.

For example:
```
// A.cpp
void f(const int x); // c:@F@f#1I#

// B.cpp
void f(int x);   // c:@F@f#I#
``` 
With this patch, the USR for both functions will be
`c:@F@f#I#`.

Added: 


Modified: 
clang/lib/Index/USRGeneration.cpp
clang/test/Index/USR/func-type.cpp

Removed: 




diff  --git a/clang/lib/Index/USRGeneration.cpp 
b/clang/lib/Index/USRGeneration.cpp
index 5acc86191f8f9c..31c4a3345c09d1 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -267,10 +267,13 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl 
*D) {
 Out << '>';
   }
 
+  QualType CanonicalType = D->getType().getCanonicalType();
   // Mangle in type information for the arguments.
-  for (auto *PD : D->parameters()) {
-Out << '#';
-VisitType(PD->getType());
+  if (const auto *FPT = CanonicalType->getAs()) {
+for (QualType PT : FPT->param_types()) {
+  Out << '#';
+  VisitType(PT);
+}
   }
   if (D->isVariadic())
 Out << '.';

diff  --git a/clang/test/Index/USR/func-type.cpp 
b/clang/test/Index/USR/func-type.cpp
index ff1cd37a7fc421..459a8cd6da5584 100644
--- a/clang/test/Index/USR/func-type.cpp
+++ b/clang/test/Index/USR/func-type.cpp
@@ -16,3 +16,15 @@ void Func( void (* (*)(int, int))(int, int) );
 // CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
 void Func( void (* (*)(int, int, int))(int) );
 // CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |
+
+// Functions with parameter types that only 
diff er in top-level cv-qualification should generate the same USR.
+
+void f( const int );
+// CHECK: {{[0-9]+}}:6 | function/C | f | c:@F@f#I# |
+void f( int );
+// CHECK: {{[0-9]+}}:6 | function/C | f | c:@F@f#I# |
+
+void g( int );
+// CHECK: {{[0-9]+}}:6 | function/C | g | c:@F@g#I# |
+void g( const int );
+// CHECK: {{[0-9]+}}:6 | function/C | g | c:@F@g#I# |



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


[clang] [clang][Index] Use canonical function parameter types in USRs (PR #68222)

2024-04-16 Thread Krystian Stasiowski via cfe-commits

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


[clang] [OpenACC] Implement `self` clause for compute constructs (PR #88760)

2024-04-16 Thread Alexey Bataev via cfe-commits


@@ -835,18 +835,23 @@ Parser::OpenACCClauseParseResult 
Parser::ParseOpenACCClauseParams(
 case OpenACCClauseKind::Default: {
   Token DefKindTok = getCurToken();
 
-  if (expectIdentifierOrKeyword(*this))
-break;
+  if (expectIdentifierOrKeyword(*this)) {
+Parens.skipToEnd();
+return OpenACCCanContinue();
+  }
 
   ConsumeToken();
 
   OpenACCDefaultClauseKind DefKind =
   getOpenACCDefaultClauseKind(DefKindTok);
 
-  if (DefKind == OpenACCDefaultClauseKind::Invalid)
+  if (DefKind == OpenACCDefaultClauseKind::Invalid) {
 Diag(DefKindTok, diag::err_acc_invalid_default_clause_kind);
-  else
+Parens.skipToEnd();
+return OpenACCCanContinue();
+  } else {
 ParsedClause.setDefaultDetails(DefKind);
+  }

alexey-bataev wrote:

No need for else here

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


[clang] [OpenACC] Implement `self` clause for compute constructs (PR #88760)

2024-04-16 Thread Alexey Bataev via cfe-commits


@@ -160,12 +169,58 @@ SemaOpenACC::ActOnClause(ArrayRef 
ExistingClauses,
 // The parser has ensured that we have a proper condition expr, so there
 // isn't really much to do here.
 
-// TODO OpenACC: When we implement 'self', this clauses causes us to
-// 'ignore' the self clause, so we should implement a warning here.
+// If the 'if' clause is true, it makes the 'self' clause have no effect,
+// diagnose that here.
+// TODO OpenACC: When we add these two to other constructs, we might not
+// want to warn on this (for example, 'update').
+const auto *Itr =
+llvm::find_if(ExistingClauses, [](const OpenACCClause *C) {
+  return C->getClauseKind() == OpenACCClauseKind::Self;
+});

alexey-bataev wrote:

```suggestion
llvm::find_if(ExistingClauses, IsaPred);
``` 
???

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


[clang] [OpenACC] Implement `self` clause for compute constructs (PR #88760)

2024-04-16 Thread Alexey Bataev via cfe-commits


@@ -160,12 +169,58 @@ SemaOpenACC::ActOnClause(ArrayRef 
ExistingClauses,
 // The parser has ensured that we have a proper condition expr, so there
 // isn't really much to do here.
 
-// TODO OpenACC: When we implement 'self', this clauses causes us to
-// 'ignore' the self clause, so we should implement a warning here.
+// If the 'if' clause is true, it makes the 'self' clause have no effect,
+// diagnose that here.
+// TODO OpenACC: When we add these two to other constructs, we might not
+// want to warn on this (for example, 'update').
+const auto *Itr =
+llvm::find_if(ExistingClauses, [](const OpenACCClause *C) {
+  return C->getClauseKind() == OpenACCClauseKind::Self;
+});
+if (Itr != ExistingClauses.end()) {
+  Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
+  Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
+}
+
 return OpenACCIfClause::Create(
 getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(),
 Clause.getConditionExpr(), Clause.getEndLoc());
   }
+
+  case OpenACCClauseKind::Self: {
+// Restrictions only properly implemented on 'compute' constructs, and
+// 'compute' constructs are the only construct that can do anything with
+// this yet, so skip/treat as unimplemented in this case.
+if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
+  break;
+
+// TODO OpenACC: When we implement this for 'update', this takes a
+// 'var-list' instead of a condition expression, so semantics/handling has
+// to happen differently here.
+
+// There is no prose in the standard that says duplicates aren't allowed,
+// but this diagnostic is present in other compilers, as well as makes
+// sense.
+if (checkAlreadyHasClauseOfKind(*this, ExistingClauses, Clause))
+  return nullptr;
+
+// If the 'if' clause is true, it makes the 'self' clause have no effect,
+// diagnose that here.
+// TODO OpenACC: When we add these two to other constructs, we might not
+// want to warn on this (for example, 'update').
+const auto *Itr =
+llvm::find_if(ExistingClauses, [](const OpenACCClause *C) {
+  return C->getClauseKind() == OpenACCClauseKind::If;
+});

alexey-bataev wrote:

```suggestion
llvm::find_if(ExistingClauses, IsaPred);
```
???

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


[clang] [Coverage] Handle array decomposition correctly (PR #88881)

2024-04-16 Thread Andrey Ali Khan Bolshakov via cfe-commits

https://github.com/bolshakov-a created 
https://github.com/llvm/llvm-project/pull/1

`ArrayInitLoopExpr` AST node has two occurences of its as-written initializing 
expression in its subexpressions through a non-unique `OpaqueValueExpr`. It 
causes double-visiting of the initializing expression if not handled 
explicitly, as discussed in #85837.

@efriedma-quic 

>From a025b2a45c2a66595c111262dd43c0890f0d54b6 Mon Sep 17 00:00:00 2001
From: Bolshakov 
Date: Tue, 16 Apr 2024 14:21:40 +0300
Subject: [PATCH] [Coverage] Handle array decomposition correctly

`ArrayInitLoopExpr` AST node has two occurences of its as-written
initializing expression in its subexpressions through a non-unique
`OpaqueValueExpr`. It causes double-visiting of the initializing
expression if not handled explicitly, as discussed in #85837.
---
 clang/lib/CodeGen/CoverageMappingGen.cpp |  4 
 clang/test/CoverageMapping/decomposition.cpp | 15 +++
 2 files changed, 19 insertions(+)
 create mode 100644 clang/test/CoverageMapping/decomposition.cpp

diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 71215da362d3d0..569fd489dc8baa 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -2171,6 +2171,10 @@ struct CounterCoverageMappingBuilder
 // propagate counts into them.
   }
 
+  void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *AILE) {
+Visit(AILE->getCommonExpr()->getSourceExpr());
+  }
+
   void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
 // Just visit syntatic expression as this is what users actually write.
 VisitStmt(POE->getSyntacticForm());
diff --git a/clang/test/CoverageMapping/decomposition.cpp 
b/clang/test/CoverageMapping/decomposition.cpp
new file mode 100644
index 00..31bd6cae2c4dec
--- /dev/null
+++ b/clang/test/CoverageMapping/decomposition.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false 
-fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping 
-emit-llvm-only %s | FileCheck %s
+
+// CHECK-LABEL:   _Z19array_decompositioni:
+// CHECK-NEXT:  File 0, [[@LINE+6]]:32 -> {{[0-9]+}}:2 = #0
+// CHECK-NEXT:  File 0, [[@LINE+8]]:20 -> [[@LINE+8]]:25 = #0
+// CHECK-NEXT:  Branch,File 0, [[@LINE+7]]:20 -> [[@LINE+7]]:25 = #1, 
(#0 - #1)
+// CHECK-NEXT:  Gap,File 0, [[@LINE+6]]:27 -> [[@LINE+6]]:28 = #1
+// CHECK-NEXT:  File 0, [[@LINE+5]]:28 -> [[@LINE+5]]:29 = #1
+// CHECK-NEXT:  File 0, [[@LINE+4]]:32 -> [[@LINE+4]]:33 = (#0 - #1)
+int array_decomposition(int i) {
+  int a[] = {1, 2, 3};
+  int b[] = {4, 5, 6};
+  auto [x, y, z] = i > 0 ? a : b;
+  return x + y + z;
+}

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


[clang] [Coverage] Handle array decomposition correctly (PR #88881)

2024-04-16 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Andrey Ali Khan Bolshakov (bolshakov-a)


Changes

`ArrayInitLoopExpr` AST node has two occurences of its as-written initializing 
expression in its subexpressions through a non-unique `OpaqueValueExpr`. It 
causes double-visiting of the initializing expression if not handled 
explicitly, as discussed in #85837.

@efriedma-quic 

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


2 Files Affected:

- (modified) clang/lib/CodeGen/CoverageMappingGen.cpp (+4) 
- (added) clang/test/CoverageMapping/decomposition.cpp (+15) 


``diff
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 71215da362d3d0..569fd489dc8baa 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -2171,6 +2171,10 @@ struct CounterCoverageMappingBuilder
 // propagate counts into them.
   }
 
+  void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *AILE) {
+Visit(AILE->getCommonExpr()->getSourceExpr());
+  }
+
   void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) {
 // Just visit syntatic expression as this is what users actually write.
 VisitStmt(POE->getSyntacticForm());
diff --git a/clang/test/CoverageMapping/decomposition.cpp 
b/clang/test/CoverageMapping/decomposition.cpp
new file mode 100644
index 00..31bd6cae2c4dec
--- /dev/null
+++ b/clang/test/CoverageMapping/decomposition.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false 
-fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping 
-emit-llvm-only %s | FileCheck %s
+
+// CHECK-LABEL:   _Z19array_decompositioni:
+// CHECK-NEXT:  File 0, [[@LINE+6]]:32 -> {{[0-9]+}}:2 = #0
+// CHECK-NEXT:  File 0, [[@LINE+8]]:20 -> [[@LINE+8]]:25 = #0
+// CHECK-NEXT:  Branch,File 0, [[@LINE+7]]:20 -> [[@LINE+7]]:25 = #1, 
(#0 - #1)
+// CHECK-NEXT:  Gap,File 0, [[@LINE+6]]:27 -> [[@LINE+6]]:28 = #1
+// CHECK-NEXT:  File 0, [[@LINE+5]]:28 -> [[@LINE+5]]:29 = #1
+// CHECK-NEXT:  File 0, [[@LINE+4]]:32 -> [[@LINE+4]]:33 = (#0 - #1)
+int array_decomposition(int i) {
+  int a[] = {1, 2, 3};
+  int b[] = {4, 5, 6};
+  auto [x, y, z] = i > 0 ? a : b;
+  return x + y + z;
+}

``




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


[clang] [Coverage] Handle array decomposition correctly (PR #88881)

2024-04-16 Thread Andrey Ali Khan Bolshakov via cfe-commits

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-04-16 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/86512

>From 10d4b9e505d5ad7476071153d2d13799f5b5cf1f Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH 1/2] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer, and implicitly create objects at the buffer
__builtin_memcpy(buffer, src, size);
return std::launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/include/clang/AST/Type.h| 12 +
 clang/include/clang/Basic/TokenKinds.def  |  1 +
 clang/lib/AST/Type.cpp| 23 
 clang/lib/Sema/SemaExprCXX.cpp|  4 +++
 .../SemaCXX/builtin-is-bitwise-copyable.cpp   | 26 +++
 5 files changed, 66 insertions(+)
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-copyable.cpp

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 99f45d518c7960..86d5f8320ac58a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -918,6 +918,18 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext &Context) const;
 
+  /// Return true if this is a bitwise copyable type.
+  ///
+  /// This is an extension in clang: bitwise copyable types act as trivially
+  /// copyable types, underlying bytes of bitwise copyable type can be safely
+  /// copied by memcpy or memmove. Clang guarantees that both source and
+  /// destination objects have the same **object** representations after the
+  /// copy, and the lifetime of the destination object implicitly starts.
+  ///
+  /// bitwise copyable types cover a wider range of types, e.g. classes with
+  /// virtual methods.
+  bool isBitwiseCopyableType(const ASTContext &Context) const;
+
   /// Return true if this is a trivially copyable type
   bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index a27fbed358a60c..b1de15a7e39f48 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -527,6 +527,7 @@ TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, 
IsPointerInterconvertibleBas
 #include "clang/Basic/TransformTypeTraits.def"
 
 // Clang-only C++ Type Traits
+TYPE_TRAIT_1(__is_bitwise_copyable, IsBitwiseCopyable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_equality_comparable, 
IsTriviallyEqualityComparable, KEYCXX)
 TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index cb22c91a12aa89..9d13256de3327c 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2718,6 +2718,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
&Context) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCopyableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise copyable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCopyableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto *const Field : RD->fields()) {
+  QualType T = Context.getBaseElementType(Field->getType());
+  if (!T.isBitwiseCopyableType(Context))
+return false;
+}
+return true;
+  }
+  return false;
+}
+
 bool QualType::isTrivial

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-04-16 Thread Haojian Wu via cfe-commits


@@ -2667,6 +2667,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
&Context) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCopyableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())

hokein wrote:

Other traits (see `isTriviallyCopyableTypeImpl`) do the similar things for 
incomplete and dependent types, we follow what they did in this type trait.

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


  1   2   3   4   5   >