[clang] Introduce paged vector (PR #66430)

2023-09-15 Thread Giulio Eulisse via cfe-commits


@@ -0,0 +1,84 @@
+//===- llvm/unittest/ADT/PagedVectorTest.cpp 
--===//
+//
+// 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
+//
+//===--===//
+//
+// PagedVector unit tests.
+//
+//===--===//
+
+#include "llvm/ADT/PagedVector.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+TEST(PagedVectorTest, FunctionalityTest) {

ktf wrote:

Thank you for your comments. I have updated the test to check for clear, empty 
and at. I tried to use EXPECT_DEATH but I get:

```
[WARNING] 
/Users/ktf/src/sw/SOURCES/llvm-upstream/master/0/third-party/unittest/googletest/src/gtest-death-test.cc:1102::
 Death tests use fork(), which is unsafe particularly in a threaded context. 
For this test, Google Test detected 11 threads. See 
https://github.com/google/googletest/blob/main/docs/advanced.md#death-tests-and-threads
 for more explanation and suggested solutions, especially if this is the last 
message you see before your test times out.
```

could you please advise?


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


[clang] Introduce paged vector (PR #66430)

2023-09-15 Thread Giulio Eulisse via cfe-commits

https://github.com/ktf updated https://github.com/llvm/llvm-project/pull/66430

>From b952f0577dfe8112f394bd5392212f843c0cc86e Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+...@users.noreply.github.com>
Date: Thu, 14 Sep 2023 21:58:21 +0200
Subject: [PATCH 01/13] Introduce PagedVector class

The goal of the class is to be an (almost) drop in replacement for
SmallVector and std::vector when those are presized and filled later,
as it happens in SourceManager and ASTReader.

By splitting the actual vector in pages of the same size and allocating
the pages only when they are needed, using this containers reduces the
memory usage by a factor 4 for the cases relevant to the ALICE
experiment ROOT / cling usage.
---
 llvm/include/llvm/ADT/PagedVector.h | 96 +
 1 file changed, 96 insertions(+)
 create mode 100644 llvm/include/llvm/ADT/PagedVector.h

diff --git a/llvm/include/llvm/ADT/PagedVector.h 
b/llvm/include/llvm/ADT/PagedVector.h
new file mode 100644
index 000..dab0d249aa706e4
--- /dev/null
+++ b/llvm/include/llvm/ADT/PagedVector.h
@@ -0,0 +1,96 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include 
+
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+template  class PagedVector {
+  size_t Size = 0;
+  // Index of where to find a given page in the data
+  mutable std::vector Lookup;
+  // Actual data
+  mutable std::vector Data;
+
+public:
+  // Add a range to the vector.
+  // When vector is accessed, it will call the callback to fill the range
+  // with data.
+
+  // Lookup an element at position i.
+  // If the given range is not filled, it will be filled.
+  // If the given range is filled, return the element.
+  T [](int Index) const { return at(Index); }
+
+  T (int Index) const {
+auto  = Lookup[Index / PAGE_SIZE];
+// If the range is not filled, fill it
+if (PageId == -1) {
+  int OldSize = Data.size();
+  PageId = OldSize / PAGE_SIZE;
+  // Allocate the memory
+  Data.resize(OldSize + PAGE_SIZE);
+  // Fill the whole capacity with empty elements
+  for (int I = 0; I < PAGE_SIZE; ++I) {
+Data[I + OldSize] = T();
+  }
+}
+// Return the element
+return Data[Index % PAGE_SIZE + PAGE_SIZE * PageId];
+  }
+
+  // Return the size of the vector
+  size_t capacity() const { return Lookup.size() * PAGE_SIZE; }
+
+  size_t size() const { return Size; }
+
+  // Expands the vector to the given size.
+  // If the vector is already bigger, does nothing.
+  void expand(size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// you would have to invalidate
+assert(NewSize >= Size);
+if (NewSize <= Size) {
+  return;
+}
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZE;
+if (Remainder) {
+  Pages += 1;
+}
+assert(Pages > Lookup.size());
+Lookup.resize(Pages, -1);
+Size = NewSize;
+  }
+
+  // Return true if the vector is empty
+  bool empty() const { return Size == 0; }
+  /// Clear the vector
+  void clear() {
+Size = 0;
+Lookup.clear();
+Data.clear();
+  }
+
+  std::vector const () const { return Data; }
+};
+
+#endif // LLVM_ADT_PAGEDVECTOR_H

>From f0c75c8af0fea27b5b758e2e5775787f33595de3 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+...@users.noreply.github.com>
Date: Thu, 14 Sep 2023 22:20:29 +0200
Subject: [PATCH 02/13] Use PagedVector to reduce memory usage of sparsely
 populated vectors

---
 clang/include/clang/Basic/SourceManager.h |  3 ++-
 clang/include/clang/Serialization/ASTReader.h |  5 +++--
 clang/lib/Basic/SourceManager.cpp | 12 ++--
 clang/lib/Serialization/ASTReader.cpp |  9 +
 4 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/SourceManager.h 
b/clang/include/clang/Basic/SourceManager.h
index 2f846502d6f3327..b1942a3d86afc37 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -43,6 +43,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/PagedVector.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include 

[clang] Fix math-errno issue (PR #66381)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits

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


[clang] Fix math-errno issue (PR #66381)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits

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


[clang] Fix math-errno issue (PR #66381)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits

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


[clang] Fix math-errno issue (PR #66381)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits

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


[clang] [clang][Interp] Handle AttributedStmts (PR #66495)

2023-09-15 Thread via cfe-commits

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


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


[clang] [clang][Interp] Handle AttributedStmts (PR #66495)

2023-09-15 Thread via cfe-commits


@@ -628,6 +630,12 @@ bool ByteCodeStmtGen::visitAsmStmt(const AsmStmt 
*S) {
   return this->emitInvalid(S);
 }
 
+template 
+bool ByteCodeStmtGen::visitAttributedStmt(const AttributedStmt *S) {
+  // Ignore all attributes.

cor3ntin wrote:

At compile time, i suppose so!

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


[clang] Introduce paged vector (PR #66430)

2023-09-15 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik commented:

Thank you for this contributions, I just have one comment so far on testing. We 
should make sure any new ADT is very well tested before landing it. 

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


[clang] Introduce paged vector (PR #66430)

2023-09-15 Thread Shafik Yaghmour via cfe-commits

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


[clang] Introduce paged vector (PR #66430)

2023-09-15 Thread Shafik Yaghmour via cfe-commits


@@ -0,0 +1,84 @@
+//===- llvm/unittest/ADT/PagedVectorTest.cpp 
--===//
+//
+// 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
+//
+//===--===//
+//
+// PagedVector unit tests.
+//
+//===--===//
+
+#include "llvm/ADT/PagedVector.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+TEST(PagedVectorTest, FunctionalityTest) {

shafik wrote:

I don't see tests for `clear()`, `empty()` or `at(..)` and I think we should 
have `EXPECT_DEATH` tests for assertions that are testable.

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


[PATCH] D159522: [Clang][C] Fixed a bug where we reject an _Atomic qualified integer in a switch statment

2023-09-15 Thread Guillot Tony via Phabricator via cfe-commits
to268 created this revision.
to268 added a reviewer: aaron.ballman.
to268 added a project: clang.
Herald added a project: All.
to268 requested review of this revision.
Herald added a subscriber: cfe-commits.

We are currently rejecting an _Atomic qualified integer in a switch statment.
This fixes the issue by doing an Lvalue conversion before trying to match on 
the type.
Fixes #65557


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159522

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/Sema/atomic-expr.c


Index: clang/test/Sema/atomic-expr.c
===
--- clang/test/Sema/atomic-expr.c
+++ clang/test/Sema/atomic-expr.c
@@ -216,3 +216,9 @@
   struct T { int a; };
   (void)(_Atomic struct T)s; // expected-error {{used type 'struct T' where 
arithmetic or pointer type is required}}
 }
+
+// Test if we can handle an _Atomic qualified integer in a switch statement.
+void func_19(void) {
+  _Atomic int a = 0;
+  switch (a) { }
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -6302,8 +6302,10 @@
 From = result.get();
   }
 
+  // Try converting the expression to an Lvalue first, to get rid of 
qualifiers.
+  ExprResult Converted = DefaultLvalueConversion(From);
+  QualType T = Converted.isUsable() ? Converted.get()->getType() : QualType();
   // If the expression already has a matching type, we're golden.
-  QualType T = From->getType();
   if (Converter.match(T))
 return DefaultLvalueConversion(From);
 


Index: clang/test/Sema/atomic-expr.c
===
--- clang/test/Sema/atomic-expr.c
+++ clang/test/Sema/atomic-expr.c
@@ -216,3 +216,9 @@
   struct T { int a; };
   (void)(_Atomic struct T)s; // expected-error {{used type 'struct T' where arithmetic or pointer type is required}}
 }
+
+// Test if we can handle an _Atomic qualified integer in a switch statement.
+void func_19(void) {
+  _Atomic int a = 0;
+  switch (a) { }
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -6302,8 +6302,10 @@
 From = result.get();
   }
 
+  // Try converting the expression to an Lvalue first, to get rid of qualifiers.
+  ExprResult Converted = DefaultLvalueConversion(From);
+  QualType T = Converted.isUsable() ? Converted.get()->getType() : QualType();
   // If the expression already has a matching type, we're golden.
-  QualType T = From->getType();
   if (Converter.match(T))
 return DefaultLvalueConversion(From);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D147844: [clang][Sema]Print diagnostic warning about precedence when integer expression is used without parentheses in an conditional operator expression

2023-09-15 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added a comment.

FWIW: adding parentheses for expressions, such as `overflow = (4608 * 1024 * 
1024) ?  4608 * 1024 * 1024 : 0;`, and `results.reason = (actions & 
_UA_SEARCH_PHASE) ? ... : ...`, looks unnatural and is too noisy to me.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147844/new/

https://reviews.llvm.org/D147844

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


[clang] [clang][deps] Load module map file from PCM (PR #66389)

2023-09-15 Thread Ben Langmuir via cfe-commits


@@ -1307,6 +1307,9 @@ void ModuleMap::setInferredModuleAllowedBy(Module *M,
 
 std::error_code
 ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl ) {
+  FileManager  = SourceMgr.getFileManager();
+  FM.makeAbsolutePath(Path);

benlangmuir wrote:

Is the idea that because the paths used by the scanner is now indirected 
through the (implicit) pcm that whatever ASTWriter does to make the path 
relative will apply to the explicit module invocation?  Before your current 
changes the scanner was using `canonicalizeModuleMapPath` directly on the path 
in the invocation, which is what I was naively thinking of.  

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


[PATCH] D159519: [clang][AST][ASTImporter] improve AST comparasion on VarDecl & GotoStmt

2023-09-15 Thread Qizhi Hu via Phabricator via cfe-commits
jcsxky updated this revision to Diff 556861.
jcsxky added a comment.

update according to llvm convention.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159519/new/

https://reviews.llvm.org/D159519

Files:
  clang/lib/AST/ASTStructuralEquivalence.cpp
  clang/unittests/AST/StructuralEquivalenceTest.cpp

Index: clang/unittests/AST/StructuralEquivalenceTest.cpp
===
--- clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1,5 +1,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Frontend/ASTUnit.h"
@@ -1801,10 +1802,10 @@
 TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
   auto TU = makeTuDecls(
   R"(
-  bool x(){ return true; }
+  bool x() { return true; }
   )",
   R"(
-  bool x(){ return false; }
+  bool x() { return false; }
   )",
   Lang_CXX03);
 
@@ -1817,6 +1818,60 @@
 
 }
 
+TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  int q;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p;
+  )",
+  R"(
+  static int p;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
+  auto TU = makeTuDecls(
+  R"(
+  int p = 1;
+  )",
+  R"(
+  int p = 2;
+  )",
+  Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+  get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto Var = findDeclPair(TU, varDecl());
+  EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
   auto TU = makeTuDecls(
   R"(
@@ -2320,5 +2375,23 @@
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
+  auto S = makeStmts(
+  R"(
+  void foo() {
+goto L1;
+L1: foo();
+  }
+  )",
+  R"(
+  void foo() {
+goto L2;
+L2: foo();
+  }
+  )",
+  Lang_CXX03, gotoStmt());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -277,6 +277,17 @@
 
   bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
 
+  bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
+LabelDecl *L1 = S1->getLabel();
+LabelDecl *L2 = S2->getLabel();
+if (!L1 || !L2)
+  return L1 == L2;
+
+IdentifierInfo *Name1 = L1->getIdentifier();
+IdentifierInfo *Name2 = L2->getIdentifier();
+return ::IsStructurallyEquivalent(Name1, Name2);
+  }
+
   bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
 return E1->getIdentKind() == E2->getIdentKind();
   }
@@ -1295,6 +1306,22 @@
   return true;
 }
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ VarDecl *D1, VarDecl *D2) {
+  if (D1->getStorageClass() != D2->getStorageClass())
+return false;
+
+  IdentifierInfo *Name1 = D1->getIdentifier();
+  IdentifierInfo *Name2 = D2->getIdentifier();
+  if (!::IsStructurallyEquivalent(Name1, Name2))
+return false;
+
+  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
+return false;
+
+  return IsStructurallyEquivalent(Context, D1->getInit(), D2->getInit());
+}
+
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  FieldDecl *Field1, FieldDecl *Field2,
  QualType Owner2Type) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][deps] Load module map file from PCM (PR #66389)

2023-09-15 Thread Jan Svoboda via cfe-commits


@@ -1307,6 +1307,9 @@ void ModuleMap::setInferredModuleAllowedBy(Module *M,
 
 std::error_code
 ModuleMap::canonicalizeModuleMapPath(SmallVectorImpl ) {
+  FileManager  = SourceMgr.getFileManager();
+  FM.makeAbsolutePath(Path);

jansvoboda11 wrote:

I don't understand how would this impact explicit module invocations? These can 
still use relative module map paths, it's just that the compiler will use the 
absolute canonical path internally (IIUC in an non-observable way).

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


[clang] [RISCV] Install sifive_vector.h to riscv-resource-headers (PR #66330)

2023-09-15 Thread Craig Topper via cfe-commits


@@ -623,6 +623,11 @@ install(
   EXCLUDE_FROM_ALL
   COMPONENT riscv-resource-headers)
 
+install(

topperc wrote:

Aren't we also missing `sifive_files` from 
`add_header_target("riscv-resource-headers" 
"${riscv_files};${riscv_generated_files}")`?

Is there any reason to have `sifive_files`? Should we put sifive_vector.h in 
`riscv_files`?

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


[clang] [libc++] Prevent calling the projection more than three times (PR #66315)

2023-09-15 Thread Jocelyn Castellano via cfe-commits

https://github.com/pandaninjas updated 
https://github.com/llvm/llvm-project/pull/66315

>From ead65bfcb70be46788bc9e88c891e7ae7f91b8d7 Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 17:38:17 -0700
Subject: [PATCH 1/8] [libc++] Prevent calling the projection more than three
 times

---
 libcxx/include/__algorithm/ranges_clamp.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 9613f7f37720a6c..ca46675eb4b3041 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,9 +37,10 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, 
__low)))
+auto  = std::invoke(__proj, __value);
+if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), 
std::invoke(__proj, __value)))
+else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
   return __high;
 else
   return __value;

>From c18d60870ac342a95a5528396a8e0c7b91717cbb Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 18:56:44 -0700
Subject: [PATCH 2/8] [libc++] Run clang-format on file

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index ca46675eb4b3041..3469a6419b2270f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto  = std::invoke(__proj, __value);
+auto& projection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From b40e791f0e9fedbb19936851e1e71decf00331fa Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:20 -0700
Subject: [PATCH 3/8] [libcxx] CamelCase projection and make variable name more
 descriptive

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3469a6419b2270f..3adb5fa828e1ee5 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto& projection = std::invoke(__proj, __value);
+auto& ValueProjection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From a8907624defa4cc4f47520a2d93a8bd042816aa2 Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:47 -0700
Subject: [PATCH 4/8] [libcxx] properly change variable name

---
 libcxx/include/__algorithm/ranges_clamp.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3adb5fa828e1ee5..3d7a224b3649a3f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -38,9 +38,9 @@ struct __fn {
  "Bad bounds passed to std::ranges::clamp");
 
 auto& ValueProjection = std::invoke(__proj, __value);
-if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
+if (std::invoke(__comp, ValueProjection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
+else if (std::invoke(__comp, std::invoke(__proj, __high), ValueProjection))
   return __high;
 else
   return __value;

>From 15d3b2b79fbd61f97b0312e0913cede36b5b202d Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Thu, 14 Sep 2023 10:37:34 -0700
Subject: [PATCH 5/8] Apply suggestions from code review

---
 libcxx/include/__algorithm/ranges_clamp.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3d7a224b3649a3f..a97538e4c0e3f65 100644
--- 

[clang-tools-extra] [libc++] Prevent calling the projection more than three times (PR #66315)

2023-09-15 Thread Jocelyn Castellano via cfe-commits

https://github.com/pandaninjas updated 
https://github.com/llvm/llvm-project/pull/66315

>From ead65bfcb70be46788bc9e88c891e7ae7f91b8d7 Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 17:38:17 -0700
Subject: [PATCH 1/8] [libc++] Prevent calling the projection more than three
 times

---
 libcxx/include/__algorithm/ranges_clamp.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 9613f7f37720a6c..ca46675eb4b3041 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,9 +37,10 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, 
__low)))
+auto  = std::invoke(__proj, __value);
+if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), 
std::invoke(__proj, __value)))
+else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
   return __high;
 else
   return __value;

>From c18d60870ac342a95a5528396a8e0c7b91717cbb Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 18:56:44 -0700
Subject: [PATCH 2/8] [libc++] Run clang-format on file

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index ca46675eb4b3041..3469a6419b2270f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto  = std::invoke(__proj, __value);
+auto& projection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From b40e791f0e9fedbb19936851e1e71decf00331fa Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:20 -0700
Subject: [PATCH 3/8] [libcxx] CamelCase projection and make variable name more
 descriptive

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3469a6419b2270f..3adb5fa828e1ee5 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto& projection = std::invoke(__proj, __value);
+auto& ValueProjection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From a8907624defa4cc4f47520a2d93a8bd042816aa2 Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:47 -0700
Subject: [PATCH 4/8] [libcxx] properly change variable name

---
 libcxx/include/__algorithm/ranges_clamp.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3adb5fa828e1ee5..3d7a224b3649a3f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -38,9 +38,9 @@ struct __fn {
  "Bad bounds passed to std::ranges::clamp");
 
 auto& ValueProjection = std::invoke(__proj, __value);
-if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
+if (std::invoke(__comp, ValueProjection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
+else if (std::invoke(__comp, std::invoke(__proj, __high), ValueProjection))
   return __high;
 else
   return __value;

>From 15d3b2b79fbd61f97b0312e0913cede36b5b202d Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Thu, 14 Sep 2023 10:37:34 -0700
Subject: [PATCH 5/8] Apply suggestions from code review

---
 libcxx/include/__algorithm/ranges_clamp.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3d7a224b3649a3f..a97538e4c0e3f65 100644
--- 

[clang] [clang][doc] Add documentation for the ASTs used to represent C++ templates (PR #66436)

2023-09-15 Thread Tom Honermann via cfe-commits

tahonermann wrote:

Hi, Scott! It's nice to see you pop up here! :)

I'm a little concerned about maintenance of this documentation going forward. 
As you know, the Clang AST is not intended to be stable and, even though I 
don't expect dramatic changes to how templates are represented, it will take 
some effort to ensure the code and the documentation stay in sync. Do you have 
any thoughts regarding how we can implement an automated process to ensure the 
documentation is updated?

For anyone not familiar, [ded](https://github.com/smcpeak/ded) is a diagram 
editor that Scott developed. I've used it in the past and found it to be 
lightweight and easy to use.

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


[clang] [RISCV] Support predefined marcro __riscv_misaligned_{fast,avoid}. (PR #65756)

2023-09-15 Thread Craig Topper via cfe-commits


@@ -1220,3 +1220,15 @@
 // RUN: -march=rv64i_zve32x_zvkt1p0 -x c -E -dM %s \
 // RUN: -o - | FileCheck --check-prefix=CHECK-ZVKT-EXT %s
 // CHECK-ZVKT-EXT: __riscv_zvkt 100{{$}}
+
+// RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \

topperc wrote:

Should we update this test file to use `--target=` for all test cases in 
another patch? Getting a review comment for copy and pasting from an existing 
test case is frustrating.

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


[clang] [Inliner] Improve attribute propagation to callsites when inlining. (PR #66036)

2023-09-15 Thread via cfe-commits

goldsteinn wrote:

> It occurs to me that the current return attribute propagation is currently 
> buggy for poison-generating attributes: https://llvm.godbolt.org/z/x8n18q9Mj
> 
> In this case the argument to use() will now be poison as well, while before 
> inlining only the return value was poison.
> 
> This code needs to distinguish poison and UB generating attributes.

Good catch. I think this means basically `nonnull`, `noundef`, and `align` can 
only be propagated if there are no other uses in to-be-inlined function.
That sound right or do you see any more robust way forward?

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


[clang] [Inliner] Improve attribute propagation to callsites when inlining. (PR #66036)

2023-09-15 Thread Nikita Popov via cfe-commits

nikic wrote:

It occurs to me that the current return attribute propagation is currently 
buggy for poison-generating attributes: https://llvm.godbolt.org/z/x8n18q9Mj

In this case the argument to use() will now be poison as well, while before 
inlining only the return value was poison.

This code needs to distinguish poison and UB generating attributes.

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


[clang] [clang-transformer] Allow stencils to read from system headers. (PR #66480)

2023-09-15 Thread Yitzhak Mandelbaum via cfe-commits

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

Thanks!

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


[clang-tools-extra] [clang-cl] Fix for __FUNCTION__ in c++. (PR #66120)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits


@@ -2218,6 +2218,9 @@ printTo(raw_ostream , ArrayRef Args, const 
PrintingPolicy ,
 } else {
   if (!FirstArg)
 OS << Comma;
+  //if (Argument.getKind() == TemplateArgument::Type)
+  //  OS << "class ";
+

zahiraam wrote:

TODO: if we go with this solution, this needs to happen here, but it should be 
under some conditions? 

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


[clang] [clang][Sema] Fix a bug when instantiating a lambda with requires clause (PR #65193)

2023-09-15 Thread via cfe-commits

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


[clang] [clang][Sema] Fix a bug when instantiating a lambda with requires clause (PR #65193)

2023-09-15 Thread via cfe-commits


@@ -567,6 +567,58 @@ bool Sema::addInstantiatedCapturesToScope(
   return false;
 }
 
+static void addDeclsFromParentScope(Sema , FunctionDecl *FD,
+LocalInstantiationScope ) {
+  assert(isLambdaCallOperator(FD) && "FD must be a lambda call operator");
+
+  LambdaScopeInfo *LSI = cast(S.getFunctionScopes().back());
+
+  auto captureVar = [&](VarDecl *VD) {
+LSI->addCapture(VD, /*isBlock=*/false, /*isByref=*/false,
+/*isNested=*/false, VD->getBeginLoc(), SourceLocation(),
+VD->getType(), /*Invalid=*/false);
+  };
+

0x59616e wrote:

I couldn't find where the logic is in 
`LambdaScopeForCallOperatorInstantiationRAII`. Would you mind giving more hints 
? Thanks.

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


[clang-tools-extra] e8b1af9 - Fix clang-tidy sphinx docs

2023-09-15 Thread Aaron Ballman via cfe-commits

Author: Aaron Ballman
Date: 2023-09-15T10:11:10-04:00
New Revision: e8b1af9a55764e91015a4f9bbabdb39cf95caf94

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

LOG: Fix clang-tidy sphinx docs

This addresses issues found by:
https://lab.llvm.org/buildbot/#/builders/115/builds/53446

Added: 


Modified: 

clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst

Removed: 




diff  --git 
a/clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst
index 8b6749938957e86..a8293297c121211 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst
@@ -7,6 +7,7 @@ Detects unspecified behavior about equality comparison between 
pointer to member
 virtual function and anything other than null-pointer-constant.
 
 .. code-block:: c++
+
 struct A {
   void f1();
   void f2();



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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread Louis Dionne via cfe-commits

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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread Louis Dionne via cfe-commits

ldionne wrote:

I guess I'll close this and reopen when I have something that actually works 
for handling trailing whitespace.

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


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-09-15 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang


Changes
Add some primitive syntax highlighting to our code snippet output.


Before:
![Screenshot from 2023-09-15 
16-00-23](https://github.com/llvm/llvm-project/assets/49720664/8e43767a-d939-4c9f-ac2d-65e2df5de1f2)


After:
![Screenshot from 2023-09-15 
15-55-35](https://github.com/llvm/llvm-project/assets/49720664/714b536c-377f-4a0d-921c-b103b90c5706)






_Obviously_ this is kinda WIP and more of a hack in general, but IMO it 
increases readability of the source snippets (which people look at highlighted 
all the time anyway...) and LLDB does something similar, so let's see.

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

5 Files Affected:

- (added) clang/include/clang/Frontend/CodeSnippetHighlighter.h (+46) 
- (modified) clang/include/clang/Frontend/TextDiagnostic.h (+3-1) 
- (modified) clang/lib/Frontend/CMakeLists.txt (+1) 
- (added) clang/lib/Frontend/CodeSnippetHighlighter.cpp (+120) 
- (modified) clang/lib/Frontend/TextDiagnostic.cpp (+29-2) 



diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include quot;clang/Basic/LangOptions.hquot;
+#include quot;llvm/ADT/SmallSet.hquot;
+#include quot;llvm/Support/raw_ostream.hquot;
+#include lt;vectorgt;
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vectorlt;StyleRangegt; highlightLine(llvm::StringRef 
SourceLine,
+const LangOptions amp;LangOpts);
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSetlt;StringRef, 12gt; Keywords;
+  llvm::SmallSetlt;StringRef, 12gt; Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..39e09fe553dd4b9 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include quot;clang/Frontend/CodeSnippetHighlighter.hquot;
 #include quot;clang/Frontend/DiagnosticRenderer.hquot;
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream amp;OS;
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream amp;OS,
@@ -104,7 +106,7 @@ class TextDiagnostic : public DiagnosticRenderer {
ArrayReflt;FixItHintgt; Hints);
 
   void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth,
-   unsigned LineNo);
+   unsigned LineNo, bool A, const SourceManager amp;SM);
 
   void emitParseableFixits(ArrayReflt;FixItHintgt; Hints, const 
SourceManager amp;SM);
 };
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include quot;clang/Frontend/CodeSnippetHighlighter.hquot;
+#include quot;clang/Basic/DiagnosticOptions.hquot;
+#include quot;clang/Basic/SourceManager.hquot;
+#include quot;clang/Lex/Lexer.hquot;
+#include quot;llvm/Support/raw_ostream.hquot;
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types 

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-09-15 Thread Timm Baeder via cfe-commits

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

Add some primitive syntax highlighting to our code snippet output.


Before:
![Screenshot from 2023-09-15 
16-00-23](https://github.com/llvm/llvm-project/assets/49720664/8e43767a-d939-4c9f-ac2d-65e2df5de1f2)


After:
![Screenshot from 2023-09-15 
15-55-35](https://github.com/llvm/llvm-project/assets/49720664/714b536c-377f-4a0d-921c-b103b90c5706)






_Obviously_ this is kinda WIP and more of a hack in general, but IMO it 
increases readability of the source snippets (which people look at highlighted 
all the time anyway...) and LLDB does something similar, so let's see.


>From b4f4d29c8780752629f78b4debb86bd9f9dff0d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   4 +-
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  31 -
 5 files changed, 199 insertions(+), 3 deletions(-)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..39e09fe553dd4b9 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
@@ -104,7 +106,7 @@ class TextDiagnostic : public DiagnosticRenderer {
ArrayRef Hints);
 
   void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth,
-   unsigned LineNo);
+   unsigned LineNo, bool A, const SourceManager );
 
   void emitParseableFixits(ArrayRef Hints, const SourceManager );
 };
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include 

[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }
+
+  CallEventManager  = State->getStateManager().getCallEventManager();
+  return CEMgr.getCaller(CallStackFrameContext, State);
+}
+
+const CXXConstructorDecl *
+getConstructorDeclarationForCall(const CallEvent ) {
+  const auto *ConstructorCall = dyn_cast();
+  if (!ConstructorCall) {
+return nullptr;
+  }
+  return ConstructorCall->getDecl();
+}
+
+bool isCopyConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isCopyConstructor();
+}
+
+bool isCopyAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isCopyAssignmentOperator();
+}
+
+bool isMoveConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isMoveConstructor();
+}
+
+bool isMoveAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isMoveAssignmentOperator();
+}
+
+const TemplateArgument (const CallEvent ) {
+  const CallExpr *CE = cast(Call.getOriginExpr());
+  const FunctionDecl *FD = CE->getDirectCallee();
+  assert(1 <= FD->getTemplateSpecializationArgs()->asArray().size() &&
+ "std::get should have at least 1 template argument!");
+  return FD->getTemplateSpecializationArgs()->asArray()[0];
+}
+
+bool isStdType(const Type *Type, const std::string ) {
+  auto *Decl = Type->getAsRecordDecl();
+  if (!Decl) {
+return false;
+  }
+
+  return (Decl->getNameAsString() == TypeName) && Decl->isInStdNamespace();
+}
+
+bool isStdVariant(const Type *Type) {
+  return isStdType(Type, std::string("variant"));
+}
+
+bool calledFromSystemHeader(const CallEvent ,
+const ProgramStateRef ) {
+  auto Caller = getCaller(Call, State);
+  if (Caller) {
+return Caller->isInSystemHeader();
+  }
+  return false;
+}
+
+bool calledFromSystemHeader(const CallEvent , CheckerContext ) {
+  return calledFromSystemHeader(Call, C.getState());
+}
+
+} // end of namespace variant_modeling
+} // end of namespace ento
+} // end of namespace clang
+
+static ArrayRef
+getTemplateArgsFromVariant(const Type *VariantType) {
+  const auto *TempSpecType = VariantType->getAs();
+  assert(TempSpecType &&
+ "We are in a variant instance. It must be a template 
specialization!");

DonatNagyE wrote:

As above, this depends on user input, so it should be an early return (and not 
an assert).

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.
+template 
+ProgramStateRef
+removeInformationStoredForDeadInstances(const CallEvent *Call,
+ProgramStateRef State,
+ArrayRef Regions) {
+  // If we do not know anything about the call we shall not continue.
+  if (!Call) {
+return State;
+  }
+
+  // If the call is coming from a system header it is implementation detail.
+  // We should not take it into consideration.
+  if (Call->isInSystemHeader()) {
+return State;
+  }
+
+  // Remove the information we know about the invalidate region.
+  // It is not relevant anymore.
+  State = std::accumulate(
+  Regions.begin(), Regions.end(), State,
+  [](ProgramStateRef State, const MemRegion *CurrentMemRegion) {
+if (State->contains(CurrentMemRegion)) {
+  State = State->remove(CurrentMemRegion);
+}
+return State;
+  });
+  return State;
+}
+
+template 
+void handleConstructorAndAssignment(const CallEvent , CheckerContext ,
+const SVal ) {
+  ProgramStateRef State = Call.getState();
+
+  auto ArgSVal = Call.getArgSVal(0);
+  const auto *ThisRegion = ThisSVal.getAsRegion();
+  const auto *ArgMemRegion = ArgSVal.getAsRegion();
+
+  // Make changes to the state according to type of constructor/assignment
+  State = [&]() {
+bool IsCopy = isCopyConstructorCall(Call) || isCopyAssignmentCall(Call);
+bool IsMove = isMoveConstructorCall(Call) || isMoveAssignmentCall(Call);
+
+// First we handle copy and move operations
+if (IsCopy || IsMove) {
+  // If the argument of a copy constructor or assignment is unknown then
+  // we will not know the argument of the copied to object.
+  bool OtherQTypeKnown = State->contains(ArgMemRegion);
+
+  const QualType *OtherQType;
+  if (OtherQTypeKnown) {
+OtherQType = State->get(ArgMemRegion);
+  } else {
+return State->contains(ThisRegion)
+   ? State->remove(ThisRegion)
+   : State;
+  }
+
+  // When move semantics is used we can only know that the moved from
+  // object must be in a destructible state. Other usage of the object
+  // than destruction is undefined.
+  if (IsMove) {
+State = State->contains(ArgMemRegion)
+? State->remove(ArgMemRegion)
+: State;
+  }
+  return State->set(ThisRegion, *OtherQType);
+}
+// Then the other constructor/assignment where the argument is the new
+// object held by the std::variant or std::any

DonatNagyE wrote:

Perhaps include the signature of the referenced constructors / assignment 
operators (here and above) for the sake of lazy readers like me :)

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.
+template 
+ProgramStateRef
+removeInformationStoredForDeadInstances(const CallEvent *Call,
+ProgramStateRef State,
+ArrayRef Regions) {
+  // If we do not know anything about the call we shall not continue.
+  if (!Call) {
+return State;
+  }
+
+  // If the call is coming from a system header it is implementation detail.
+  // We should not take it into consideration.
+  if (Call->isInSystemHeader()) {
+return State;
+  }
+
+  // Remove the information we know about the invalidate region.
+  // It is not relevant anymore.
+  State = std::accumulate(
+  Regions.begin(), Regions.end(), State,
+  [](ProgramStateRef State, const MemRegion *CurrentMemRegion) {
+if (State->contains(CurrentMemRegion)) {
+  State = State->remove(CurrentMemRegion);
+}
+return State;
+  });
+  return State;
+}
+
+template 
+void handleConstructorAndAssignment(const CallEvent , CheckerContext ,
+const SVal ) {
+  ProgramStateRef State = Call.getState();
+
+  auto ArgSVal = Call.getArgSVal(0);
+  const auto *ThisRegion = ThisSVal.getAsRegion();
+  const auto *ArgMemRegion = ArgSVal.getAsRegion();
+
+  // Make changes to the state according to type of constructor/assignment
+  State = [&]() {
+bool IsCopy = isCopyConstructorCall(Call) || isCopyAssignmentCall(Call);
+bool IsMove = isMoveConstructorCall(Call) || isMoveAssignmentCall(Call);
+
+// First we handle copy and move operations
+if (IsCopy || IsMove) {
+  // If the argument of a copy constructor or assignment is unknown then
+  // we will not know the argument of the copied to object.
+  bool OtherQTypeKnown = State->contains(ArgMemRegion);
+
+  const QualType *OtherQType;
+  if (OtherQTypeKnown) {
+OtherQType = State->get(ArgMemRegion);
+  } else {
+return State->contains(ThisRegion)
+   ? State->remove(ThisRegion)
+   : State;

DonatNagyE wrote:

Please check what `State->remove(ThisRegion)` does when the map does 
not contain `ThisRegion`. Its definition is very complex template magic, but I 
think it's plausible that it'll just return an unchanged state and then you can 
simplify code like this in many locations.

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.
+template 
+ProgramStateRef
+removeInformationStoredForDeadInstances(const CallEvent *Call,
+ProgramStateRef State,
+ArrayRef Regions) {
+  // If we do not know anything about the call we shall not continue.
+  if (!Call) {
+return State;
+  }
+
+  // If the call is coming from a system header it is implementation detail.
+  // We should not take it into consideration.
+  if (Call->isInSystemHeader()) {
+return State;
+  }
+
+  // Remove the information we know about the invalidate region.
+  // It is not relevant anymore.
+  State = std::accumulate(
+  Regions.begin(), Regions.end(), State,
+  [](ProgramStateRef State, const MemRegion *CurrentMemRegion) {
+if (State->contains(CurrentMemRegion)) {
+  State = State->remove(CurrentMemRegion);
+}
+return State;
+  });
+  return State;
+}
+
+template 
+void handleConstructorAndAssignment(const CallEvent , CheckerContext ,
+const SVal ) {
+  ProgramStateRef State = Call.getState();
+
+  auto ArgSVal = Call.getArgSVal(0);
+  const auto *ThisRegion = ThisSVal.getAsRegion();
+  const auto *ArgMemRegion = ArgSVal.getAsRegion();
+
+  // Make changes to the state according to type of constructor/assignment
+  State = [&]() {

DonatNagyE wrote:

Remove this fat immediately executed lambda, it just obfuscates the control and 
data flow without any advantage.

A plain old `State = /* do something with old State */` is much more readable 
than `return /*do something with old State*/` with a dangling `State =` for 
which you need to scroll up a screen.

If you really like to jump around, use `break`s within a `do { } while (false)` 
or even plain `goto` instead of the early `return`s from the lambda -- but I 
think this logic can be clearly described with simple `else` branches.

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }
+
+  CallEventManager  = State->getStateManager().getCallEventManager();
+  return CEMgr.getCaller(CallStackFrameContext, State);
+}
+
+const CXXConstructorDecl *
+getConstructorDeclarationForCall(const CallEvent ) {
+  const auto *ConstructorCall = dyn_cast();
+  if (!ConstructorCall) {
+return nullptr;
+  }
+  return ConstructorCall->getDecl();
+}
+
+bool isCopyConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isCopyConstructor();
+}
+
+bool isCopyAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isCopyAssignmentOperator();
+}
+
+bool isMoveConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isMoveConstructor();
+}
+
+bool isMoveAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isMoveAssignmentOperator();
+}
+
+const TemplateArgument (const CallEvent ) {
+  const CallExpr *CE = cast(Call.getOriginExpr());
+  const FunctionDecl *FD = CE->getDirectCallee();
+  assert(1 <= FD->getTemplateSpecializationArgs()->asArray().size() &&
+ "std::get should have at least 1 template argument!");
+  return FD->getTemplateSpecializationArgs()->asArray()[0];
+}
+
+bool isStdType(const Type *Type, const std::string ) {
+  auto *Decl = Type->getAsRecordDecl();
+  if (!Decl) {
+return false;
+  }
+
+  return (Decl->getNameAsString() == TypeName) && Decl->isInStdNamespace();
+}
+
+bool isStdVariant(const Type *Type) {
+  return isStdType(Type, std::string("variant"));
+}
+
+bool calledFromSystemHeader(const CallEvent ,
+const ProgramStateRef ) {
+  auto Caller = getCaller(Call, State);
+  if (Caller) {
+return Caller->isInSystemHeader();
+  }
+  return false;
+}
+
+bool calledFromSystemHeader(const CallEvent , CheckerContext ) {
+  return calledFromSystemHeader(Call, C.getState());
+}
+
+} // end of namespace variant_modeling
+} // end of namespace ento
+} // end of namespace clang
+
+static ArrayRef
+getTemplateArgsFromVariant(const Type *VariantType) {
+  const auto *TempSpecType = VariantType->getAs();
+  assert(TempSpecType &&
+ "We are in a variant instance. It must be a template 
specialization!");
+  return TempSpecType->template_arguments();
+}
+
+static QualType getNthTemplateTypeArgFromVariant(const Type *varType,
+ unsigned i) {
+  return getTemplateArgsFromVariant(varType)[i].getAsType();
+}
+
+class StdVariantChecker : public Checker {
+  // Call descriptors to find relevant calls
+  CallDescription 

[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }

DonatNagyE wrote:

```suggestion
  if (!CallStackFrameContext)
return nullptr;
```
See the [LLVM Coding 
Standards](https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements);
 also check the braces in the rest of the code.

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {

DonatNagyE wrote:

Probably this should be renamed to e.g. "tagged_union_modeling" or just 
"tagged_unions".

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }
+
+  CallEventManager  = State->getStateManager().getCallEventManager();
+  return CEMgr.getCaller(CallStackFrameContext, State);
+}
+
+const CXXConstructorDecl *
+getConstructorDeclarationForCall(const CallEvent ) {
+  const auto *ConstructorCall = dyn_cast();
+  if (!ConstructorCall) {
+return nullptr;
+  }
+  return ConstructorCall->getDecl();
+}
+
+bool isCopyConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isCopyConstructor();
+}
+
+bool isCopyAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);

DonatNagyE wrote:

```suggestion
  const auto *AsMethodDecl = 
dyn_cast_or_null(CopyAssignmentDecl);
```

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.
+template 
+ProgramStateRef
+removeInformationStoredForDeadInstances(const CallEvent *Call,
+ProgramStateRef State,
+ArrayRef Regions) {
+  // If we do not know anything about the call we shall not continue.
+  if (!Call) {
+return State;
+  }
+
+  // If the call is coming from a system header it is implementation detail.

DonatNagyE wrote:

```suggestion
  // If the call happens within a system header it is implementation detail.
```
If I understand it correctly, this check filters out calls _within the system 
header_ (as opposed to calls _of functions which are defined in_ a system 
header); if that's the case, then I'd suggest replacing "coming from" with a 
less ambiguous word choice.

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.

DonatNagyE wrote:

```suggestion
// file StdVariantChecker.cpp under the same directory as this file.
```

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.
+template 
+ProgramStateRef
+removeInformationStoredForDeadInstances(const CallEvent *Call,
+ProgramStateRef State,
+ArrayRef Regions) {
+  // If we do not know anything about the call we shall not continue.
+  if (!Call) {
+return State;
+  }
+
+  // If the call is coming from a system header it is implementation detail.
+  // We should not take it into consideration.
+  if (Call->isInSystemHeader()) {
+return State;
+  }
+
+  // Remove the information we know about the invalidate region.
+  // It is not relevant anymore.
+  State = std::accumulate(
+  Regions.begin(), Regions.end(), State,
+  [](ProgramStateRef State, const MemRegion *CurrentMemRegion) {
+if (State->contains(CurrentMemRegion)) {
+  State = State->remove(CurrentMemRegion);
+}
+return State;
+  });

DonatNagyE wrote:

```suggestion
for (const MemRegion *CurrentMemRegion : Regions) {
  if (State->contains(CurrentMemRegion)) {
State = State->remove(CurrentMemRegion);
  }
}
```
This is not Haskell, we have perfectly fine `for` loops ;)

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }

DonatNagyE wrote:

```suggestion
  if (!CallLocationContext || CallLocationContext->inTopFrame())
return nullptr;
```

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits


@@ -0,0 +1,128 @@
+//===- TaggedUnionModeling.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
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKER_VARIANTLIKETYPEMODELING_H
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+#include 
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// The implementation of all these functions can be found in the
+// StdVariantChecker.cpp file under the same directory as this file.
+CallEventRef<> getCaller(const CallEvent , CheckerContext );
+const TemplateArgument (const CallEvent );
+bool isCopyConstructorCall(const CallEvent );
+bool isCopyAssignmentCall(const CallEvent );
+bool isMoveAssignmentCall(const CallEvent );
+bool isMoveConstructorCall(const CallEvent );
+bool isStdType(const Type *Type, const std::string );
+bool isStdVariant(const Type *Type);
+bool calledFromSystemHeader(const CallEvent , CheckerContext );
+
+// When invalidating regions we also have to follow that with our data
+// storages in the program state.

DonatNagyE wrote:

```suggestion
// When invalidating regions, we have to follow that by invalidating
// the corresponding custom data in the program state.
```

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits

https://github.com/DonatNagyE commented:

Very promising checker with straightforward and clean logic! I have lots of 
comments, but they are all minor/cosmetic issues.

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread via cfe-commits

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


[clang] Fix math-errno issue (PR #66381)

2023-09-15 Thread Zahira Ammarguellat via cfe-commits

https://github.com/zahiraam updated 
https://github.com/llvm/llvm-project/pull/66381

>From 997e3b69ac5c20a9130b957c86c08b16d23af07c Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat 
Date: Thu, 14 Sep 2023 06:27:35 -0700
Subject: [PATCH 1/4] Fix math-errno issue

---
 clang/lib/CodeGen/CGBuiltin.cpp| 41 +-
 clang/test/CodeGen/math-builtins.c |  2 ++
 clang/test/CodeGen/math-libcalls.c |  2 ++
 3 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 8b19bf85d47a19f..c69ccdb0eb522bf 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2313,14 +2313,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
   FD->hasAttr() ? 0 : BuiltinID;
 
   bool ErrnoOverriden = false;
+  bool ErrnoOverrideValue = false;
   // True if math-errno is overriden via the
   // '#pragma float_control(precise, on)'. This pragma disables fast-math,
   // which implies math-errno.
   if (E->hasStoredFPFeatures()) {
 FPOptionsOverride OP = E->getFPFeatures();
-if (OP.hasMathErrnoOverride())
-  ErrnoOverriden = OP.getMathErrnoOverride();
+if (OP.hasMathErrnoOverride()) {
+  ErrnoOverriden = true;
+  ErrnoOverrideValue = OP.getMathErrnoOverride();
+}
   }
+
   // True if 'atttibute__((optnone)) is used. This attibute overrides
   // fast-math which implies math-errno.
   bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr();
@@ -2329,8 +2333,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   // using the '#pragma float_control(precise, off)', and
   // attribute opt-none hasn't been seen.
   bool ErrnoOverridenToFalseWithOpt =
-  !ErrnoOverriden && !OptNone &&
-  CGM.getCodeGenOpts().OptimizationLevel != 0;
+   ErrnoOverriden && !ErrnoOverrideValue && !OptNone &&
+   CGM.getCodeGenOpts().OptimizationLevel != 0;
 
   // There are LLVM math intrinsics/instructions corresponding to math library
   // functions except the LLVM op will never set errno while the math library
@@ -2339,6 +2343,28 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   // LLVM counterparts if the call is marked 'const' (known to never set 
errno).
   // In case FP exceptions are enabled, the experimental versions of the
   // intrinsics model those.
+  bool ConstAlways =
+  getContext().BuiltinInfo.isConst(BuiltinID);
+
+  // There's a special case with the fma builtins where they are always const
+  // if the target environment is GNU or the target is OS is Windows and we're
+  // targeting the MSVCRT.dll environment.
+  switch (BuiltinID) {
+  case Builtin::BI__builtin_fma:
+  case Builtin::BI__builtin_fmaf:
+  case Builtin::BI__builtin_fmal:
+  case Builtin::BIfma:
+  case Builtin::BIfmaf:
+  case Builtin::BIfmal: {
+auto  = CGM.getTriple();
+if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
+  ConstAlways = true;
+break;
+}
+  default:
+break;
+  }  
+
   bool ConstWithoutErrnoAndExceptions =
   getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
   bool ConstWithoutExceptions =
@@ -2362,14 +2388,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
   bool ConstWithoutErrnoOrExceptions =
   ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
   bool GenerateIntrinsics =
-  FD->hasAttr() && !ErrnoOverriden && !OptNone;
+   (ConstAlways && !OptNone) ||
+   (!getLangOpts().MathErrno && !(ErrnoOverriden && ErrnoOverrideValue) &&
+   !OptNone);
   if (!GenerateIntrinsics) {
 GenerateIntrinsics =
 ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
 if (!GenerateIntrinsics)
   GenerateIntrinsics =
   ConstWithoutErrnoOrExceptions &&
-  (!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone);
+ (!getLangOpts().MathErrno &&
+   !(ErrnoOverriden && ErrnoOverrideValue) && !OptNone);
 if (!GenerateIntrinsics)
   GenerateIntrinsics =
   ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
diff --git a/clang/test/CodeGen/math-builtins.c 
b/clang/test/CodeGen/math-builtins.c
index 962e311698f5755..554c604219957ca 100644
--- a/clang/test/CodeGen/math-builtins.c
+++ b/clang/test/CodeGen/math-builtins.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm
  %s | FileCheck %s -check-prefix=NO__ERRNO
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm 
-fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
+//  RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm 
-disable-llvm-passes -O2  %s | FileCheck %s -check-prefix=NO__ERRNO
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm 
-disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
 // 

[clang] [NFC][CodeGen] Change CodeGenOpt::Level/CodeGenFileType into enum classes (PR #66295)

2023-09-15 Thread Paul T Robinson via cfe-commits


@@ -661,27 +661,27 @@ static bool FixupInvocation(CompilerInvocation 
,
 
 static unsigned getOptimizationLevel(ArgList , InputKind IK,
  DiagnosticsEngine ) {
-  unsigned DefaultOpt = llvm::CodeGenOpt::None;
+  unsigned DefaultOpt = 0;
   if ((IK.getLanguage() == Language::OpenCL ||
IK.getLanguage() == Language::OpenCLCXX) &&
   !Args.hasArg(OPT_cl_opt_disable))
-DefaultOpt = llvm::CodeGenOpt::Default;
+DefaultOpt = 2;

pogo59 wrote:

Actually it looks to me like clang only cares about 0/not-0, and the specific 
non-zero number is irrelevant. So, internally clang codegen would be better off 
with a simple Optimize bool. (It looks like LangOpts does it this way already.) 
CodeGenOpts probably does need to track the actual user-specified level to pass 
down to LLVM, but it doesn't need it for its own purposes.

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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread Louis Dionne via cfe-commits

ldionne wrote:

@tru Sounds good! I gave you https://github.com/llvm/llvm-project/issues/66468 
too.

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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread Tobias Hieta via cfe-commits

tru wrote:

@ldionne thanks for the whitespace check! I have already put some work into the 
clang-format action on my end. Would you mind dropping it from this PR and let 
me push mine first? My action is not just restricted to the clang subdir. 

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


[clang] [analyzer] Fix StackAddrEscapeChecker crash on temporary object fields (PR #66493)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -398,7 +400,7 @@ void StackAddrEscapeChecker::checkEndFunction(const 
ReturnStmt *RS,
 }(Referrer->getMemorySpace());
 
 // This cast supposed to succeed.

steakhal wrote:

> I think the best would be either a comment that explains _why_ we expect a 
> `VarRegion` here (e.g. it's already checked in function `fooBar()` etc.) or 
> if possible, then a crash-less logic (converting an earlier `isa`-like check 
> + this `cast` into a single `getAs`).

There is nothing that would directly imply this.
It's like, ATM I don't know of any other situations where it could be not a 
`VarRegion`, and so far it didn't appear in practice that would disprove this.

I'm not exactly sure if a comment like that would suffice. Would you accept it? 
And do you think it's necessary?

Another alternative could be a combination:

```c++
if (!isa(Referrer)) {
  assert(false && "We should really only have VarRegions here");
  continue;
}
// ...
cast(Referrer)...
```

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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-github-workflow


Changes
Instead of using the BuildKite jobs, use GitHub actions to detect clang-format 
violations and trailing whitespace in PRs.

Fixes #66468
--
Full diff: https://github.com/llvm/llvm-project/pull/66509.diff

6 Files Affected:

- (added) .github/workflows/clang/pr-check-trailing-whitespace.yml (+14) 
- (added) .github/workflows/clang/pr-clang-format.yml (+18) 
- (modified) clang/lib/AST/Expr.cpp (+1-1) 
- (modified) clang/lib/AST/ExprClassification.cpp (+6) 
- (modified) clang/utils/ci/buildkite-pipeline.yml (-11) 
- (modified) clang/utils/ci/run-buildbot (-3) 



diff --git a/.github/workflows/clang/pr-check-trailing-whitespace.yml 
b/.github/workflows/clang/pr-check-trailing-whitespace.yml
new file mode 100644
index 000..b08f1e24d785ac5
--- /dev/null
+++ b/.github/workflows/clang/pr-check-trailing-whitespace.yml
@@ -0,0 +1,14 @@
+name: Ensure there are no trailing whitespace
+
+on:
+  pull_request:
+paths:
+- #x27;clang/**#x27;
+
+jobs:
+  example:
+name: Find Trailing Whitespace
+runs-on: ubuntu-latest
+steps:
+  - uses: actions/checkout@v3
+  - uses: harupy/find-trailing-whitespace@master
diff --git a/.github/workflows/clang/pr-clang-format.yml 
b/.github/workflows/clang/pr-clang-format.yml
new file mode 100644
index 000..2589b815a480f09
--- /dev/null
+++ b/.github/workflows/clang/pr-clang-format.yml
@@ -0,0 +1,18 @@
+name: clang-format Check
+
+on:
+  pull_request:
+paths:
+- #x27;clang/**#x27;
+
+jobs:
+  formatting-check:
+name: Formatting Check
+runs-on: ubuntu-latest
+steps:
+- uses: actions/checkout@v3
+- name: Run clang-format style check
+  uses: jidicula/clang-format-action@v4.11.0
+  with:
+clang-format-version: #x27;16#x27;
+check-path: #x27;clang/#x27;
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 4f3837371b3fc5e..342a7e3e47144bd 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -63,7 +63,7 @@ const Expr *Expr::getBestDynamicClassTypeExpr() const {
   }
 
   return E;
-}
+}   
 
 const CXXRecordDecl *Expr::getBestDynamicClassType() const {
   const Expr *E = getBestDynamicClassTypeExpr();
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 12193b7812f9bf8..18d35d1d47cfb82 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -79,6 +79,12 @@ Cl Expr::ClassifyImpl(ASTContext amp;Ctx, 
SourceLocation *Loc) const {
   return Classification(kind, modifiable);
 }
 
+static int not_well_formatted_code(int i)
+{
+   int hi = i ;
+return hi;
+}
+
 /// Classify an expression which creates a temporary, based on its type.
 static Cl::Kinds ClassifyTemporary(QualType T) {
   if (T-gt;isRecordType())
diff --git a/clang/utils/ci/buildkite-pipeline.yml 
b/clang/utils/ci/buildkite-pipeline.yml
index 7a679176038c693..22ee165d1edf4e1 100644
--- a/clang/utils/ci/buildkite-pipeline.yml
+++ b/clang/utils/ci/buildkite-pipeline.yml
@@ -17,17 +17,6 @@ env:
 # LLVM RELEASE bump version
 LLVM_HEAD_VERSION: quot;17quot;
 steps:
-  - label: quot;Formatquot;
-commands:
-  - quot;clang/utils/ci/run-buildbot check-formatquot;
-agents:
-  queue: quot;linuxquot;
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   - label: quot;Building and testing clang (Linux)quot;
 commands:
   - quot;clang/utils/ci/run-buildbot build-clangquot;
diff --git a/clang/utils/ci/run-buildbot b/clang/utils/ci/run-buildbot
index d117fccc7e3fbd8..56a1a9a8c8cfa22 100755
--- a/clang/utils/ci/run-buildbot
+++ b/clang/utils/ci/run-buildbot
@@ -69,9 +69,6 @@ cmake --version
 ninja --version
 
 case quot;${BUILDER}quot; in
-check-format)
-! grep -rnI #x27;[[:blank:]]$#x27; clang/lib clang/include 
clang/docs
-;;
 build-clang)
 mkdir install
 # We use Release here to avoid including debug information. Otherwise, the




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


[clang] [clang] Setup whitespace detection and clang-format as Github actions (PR #66509)

2023-09-15 Thread Louis Dionne via cfe-commits

https://github.com/ldionne created 
https://github.com/llvm/llvm-project/pull/66509

Instead of using the BuildKite jobs, use GitHub actions to detect clang-format 
violations and trailing whitespace in PRs.

Fixes #66468

>From 46330c22414ed8722e85ff349f502d4e5a1bac5d Mon Sep 17 00:00:00 2001
From: Louis Dionne 
Date: Fri, 15 Sep 2023 09:17:18 -0400
Subject: [PATCH] [clang] Setup whitespace detection and clang-format as Github
 actions

Instead of using the BuildKite jobs, use GitHub actions to detect
clang-format violations and trailing whitespace in PRs.

Fixes #66468
---
 .../clang/pr-check-trailing-whitespace.yml | 14 ++
 .github/workflows/clang/pr-clang-format.yml| 18 ++
 clang/lib/AST/Expr.cpp |  2 +-
 clang/lib/AST/ExprClassification.cpp   |  6 ++
 clang/utils/ci/buildkite-pipeline.yml  | 11 ---
 clang/utils/ci/run-buildbot|  3 ---
 6 files changed, 39 insertions(+), 15 deletions(-)
 create mode 100644 .github/workflows/clang/pr-check-trailing-whitespace.yml
 create mode 100644 .github/workflows/clang/pr-clang-format.yml

diff --git a/.github/workflows/clang/pr-check-trailing-whitespace.yml 
b/.github/workflows/clang/pr-check-trailing-whitespace.yml
new file mode 100644
index 000..b08f1e24d785ac5
--- /dev/null
+++ b/.github/workflows/clang/pr-check-trailing-whitespace.yml
@@ -0,0 +1,14 @@
+name: Ensure there are no trailing whitespace
+
+on:
+  pull_request:
+paths:
+- 'clang/**'
+
+jobs:
+  example:
+name: Find Trailing Whitespace
+runs-on: ubuntu-latest
+steps:
+  - uses: actions/checkout@v3
+  - uses: harupy/find-trailing-whitespace@master
diff --git a/.github/workflows/clang/pr-clang-format.yml 
b/.github/workflows/clang/pr-clang-format.yml
new file mode 100644
index 000..2589b815a480f09
--- /dev/null
+++ b/.github/workflows/clang/pr-clang-format.yml
@@ -0,0 +1,18 @@
+name: clang-format Check
+
+on:
+  pull_request:
+paths:
+- 'clang/**'
+
+jobs:
+  formatting-check:
+name: Formatting Check
+runs-on: ubuntu-latest
+steps:
+- uses: actions/checkout@v3
+- name: Run clang-format style check
+  uses: jidicula/clang-format-action@v4.11.0
+  with:
+clang-format-version: '16'
+check-path: 'clang/'
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 4f3837371b3fc5e..342a7e3e47144bd 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -63,7 +63,7 @@ const Expr *Expr::getBestDynamicClassTypeExpr() const {
   }
 
   return E;
-}
+}   
 
 const CXXRecordDecl *Expr::getBestDynamicClassType() const {
   const Expr *E = getBestDynamicClassTypeExpr();
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 12193b7812f9bf8..18d35d1d47cfb82 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -79,6 +79,12 @@ Cl Expr::ClassifyImpl(ASTContext , SourceLocation *Loc) 
const {
   return Classification(kind, modifiable);
 }
 
+static int not_well_formatted_code(int i)
+{
+   int hi = i ;
+return hi;
+}
+
 /// Classify an expression which creates a temporary, based on its type.
 static Cl::Kinds ClassifyTemporary(QualType T) {
   if (T->isRecordType())
diff --git a/clang/utils/ci/buildkite-pipeline.yml 
b/clang/utils/ci/buildkite-pipeline.yml
index 7a679176038c693..22ee165d1edf4e1 100644
--- a/clang/utils/ci/buildkite-pipeline.yml
+++ b/clang/utils/ci/buildkite-pipeline.yml
@@ -17,17 +17,6 @@ env:
 # LLVM RELEASE bump version
 LLVM_HEAD_VERSION: "17"
 steps:
-  - label: "Format"
-commands:
-  - "clang/utils/ci/run-buildbot check-format"
-agents:
-  queue: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   - label: "Building and testing clang (Linux)"
 commands:
   - "clang/utils/ci/run-buildbot build-clang"
diff --git a/clang/utils/ci/run-buildbot b/clang/utils/ci/run-buildbot
index d117fccc7e3fbd8..56a1a9a8c8cfa22 100755
--- a/clang/utils/ci/run-buildbot
+++ b/clang/utils/ci/run-buildbot
@@ -69,9 +69,6 @@ cmake --version
 ninja --version
 
 case "${BUILDER}" in
-check-format)
-! grep -rnI '[[:blank:]]$' clang/lib clang/include clang/docs
-;;
 build-clang)
 mkdir install
 # We use Release here to avoid including debug information. Otherwise, the

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits


@@ -1446,6 +1446,51 @@ TEST(TransferTest, BaseClassInitializer) {
   llvm::Succeeded());
 }
 
+TEST(TransferTest, StructModeledFieldsWithAccessor) {
+  std::string Code = R"(
+class S {
+  int *P;
+  int *Q;
+  int X;
+  int Y;
+  int Z;

martinboehme wrote:

Rename these to match the methods that return them (e.g. `Ptr`, `PtrNonConst` 
etc.)? This would make it easier to read the assertion below.

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits


@@ -288,6 +288,18 @@ static void insertIfFunction(const Decl ,
 Funcs.insert(FD);
 }
 
+static Expr *getRetValueFromSingleReturnStmtMethod(const CXXMemberCallExpr ) 
{
+  auto *D = cast_or_null(C.getMethodDecl()->getDefinition());
+  if (!D)
+return nullptr;
+  auto *S = cast(D->getBody());
+  if (S->size() != 1)
+return nullptr;
+  if (auto *RS = dyn_cast(*S->body_begin()))
+return RS->getRetValue()->IgnoreParenImpCasts();
+  return nullptr;

martinboehme wrote:

```suggestion
  auto *Body = dyn_cast(C.getBody());
  if (!Body || Body->size() != 1)
return nullptr;
  if (auto *RS = dyn_cast(*Body->body_begin()))
return RS->getRetValue()->IgnoreParenImpCasts();
  return nullptr;
```

- `getBody()` can be called on any declaration, not just the definition
- Suggest renaming `S` to `Body` for clarity
- The fact that `getBody()` returns just a `Stmt *` makes me wary that casting 
unconditionally to `CompoundStmt` may not be safe, so suggest using `dyn_cast` 
instead.

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits


@@ -324,6 +336,12 @@ getFieldsGlobalsAndFuncs(const Stmt , FieldSet ,
   } else if (auto *E = dyn_cast()) {
 insertIfGlobal(*E->getDecl(), Vars);
 insertIfFunction(*E->getDecl(), Funcs);
+  } else if (const auto *C = dyn_cast()) {
+// If this is a method that returns a member variable but does nothing 
else,
+// model the field of the return value.
+if (MemberExpr *E = dyn_cast_or_null(
+getRetValueFromSingleReturnStmtMethod(*C)))
+  getFieldsGlobalsAndFuncs(*E, Fields, Vars, Funcs);

martinboehme wrote:

```suggestion
  if (const auto *FD = dyn_cast(E->getMemberDecl()))
Fields.insert(FD);
```

This is all of the logic that you really need from the recursive 
`getFieldsGlobalsAndFuncs()` call. I would suggest simply repeating these two 
lines here:

- The intent is clearer
- You save quite a few unnecessary `dyn_cast`s

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits


@@ -1446,6 +1446,51 @@ TEST(TransferTest, BaseClassInitializer) {
   llvm::Succeeded());
 }
 
+TEST(TransferTest, StructModeledFieldsWithAccessor) {
+  std::string Code = R"(
+class S {
+  int *P;
+  int *Q;
+  int X;
+  int Y;
+  int Z;
+public:
+  int *getPtr() const { return P; }
+  int *getPtrNonConst() { return Q; }
+  int getInt(int i) const { return X; }

martinboehme wrote:

Can you add a case that returns a reference? This produces a slightly different 
shape of AST (without an `LValueToRValue` cast).

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits


@@ -324,6 +336,12 @@ getFieldsGlobalsAndFuncs(const Stmt , FieldSet ,
   } else if (auto *E = dyn_cast()) {
 insertIfGlobal(*E->getDecl(), Vars);
 insertIfFunction(*E->getDecl(), Funcs);
+  } else if (const auto *C = dyn_cast()) {
+// If this is a method that returns a member variable but does nothing 
else,
+// model the field of the return value.
+if (MemberExpr *E = dyn_cast_or_null(

martinboehme wrote:

Maybe include the cast to `MemberExpr` in 
`getRetValueFromSingleReturnStmtMethod()`?

This would put all of the checking in a single function and make the callsite 
here cleaner. The function should then be renamed to something like 
`getMemberForAccessor()`.

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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits

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


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


[clang] [clang][dataflow] Model the fields that are accessed via inline accessors (PR #66368)

2023-09-15 Thread via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66498)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66498)

2023-09-15 Thread Balazs Benics via cfe-commits

steakhal wrote:

Pushed manually with an adjusted commit message:
https://github.com/llvm/llvm-project/commit/7c9abbd8a41e85a7e82a454c62138ea72f981597

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


[clang] 7c9abbd - Reapply [analyzer] Simplify SVal for simple NonLoc->Loc casts

2023-09-15 Thread Balazs Benics via cfe-commits

Author: dingfei
Date: 2023-09-15T15:07:39+02:00
New Revision: 7c9abbd8a41e85a7e82a454c62138ea72f981597

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

LOG: Reapply [analyzer] Simplify SVal for simple NonLoc->Loc casts

Reapply after fixing the test by enabling the `debug.ExprInspection` checker.

-

NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.

This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:

  void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
  int *p = (int *) t2;
  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
  }

If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.

Fixes #62232

Added: 


Modified: 
clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
clang/test/Analysis/symbol-simplification-nonloc-loc.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2a47116db55a1ad..7e431f7e598c4cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -264,7 +264,8 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
   }
   // Delegate to SValBuilder to process.
   SVal OrigV = state->getSVal(Ex, LCtx);
-  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
+  SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
+  SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
   // Negate the result if we're treating the boolean as a signed i1
   if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
 V = svalBuilder.evalMinus(V.castAs());

diff  --git a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp 
b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
index 485f68d9a5acfba..6cfe8da971429c3 100644
--- a/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
+++ b/clang/test/Analysis/symbol-simplification-nonloc-loc.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core %s \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s \
 // RUN:-triple x86_64-pc-linux-gnu -verify
 
+void clang_analyzer_eval(int);
+
 #define BINOP(OP) [](auto x, auto y) { return x OP y; }
 
 template 
@@ -73,3 +75,27 @@ void zoo1backwards() {
   *(0 + p) = nullptr;  // warn
   **(0 + p) = 'a'; // no-warning: this should be unreachable
 }
+
+void test_simplified_before_cast_add(long t1) {
+  long t2 = t1 + 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_sub(long t1) {
+  long t2 = t1 - 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}
+
+void test_simplified_before_cast_mul(long t1) {
+  long t2 = t1 * 3;
+  if (!t2) {
+int *p = (int *) t2;
+clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+  }
+}



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


[clang] [analyzer] Simplify SVal for simple NonLoc->Loc casts (PR #66463)

2023-09-15 Thread Ding Fei via cfe-commits

danix800 wrote:

`auto-merge` might be disabled probably. I can't find the button mentioned 
[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request).

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


[clang] [Driver] Link Flang runtime on Solaris (PR #65644)

2023-09-15 Thread Rainer Orth via cfe-commits

rorth wrote:

I'd argue that handling the Flang runtime libs like C++ is the right thing to 
do here.  However, `flang-new` currently rejects all of `-r`, `-nostdlib`, and 
`-nodefaultlibs` on both Linux and Solaris.  On top of that, Solaris `clang` 
doesn't handle `-r` correctly, passing `-e _start -Bdynamic` to `ld`, which 
makes it choke...

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


[clang] [RISCV] Support predefined marcro __riscv_misaligned_{fast,avoid}. (PR #65756)

2023-09-15 Thread Yeting Kuo via cfe-commits

yetingk wrote:

Ping.

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


[clang-tools-extra] [clang-tidy]add new check `bugprone-compare-pointer-to-member-virtual-function` (PR #66055)

2023-09-15 Thread Congcong Cai via cfe-commits

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


[clang] [clang-tidy]add new check `bugprone-compare-pointer-to-member-virtual-function` (PR #66055)

2023-09-15 Thread Congcong Cai via cfe-commits

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


[clang-tools-extra] 72d4d4e - [clang-tidy]add new check `bugprone-compare-pointer-to-member-virtual-function` (#66055)

2023-09-15 Thread via cfe-commits

Author: Congcong Cai
Date: 2023-09-15T20:59:12+08:00
New Revision: 72d4d4e3b9f6b54582358ac5c1006e295b9ed58e

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

LOG: [clang-tidy]add new check 
`bugprone-compare-pointer-to-member-virtual-function` (#66055)

Added: 

clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp

clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.h

clang-tools-extra/docs/clang-tidy/checks/bugprone/compare-pointer-to-member-virtual-function.rst

clang-tools-extra/test/clang-tidy/checkers/bugprone/compare-pointer-to-member-virtual-function.cpp

Modified: 
clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp 
b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index a67a91eedd10482..543c522899d7a52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -16,6 +16,7 @@
 #include "BadSignalToKillThreadCheck.h"
 #include "BoolPointerImplicitConversionCheck.h"
 #include "BranchCloneCheck.h"
+#include "ComparePointerToMemberVirtualFunctionCheck.h"
 #include "CopyConstructorInitCheck.h"
 #include "DanglingHandleCheck.h"
 #include "DynamicStaticInitializersCheck.h"
@@ -103,6 +104,8 @@ class BugproneModule : public ClangTidyModule {
 CheckFactories.registerCheck(
 "bugprone-bool-pointer-implicit-conversion");
 CheckFactories.registerCheck("bugprone-branch-clone");
+CheckFactories.registerCheck(
+"bugprone-compare-pointer-to-member-virtual-function");
 CheckFactories.registerCheck(
 "bugprone-copy-constructor-init");
 CheckFactories.registerCheck(

diff  --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 3c768021feb1502..0df9e439b715e5a 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_library(clangTidyBugproneModule
   BoolPointerImplicitConversionCheck.cpp
   BranchCloneCheck.cpp
   BugproneTidyModule.cpp
+  ComparePointerToMemberVirtualFunctionCheck.cpp
   CopyConstructorInitCheck.cpp
   DanglingHandleCheck.cpp
   DynamicStaticInitializersCheck.cpp

diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
 
b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
new file mode 100644
index 000..9d1d92b989bf1f0
--- /dev/null
+++ 
b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -0,0 +1,106 @@
+//===--- ComparePointerToMemberVirtualFunctionCheck.cpp - clang-tidy 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ComparePointerToMemberVirtualFunctionCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+
+AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); }
+
+static const char *const ErrorMsg =
+"comparing a pointer to member virtual function with other pointer is "
+"unspecified behavior, only compare it with a null-pointer constant for "
+"equality.";
+
+} // namespace
+
+void ComparePointerToMemberVirtualFunctionCheck::registerMatchers(
+MatchFinder *Finder) {
+
+  auto DirectMemberVirtualFunctionPointer = unaryOperator(
+  allOf(hasOperatorName("&"),
+hasUnaryOperand(declRefExpr(to(cxxMethodDecl(isVirtual()));
+  auto IndirectMemberPointer =
+  ignoringImpCasts(declRefExpr().bind("indirect_member_pointer"));
+
+  Finder->addMatcher(
+  binaryOperator(
+  allOf(hasAnyOperatorName("==", "!="),
+hasEitherOperand(
+hasType(memberPointerType(pointee(functionType(),
+   

[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread Gábor Spaits via cfe-commits

https://github.com/spaits updated 
https://github.com/llvm/llvm-project/pull/66481

From 5472e377f9a4b51a8c400f1cc1703aa83fa45d1b Mon Sep 17 00:00:00 2001
From: Gabor Spaits 
Date: Fri, 15 Sep 2023 10:21:30 +0200
Subject: [PATCH] [analyzer] Add std::variant checker

Adding a checker that checks for bad std::variant type access.
---
 .../clang/StaticAnalyzer/Checkers/Checkers.td |   4 +
 .../StaticAnalyzer/Checkers/CMakeLists.txt|   1 +
 .../Checkers/StdVariantChecker.cpp| 312 +
 .../Checkers/TaggedUnionModeling.h| 128 +++
 .../Inputs/system-header-simulator-cxx.h  | 117 +++
 .../diagnostics/explicit-suppression.cpp  |   2 +-
 clang/test/Analysis/std-variant-checker.cpp   | 326 ++
 7 files changed, 889 insertions(+), 1 deletion(-)
 create mode 100644 clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
 create mode 100644 clang/lib/StaticAnalyzer/Checkers/TaggedUnionModeling.h
 create mode 100644 clang/test/Analysis/std-variant-checker.cpp

diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 65c1595eb6245dd..ec77ba1dc474d60 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -318,6 +318,10 @@ def C11LockChecker : Checker<"C11Lock">,
   Dependencies<[PthreadLockBase]>,
   Documentation;
 
+def StdVariantChecker : Checker<"StdVariant">,
+  HelpText<"Check wether we access the right type stored in std::variant">,
+  Documentation;
+
 } // end "alpha.core"
 
 
//===--===//
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index ae849f59f90d3d9..d7cb51e1a0819a8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -108,6 +108,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   SmartPtrModeling.cpp
   StackAddrEscapeChecker.cpp
   StdLibraryFunctionsChecker.cpp
+  StdVariantChecker.cpp
   STLAlgorithmModeling.cpp
   StreamChecker.cpp
   StringChecker.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
new file mode 100644
index 000..314dab24650dcd2
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
@@ -0,0 +1,312 @@
+//===- StdVariantChecker.cpp -*- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent , const ProgramStateRef ) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }
+
+  CallEventManager  = State->getStateManager().getCallEventManager();
+  return CEMgr.getCaller(CallStackFrameContext, State);
+}
+
+const CXXConstructorDecl *
+getConstructorDeclarationForCall(const CallEvent ) {
+  const auto *ConstructorCall = dyn_cast();
+  if (!ConstructorCall) {
+return nullptr;
+  }
+  return ConstructorCall->getDecl();
+}
+
+bool isCopyConstructorCall(const CallEvent ) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isCopyConstructor();
+}
+
+bool isCopyAssignmentCall(const CallEvent ) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+

[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Balazs Benics via cfe-commits

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


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Balazs Benics via cfe-commits

https://github.com/steakhal commented:

Uh, this isn't my expertiese. I'm a bit scared to do this alone.
I'm also short on time to verify this patch at scale.

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


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -1824,6 +1835,94 @@ RangeSet 
SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
   return {RangeFactory, ValueFactory.getValue(Min), 
ValueFactory.getValue(Max)};
 }
 
+RangeSet SymbolicRangeInferrer::handleConcreteModulo(Range LHS,
+ llvm::APSInt Modulo,
+ QualType T) {
+  APSIntType ResultType = ValueFactory.getAPSIntType(T);
+  llvm::APSInt Zero = ResultType.getZeroValue();
+  llvm::APSInt One = ResultType.getValue(1);
+
+  if (Modulo == Zero)
+return RangeFactory.getEmptySet();
+  if (Modulo < 0)
+Modulo = -Modulo;
+
+  auto ComputeModuloN = [&](llvm::APSInt From, llvm::APSInt To,
+llvm::APSInt N) -> RangeSet {
+assert(N > Zero && "Non-positive N!");
+bool NonNegative = From >= Zero;
+assert(NonNegative == (To >= Zero) && "Signedness mismatch!");
+
+if (From > To)
+  return RangeFactory.getEmptySet();
+
+llvm::APSInt N1 = N - One;

steakhal wrote:

APSInt cannot wrap, right? So if N was the minimum representable on the same 
number of bits, it would extend the number of bits used for the representation, 
which might be different from the bitwidth of `Zero` and friends.
This could lead to constructing Ranges with APSInts of different widths, which 
is unexpected.

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


[clang] [analyzer] Reduce constraint on modulo with small concrete range (PR #65448)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -1824,6 +1835,94 @@ RangeSet 
SymbolicRangeInferrer::VisitBinaryOperator(Range LHS,
   return {RangeFactory, ValueFactory.getValue(Min), 
ValueFactory.getValue(Max)};
 }
 
+RangeSet SymbolicRangeInferrer::handleConcreteModulo(Range LHS,
+ llvm::APSInt Modulo,
+ QualType T) {
+  APSIntType ResultType = ValueFactory.getAPSIntType(T);
+  llvm::APSInt Zero = ResultType.getZeroValue();
+  llvm::APSInt One = ResultType.getValue(1);
+
+  if (Modulo == Zero)
+return RangeFactory.getEmptySet();
+  if (Modulo < 0)
+Modulo = -Modulo;

steakhal wrote:

If we swap the sign of the RHS, we should also swap it on the LHS: `X % Y  <=> 
-X % -Y` right?

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -258,114 +276,71 @@ TEST(SolverTest, IffWithUnits) {
 }
 
 TEST(SolverTest, IffWithUnitsConflict) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto XEqY = Ctx.iff(X, Y);
-  auto NotY = Ctx.neg(Y);
-
-  // (X <=> Y) ^ X  !Y
-  EXPECT_THAT(solve({XEqY, X, NotY}), unsat());
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ (V0 = V1)
+ V0
+ !V1
+  )");
+  EXPECT_THAT(solve(Constraints), unsat());
 }
 
 TEST(SolverTest, IffTransitiveConflict) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto Z = Ctx.atom();
-  auto XEqY = Ctx.iff(X, Y);
-  auto YEqZ = Ctx.iff(Y, Z);
-  auto NotX = Ctx.neg(X);
-
-  // (X <=> Y) ^ (Y <=> Z) ^ Z ^ !X
-  EXPECT_THAT(solve({XEqY, YEqZ, Z, NotX}), unsat());
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ (V0 = V1)
+ (V1 = V2)
+ V2
+ !V0
+  )");
+  EXPECT_THAT(solve(Constraints), unsat());
 }
 
 TEST(SolverTest, DeMorgan) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto Z = Ctx.atom();
-  auto W = Ctx.atom();
-
-  // !(X v Y) <=> !X ^ !Y
-  auto A = Ctx.iff(Ctx.neg(Ctx.disj(X, Y)), Ctx.conj(Ctx.neg(X), Ctx.neg(Y)));
-
-  // !(Z ^ W) <=> !Z v !W
-  auto B = Ctx.iff(Ctx.neg(Ctx.conj(Z, W)), Ctx.disj(Ctx.neg(Z), Ctx.neg(W)));
-
-  // A ^ B
-  EXPECT_THAT(solve({A, B}), sat(_));
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ (!(V0 | V1) = (!V0 & !V1))
+ (!(V2 & V3) = (!V2 | !V3))
+  )");
+  EXPECT_THAT(solve(Constraints), sat(_));
 }
 
 TEST(SolverTest, RespectsAdditionalConstraints) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto XEqY = Ctx.iff(X, Y);
-  auto NotY = Ctx.neg(Y);
-
-  // (X <=> Y) ^ X ^ !Y
-  EXPECT_THAT(solve({XEqY, X, NotY}), unsat());
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ (V0 = V1)
+ V0
+ !V1
+  )");
+  EXPECT_THAT(solve(Constraints), unsat());
 }
 
 TEST(SolverTest, ImplicationIsEquivalentToDNF) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto XImpliesY = Ctx.impl(X, Y);
-  auto XImpliesYDNF = Ctx.disj(Ctx.neg(X), Y);
-  auto NotEquivalent = Ctx.neg(Ctx.iff(XImpliesY, XImpliesYDNF));
-
-  // !((X => Y) <=> (!X v Y))
-  EXPECT_THAT(solve({NotEquivalent}), unsat());
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ !((V0 => V1) = (!V0 | V1))
+  )");
+  EXPECT_THAT(solve(Constraints), unsat());
 }
 
 TEST(SolverTest, ImplicationConflict) {
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto *XImplY = Ctx.impl(X, Y);
-  auto *XAndNotY = Ctx.conj(X, Ctx.neg(Y));
-
-  // X => Y ^ X ^ !Y
-  EXPECT_THAT(solve({XImplY, XAndNotY}), unsat());
-}
-
-TEST(SolverTest, LowTimeoutResultsInTimedOut) {
-  WatchedLiteralsSolver solver(10);
-  ConstraintContext Ctx;
-  auto X = Ctx.atom();
-  auto Y = Ctx.atom();
-  auto Z = Ctx.atom();
-  auto W = Ctx.atom();
-
-  // !(X v Y) <=> !X ^ !Y
-  auto A = Ctx.iff(Ctx.neg(Ctx.disj(X, Y)), Ctx.conj(Ctx.neg(X), Ctx.neg(Y)));
-
-  // !(Z ^ W) <=> !Z v !W
-  auto B = Ctx.iff(Ctx.neg(Ctx.conj(Z, W)), Ctx.disj(Ctx.neg(Z), Ctx.neg(W)));
-
-  // A ^ B
-  EXPECT_EQ(solver.solve({A, B}).getStatus(), 
Solver::Result::Status::TimedOut);
+  Arena A;
+  auto Constraints = parseAll(A, R"(
+ (V0 => V1)
+ (V0 & !V1)

martinboehme wrote:

```suggestion
 (V0 => V1)
 V0
 !V1
```

Nit: This is the way you notated this kind of thing above.

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -87,6 +87,9 @@ class alignas(const Formula *) Formula {
  ArrayRef Operands,
  unsigned Value = 0);
 
+  // Parse Formulas using Arena rather than caling this function directly.
+  static Formula *parse(llvm::BumpPtrAllocator , llvm::StringRef &);

martinboehme wrote:

I can't find a definition for this function. Was this later replaced by 
`parse()` in Arena.cpp?

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -13,6 +13,7 @@
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 

martinboehme wrote:

Inadvertent change? (There are no other changes in this file.)

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -87,6 +87,9 @@ class alignas(const Formula *) Formula {
  ArrayRef Operands,
  unsigned Value = 0);
 
+  // Parse Formulas using Arena rather than caling this function directly.

martinboehme wrote:

```suggestion
  // Don't call this function directly. Use `Arena::parseFormula()` instead.
```

Nit: When I began reading the comment, "Parse Formulas using Arena" initially 
sounded like a description of what the function is doing. "Don't call directly" 
seems like the most helpful thing to put at the beginning.

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -137,5 +140,46 @@ TEST_F(ArenaTest, Interning) {
   EXPECT_EQ((), );
 }
 
+TEST_F(ArenaTest, Parse) {

martinboehme wrote:

```suggestion
TEST_F(ArenaTest, ParseFormula) {
```

Matches name of the function, and we might conceivably add other parsing 
functions to `Arena` in the future.

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -95,4 +98,94 @@ BoolValue ::makeBoolValue(const Formula ) {
   return *It->second;
 }
 
+namespace {
+const Formula *parse(Arena , llvm::StringRef ) {
+  auto EatWhitespace = [&] { In = In.ltrim(' '); };

martinboehme wrote:

```suggestion
  auto EatWhitespace = [&] { In = In.ltrim(); };
```

I think you initially thought you shouldn't eat newlines here, but AFAICT, this 
isn't an issue because `parseAll()` below splits lines before it ever calls 
this.

Alternatively, if you really do want to eat only spaces here, I'd suggest 
renaming this `EatSpaces`.

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits


@@ -95,4 +98,94 @@ BoolValue ::makeBoolValue(const Formula ) {
   return *It->second;
 }
 
+namespace {
+const Formula *parse(Arena , llvm::StringRef ) {
+  auto EatWhitespace = [&] { In = In.ltrim(' '); };
+  EatWhitespace();
+
+  if (In.consume_front("!")) {
+if (auto *Arg = parse(A, In))
+  return (*Arg);
+return nullptr;
+  }
+
+  if (In.consume_front("(")) {
+auto *Arg1 = parse(A, In);
+if (!Arg1)
+  return nullptr;
+
+EatWhitespace();
+decltype(::makeOr) Op;
+if (In.consume_front("|"))
+  Op = ::makeOr;
+else if (In.consume_front("&"))
+  Op = ::makeAnd;
+else if (In.consume_front("=>"))
+  Op = ::makeImplies;
+else if (In.consume_front("="))
+  Op = ::makeEquals;
+else
+  return nullptr;
+
+auto *Arg2 = parse(A, In);
+if (!Arg2)
+  return nullptr;
+
+EatWhitespace();
+if (!In.consume_front(")"))
+  return nullptr;
+
+return &(A.*Op)(*Arg1, *Arg2);
+  }
+
+  if (In.consume_front("V")) {
+std::underlying_type_t At;
+if (In.consumeInteger(10, At))
+  return nullptr;
+return (static_cast(At));
+  }
+
+  if (In.consume_front("true"))
+return (true);
+  if (In.consume_front("false"))
+return (false);
+
+  return nullptr;
+}
+
+class FormulaParseError : public llvm::ErrorInfo {
+  unsigned Offset;
+  std::string Formula;

martinboehme wrote:

Nit: Reorder to match order of constructor parameters?

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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits

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


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


[clang] [dataflow] Parse formulas from text (PR #66424)

2023-09-15 Thread via cfe-commits

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


[clang] [analyzer] Fix StackAddrEscapeChecker crash on temporary object fields (PR #66493)

2023-09-15 Thread via cfe-commits


@@ -398,7 +400,7 @@ void StackAddrEscapeChecker::checkEndFunction(const 
ReturnStmt *RS,
 }(Referrer->getMemorySpace());
 
 // This cast supposed to succeed.

DonatNagyE wrote:

I think the best would be either a comment that explains _why_ we expect a 
`VarRegion` here (e.g. it's already checked in function `fooBar()` etc.) or if 
possible, then a crash-less logic (converting an earlier `isa`-like check + 
this `cast` into a single `getAs`).

I don't think that we should add defensive/paranoid checks; if this logic is 
broken by some change in the distant future, then a fixable crash is better 
than silent degradation. 

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


[clang] [Clang][ObjC] Add optionality to property attribute strings. (PR #66507)

2023-09-15 Thread Alastair Houghton via cfe-commits

https://github.com/al45tair created 
https://github.com/llvm/llvm-project/pull/66507

Add a new attribute, "?", to the property attribute string for properties of 
protocols that are declared @optional.

(Previously https://reviews.llvm.org/D135273)

rdar://100463524

>From 3514013089dcf9fa798e9ba5812b34df497a493b Mon Sep 17 00:00:00 2001
From: Alastair Houghton 
Date: Fri, 15 Sep 2023 13:46:19 +0100
Subject: [PATCH] [Clang][ObjC] Add optionality to property attribute strings.

Add a new attribute, "?", to the property attribute string for
properties of protocols that are declared @optional.

(Previously https://reviews.llvm.org/D135273)

rdar://100463524
---
 clang/lib/AST/ASTContext.cpp |  4 
 clang/test/CodeGenObjC/objc-asm-attribute-test.m | 10 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4b1d9e86797b778..57aaa05b1d81ddb 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7890,6 +7890,7 @@ ASTContext::getObjCPropertyImplDeclForPropertyDecl(
 /// kPropertyWeak = 'W'  // 'weak' property
 /// kPropertyStrong = 'P'// property GC'able
 /// kPropertyNonAtomic = 'N' // property non-atomic
+/// kPropertyOptional = '?'  // property optional
 /// };
 /// @endcode
 std::string
@@ -7915,6 +7916,9 @@ ASTContext::getObjCEncodingForPropertyDecl(const 
ObjCPropertyDecl *PD,
   // closely resembles encoding of ivars.
   getObjCEncodingForPropertyType(PD->getType(), S);
 
+  if (PD->isOptional())
+S += ",?";
+
   if (PD->isReadOnly()) {
 S += ",R";
 if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy)
diff --git a/clang/test/CodeGenObjC/objc-asm-attribute-test.m 
b/clang/test/CodeGenObjC/objc-asm-attribute-test.m
index 876370115bfc424..e57e42535f67274 100644
--- a/clang/test/CodeGenObjC/objc-asm-attribute-test.m
+++ b/clang/test/CodeGenObjC/objc-asm-attribute-test.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o - | FileCheck 
%s
+// RUN: %clang_cc1 -Wno-objc-root-class -emit-llvm -triple x86_64-apple-darwin 
%s -o - | FileCheck %s
 
 __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
 @protocol Protocol
@@ -10,6 +10,10 @@ + (void) ClsMethodP;
 @protocol Protocol2
 - (void) MethodP2;
 + (void) ClsMethodP2;
+
+@optional
+@property(retain) id optionalProp;
+
 @end
 
 __attribute__((objc_runtime_name("MySecretNamespace.Protocol3")))
@@ -57,6 +61,10 @@ id Test16877359(void) {
 // CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" ={{.*}} global 
%struct._class_t
 // CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" ={{.*}} global 
%struct._class_t
 
+// CHECK: @OBJC_PROP_NAME_ATTR_ = private unnamed_addr constant [13 x i8] 
c"optionalProp\00"
+// CHECK-NEXT: @OBJC_PROP_NAME_ATTR_.11 = private unnamed_addr constant [7 x 
i8] c"T@,?,&\00"
+// CHECK: @"_OBJC_$_PROP_LIST_MySecretNamespace.Protocol2" ={{.*}} 
[%struct._prop_t { ptr @OBJC_PROP_NAME_ATTR_, ptr @OBJC_PROP_NAME_ATTR_.11 }]
+
 // CHECK: private unnamed_addr constant [42 x i8] 
c"T@\22MySecretNamespace.Message\22,&,V_msgProp\00"
 // CHECK: private unnamed_addr constant [76 x i8] 
c"T@\22MySecretNamespace.Message\22,&,V_msgProtoProp\00"
 // CHECK: private unnamed_addr constant [50 x i8] 
c"T@\22\22,&,V_idProtoProp\00"

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-15 Thread Kristóf Umann via cfe-commits

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


[clang] [clang-transformer] Allow stencils to read from system headers. (PR #66480)

2023-09-15 Thread Clement Courbet via cfe-commits

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

>From b23472e55093ea1d48d11386cc4ced43f913c170 Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Fri, 15 Sep 2023 10:42:16 +0200
Subject: [PATCH] [clang-transformer] Allow stencils to read from system
 headers.

We were previously checking that stencil input ranges were writable. It 
suffices for them to be readable.
---
 clang/include/clang/Tooling/Transformer/SourceCode.h | 6 ++
 clang/lib/Tooling/Transformer/SourceCode.cpp | 6 +++---
 clang/lib/Tooling/Transformer/Stencil.cpp| 9 +
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Tooling/Transformer/SourceCode.h 
b/clang/include/clang/Tooling/Transformer/SourceCode.h
index 44a4749db74c96c..004c614b0b9d93c 100644
--- a/clang/include/clang/Tooling/Transformer/SourceCode.h
+++ b/clang/include/clang/Tooling/Transformer/SourceCode.h
@@ -91,6 +91,12 @@ StringRef getExtendedText(const T , tok::TokenKind Next,
 llvm::Error validateEditRange(const CharSourceRange ,
   const SourceManager );
 
+/// Determines whether \p Range is one that can be read from. If
+/// `AllowSystemHeaders` is false, a range that falls within a system header
+/// fails validation.
+llvm::Error validateRange(const CharSourceRange , const SourceManager 
,
+  bool AllowSystemHeaders);
+
 /// Attempts to resolve the given range to one that can be edited by a rewrite;
 /// generally, one that starts and ends within a particular file. If a value is
 /// returned, it satisfies \c validateEditRange.
diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp 
b/clang/lib/Tooling/Transformer/SourceCode.cpp
index 35edc261ef09670..30009537b5923ce 100644
--- a/clang/lib/Tooling/Transformer/SourceCode.cpp
+++ b/clang/lib/Tooling/Transformer/SourceCode.cpp
@@ -50,9 +50,9 @@ CharSourceRange 
clang::tooling::maybeExtendRange(CharSourceRange Range,
   return CharSourceRange::getTokenRange(Range.getBegin(), Tok.getLocation());
 }
 
-static llvm::Error validateRange(const CharSourceRange ,
- const SourceManager ,
- bool AllowSystemHeaders) {
+llvm::Error clang::tooling::validateRange(const CharSourceRange ,
+  const SourceManager ,
+  bool AllowSystemHeaders) {
   if (Range.isInvalid())
 return llvm::make_error(errc::invalid_argument,
  "Invalid range");
diff --git a/clang/lib/Tooling/Transformer/Stencil.cpp 
b/clang/lib/Tooling/Transformer/Stencil.cpp
index f2c1b6f8520a8cb..d91c9e0a20cc1b0 100644
--- a/clang/lib/Tooling/Transformer/Stencil.cpp
+++ b/clang/lib/Tooling/Transformer/Stencil.cpp
@@ -229,8 +229,8 @@ class SelectorStencil : public StencilInterface {
   // Validate the original range to attempt to get a meaningful error
   // message. If it's valid, then something else is the cause and we just
   // return the generic failure message.
-  if (auto Err =
-  tooling::validateEditRange(*RawRange, *Match.SourceManager))
+  if (auto Err = tooling::validateRange(*RawRange, *Match.SourceManager,
+/*AllowSystemHeaders=*/true))
 return handleErrors(std::move(Err), [](std::unique_ptr E) 
{
   assert(E->convertToErrorCode() ==
  llvm::make_error_code(errc::invalid_argument) &&
@@ -245,8 +245,9 @@ class SelectorStencil : public StencilInterface {
   "selected range could not be resolved to a valid source range");
 }
 // Validate `Range`, because `makeFileCharRange` accepts some ranges that
-// `validateEditRange` rejects.
-if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager))
+// `validateRange` rejects.
+if (auto Err = tooling::validateRange(Range, *Match.SourceManager,
+  /*AllowSystemHeaders=*/true))
   return joinErrors(
   llvm::createStringError(errc::invalid_argument,
   "selected range is not valid for editing"),

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


[clang] [clang-transformer] Allow stencils to read from system headers. (PR #66480)

2023-09-15 Thread Clement Courbet via cfe-commits


@@ -91,6 +91,10 @@ StringRef getExtendedText(const T , tok::TokenKind Next,
 llvm::Error validateEditRange(const CharSourceRange ,
   const SourceManager );
 
+/// Determines whether \p Range is one that can be read from.
+llvm::Error validateRange(const CharSourceRange , const SourceManager 
,
+  bool AllowSystemHeaders);

legrosbuffle wrote:

done

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


[clang] [clang-transformer] Allow stencils to read from system headers. (PR #66480)

2023-09-15 Thread Clement Courbet via cfe-commits


@@ -230,7 +230,7 @@ class SelectorStencil : public StencilInterface {
   // message. If it's valid, then something else is the cause and we just
   // return the generic failure message.
   if (auto Err =
-  tooling::validateEditRange(*RawRange, *Match.SourceManager))
+  tooling::validateRange(*RawRange, *Match.SourceManager, true))

legrosbuffle wrote:

done

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


[clang] [clang-transformer] Allow stencils to read from system headers. (PR #66480)

2023-09-15 Thread Clement Courbet via cfe-commits

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

>From 312eeef4c301e1049f50436fa3aa8d070b5cb4e9 Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Fri, 15 Sep 2023 10:42:16 +0200
Subject: [PATCH] [clang-transformer] Allow stencils to read from system
 headers.

We were previously checking that stencil input ranges were writable. It 
suffices for them to be readable.
---
 clang/include/clang/Tooling/Transformer/SourceCode.h | 6 ++
 clang/lib/Tooling/Transformer/SourceCode.cpp | 6 +++---
 clang/lib/Tooling/Transformer/Stencil.cpp| 9 +
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Tooling/Transformer/SourceCode.h 
b/clang/include/clang/Tooling/Transformer/SourceCode.h
index 44a4749db74c96c..cbb92b30a100290 100644
--- a/clang/include/clang/Tooling/Transformer/SourceCode.h
+++ b/clang/include/clang/Tooling/Transformer/SourceCode.h
@@ -91,6 +91,12 @@ StringRef getExtendedText(const T , tok::TokenKind Next,
 llvm::Error validateEditRange(const CharSourceRange ,
   const SourceManager );
 
+/// Determines whether \p Range is one that can be read from. If
+// `AllowSystemHeaders` is false, a range that falls within a system header
+// fails validation.
+llvm::Error validateRange(const CharSourceRange , const SourceManager 
,
+  bool AllowSystemHeaders);
+
 /// Attempts to resolve the given range to one that can be edited by a rewrite;
 /// generally, one that starts and ends within a particular file. If a value is
 /// returned, it satisfies \c validateEditRange.
diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp 
b/clang/lib/Tooling/Transformer/SourceCode.cpp
index 35edc261ef09670..30009537b5923ce 100644
--- a/clang/lib/Tooling/Transformer/SourceCode.cpp
+++ b/clang/lib/Tooling/Transformer/SourceCode.cpp
@@ -50,9 +50,9 @@ CharSourceRange 
clang::tooling::maybeExtendRange(CharSourceRange Range,
   return CharSourceRange::getTokenRange(Range.getBegin(), Tok.getLocation());
 }
 
-static llvm::Error validateRange(const CharSourceRange ,
- const SourceManager ,
- bool AllowSystemHeaders) {
+llvm::Error clang::tooling::validateRange(const CharSourceRange ,
+  const SourceManager ,
+  bool AllowSystemHeaders) {
   if (Range.isInvalid())
 return llvm::make_error(errc::invalid_argument,
  "Invalid range");
diff --git a/clang/lib/Tooling/Transformer/Stencil.cpp 
b/clang/lib/Tooling/Transformer/Stencil.cpp
index f2c1b6f8520a8cb..d91c9e0a20cc1b0 100644
--- a/clang/lib/Tooling/Transformer/Stencil.cpp
+++ b/clang/lib/Tooling/Transformer/Stencil.cpp
@@ -229,8 +229,8 @@ class SelectorStencil : public StencilInterface {
   // Validate the original range to attempt to get a meaningful error
   // message. If it's valid, then something else is the cause and we just
   // return the generic failure message.
-  if (auto Err =
-  tooling::validateEditRange(*RawRange, *Match.SourceManager))
+  if (auto Err = tooling::validateRange(*RawRange, *Match.SourceManager,
+/*AllowSystemHeaders=*/true))
 return handleErrors(std::move(Err), [](std::unique_ptr E) 
{
   assert(E->convertToErrorCode() ==
  llvm::make_error_code(errc::invalid_argument) &&
@@ -245,8 +245,9 @@ class SelectorStencil : public StencilInterface {
   "selected range could not be resolved to a valid source range");
 }
 // Validate `Range`, because `makeFileCharRange` accepts some ranges that
-// `validateEditRange` rejects.
-if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager))
+// `validateRange` rejects.
+if (auto Err = tooling::validateRange(Range, *Match.SourceManager,
+  /*AllowSystemHeaders=*/true))
   return joinErrors(
   llvm::createStringError(errc::invalid_argument,
   "selected range is not valid for editing"),

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


[clang] a20f485 - [clang-format] Generate the style options

2023-09-15 Thread via cfe-commits

Author: sstwcw
Date: 2023-09-15T12:37:21Z
New Revision: a20f485bb0c9af3c7a7179bd71ae910c58278341

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

LOG: [clang-format] Generate the style options

I was in a hurry and I forgot to do it for the last commit.

Added: 


Modified: 
clang/docs/ClangFormatStyleOptions.rst

Removed: 




diff  --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index 4ab0b3a207270dc..fea52679585a6cb 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2796,7 +2796,7 @@ the configuration (without a prefix: ``Auto``).
  string x =
  "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
 
-  C# and JavaScript interpolated strings are not broken.
+  C# interpolated strings are not broken.
 
   In Verilog:
 



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


[clang] [analyzer] Fix StackAddrEscapeChecker crash on temporary object fields (PR #66493)

2023-09-15 Thread Balazs Benics via cfe-commits


@@ -398,7 +400,7 @@ void StackAddrEscapeChecker::checkEndFunction(const 
ReturnStmt *RS,
 }(Referrer->getMemorySpace());
 
 // This cast supposed to succeed.

steakhal wrote:

I was thinking about it once you raised this comment.
To me, to have a proper diagnostic we need something that we can name here; and 
they are usually variables.

Now, if we check and bail out if it's not a VarRegion, we would not get 
notified if we suddenly have some other value that we could cover but we don't. 
It took a long time to even hit this crash, so I don't think they are too 
frequent.

So the question is which we prefer:
 - Crash (possible in the long future) to get notified or
 - Silently ignore these unthought, interesting cases for which we didn't 
account for
 
 If this would be a mission-critical software I'd vote for (2), but now I'm a 
bit hesitant in between the two options.
 
 Maybe, given that this is a core checker, we should lean towards gracefully 
handling this. WDYT?

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


[clang] Bugfix for chosing the correct deduction guide (PR #66487)

2023-09-15 Thread via cfe-commits

HoBoIs wrote:

@zygoloid @yuanfang-chen @faisalv @OleStrohm  
Could you review my commit and/or suggest more appropriate reviewers?
Thanks in advance!

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


[clang] Bugfix for chosing the correct deduction guide (PR #66487)

2023-09-15 Thread via cfe-commits

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


[clang] [clang][Interp] Handle AttributedStmts (PR #66495)

2023-09-15 Thread Timm Baeder via cfe-commits


@@ -628,6 +630,12 @@ bool ByteCodeStmtGen::visitAsmStmt(const AsmStmt 
*S) {
   return this->emitInvalid(S);
 }
 
+template 
+bool ByteCodeStmtGen::visitAttributedStmt(const AttributedStmt *S) {
+  // Ignore all attributes.

tbaederr wrote:

> Is this what we want to do for [[assume]]? We can do it this way: 
> https://eel.is/c++draft/expr.const#5.8 but we can also do it better: 
> https://eel.is/c++draft/expr.const#5.33

The second case would essentially work like an assertion? If this fails, the 
statement isn't a constant expression?

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


[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

2023-09-15 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tidy


Changes
This is the implementation of step 3 of
https://discourse.llvm.org/t/rfc-customizable-namespace-to-allow-testing-the-libc-when-the-system-libc-is-also-llvms-libc/73079.

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

3 Files Affected:

- (modified) 
clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp 
(+13-8) 
- (modified) 
clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
 (+16-7) 
- (modified) 
clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
 (+21-10) 



diff --git 
a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp 
b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index d05310f09ef773a..69a385f5be9807f 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -14,7 +14,9 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::llvm_libc {
 
-const static StringRef RequiredNamespace = quot;__llvm_libcquot;;
+const static StringRef RequiredNamespaceStart = 
quot;__llvm_libcquot;;
+const static StringRef RequiredNamespaceMacroName = 
quot;LIBC_NAMESPACEquot;;
+
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder-gt;addMatcher(
   decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))
@@ -29,16 +31,19 @@ void ImplementationInNamespaceCheck::check(
   if 
(!Result.SourceManager-gt;isInMainFile(MatchedDecl-gt;getLocation()))
 return;
 
-  if (const auto *NS = dyn_castlt;NamespaceDeclgt;(MatchedDecl)) {
-if (NS-gt;getName() != RequiredNamespace) {
-  diag(NS-gt;getLocation(), quot;#x27;%0#x27; needs to 
be the outermost namespacequot;)
-  lt;lt; RequiredNamespace;
-}
+  if (auto *NS = dyn_castlt;NamespaceDeclgt;(MatchedDecl)) {
+if 
(!Result.SourceManager-gt;isMacroBodyExpansion(NS-gt;getLocation()))
+  diag(NS-gt;getLocation(),
+   quot;the outermost namespace should be the 
#x27;%0#x27; macroquot;)
+  lt;lt; RequiredNamespaceMacroName;
+else if (!NS-gt;getName().starts_with(RequiredNamespaceStart))
+  diag(NS-gt;getLocation(), quot;the outermost namespace should 
start with #x27;%0#x27;quot;)
+  lt;lt; RequiredNamespaceStart;
 return;
   }
   diag(MatchedDecl-gt;getLocation(),
-   quot;declaration must be declared within the 
#x27;%0#x27; namespacequot;)
-  lt;lt; RequiredNamespace;
+   quot;declaration must be declared within a namespace starting with 
#x27;%0#x27;quot;)
+  lt;lt; RequiredNamespaceStart;
 }
 
 } // namespace clang::tidy::llvm_libc
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
index 33d6dc8ff125c84..47ea2b866a93404 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
@@ -8,21 +8,30 @@ correct namespace.
 
 .. code-block:: c++
 
-// Correct: implementation inside the correct namespace.
-namespace __llvm_libc {
+// Implementation inside the LIBC_NAMESPACE namespace.
+// Correct if:
+// - LIBC_NAMESPACE is a macro
+// - LIBC_NAMESPACE expansion starts with `__llvm_libc`
+namespace LIBC_NAMESPACE {
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
-// Namespaces within __llvm_libc namespace are allowed.
-namespace inner{
+// Namespaces within LIBC_NAMESPACE namespace are allowed.
+namespace inner {
 int localVar = 0;
 }
 // Functions with C linkage are allowed.
-extern quot;Cquot; void str_fuzz(){}
+extern quot;Cquot; void str_fuzz() {}
 }
 
-// Incorrect: implementation not in a namespace.
+// Incorrect: implementation not in the LIBC_NAMESPACE namespace.
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
 
-// Incorrect: outer most namespace is not correct.
+// Incorrect: outer most namespace is not the LIBC_NAMESPACE macro.
 namespace something_else {
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
 }
+
+// Incorrect: outer most namespace expansion does not start with 
`__llvm_libc`.
+#define LIBC_NAMESPACE custom_namespace
+namespace LIBC_NAMESPACE {
+void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
+}
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
index e75556a623b655c..16c5f9ca1067ec5 100644
--- 

[clang] Bugfix for chosing the correct deduction guide (PR #66487)

2023-09-15 Thread via cfe-commits

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


[clang] Bugfix for chosing the correct deduction guide (PR #66487)

2023-09-15 Thread via cfe-commits

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


[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

2023-09-15 Thread Guillaume Chatelet via cfe-commits

https://github.com/gchatelet created 
https://github.com/llvm/llvm-project/pull/66504

This is the implementation of step 3 of
https://discourse.llvm.org/t/rfc-customizable-namespace-to-allow-testing-the-libc-when-the-system-libc-is-also-llvms-libc/73079.


>From f1427a81c4a3425c1a574316fc26d2c74297b34b Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet 
Date: Fri, 15 Sep 2023 12:34:17 +
Subject: [PATCH] [clang-tidy] Update llvmlibc-implementation-in-namespace to
 new rules

This is the implementation of step 3 of
https://discourse.llvm.org/t/rfc-customizable-namespace-to-allow-testing-the-libc-when-the-system-libc-is-also-llvms-libc/73079.
---
 .../ImplementationInNamespaceCheck.cpp| 21 -
 .../llvmlibc/implementation-in-namespace.rst  | 23 +-
 .../llvmlibc/implementation-in-namespace.cpp  | 31 +--
 3 files changed, 50 insertions(+), 25 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp 
b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
index d05310f09ef773a..69a385f5be9807f 100644
--- a/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp
@@ -14,7 +14,9 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::llvm_libc {
 
-const static StringRef RequiredNamespace = "__llvm_libc";
+const static StringRef RequiredNamespaceStart = "__llvm_libc";
+const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
+
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
   decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))
@@ -29,16 +31,19 @@ void ImplementationInNamespaceCheck::check(
   if (!Result.SourceManager->isInMainFile(MatchedDecl->getLocation()))
 return;
 
-  if (const auto *NS = dyn_cast(MatchedDecl)) {
-if (NS->getName() != RequiredNamespace) {
-  diag(NS->getLocation(), "'%0' needs to be the outermost namespace")
-  << RequiredNamespace;
-}
+  if (auto *NS = dyn_cast(MatchedDecl)) {
+if (!Result.SourceManager->isMacroBodyExpansion(NS->getLocation()))
+  diag(NS->getLocation(),
+   "the outermost namespace should be the '%0' macro")
+  << RequiredNamespaceMacroName;
+else if (!NS->getName().starts_with(RequiredNamespaceStart))
+  diag(NS->getLocation(), "the outermost namespace should start with '%0'")
+  << RequiredNamespaceStart;
 return;
   }
   diag(MatchedDecl->getLocation(),
-   "declaration must be declared within the '%0' namespace")
-  << RequiredNamespace;
+   "declaration must be declared within a namespace starting with '%0'")
+  << RequiredNamespaceStart;
 }
 
 } // namespace clang::tidy::llvm_libc
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
index 33d6dc8ff125c84..47ea2b866a93404 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst
@@ -8,21 +8,30 @@ correct namespace.
 
 .. code-block:: c++
 
-// Correct: implementation inside the correct namespace.
-namespace __llvm_libc {
+// Implementation inside the LIBC_NAMESPACE namespace.
+// Correct if:
+// - LIBC_NAMESPACE is a macro
+// - LIBC_NAMESPACE expansion starts with `__llvm_libc`
+namespace LIBC_NAMESPACE {
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
-// Namespaces within __llvm_libc namespace are allowed.
-namespace inner{
+// Namespaces within LIBC_NAMESPACE namespace are allowed.
+namespace inner {
 int localVar = 0;
 }
 // Functions with C linkage are allowed.
-extern "C" void str_fuzz(){}
+extern "C" void str_fuzz() {}
 }
 
-// Incorrect: implementation not in a namespace.
+// Incorrect: implementation not in the LIBC_NAMESPACE namespace.
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
 
-// Incorrect: outer most namespace is not correct.
+// Incorrect: outer most namespace is not the LIBC_NAMESPACE macro.
 namespace something_else {
 void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
 }
+
+// Incorrect: outer most namespace expansion does not start with 
`__llvm_libc`.
+#define LIBC_NAMESPACE custom_namespace
+namespace LIBC_NAMESPACE {
+void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
+}
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/implementation-in-namespace.cpp
index e75556a623b655c..16c5f9ca1067ec5 100644
--- 

<    1   2   3   4   5   >