[PATCH] D122768: [WIP][Clang] Support capturing structured bindings in lambdas

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419650.
cor3ntin added a comment.

Fix tests?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,10 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+continue;
+if(Visit(MakeCursorVariableRef(cast(C->getCapturedVar()), C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+int i : 1;
+int j;
+};
+
+void run(void (^)());
+void test() {
+auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+run(^{ (void) i; }); // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+}
Index: clang/test/SemaCXX/cxx1z-decomposition.cpp
===
--- clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s
+// RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s
 
 void use_from_own_init() {
   auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
@@ -46,27 +47,60 @@
 }
 static_assert(f({1, 2}) == 12);
 
-constexpr bool g(S &&s) { 
+constexpr bool g(S &&s) {
   auto &[a, b] = s;
   return &a == &s.a && &b == &s.b && &a != &b;
 }
 static_assert(g({1, 2}));
 
-auto [outer1, outer2] = S{1, 2};
+struct S1 {
+  int a, b;
+};
+struct S2 {
+  int a : 1; // expected-note 2{{bit-field is declared here}}
+  int b;
+};
+
+
+auto [outer1, outer2] = S1{1, 2};
+auto [outerbit1, outerbit2] = S1{1, 2}; // expected-note {{declared here}}
+
 void enclosing() {
   struct S { int a = outer1; };
-  auto [n] = S(); // expected-note 2{{'n' declared here}}
+  auto [n] = S(); // expected-note 3{{'n' declared here}}
+
+  struct Q { int f() { return n; } }; // expected-error {{reference to local binding 'n' declared in enclosing function 'enclosing'}}
+
+  (void) [&] { return n; };  // expected-warning {{C++20}}
+  (void) [n] {return n;};   //expected-warning {{C++20}}
 
-  struct Q { int f() { return n; } }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
-  (void) [&] { return n; }; // expected-error {{reference to local binding 'n' declared in enclosing function}}
-  (void) [n] {}

[PATCH] D120540: [Driver] Enable to use C++20 modules standalone by -fcxx-modules

2022-04-01 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 419649.
ChuanqiXu added a reviewer: MaskRay.
ChuanqiXu added a comment.
Herald added a subscriber: StephenFan.

Address comments.


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

https://reviews.llvm.org/D120540

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/modules.cpp
  clang/test/Modules/cxx-modules.cppm


Index: clang/test/Modules/cxx-modules.cppm
===
--- /dev/null
+++ clang/test/Modules/cxx-modules.cppm
@@ -0,0 +1,7 @@
+// This tests that we could use C++20 modules standalone.
+// RUN: %clang -std=c++03 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++11 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++14 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++17 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// expected-no-diagnostics
+export module M;
Index: clang/test/Driver/modules.cpp
===
--- clang/test/Driver/modules.cpp
+++ clang/test/Driver/modules.cpp
@@ -73,3 +73,14 @@
 // CHECK-HEADER-UNIT-USE: BAR;
 FOO;
 #endif
+
+// Check the independent use of -fcxx-modules
+//
+// RUN: %clang++ -fcxx-modules -std=c++17 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-CXX17-MODULES
+// CHECK-CXX17-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++14 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-CXX14-MODULES
+// CHECK-CXX14-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++11 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-CXX11-MODULES
+// CHECK-CXX11-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++03 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-CXX03-MODULES
+// CHECK-CXX03-MODULES: "-fcxx-modules"
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3595,6 +3595,12 @@
 HaveModules = true;
   }
 
+  if (Args.hasFlag(options::OPT_fcxx_modules, options::OPT_fno_cxx_modules,
+   false)) {
+CmdArgs.push_back("-fcxx-modules");
+HaveModules = true;
+  }
+
   // -fmodule-maps enables implicit reading of module map files. By default,
   // this is enabled if we are using Clang's flavor of precompiled modules.
   if (Args.hasFlag(options::OPT_fimplicit_module_maps,
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1400,7 +1400,7 @@
   PosFlag, 
NegFlag>;
 defm cxx_modules : BoolFOption<"cxx-modules",
   LangOpts<"CPlusPlusModules">, Default,
-  NegFlag, PosFlag,
+  NegFlag, PosFlag,
   BothFlags<[NoXarchOption], " modules for C++">>,
   ShouldParseIf;
 def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, 
Group;


Index: clang/test/Modules/cxx-modules.cppm
===
--- /dev/null
+++ clang/test/Modules/cxx-modules.cppm
@@ -0,0 +1,7 @@
+// This tests that we could use C++20 modules standalone.
+// RUN: %clang -std=c++03 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++11 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++14 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// RUN: %clang -std=c++17 -fcxx-modules -fsyntax-only -Xclang -verify %s
+// expected-no-diagnostics
+export module M;
Index: clang/test/Driver/modules.cpp
===
--- clang/test/Driver/modules.cpp
+++ clang/test/Driver/modules.cpp
@@ -73,3 +73,14 @@
 // CHECK-HEADER-UNIT-USE: BAR;
 FOO;
 #endif
+
+// Check the independent use of -fcxx-modules
+//
+// RUN: %clang++ -fcxx-modules -std=c++17 -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX17-MODULES
+// CHECK-CXX17-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++14 -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX14-MODULES
+// CHECK-CXX14-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++11 -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX11-MODULES
+// CHECK-CXX11-MODULES: "-fcxx-modules"
+// RUN: %clang++ -fcxx-modules -std=c++03 -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-CXX03-MODULES
+// CHECK-CXX03-MODULES: "-fcxx-modules"
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3595,6 +3595,12 @@
 HaveModules = true;
   }
 
+  if (Args.hasFlag(options::OPT_fcxx_modules, options::OPT_fno_cxx_modules,
+   false)) {
+CmdArgs.push_back("-fcxx-modules");
+HaveModules = true;
+  }
+
   // -fmodule-maps enables implicit reading o

[PATCH] D122768: [WIP][Clang] Support capturing structured bindings in lambdas

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419657.
cor3ntin added a comment.

- formatting
- add more tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+int i : 1;
+int j;
+};
+
+void run(void (^)());
+void test() {
+auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+run(^{ (void) i; }); // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -stdc++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+auto [v, r] = S{1, a};
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+}
Index: clang/test/SemaCXX/cxx1z-decomposition.cpp
===
--- clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s
+// RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s
 
 void use_from_own_init() {
   auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}
@@ -46,25 +47,56 @@
 }
 static_assert(f({1, 2}) == 12);

[PATCH] D122838: [clang][dataflow] Add support for correlation of boolean (tracked) values

2022-04-01 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev accepted this revision.
sgatev added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:79
+for (BoolValue *Constraint : Env1.getFlowConditionConstraints()) {
+  Expr1 = &Env1.makeAnd(*Expr1, *Constraint);
+}

xazax.hun wrote:
> Hmm, interesting.
> I think we view every boolean formula at a certain program point implicitly 
> as `FlowConditionAtThatPoint && Formula`. And the flow condition at a program 
> point should already be a disjunction of its predecessors.
> 
> So it would be interpreted as: `(FlowConditionPred1 || FlowConditionPred2) && 
> (FormulaAtPred1 || FormulaAtPred2)`.
> While this is great, this is not the strongest condition we could derive. 
> `(FlowConditionPred1 && FormulaAtPred1)  || (FormulaAtPred2 && 
> FlowConditionPred2)` created by this code snippet is stronger which is great.
> 
> My main concern is whether we would end up seeing an exponential explosion in 
> the size of these formulas in the number of branches following each other in 
> a sequence.
> 
Yeap, I agree this is suboptimal and I believe I'm the one to blame for 
introducing it downstream.

I wonder if we can represent the flow condition of each environment using a 
bool atom and have a mapping of bi-conditionals between flow condition atoms 
and flow condition constraints. Something like:

```
FC1 <=> C1 ^ C2
FC2 <=> C2 ^ C3 ^ C4
FC3 <=> (FC1 v FC2) ^ C5
... 
```

We can use that to simplify the formulas here and in `joinConstraints`. The 
mapping can be stored in `DataflowAnalysisContext`. We can track dependencies 
between flow conditions (e.g. above `FC3` depends on `FC1` and `FC2`) and 
modify `flowConditionImplies` to construct a formula that includes the 
bi-conditionals for all flow condition atoms in the transitive set before 
invoking the solver.

I suggest putting the optimization in its own patch. I'd love to look into it 
right after this patch is submitted if both of you think it makes sense on a 
high level.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122838

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


[PATCH] D119136: [clang] Implement Change scope of lambda trailing-return-type

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419658.
cor3ntin added a comment.

- Add missing static


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119136

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Scope.h
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/Scope.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaCXXScopeSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
  clang/test/SemaCXX/lambda-capture-type-deduction.cpp
  clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1355,7 +1355,7 @@
 
   Change scope of lambda trailing-return-type
   https://wg21.link/P2036R3";>P2036R3
-  No
+  Clang 15
 
 
   Multidimensional subscript operator
Index: clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
===
--- clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ clang/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -95,7 +95,7 @@
 #ifdef AVOID
   auto l4 = [var = param] (int param) { ; }; // no warning
 #else
-  auto l4 = [var = param] (int param) { ; }; // expected-warning {{declaration shadows a local variable}}
+  auto l4 = [var = param](int param) { ; }; // expected-warning 2{{declaration shadows a local variable}}
 #endif
 
   // Make sure that inner lambdas work as well.
Index: clang/test/SemaCXX/lambda-capture-type-deduction.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -std=c++2b -verify -fsyntax-only %s
+
+template 
+constexpr bool is_same = false;
+
+template 
+constexpr bool is_same = true;
+
+void f() {
+
+  int y;
+
+  static_assert(is_same decltype((x)) { return x; }())>);
+
+  static_assert(is_same decltype((x)) { return x; }())>);
+
+  static_assert(is_same decltype((y)) { return y; }())>);
+
+  static_assert(is_same decltype((y)) { return y; }())>);
+
+  static_assert(is_same decltype((y)) { return y; }())>);
+
+  static_assert(is_same decltype((y)) { return y; }())>);
+
+  auto ref = [&x = y](
+ decltype([&](decltype(x)) { return 0; }) y) {
+return x;
+  };
+}
+
+void test_noexcept() {
+
+  int y;
+
+  static_assert(noexcept([x = 1] noexcept(is_same) {}()));
+  static_assert(noexcept([x = 1] mutable noexcept(is_same) {}()));
+  static_assert(noexcept([y] noexcept(is_same) {}()));
+  static_assert(noexcept([y] mutable noexcept(is_same) {}()));
+  static_assert(noexcept([=] noexcept(is_same) {}()));
+  static_assert(noexcept([=] mutable noexcept(is_same) {}()));
+  static_assert(noexcept([&] noexcept(is_same) {}()));
+  static_assert(noexcept([&] mutable noexcept(is_same) {}()));
+
+  static_assert(noexcept([&] mutable noexcept(!is_same) {}())); // expected-error {{static_assert failed due}}
+}
+
+void test_requires() {
+
+  int x;
+
+  [x = 1]() requires is_same {}();
+  [x = 1]() mutable requires is_same {}();
+  [x]() requires is_same {} ();
+  [x]() mutable requires is_same {} ();
+  [=]() requires is_same {} ();
+  [=]() mutable requires is_same {} ();
+  [&]() requires is_same {} ();
+  [&]() mutable requires is_same {} ();
+  [&x]() requires is_same {} ();
+  [&x]() mutable requires is_same {}();
+
+  [x = 1]() requires is_same {} (); // expected-error {{no matching function for call to object of type}} \
+  // expected-note {{candidate function not viable}} \
+  // expected-note {{'is_same' evaluated to false}}
+
+  [x = 1]() mutable requires is_same {} (); // expected-error {{no matching function for call to object of type}} \
+// expected-note {{candidate function not viable}} \
+// expected-note {{'is_same' evaluated to false}}
+}
+
+void err() {
+  int y, z;// expected-note 2{{declared here}}
+  auto implicit_tpl = [=]( // expected-note {{variable 'y' is captured here}}
+  decltype([&] { return 0; }) y) { //expected-error{{captured variable 'y' cannot appear}}
+return y;
+  };
+
+  auto init_tpl = [x = 1](  // expected-note{{explicitly captured here}}
+  decltype([&] { return 0; }) y) { // expected-error {{captured variable 'x' cannot appea

[PATCH] D119136: [clang] Implement Change scope of lambda trailing-return-type

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin marked an inline comment as done.
cor3ntin added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:18242
 
+bool CheckCaptureUseBeforeLambdaQualifiers(Sema &S, VarDecl *Var,
+   SourceLocation ExprLoc,

ChuanqiXu wrote:
> If this is only used in current file, we should mark it as static or put in 
> anonymous namespace. And I think this lacks a comment
Good catch, thanks


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119136

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


[PATCH] D119136: [clang] Implement Change scope of lambda trailing-return-type

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin marked an inline comment as done.
cor3ntin added a comment.

In D119136#3418585 , @ChuanqiXu wrote:

> I've just skimmed over the patch and it is a little bit hard to understand 
> for people who don't have a strong background. Is it possible to split this 
> one into several parts?

Unfortunately, I don't thing that would be very practical. The patch is not 
small but what it changes is rather small, and if we tried to split it the 
intermediate patches would be inconsistent and untested


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119136

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


[clang] c7ed65b - [C++20][Modules] Limit ModuleInternalLinkage to modules-ts.

2022-04-01 Thread Iain Sandoe via cfe-commits

Author: Iain Sandoe
Date: 2022-04-01T09:10:30+01:00
New Revision: c7ed65b4bcbd8c26704efc4193243831e3c13d3c

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

LOG: [C++20][Modules] Limit ModuleInternalLinkage to modules-ts.

At present, we are generating wrong code for C++20 modules entities which
should have internal linkage.  This is because we are assigning
'ModuleInternalLinkage' unconditionally to such entities.  However this mode
is only applicable to the modules-ts.

This change makes the special linkage mode conditional on fmodules-ts and
adds a unit test to verify that we generate the correct linkage.

Currently, static variables and functions in module purview are emitted into
object files as external. On some platforms, lambdas are emitted as global
weak defintions (on Windows this causes a mangler crash).

Differential Revision: https://reviews.llvm.org/D122413

Added: 


Modified: 
clang/lib/AST/Decl.cpp
clang/unittests/AST/DeclTest.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 46c888430bb07..6af7a37dfc7b2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -596,11 +596,12 @@ static bool isExportedFromModuleInterfaceUnit(const 
NamedDecl *D) {
 }
 
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
-  // Internal linkage declarations within a module interface unit are modeled
-  // as "module-internal linkage", which means that they have internal linkage
-  // formally but can be indirectly accessed from outside the module via inline
-  // functions and templates defined within the module.
-  if (isInModulePurview(D))
+  // (for the modules ts) Internal linkage declarations within a module
+  // interface unit are modeled as "module-internal linkage", which means that
+  // they have internal linkage formally but can be indirectly accessed from
+  // outside the module via inline functions and templates defined within the
+  // module.
+  if (isInModulePurview(D) && D->getASTContext().getLangOpts().ModulesTS)
 return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
 
   return LinkageInfo::internal();

diff  --git a/clang/unittests/AST/DeclTest.cpp 
b/clang/unittests/AST/DeclTest.cpp
index 7c227d40af86b..560c6b3ddf434 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -194,3 +194,50 @@ TEST(Decl, InConsistLinkageForTemplates) {
   EXPECT_EQ(TemplateF->getLinkageInternal(),
 SpecializedF->getLinkageInternal());
 }
+
+TEST(Decl, ModuleAndInternalLinkage) {
+  llvm::Annotations Code(R"(
+export module M;
+static int a;
+static int f(int x);
+
+int b;
+int g(int x);)");
+
+  auto AST =
+  tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+
+  const auto *a =
+  selectFirst("a", match(varDecl(hasName("a")).bind("a"), Ctx));
+  const auto *f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), Ctx));
+
+  EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+
+  const auto *b =
+  selectFirst("b", match(varDecl(hasName("b")).bind("b"), Ctx));
+  const auto *g = selectFirst(
+  "g", match(functionDecl(hasName("g")).bind("g"), Ctx));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+
+  AST = tooling::buildASTFromCodeWithArgs(
+  Code.code(), /*Args=*/{"-std=c++20", "-fmodules-ts"});
+  ASTContext &CtxTS = AST->getASTContext();
+  a = selectFirst("a", match(varDecl(hasName("a")).bind("a"), CtxTS));
+  f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), CtxTS));
+
+  EXPECT_EQ(a->getLinkageInternal(), ModuleInternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), ModuleInternalLinkage);
+
+  b = selectFirst("b", match(varDecl(hasName("b")).bind("b"), CtxTS));
+  g = selectFirst(
+  "g", match(functionDecl(hasName("g")).bind("g"), CtxTS));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+}



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


[PATCH] D122413: [C++20][Modules] Limit ModuleInternalLinkage to modules-ts.

2022-04-01 Thread Iain Sandoe via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc7ed65b4bcbd: [C++20][Modules] Limit ModuleInternalLinkage 
to modules-ts. (authored by iains).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122413

Files:
  clang/lib/AST/Decl.cpp
  clang/unittests/AST/DeclTest.cpp


Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -194,3 +194,50 @@
   EXPECT_EQ(TemplateF->getLinkageInternal(),
 SpecializedF->getLinkageInternal());
 }
+
+TEST(Decl, ModuleAndInternalLinkage) {
+  llvm::Annotations Code(R"(
+export module M;
+static int a;
+static int f(int x);
+
+int b;
+int g(int x);)");
+
+  auto AST =
+  tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+
+  const auto *a =
+  selectFirst("a", match(varDecl(hasName("a")).bind("a"), Ctx));
+  const auto *f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), Ctx));
+
+  EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+
+  const auto *b =
+  selectFirst("b", match(varDecl(hasName("b")).bind("b"), Ctx));
+  const auto *g = selectFirst(
+  "g", match(functionDecl(hasName("g")).bind("g"), Ctx));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+
+  AST = tooling::buildASTFromCodeWithArgs(
+  Code.code(), /*Args=*/{"-std=c++20", "-fmodules-ts"});
+  ASTContext &CtxTS = AST->getASTContext();
+  a = selectFirst("a", match(varDecl(hasName("a")).bind("a"), CtxTS));
+  f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), CtxTS));
+
+  EXPECT_EQ(a->getLinkageInternal(), ModuleInternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), ModuleInternalLinkage);
+
+  b = selectFirst("b", match(varDecl(hasName("b")).bind("b"), CtxTS));
+  g = selectFirst(
+  "g", match(functionDecl(hasName("g")).bind("g"), CtxTS));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+}
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -596,11 +596,12 @@
 }
 
 static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
-  // Internal linkage declarations within a module interface unit are modeled
-  // as "module-internal linkage", which means that they have internal linkage
-  // formally but can be indirectly accessed from outside the module via inline
-  // functions and templates defined within the module.
-  if (isInModulePurview(D))
+  // (for the modules ts) Internal linkage declarations within a module
+  // interface unit are modeled as "module-internal linkage", which means that
+  // they have internal linkage formally but can be indirectly accessed from
+  // outside the module via inline functions and templates defined within the
+  // module.
+  if (isInModulePurview(D) && D->getASTContext().getLangOpts().ModulesTS)
 return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
 
   return LinkageInfo::internal();


Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -194,3 +194,50 @@
   EXPECT_EQ(TemplateF->getLinkageInternal(),
 SpecializedF->getLinkageInternal());
 }
+
+TEST(Decl, ModuleAndInternalLinkage) {
+  llvm::Annotations Code(R"(
+export module M;
+static int a;
+static int f(int x);
+
+int b;
+int g(int x);)");
+
+  auto AST =
+  tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+
+  const auto *a =
+  selectFirst("a", match(varDecl(hasName("a")).bind("a"), Ctx));
+  const auto *f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), Ctx));
+
+  EXPECT_EQ(a->getLinkageInternal(), InternalLinkage);
+  EXPECT_EQ(f->getLinkageInternal(), InternalLinkage);
+
+  const auto *b =
+  selectFirst("b", match(varDecl(hasName("b")).bind("b"), Ctx));
+  const auto *g = selectFirst(
+  "g", match(functionDecl(hasName("g")).bind("g"), Ctx));
+
+  EXPECT_EQ(b->getLinkageInternal(), ModuleLinkage);
+  EXPECT_EQ(g->getLinkageInternal(), ModuleLinkage);
+
+  AST = tooling::buildASTFromCodeWithArgs(
+  Code.code(), /*Args=*/{"-std=c++20", "-fmodules-ts"});
+  ASTContext &CtxTS = AST->getASTContext();
+  a = selectFirst("a", match(varDecl(hasName("a")).bind("a"), CtxTS));
+  f = selectFirst(
+  "f", match(functionDecl(hasName("f")).bind("f"), CtxTS));
+
+  EXPECT_EQ(a->getLinkageInternal(), ModuleInternalLinkage);
+  EXPECT_E

[PATCH] D122529: [ASTMatchers] Output currently matching node on crash

2022-04-01 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 419662.
njames93 added a comment.

Split PointerUnion to work on 32bit platforms


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122529

Files:
  clang/lib/ASTMatchers/ASTMatchFinder.cpp
  clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -39,10 +39,24 @@
 // FIXME: Figure out why back traces aren't being generated on clang builds on
 // windows.
 #if ENABLE_BACKTRACES && (!defined(_MSC_VER) || !defined(__clang__))
+
+AST_MATCHER(Decl, causeCrash) {
+  abort();
+  return true;
+}
+
+TEST(MatcherCrashDeathTest, CrashOnMatcherDump) {
+  llvm::EnablePrettyStackTrace();
+  auto Matcher = testing::HasSubstr(
+  "ASTMatcher: Matching '' against:\n\tFunctionDecl foo : "
+  "");
+  ASSERT_DEATH(matches("void foo();", functionDecl(causeCrash())), Matcher);
+}
+
 template 
 static void crashTestNodeDump(MatcherT Matcher,
   ArrayRef MatchedNodes,
-  StringRef Code) {
+  StringRef Against, StringRef Code) {
   llvm::EnablePrettyStackTrace();
   MatchFinder Finder;
 
@@ -58,7 +72,9 @@
 ASSERT_DEATH(tooling::runToolOnCode(
  newFrontendActionFactory(&Finder)->create(), Code),
  testing::HasSubstr(
- "ASTMatcher: Processing 'CrashTester'\nNo bound nodes"));
+ ("ASTMatcher: Processing 'CrashTester' against:\n\t" +
+  Against + "\nNo bound nodes")
+ .str()));
   } else {
 std::vector>>
@@ -69,7 +85,9 @@
 }
 auto CrashMatcher = testing::AllOf(
 testing::HasSubstr(
-"ASTMatcher: Processing 'CrashTester'\n--- Bound Nodes Begin ---"),
+("ASTMatcher: Processing 'CrashTester' against:\n\t" + Against +
+ "\n--- Bound Nodes Begin ---")
+.str()),
 testing::HasSubstr("--- Bound Nodes End ---"),
 testing::AllOfArray(Matchers));
 
@@ -79,7 +97,8 @@
   }
 }
 TEST(MatcherCrashDeathTest, CrashOnCallbackDump) {
-  crashTestNodeDump(forStmt(), {}, "void foo() { for(;;); }");
+  crashTestNodeDump(forStmt(), {}, "ForStmt : ",
+"void foo() { for(;;); }");
   crashTestNodeDump(
   forStmt(hasLoopInit(declStmt(hasSingleDecl(
varDecl(hasType(qualType().bind("QT")),
@@ -94,6 +113,7 @@
"IL - { IntegerLiteral :  }", "QT - { QualType : int }",
"T - { BuiltinType : int }",
"VD - { VarDecl I :  }"},
+  "ForStmt : ",
   R"cpp(
   void foo() {
 for (int I = 0; I < 5; ++I) {
@@ -106,12 +126,14 @@
   {"Unnamed - { CXXRecordDecl (anonymous) :  }",
"Op+ - { CXXMethodDecl (anonymous struct)::operator+ :  }"},
+  "CXXRecordDecl (anonymous) : ",
   "struct { int operator+(int) const; } Unnamed;");
   crashTestNodeDump(
   cxxRecordDecl(hasMethod(cxxConstructorDecl(isDefaulted()).bind("Ctor")),
 hasMethod(cxxDestructorDecl(isDefaulted()).bind("Dtor"))),
   {"Ctor - { CXXConstructorDecl Foo::Foo :  }",
"Dtor - { CXXDestructorDecl Foo::~Foo :  }"},
+  "CXXRecordDecl Foo : ",
   "struct Foo { Foo() = default; ~Foo() = default; };");
 }
 #endif // ENABLE_BACKTRACES
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -761,53 +761,200 @@
 D);
   }
 
+private:
+  bool TraversingASTNodeNotSpelledInSource = false;
+  bool TraversingASTNodeNotAsIs = false;
+  bool TraversingASTChildrenNotSpelledInSource = false;
+
+  class CurMatchData {
+// We don't have enough free low bits in 32bit builds to discriminate 8 pointer
+// types in PointerUnion. so split the union in 2 using a free bit from the
+// callback pointer.
+#define CMD_TYPES_0\
+  const QualType *, const TypeLoc *, const NestedNameSpecifier *,  \
+  const NestedNameSpecifierLoc *
+#define CMD_TYPES_1\
+  const CXXCtorInitializer *, const TemplateArgumentLoc *, const Attr *,   \
+  const DynTypedNode *
+
+  public:
+CurMatchData() : Node1(nullptr) {}
+
+template 
+typename std::enable_if_t<
+llvm::is_one_of::value>
+SetCallbackAndRawNode(const MatchCallback *CB, const NodeType &N) {
+  assertEmpty();
+  Callback.setPointerAndInt(CB, 0);
+  Node1 = &N;
+}
+
+template 
+typename std::enable_if_t<
+llvm::is_one_of::value

[PATCH] D122789: [compiler-rt] [scudo] Use -mcrc32 on x86 when available

2022-04-01 Thread Michał Górny via Phabricator via cfe-commits
mgorny updated this revision to Diff 419666.
mgorny added a comment.

Used `__builtin_ia32_crc32*` along with `-mcrc32` to fix compatibility with GCC.


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

https://reviews.llvm.org/D122789

Files:
  compiler-rt/cmake/config-ix.cmake
  compiler-rt/lib/scudo/CMakeLists.txt
  compiler-rt/lib/scudo/scudo_allocator.cpp
  compiler-rt/lib/scudo/scudo_crc32.cpp
  compiler-rt/lib/scudo/scudo_crc32.h
  compiler-rt/lib/scudo/standalone/CMakeLists.txt
  compiler-rt/lib/scudo/standalone/checksum.h
  compiler-rt/lib/scudo/standalone/chunk.h
  compiler-rt/lib/scudo/standalone/crc32_hw.cpp

Index: compiler-rt/lib/scudo/standalone/crc32_hw.cpp
===
--- compiler-rt/lib/scudo/standalone/crc32_hw.cpp
+++ compiler-rt/lib/scudo/standalone/crc32_hw.cpp
@@ -10,10 +10,10 @@
 
 namespace scudo {
 
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 u32 computeHardwareCRC32(u32 Crc, uptr Data) {
   return static_cast(CRC32_INTRINSIC(Crc, Data));
 }
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 
 } // namespace scudo
Index: compiler-rt/lib/scudo/standalone/chunk.h
===
--- compiler-rt/lib/scudo/standalone/chunk.h
+++ compiler-rt/lib/scudo/standalone/chunk.h
@@ -25,7 +25,7 @@
   // as opposed to only for crc32_hw.cpp. This means that other hardware
   // specific instructions were likely emitted at other places, and as a result
   // there is no reason to not use it here.
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
   u32 Crc = static_cast(CRC32_INTRINSIC(Seed, Value));
   for (uptr I = 0; I < ArraySize; I++)
 Crc = static_cast(CRC32_INTRINSIC(Crc, Array[I]));
@@ -42,7 +42,7 @@
   Checksum = computeBSDChecksum(Checksum, Array[I]);
 return Checksum;
   }
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 }
 
 namespace Chunk {
Index: compiler-rt/lib/scudo/standalone/checksum.h
===
--- compiler-rt/lib/scudo/standalone/checksum.h
+++ compiler-rt/lib/scudo/standalone/checksum.h
@@ -12,12 +12,16 @@
 #include "internal_defs.h"
 
 // Hardware CRC32 is supported at compilation via the following:
-// - for i386 & x86_64: -msse4.2
+// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
 // - for ARM & AArch64: -march=armv8-a+crc or -mcrc
 // An additional check must be performed at runtime as well to make sure the
 // emitted instructions are valid on the target host.
 
-#ifdef __SSE4_2__
+#if defined(__CRC32__)
+// NB: clang has  but GCC does not
+#include 
+#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
+#elif defined(__SSE4_2__)
 #include 
 #define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
 #endif
Index: compiler-rt/lib/scudo/standalone/CMakeLists.txt
===
--- compiler-rt/lib/scudo/standalone/CMakeLists.txt
+++ compiler-rt/lib/scudo/standalone/CMakeLists.txt
@@ -97,8 +97,11 @@
   string_utils.cpp
   )
 
-# Enable the SSE 4.2 instruction set for crc32_hw.cpp, if available.
-if (COMPILER_RT_HAS_MSSE4_2_FLAG)
+# Enable the necessary instruction set for scudo_crc32.cpp, if available.
+# Newer compiler versions use -mcrc32 rather than -msse4.2.
+if (COMPILER_RT_HAS_MCRC32_FLAG)
+  set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -mcrc32)
+elseif (COMPILER_RT_HAS_MSSE4_2_FLAG)
   set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
 endif()
 
Index: compiler-rt/lib/scudo/scudo_crc32.h
===
--- compiler-rt/lib/scudo/scudo_crc32.h
+++ compiler-rt/lib/scudo/scudo_crc32.h
@@ -16,13 +16,17 @@
 #include "sanitizer_common/sanitizer_internal_defs.h"
 
 // Hardware CRC32 is supported at compilation via the following:
-// - for i386 & x86_64: -msse4.2
+// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
 // - for ARM & AArch64: -march=armv8-a+crc or -mcrc
 // An additional check must be performed at runtime as well to make sure the
 // emitted instructions are valid on the target host.
 
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
-# ifdef __SSE4_2__
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+# if defined(__CRC32__)
+// NB: clang has  but GCC does not
+#  include 
+#  define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
+# elif defined(__SSE4_2__)
 #  include 
 #  define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32

[PATCH] D121165: [pseudo] Add crude heuristics to choose taken preprocessor branches.

2022-04-01 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added a comment.
This revision is now accepted and ready to land.

Thanks, looks good!




Comment at: clang-tools-extra/pseudo/include/clang-pseudo/DirectiveMap.h:95
 
   // FIXME: add heuristically selection of conditional branches.
   // FIXME: allow deriving a preprocessed stream

it is done in this patch, can be removed now.



Comment at: clang-tools-extra/pseudo/lib/DirectiveMap.cpp:329
+const auto &Tokens = Code.tokens(Dir.Tokens);
+if (Tokens.empty() || Tokens.front().Kind != tok::hash)
+  return llvm::None;

I thought the first token of the `Directive` should always be `tok::hash`, 
isn't it?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121165

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


[PATCH] D122478: [PowerPC] Add max/min intrinsics to Clang and PPC backend

2022-04-01 Thread Qiu Chaofan via Phabricator via cfe-commits
qiucf added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:9897
+def err_ppc_unsupported_argument_type : Error<
+  "unsupported argument type %0 for target %1">;
 def err_x86_builtin_invalid_rounding : Error<

Use `err_target_unsupported_type`?



Comment at: llvm/include/llvm/IR/IntrinsicsPowerPC.td:192
+  [llvm_float_ty, llvm_float_ty, llvm_float_ty, 
llvm_vararg_ty],
+  [IntrNoMem]>;
 }

tingwang wrote:
> qiucf wrote:
> > Will we support `llvm_f128_ty`?
> I'm afraid not at this moment. Document mentions only three types: float, 
> double, or long double.
Can we at least leave a TODO comment here for `llvm_f128_ty` support?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122478

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D122805#3420111 , @steakhal wrote:

> In D122805#3419662 , @martong wrote:
>
>> In D122805#3419129 , @steakhal 
>> wrote:
>>
>>> Please add a test case where the class is trivial but the global variable 
>>> of such is non-const, thus the initialized expression is not imported.
>>
>> I've added a new case, but that is not very meaningful, because 
>> `clang-extdef-mapping` is not capable of emitting the USR for the non-const 
>> variable.
>
> What do you mean by //not capable//?

It uses `cross_tu::shouldImport()` which returns true only for `const` 
declarations. So, having a hand-written `extDevMapping.txt` that contains an 
USR for a non-const is not that meaningful, imho.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122885: [clang] Draft: Implement P1703R1

2022-04-01 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, iains, urnathan, ChuanqiXu.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As in: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1703r1.html

Posting this mostly to get some feedback on the general path taken.

>From reading the paper, I understand that the preprocessor should gain a 
>"import-keyword" token, but that is already taken by the GNU `#import` 
>extension.

The implementation here starts converting newlines to `eod` tokens when seeing 
a `export` or `import` token. However, that means ignoring the `eod` tokens 
when parsing an export block, an exported declaration or a non-header-unit 
module import.

Let me know what you think.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122885

Files:
  clang/include/clang/Basic/DiagnosticLexKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/Parser.cpp
  clang/test/CXX/cpp/cpp.module/p1.cpp
  clang/test/CXX/lex/lex.pptoken/p3-2a.cpp
  clang/test/Modules/P1703R1.cpp

Index: clang/test/Modules/P1703R1.cpp
===
--- /dev/null
+++ clang/test/Modules/P1703R1.cpp
@@ -0,0 +1,103 @@
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: mkdir -p %t/system
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit \
+// RUN: -xc++-header header.h -o header.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -isystem system \
+// RUN: -xc++-system-header system-header.h -o system/system-header.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface dummy.cpp -o dummy.pcm
+
+// RUN: %clang_cc1 -std=c++20 -fmodule-file=header.pcm \
+// RUN: -fmodule-file=system/system-header.pcm \
+// RUN: -fmodule-file=dummy.pcm \
+// RUN: -emit-module-interface -isystem system \
+// RUN: main.cpp -verify
+
+//--- header.h
+int foo(int);
+
+//--- system/system-header.h
+int foo2(int);
+
+//--- dummy.cpp
+export module dummy;
+
+//--- main.cpp
+export module main;
+#define IMPORT import
+#define EXPORT export
+#define HEADER "header.h"
+#define SYSTEM_HEADER 
+#define SEMI ;
+
+
+/// Fine.
+import "header.h";
+export import "header.h";
+
+
+import
+"header.h";// expected-error {{expected a module name after 'import'}}
+export import
+"header.h"; // expected-error {{expected a module name after 'import'}}
+export
+import "header.h"; // expected-error {{expected a module name after 'import'}}
+
+import "header.h"; import "header.h"; // expected-error {{import keyword must be at start of line}}
+  // expected-error@-1 {{extra tokens after module import}}
+
+import "header.h" SEMI // expected-error {{semicolon terminating header import declaration cannot be produced by a macro}}
+IMPORT "header.h"; // expected-error {{import keyword cannot be produced by a macro}}
+EXPORT import "header.h"; // expected-error {{export keyword cannot be produced by a macro}}
+import HEADER; /// Fine.
+
+
+import ;
+export import ;
+
+import
+; // expected-error {{expected a module name after 'import'}}
+IMPORT ;// expected-error {{import keyword cannot be produced by a macro}}
+EXPORT import ;// expected-error {{export keyword cannot be produced by a macro}}
+import SYSTEM_HEADER;
+
+
+
+/// Normal module imports are unaffected
+import dummy;
+import
+dummy;
+export
+import
+dummy;
+export import
+dummy;
+export
+import dummy;
+import dummy; import dummy;
+
+
+
+// TODO: The diagnostics here could be much better.
+export
+import "header.h"; // expected-error {{expected a module name after 'import'}}
+
+export import
+"header.h" // expected-error {{expected a module name after 'import'}}
+
+
+export void foo() {}
+export void
+baz(){}
+export
+void bar(){}
+
+export {
+  void a(){}
+}
Index: clang/test/CXX/lex/lex.pptoken/p3-2a.cpp
===
--- clang/test/CXX/lex/lex.pptoken/p3-2a.cpp
+++ clang/test/CXX/lex/lex.pptoken/p3-2a.cpp
@@ -56,26 +56,3 @@
 #define HEADER 
 // CHECK: import ;
 import HEADER;
-
-// CHECK: import ;
-import <
-foo
-  bar
->;
-
-// CHECK: import{{$}}
-// CHECK: {{^}};
-import
-<
-foo
-  bar
->;
-
-// CHECK: import{{$}}
-// CHECK: {{^}};
-import
-;
-
-#define IMPORT import 
-// CHECK: import ;
-IMPORT;
Index: clang/test/CXX/cpp/cpp.module/p1.cpp
===
--- clang/test/CXX/cpp/cpp.module/p1.cpp
+++ clang/test/CXX/cpp/cpp.module/p1.cpp
@@ -5,11 +5,11 @@
 // expected-error@+1 {{semicolon terminating header import declaration cannot be produced by a macro}}
 import "empty.h" SEMI // CHECK: import attrs.{{.*}};
 
-#define IMPORT import "empty.h"
-IMPORT; // CHECK: import attrs.{{.*}};
+#define IMPORT "empty.h"
+import IMPORT; // CHECK: import attrs.{{.*}};

[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D122805#3421676 , @martong wrote:

> In D122805#3420111 , @steakhal 
> wrote:
>
>> In D122805#3419662 , @martong 
>> wrote:
>>
>>> In D122805#3419129 , @steakhal 
>>> wrote:
>>>
 Please add a test case where the class is trivial but the global variable 
 of such is non-const, thus the initialized expression is not imported.
>>>
>>> I've added a new case, but that is not very meaningful, because 
>>> `clang-extdef-mapping` is not capable of emitting the USR for the non-const 
>>> variable.
>>
>> What do you mean by //not capable//?
>
> It uses `cross_tu::shouldImport()` which returns true only for `const` 
> declarations. So, having a hand-written `extDevMapping.txt` that contains an 
> USR for a non-const is not that meaningful, imho.

I changed my mind: we can test one side of the logic if we do add 
`extNonConstS` to the `externalDefMap.txt`. So, just did that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 419683.
martong added a comment.

- Add extNonConstS to the externalDefMap.txt


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
  clang/test/Analysis/ctu-main.cpp
  clang/test/Analysis/func-mapping-test.cpp
  clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Index: clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
===
--- clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -64,7 +64,7 @@
   if (const Stmt *Body = FD->getBody())
 addIfInMain(FD, Body->getBeginLoc());
   } else if (const auto *VD = dyn_cast(D)) {
-if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+if (cross_tu::shouldImport(VD, Ctx) && VD->hasInit())
   if (const Expr *Init = VD->getInit())
 addIfInMain(VD, Init->getBeginLoc());
   }
Index: clang/test/Analysis/func-mapping-test.cpp
===
--- clang/test/Analysis/func-mapping-test.cpp
+++ clang/test/Analysis/func-mapping-test.cpp
@@ -23,7 +23,7 @@
 struct SF {
   const int a;
 };
-SF sf = {.a = 2};
+extern const SF sf = {.a = 2};
 // CHECK-DAG: c:@sf
 
 struct SStatic {
@@ -39,7 +39,7 @@
   const int a;
   const unsigned int b;
 };
-U u = {.a = 6};
+extern const U u = {.a = 6};
 // CHECK-DAG: c:@u
 
 // No USR can be generated for this.
Index: clang/test/Analysis/ctu-main.cpp
===
--- clang/test/Analysis/ctu-main.cpp
+++ clang/test/Analysis/ctu-main.cpp
@@ -75,6 +75,13 @@
   int a;
 };
 extern const S extS;
+extern S extNonConstS;
+struct NonTrivialS {
+  int a;
+  // User declaring a dtor makes it non-trivial.
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS;
 extern const int extHere;
 const int extHere = 6;
 struct A {
@@ -83,9 +90,9 @@
 struct SC {
   const int a;
 };
-extern SC extSC;
+extern const SC extSC;
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
 struct SCNest {
   struct SCN {
@@ -93,7 +100,7 @@
   } scn;
 };
 extern SCNest extSCN;
-extern SCNest::SCN extSubSCN;
+extern const SCNest::SCN extSubSCN;
 struct SCC {
   SCC(int c);
   const int a;
@@ -103,7 +110,7 @@
   const int a;
   const unsigned int b;
 };
-extern U extU;
+extern const U extU;
 
 void test_virtual_functions(mycls* obj) {
   // The dynamic type is known.
@@ -172,6 +179,9 @@
   clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
   clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{UNKNOWN}}
+  // Do not import non-trivial classes' initializers.
+  clang_analyzer_eval(extNTS.a == 4); // expected-warning{{UNKNOWN}}
   clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
   clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
Index: clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
===
--- clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
@@ -18,6 +18,8 @@
 c:@extInt ctu-other.cpp.ast
 c:@N@intns@extInt ctu-other.cpp.ast
 c:@extS ctu-other.cpp.ast
+c:@extNonConstS ctu-other.cpp.ast
+c:@extNTS ctu-other.cpp.ast
 c:@S@A@a ctu-other.cpp.ast
 c:@extSC ctu-other.cpp.ast
 c:@S@ST@sc ctu-other.cpp.ast
@@ -27,4 +29,4 @@
 c:@extU ctu-other.cpp.ast
 c:@S@TestAnonUnionUSR@Test ctu-other.cpp.ast
 c:@F@testImportOfIncompleteDefaultParmDuringImport#I# ctu-other.cpp.ast
-c:@F@testImportOfDelegateConstructor#I# ctu-other.cpp.ast
\ No newline at end of file
+c:@F@testImportOfDelegateConstructor#I# ctu-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-other.cpp
===
--- clang/test/Analysis/Inputs/ctu-other.cpp
+++ clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@
   int a;
 };
 extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+  int a;
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
 struct A {
   static const int a;
 };
@@ -109,18 +115,18 @@
 struct SC {
   const int a;
 };
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};

[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Balázs Benics via Phabricator via cfe-commits
steakhal added a comment.

In D122805#3421746 , @martong wrote:

> In D122805#3421676 , @martong wrote:
>
>> In D122805#3420111 , @steakhal 
>> wrote:
>>
>>> In D122805#3419662 , @martong 
>>> wrote:
>>>
 In D122805#3419129 , @steakhal 
 wrote:

> Please add a test case where the class is trivial but the global variable 
> of such is non-const, thus the initialized expression is not imported.

 I've added a new case, but that is not very meaningful, because 
 `clang-extdef-mapping` is not capable of emitting the USR for the 
 non-const variable.
>>>
>>> What do you mean by //not capable//?
>>
>> It uses `cross_tu::shouldImport()` which returns true only for `const` 
>> declarations. So, having a hand-written `extDevMapping.txt` that contains an 
>> USR for a non-const is not that meaningful, IMHO.

What I wanted to emphasize is that previously for all `const` globals it 
returned `true`, unlike now when we only return `true` if it's `const` AND 
//trivial//.
This test case would demonstrate the behavioral change and would nicely 
underpin the reason behind this patch.

In D122805#3421746 , @martong wrote:

> I changed my mind: we can test one side of the logic if we do add 
> `extNonConstS` to the `externalDefMap.txt`. So, just did that.

I don't think it's necessary, I would rather see an on-the-fly generated 
`externalDefMap.txt` to enforce that this is supposed to work all the time, 
even if something changes in the `extdefmap` tool.
Forcefully putting entries into that map is sortof like introducing dead-code, 
I'm not on board with that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122529: [ASTMatchers] Output currently matching node on crash

2022-04-01 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 419690.
njames93 added a comment.

Use macro to reduce duplication


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122529

Files:
  clang/lib/ASTMatchers/ASTMatchFinder.cpp
  clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -39,10 +39,24 @@
 // FIXME: Figure out why back traces aren't being generated on clang builds on
 // windows.
 #if ENABLE_BACKTRACES && (!defined(_MSC_VER) || !defined(__clang__))
+
+AST_MATCHER(Decl, causeCrash) {
+  abort();
+  return true;
+}
+
+TEST(MatcherCrashDeathTest, CrashOnMatcherDump) {
+  llvm::EnablePrettyStackTrace();
+  auto Matcher = testing::HasSubstr(
+  "ASTMatcher: Matching '' against:\n\tFunctionDecl foo : "
+  "");
+  ASSERT_DEATH(matches("void foo();", functionDecl(causeCrash())), Matcher);
+}
+
 template 
 static void crashTestNodeDump(MatcherT Matcher,
   ArrayRef MatchedNodes,
-  StringRef Code) {
+  StringRef Against, StringRef Code) {
   llvm::EnablePrettyStackTrace();
   MatchFinder Finder;
 
@@ -58,7 +72,9 @@
 ASSERT_DEATH(tooling::runToolOnCode(
  newFrontendActionFactory(&Finder)->create(), Code),
  testing::HasSubstr(
- "ASTMatcher: Processing 'CrashTester'\nNo bound nodes"));
+ ("ASTMatcher: Processing 'CrashTester' against:\n\t" +
+  Against + "\nNo bound nodes")
+ .str()));
   } else {
 std::vector>>
@@ -69,7 +85,9 @@
 }
 auto CrashMatcher = testing::AllOf(
 testing::HasSubstr(
-"ASTMatcher: Processing 'CrashTester'\n--- Bound Nodes Begin ---"),
+("ASTMatcher: Processing 'CrashTester' against:\n\t" + Against +
+ "\n--- Bound Nodes Begin ---")
+.str()),
 testing::HasSubstr("--- Bound Nodes End ---"),
 testing::AllOfArray(Matchers));
 
@@ -79,7 +97,8 @@
   }
 }
 TEST(MatcherCrashDeathTest, CrashOnCallbackDump) {
-  crashTestNodeDump(forStmt(), {}, "void foo() { for(;;); }");
+  crashTestNodeDump(forStmt(), {}, "ForStmt : ",
+"void foo() { for(;;); }");
   crashTestNodeDump(
   forStmt(hasLoopInit(declStmt(hasSingleDecl(
varDecl(hasType(qualType().bind("QT")),
@@ -94,6 +113,7 @@
"IL - { IntegerLiteral :  }", "QT - { QualType : int }",
"T - { BuiltinType : int }",
"VD - { VarDecl I :  }"},
+  "ForStmt : ",
   R"cpp(
   void foo() {
 for (int I = 0; I < 5; ++I) {
@@ -106,12 +126,14 @@
   {"Unnamed - { CXXRecordDecl (anonymous) :  }",
"Op+ - { CXXMethodDecl (anonymous struct)::operator+ :  }"},
+  "CXXRecordDecl (anonymous) : ",
   "struct { int operator+(int) const; } Unnamed;");
   crashTestNodeDump(
   cxxRecordDecl(hasMethod(cxxConstructorDecl(isDefaulted()).bind("Ctor")),
 hasMethod(cxxDestructorDecl(isDefaulted()).bind("Dtor"))),
   {"Ctor - { CXXConstructorDecl Foo::Foo :  }",
"Dtor - { CXXDestructorDecl Foo::~Foo :  }"},
+  "CXXRecordDecl Foo : ",
   "struct Foo { Foo() = default; ~Foo() = default; };");
 }
 #endif // ENABLE_BACKTRACES
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -761,53 +761,189 @@
 D);
   }
 
+private:
+  bool TraversingASTNodeNotSpelledInSource = false;
+  bool TraversingASTNodeNotAsIs = false;
+  bool TraversingASTChildrenNotSpelledInSource = false;
+
+  class CurMatchData {
+// We don't have enough free low bits in 32bit builds to discriminate 8 pointer
+// types in PointerUnion. so split the union in 2 using a free bit from the
+// callback pointer.
+#define CMD_TYPES_0\
+  const QualType *, const TypeLoc *, const NestedNameSpecifier *,  \
+  const NestedNameSpecifierLoc *
+#define CMD_TYPES_1\
+  const CXXCtorInitializer *, const TemplateArgumentLoc *, const Attr *,   \
+  const DynTypedNode *
+
+#define IMPL(Index)\
+  template  \
+  typename std::enable_if_t<   \
+  llvm::is_one_of::value> \
+  SetCallbackAndRawNode(const MatchCallback *CB, const NodeType &N) {  \
+assertEmpty();

[PATCH] D122789: [compiler-rt] [scudo] Use -mcrc32 on x86 when available

2022-04-01 Thread Nikita Popov via Phabricator via cfe-commits
nikic accepted this revision.
nikic added a comment.
This revision is now accepted and ready to land.

Not familiar with this code, but the newest version does resolve the build 
failure with GCC, so I guess this is fine.


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

https://reviews.llvm.org/D122789

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


[PATCH] D122008: [flang][driver] Add support for generating executables

2022-04-01 Thread Mats Petersson via Phabricator via cfe-commits
Leporacanthicus accepted this revision.
Leporacanthicus added a comment.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122008

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

In D122805#3421802 , @steakhal wrote:

> In D122805#3421746 , @martong wrote:
>
>> In D122805#3421676 , @martong 
>> wrote:
>>
>>> In D122805#3420111 , @steakhal 
>>> wrote:
>>>
 In D122805#3419662 , @martong 
 wrote:

> In D122805#3419129 , @steakhal 
> wrote:
>
>> Please add a test case where the class is trivial but the global 
>> variable of such is non-const, thus the initialized expression is not 
>> imported.
>
> I've added a new case, but that is not very meaningful, because 
> `clang-extdef-mapping` is not capable of emitting the USR for the 
> non-const variable.

 What do you mean by //not capable//?
>>>
>>> It uses `cross_tu::shouldImport()` which returns true only for `const` 
>>> declarations. So, having a hand-written `extDevMapping.txt` that contains 
>>> an USR for a non-const is not that meaningful, IMHO.
>
> What I wanted to emphasize is that previously for all `const` globals it 
> returned `true`, unlike now when we only return `true` if it's `const` AND 
> //trivial//.
> This test case would demonstrate the behavioral change and would nicely 
> underpin the reason behind this patch.
>
> In D122805#3421746 , @martong wrote:
>
>> I changed my mind: we can test one side of the logic if we do add 
>> `extNonConstS` to the `externalDefMap.txt`. So, just did that.
>
> I don't think it's necessary, I would rather see an on-the-fly generated 
> `externalDefMap.txt` to enforce that this is supposed to work all the time, 
> even if something changes in the `extdefmap` tool.
> Forcefully putting entries into that map is sortof like introducing 
> dead-code, I'm not on board with that.

Currently **ALL** ctu tests are done with hand-written `externalDefMap.txt`s. I 
agree it would be nice to generate them on-the-fly, but that should be the 
subject of another change. And if we do that then we will not have 
`extNonConstS` in the extdef file for this test which makes it impossible to 
test what you request. Please be consistent with your review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

> even if something changes in the extdefmap tool

We already have a separate test file for that. That is `func-mapping-test.cpp`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 419702.
martong added a comment.

- Rebase to llvm/main


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
  clang/test/Analysis/ctu-main.cpp
  clang/test/Analysis/func-mapping-test.cpp
  clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Index: clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
===
--- clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -64,7 +64,7 @@
   if (const Stmt *Body = FD->getBody())
 addIfInMain(FD, Body->getBeginLoc());
   } else if (const auto *VD = dyn_cast(D)) {
-if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+if (cross_tu::shouldImport(VD, Ctx) && VD->hasInit())
   if (const Expr *Init = VD->getInit())
 addIfInMain(VD, Init->getBeginLoc());
   }
Index: clang/test/Analysis/func-mapping-test.cpp
===
--- clang/test/Analysis/func-mapping-test.cpp
+++ clang/test/Analysis/func-mapping-test.cpp
@@ -23,7 +23,7 @@
 struct SF {
   const int a;
 };
-SF sf = {.a = 2};
+extern const SF sf = {.a = 2};
 // CHECK-DAG: 5:c:@sf
 
 struct SStatic {
@@ -39,7 +39,7 @@
   const int a;
   const unsigned int b;
 };
-U u = {.a = 6};
+extern const U u = {.a = 6};
 // CHECK-DAG: 4:c:@u
 
 // No USR can be generated for this.
Index: clang/test/Analysis/ctu-main.cpp
===
--- clang/test/Analysis/ctu-main.cpp
+++ clang/test/Analysis/ctu-main.cpp
@@ -74,6 +74,13 @@
   int a;
 };
 extern const S extS;
+extern S extNonConstS;
+struct NonTrivialS {
+  int a;
+  // User declaring a dtor makes it non-trivial.
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS;
 extern const int extHere;
 const int extHere = 6;
 struct A {
@@ -82,9 +89,9 @@
 struct SC {
   const int a;
 };
-extern SC extSC;
+extern const SC extSC;
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
 struct SCNest {
   struct SCN {
@@ -92,7 +99,7 @@
   } scn;
 };
 extern SCNest extSCN;
-extern SCNest::SCN extSubSCN;
+extern const SCNest::SCN extSubSCN;
 struct SCC {
   SCC(int c);
   const int a;
@@ -102,7 +109,7 @@
   const int a;
   const unsigned int b;
 };
-extern U extU;
+extern const U extU;
 
 void test_virtual_functions(mycls* obj) {
   // The dynamic type is known.
@@ -153,6 +160,9 @@
   clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
   clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+  // Do not import non-trivial classes' initializers.
+  clang_analyzer_eval(extNTS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
   clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
   clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
Index: clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
===
--- clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
@@ -18,6 +18,8 @@
 9:c:@extInt ctu-other.cpp.ast
 17:c:@N@intns@extInt ctu-other.cpp.ast
 7:c:@extS ctu-other.cpp.ast
+15:c:@extNonConstS ctu-other.cpp.ast
+9:c:@extNTS ctu-other.cpp.ast
 8:c:@S@A@a ctu-other.cpp.ast
 8:c:@extSC ctu-other.cpp.ast
 10:c:@S@ST@sc ctu-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-other.cpp
===
--- clang/test/Analysis/Inputs/ctu-other.cpp
+++ clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@
   int a;
 };
 extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+  int a;
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
 struct A {
   static const int a;
 };
@@ -109,18 +115,18 @@
 struct SC {
   const int a;
 };
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};
 struct SCNest {
   struct SCN {
 const int a;
   } scn;
 };
 SCNest extSCN = {.scn = {.a = 9}};
-SCNest::SCN extSubSCN = {.a = 1};
+extern SCNest::SCN const extSubSCN = {.a = 1};
 struct SCC {
   SCC(int c) : a(c) {}
   const int a;
@@ -130,7 +136,7 @@
   con

[PATCH] D122478: [PowerPC] Add max/min intrinsics to Clang and PPC backend

2022-04-01 Thread Ting Wang via Phabricator via cfe-commits
tingwang updated this revision to Diff 419704.
tingwang added a comment.

Update based on comments:
(1) Reuse diag error message.
(2) Update clang test case for those diag messages.
(3) Add TODO comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122478

Files:
  clang/include/clang/Basic/BuiltinsPPC.def
  clang/lib/Basic/Targets/PPC.cpp
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/PowerPC/builtins-ppc.c
  clang/test/Sema/builtins-ppc.c
  llvm/include/llvm/IR/IntrinsicsPowerPC.td
  llvm/lib/Target/PowerPC/PPCISelLowering.cpp
  llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll

Index: llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-maxmin.ll
@@ -0,0 +1,257 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mcpu=pwr9 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
+; RUN:< %s | FileCheck --check-prefixes=CHECK,CHECK-P9 %s
+; RUN: llc -mcpu=pwr8 -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
+; RUN:< %s | FileCheck --check-prefixes=CHECK,CHECK-P8 %s
+
+declare ppc_fp128 @llvm.ppc.maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ...)
+define ppc_fp128 @test_maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) {
+; CHECK-LABEL: test_maxfe:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:fcmpu 0, 6, 4
+; CHECK-NEXT:fcmpu 1, 5, 3
+; CHECK-NEXT:crand 20, 6, 1
+; CHECK-NEXT:cror 20, 5, 20
+; CHECK-NEXT:bc 12, 20, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %entry
+; CHECK-NEXT:fmr 6, 4
+; CHECK-NEXT:  .LBB0_2: # %entry
+; CHECK-NEXT:fcmpu 0, 6, 2
+; CHECK-NEXT:bc 12, 20, .LBB0_4
+; CHECK-NEXT:  # %bb.3: # %entry
+; CHECK-NEXT:fmr 5, 3
+; CHECK-NEXT:  .LBB0_4: # %entry
+; CHECK-NEXT:fcmpu 1, 5, 1
+; CHECK-NEXT:crand 20, 6, 1
+; CHECK-NEXT:cror 20, 5, 20
+; CHECK-NEXT:bc 12, 20, .LBB0_6
+; CHECK-NEXT:  # %bb.5: # %entry
+; CHECK-NEXT:fmr 6, 2
+; CHECK-NEXT:  .LBB0_6: # %entry
+; CHECK-NEXT:fcmpu 0, 6, 8
+; CHECK-NEXT:bc 12, 20, .LBB0_8
+; CHECK-NEXT:  # %bb.7: # %entry
+; CHECK-NEXT:fmr 5, 1
+; CHECK-NEXT:  .LBB0_8: # %entry
+; CHECK-NEXT:fcmpu 1, 5, 7
+; CHECK-NEXT:crand 20, 6, 1
+; CHECK-NEXT:cror 20, 5, 20
+; CHECK-NEXT:bc 12, 20, .LBB0_10
+; CHECK-NEXT:  # %bb.9: # %entry
+; CHECK-NEXT:fmr 5, 7
+; CHECK-NEXT:  .LBB0_10: # %entry
+; CHECK-NEXT:bc 12, 20, .LBB0_12
+; CHECK-NEXT:  # %bb.11: # %entry
+; CHECK-NEXT:fmr 6, 8
+; CHECK-NEXT:  .LBB0_12: # %entry
+; CHECK-NEXT:fmr 1, 5
+; CHECK-NEXT:fmr 2, 6
+; CHECK-NEXT:blr
+entry:
+  %0 = call ppc_fp128 (ppc_fp128, ppc_fp128, ppc_fp128, ...) @llvm.ppc.maxfe(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d)
+  ret ppc_fp128 %0
+}
+
+declare double @llvm.ppc.maxfl(double %a, double %b, double %c, ...)
+define double @test_maxfl(double %a, double %b, double %c, double %d) {
+; CHECK-P9-LABEL: test_maxfl:
+; CHECK-P9:   # %bb.0: # %entry
+; CHECK-P9-NEXT:xsmaxcdp 0, 3, 2
+; CHECK-P9-NEXT:xsmaxcdp 0, 0, 1
+; CHECK-P9-NEXT:xsmaxcdp 1, 0, 4
+; CHECK-P9-NEXT:blr
+;
+; CHECK-P8-LABEL: test_maxfl:
+; CHECK-P8:   # %bb.0: # %entry
+; CHECK-P8-NEXT:xscmpudp 0, 3, 2
+; CHECK-P8-NEXT:ble 0, .LBB1_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:ble 0, .LBB1_5
+; CHECK-P8-NEXT:  .LBB1_2: # %entry
+; CHECK-P8-NEXT:xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:ble 0, .LBB1_6
+; CHECK-P8-NEXT:  .LBB1_3: # %entry
+; CHECK-P8-NEXT:fmr 1, 3
+; CHECK-P8-NEXT:blr
+; CHECK-P8-NEXT:  .LBB1_4: # %entry
+; CHECK-P8-NEXT:fmr 3, 2
+; CHECK-P8-NEXT:xscmpudp 0, 3, 1
+; CHECK-P8-NEXT:bgt 0, .LBB1_2
+; CHECK-P8-NEXT:  .LBB1_5: # %entry
+; CHECK-P8-NEXT:fmr 3, 1
+; CHECK-P8-NEXT:xscmpudp 0, 3, 4
+; CHECK-P8-NEXT:bgt 0, .LBB1_3
+; CHECK-P8-NEXT:  .LBB1_6: # %entry
+; CHECK-P8-NEXT:fmr 3, 4
+; CHECK-P8-NEXT:fmr 1, 3
+; CHECK-P8-NEXT:blr
+entry:
+  %0 = call double (double, double, double, ...) @llvm.ppc.maxfl(double %a, double %b, double %c, double %d)
+  ret double %0
+}
+
+declare float @llvm.ppc.maxfs(float %a, float %b, float %c, ...)
+define float @test_maxfs(float %a, float %b, float %c, float %d) {
+; CHECK-P9-LABEL: test_maxfs:
+; CHECK-P9:   # %bb.0: # %entry
+; CHECK-P9-NEXT:xsmaxcdp 0, 3, 2
+; CHECK-P9-NEXT:xsmaxcdp 0, 0, 1
+; CHECK-P9-NEXT:xsmaxcdp 1, 0, 4
+; CHECK-P9-NEXT:blr
+;
+; CHECK-P8-LABEL: test_maxfs:
+; CHECK-P8:   # %bb.0: # %entry
+; CHECK-P8-NEXT:fcmpu 0, 3, 2
+; CHECK-P8-NEXT:ble 0, .LBB2_4
+; CHECK-P8-NEXT:  # %bb.1: # %entry
+; CHECK-P8-NEXT:fcmpu 0, 3, 1
+; CHECK-P8-NEXT:ble 0, .LBB2_5
+; CHECK-P8-NEXT:  .LBB2_2: # %entry
+; CHECK-P8-NEXT:fcmpu 0, 3

[PATCH] D122478: [PowerPC] Add max/min intrinsics to Clang and PPC backend

2022-04-01 Thread Ting Wang via Phabricator via cfe-commits
tingwang marked an inline comment as done.
tingwang added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:9897
+def err_ppc_unsupported_argument_type : Error<
+  "unsupported argument type %0 for target %1">;
 def err_x86_builtin_invalid_rounding : Error<

qiucf wrote:
> Use `err_target_unsupported_type`?
Thanks again for pointing it out!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122478

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


[PATCH] D121097: [C++20][Modules][HU 3/5] Emit module macros for header units.

2022-04-01 Thread Harald van Dijk via Phabricator via cfe-commits
hvdijk added inline comments.



Comment at: clang/test/Modules/cxx20-hu-04.cpp:22
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface importer-01.cpp \
+// RUN:  -fmodule-file=hu-02.pcm -o B.pcm -DTDIR=%t -verify
+

On Windows, when the path starts with `C:\Users\...`, I am seeing
```
error: 'warning' diagnostics seen but not expected: 

  Line 1: \U used with no following hex digits; treating as '\' followed by 
identifier

1 error generated.
```
Looking at this test, `TDIR` is only used as a FileCheck variable, can it just 
be removed from this line?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121097

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


[PATCH] D122789: [compiler-rt] [scudo] Use -mcrc32 on x86 when available

2022-04-01 Thread Michał Górny via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfd1da784ac64: [compiler-rt] [scudo] Use -mcrc32 on x86 when 
available (authored by mgorny).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122789

Files:
  compiler-rt/cmake/config-ix.cmake
  compiler-rt/lib/scudo/CMakeLists.txt
  compiler-rt/lib/scudo/scudo_allocator.cpp
  compiler-rt/lib/scudo/scudo_crc32.cpp
  compiler-rt/lib/scudo/scudo_crc32.h
  compiler-rt/lib/scudo/standalone/CMakeLists.txt
  compiler-rt/lib/scudo/standalone/checksum.h
  compiler-rt/lib/scudo/standalone/chunk.h
  compiler-rt/lib/scudo/standalone/crc32_hw.cpp

Index: compiler-rt/lib/scudo/standalone/crc32_hw.cpp
===
--- compiler-rt/lib/scudo/standalone/crc32_hw.cpp
+++ compiler-rt/lib/scudo/standalone/crc32_hw.cpp
@@ -10,10 +10,10 @@
 
 namespace scudo {
 
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 u32 computeHardwareCRC32(u32 Crc, uptr Data) {
   return static_cast(CRC32_INTRINSIC(Crc, Data));
 }
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 
 } // namespace scudo
Index: compiler-rt/lib/scudo/standalone/chunk.h
===
--- compiler-rt/lib/scudo/standalone/chunk.h
+++ compiler-rt/lib/scudo/standalone/chunk.h
@@ -25,7 +25,7 @@
   // as opposed to only for crc32_hw.cpp. This means that other hardware
   // specific instructions were likely emitted at other places, and as a result
   // there is no reason to not use it here.
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
   u32 Crc = static_cast(CRC32_INTRINSIC(Seed, Value));
   for (uptr I = 0; I < ArraySize; I++)
 Crc = static_cast(CRC32_INTRINSIC(Crc, Array[I]));
@@ -42,7 +42,7 @@
   Checksum = computeBSDChecksum(Checksum, Array[I]);
 return Checksum;
   }
-#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
 }
 
 namespace Chunk {
Index: compiler-rt/lib/scudo/standalone/checksum.h
===
--- compiler-rt/lib/scudo/standalone/checksum.h
+++ compiler-rt/lib/scudo/standalone/checksum.h
@@ -12,12 +12,16 @@
 #include "internal_defs.h"
 
 // Hardware CRC32 is supported at compilation via the following:
-// - for i386 & x86_64: -msse4.2
+// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
 // - for ARM & AArch64: -march=armv8-a+crc or -mcrc
 // An additional check must be performed at runtime as well to make sure the
 // emitted instructions are valid on the target host.
 
-#ifdef __SSE4_2__
+#if defined(__CRC32__)
+// NB: clang has  but GCC does not
+#include 
+#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di)
+#elif defined(__SSE4_2__)
 #include 
 #define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
 #endif
Index: compiler-rt/lib/scudo/standalone/CMakeLists.txt
===
--- compiler-rt/lib/scudo/standalone/CMakeLists.txt
+++ compiler-rt/lib/scudo/standalone/CMakeLists.txt
@@ -97,8 +97,11 @@
   string_utils.cpp
   )
 
-# Enable the SSE 4.2 instruction set for crc32_hw.cpp, if available.
-if (COMPILER_RT_HAS_MSSE4_2_FLAG)
+# Enable the necessary instruction set for scudo_crc32.cpp, if available.
+# Newer compiler versions use -mcrc32 rather than -msse4.2.
+if (COMPILER_RT_HAS_MCRC32_FLAG)
+  set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -mcrc32)
+elseif (COMPILER_RT_HAS_MSSE4_2_FLAG)
   set_source_files_properties(crc32_hw.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
 endif()
 
Index: compiler-rt/lib/scudo/scudo_crc32.h
===
--- compiler-rt/lib/scudo/scudo_crc32.h
+++ compiler-rt/lib/scudo/scudo_crc32.h
@@ -16,13 +16,17 @@
 #include "sanitizer_common/sanitizer_internal_defs.h"
 
 // Hardware CRC32 is supported at compilation via the following:
-// - for i386 & x86_64: -msse4.2
+// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2)
 // - for ARM & AArch64: -march=armv8-a+crc or -mcrc
 // An additional check must be performed at runtime as well to make sure the
 // emitted instructions are valid on the target host.
 
-#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
-# ifdef __SSE4_2__
+#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
+# if defined(__CRC32__)
+// NB: clang has  but GCC does not
+#  include 
+#  define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_

[PATCH] D122885: [clang] Draft: Implement P1703R1

2022-04-01 Thread Nathan Sidwell via Phabricator via cfe-commits
urnathan added a comment.

I can;t really tell what you're doing.  C++20 lexes import (&module) 
declarations as preprocessor directives.  the parser must also recognize only 
such declarations that came through from lexing such directives.  It is 
unrelated to #import.  GCC's implementation drops the preprocessor into 
directive mode if it sees 'module' or 'import' (optionally preceeded by 
'export') at the start of a line[1].  Those keywords are converted to 
unspellable internal tokens that the parser recognizes to parse module and 
import declarations.  An end-of-pragma token is injected at the end-of-line, 
and again the parser expects that after the terminating ';'. (it's leveraging 
the pragma machinery)

[1] it also peeks the next non-white-space token for '<', '", or 
, as specified in the std.

occurrences of 'module' and 'import' that are not lexed that way go through as 
regular identifier tokens, not keywords.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122885

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


[PATCH] D122768: [WIP][Clang] Support capturing structured bindings in lambdas

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419710.
cor3ntin added a comment.

Fix typo in test, fix captureInLambda (was crashing in release and not debug)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+  int i : 1;
+  int j;
+};
+
+void run(void (^)());
+void test() {
+  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  run(^{
+(void)i;  // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+  });
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+auto [v, r] = S{1, a};
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+S s{1, a};
+const auto &[v, r] = s;
+(void)[&v, &r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+}
Index: clang/test/SemaCXX/cxx1z-decomposition.cpp
===
--- clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++17 -verify %s
+// RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s
+// RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s
 
 void use_from_own_init() {
   auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}

[PATCH] D121097: [C++20][Modules][HU 3/5] Emit module macros for header units.

2022-04-01 Thread Iain Sandoe via Phabricator via cfe-commits
iains added inline comments.



Comment at: clang/test/Modules/cxx20-hu-04.cpp:22
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface importer-01.cpp \
+// RUN:  -fmodule-file=hu-02.pcm -o B.pcm -DTDIR=%t -verify
+

hvdijk wrote:
> On Windows, when the path starts with `C:\Users\...`, I am seeing
> ```
> error: 'warning' diagnostics seen but not expected: 
> 
>   Line 1: \U used with no following hex digits; treating as '\' followed by 
> identifier
> 
> 1 error generated.
> ```
> Looking at this test, `TDIR` is only used as a FileCheck variable, can it 
> just be removed from this line?
Sorry about that,  Yes, I think that change should be fine - I will take care 
of it,


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121097

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


[PATCH] D122885: [clang] Draft: Implement P1703R1

2022-04-01 Thread Nathan Sidwell via Phabricator via cfe-commits
urnathan added a comment.

oh, also in 'import "bob";', "bob" needs to be lexed as a #include name, not a 
string.  (and likewise 'import ;')  Hence treating these lines in the 
preprocessor in directive-processing-mode was the way GCC went.




Comment at: clang/test/Modules/P1703R1.cpp:49-50
+"header.h"; // expected-error {{expected a module name after 'import'}}
+export
+import "header.h"; // expected-error {{expected a module name after 'import'}}
+

This confuses me.  That's a stray 'export' token, followed by a well-formed 
import-directive



Comment at: clang/test/Modules/P1703R1.cpp:52
+
+import "header.h"; import "header.h"; // expected-error {{import keyword must 
be at start of line}}
+  // expected-error@-1 {{extra tokens 
after module import}}

that second 'import' is not a token, it's an identifier.  This is an ill-formed 
import-directive with unexpected tokens afte the first ';'  You seem to be 
dropping into lex-import-mode not at the start of a line?



Comment at: clang/test/Modules/P1703R1.cpp:72
+
+/// Normal module imports are unaffected
+import dummy;

what is meant by 'normal'?  many of these look ill-formed to me.



Comment at: clang/test/Modules/P1703R1.cpp:87
+
+// TODO: The diagnostics here could be much better.
+export

yup :)  gcc tries to tell the user about the single logical-line requirement:
   inform (token->location, "perhaps insert a line break, or other"
  " disambiguation, to prevent this being considered a"
  " module control-line");
the expectation here is that this was pre c++20 code that fell into this lexing 
trap.  Specifically things like:

template class module {...};

module x;


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122885

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


[PATCH] D122838: [clang][dataflow] Add support for correlation of boolean (tracked) values

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel added inline comments.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:79
+for (BoolValue *Constraint : Env1.getFlowConditionConstraints()) {
+  Expr1 = &Env1.makeAnd(*Expr1, *Constraint);
+}

sgatev wrote:
> xazax.hun wrote:
> > Hmm, interesting.
> > I think we view every boolean formula at a certain program point implicitly 
> > as `FlowConditionAtThatPoint && Formula`. And the flow condition at a 
> > program point should already be a disjunction of its predecessors.
> > 
> > So it would be interpreted as: `(FlowConditionPred1 || FlowConditionPred2) 
> > && (FormulaAtPred1 || FormulaAtPred2)`.
> > While this is great, this is not the strongest condition we could derive. 
> > `(FlowConditionPred1 && FormulaAtPred1)  || (FormulaAtPred2 && 
> > FlowConditionPred2)` created by this code snippet is stronger which is 
> > great.
> > 
> > My main concern is whether we would end up seeing an exponential explosion 
> > in the size of these formulas in the number of branches following each 
> > other in a sequence.
> > 
> Yeap, I agree this is suboptimal and I believe I'm the one to blame for 
> introducing it downstream.
> 
> I wonder if we can represent the flow condition of each environment using a 
> bool atom and have a mapping of bi-conditionals between flow condition atoms 
> and flow condition constraints. Something like:
> 
> ```
> FC1 <=> C1 ^ C2
> FC2 <=> C2 ^ C3 ^ C4
> FC3 <=> (FC1 v FC2) ^ C5
> ... 
> ```
> 
> We can use that to simplify the formulas here and in `joinConstraints`. The 
> mapping can be stored in `DataflowAnalysisContext`. We can track dependencies 
> between flow conditions (e.g. above `FC3` depends on `FC1` and `FC2`) and 
> modify `flowConditionImplies` to construct a formula that includes the 
> bi-conditionals for all flow condition atoms in the transitive set before 
> invoking the solver.
> 
> I suggest putting the optimization in its own patch. I'd love to look into it 
> right after this patch is submitted if both of you think it makes sense on a 
> high level.
This sounds good to me. That said, I'm not sure how often we'd expect this to 
be an issue in practice, since, IIUC, this specialized merge only occurs when 
the value is handled differently in the two branches. So, a series of branches 
alone won't trigger the exponential behavior.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122838

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


[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman requested changes to this revision.
aaron.ballman added a comment.
This revision now requires changes to proceed.

I'm confused -- the issue you linked is for a bug with clang-format but the 
changes in your patch don't modify clang-format, just modifies a test file to 
be formatted. I don't see how the two relate, but this doesn't seem to be 
addressing the issue you linked.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 419717.
martong added a comment.

- remove extNonConstS from the externalDefMap.txt


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
  clang/test/Analysis/ctu-main.cpp
  clang/test/Analysis/func-mapping-test.cpp
  clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Index: clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
===
--- clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -64,7 +64,7 @@
   if (const Stmt *Body = FD->getBody())
 addIfInMain(FD, Body->getBeginLoc());
   } else if (const auto *VD = dyn_cast(D)) {
-if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+if (cross_tu::shouldImport(VD, Ctx) && VD->hasInit())
   if (const Expr *Init = VD->getInit())
 addIfInMain(VD, Init->getBeginLoc());
   }
Index: clang/test/Analysis/func-mapping-test.cpp
===
--- clang/test/Analysis/func-mapping-test.cpp
+++ clang/test/Analysis/func-mapping-test.cpp
@@ -23,7 +23,7 @@
 struct SF {
   const int a;
 };
-SF sf = {.a = 2};
+extern const SF sf = {.a = 2};
 // CHECK-DAG: 5:c:@sf
 
 struct SStatic {
@@ -39,7 +39,7 @@
   const int a;
   const unsigned int b;
 };
-U u = {.a = 6};
+extern const U u = {.a = 6};
 // CHECK-DAG: 4:c:@u
 
 // No USR can be generated for this.
Index: clang/test/Analysis/ctu-main.cpp
===
--- clang/test/Analysis/ctu-main.cpp
+++ clang/test/Analysis/ctu-main.cpp
@@ -74,6 +74,13 @@
   int a;
 };
 extern const S extS;
+extern S extNonConstS;
+struct NonTrivialS {
+  int a;
+  // User declaring a dtor makes it non-trivial.
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS;
 extern const int extHere;
 const int extHere = 6;
 struct A {
@@ -82,9 +89,9 @@
 struct SC {
   const int a;
 };
-extern SC extSC;
+extern const SC extSC;
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
 struct SCNest {
   struct SCN {
@@ -92,7 +99,7 @@
   } scn;
 };
 extern SCNest extSCN;
-extern SCNest::SCN extSubSCN;
+extern const SCNest::SCN extSubSCN;
 struct SCC {
   SCC(int c);
   const int a;
@@ -102,7 +109,7 @@
   const int a;
   const unsigned int b;
 };
-extern U extU;
+extern const U extU;
 
 void test_virtual_functions(mycls* obj) {
   // The dynamic type is known.
@@ -153,6 +160,9 @@
   clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
   clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+  // Do not import non-trivial classes' initializers.
+  clang_analyzer_eval(extNTS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
   clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
   clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
Index: clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
===
--- clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
@@ -18,6 +18,7 @@
 9:c:@extInt ctu-other.cpp.ast
 17:c:@N@intns@extInt ctu-other.cpp.ast
 7:c:@extS ctu-other.cpp.ast
+9:c:@extNTS ctu-other.cpp.ast
 8:c:@S@A@a ctu-other.cpp.ast
 8:c:@extSC ctu-other.cpp.ast
 10:c:@S@ST@sc ctu-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-other.cpp
===
--- clang/test/Analysis/Inputs/ctu-other.cpp
+++ clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@
   int a;
 };
 extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+  int a;
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
 struct A {
   static const int a;
 };
@@ -109,18 +115,18 @@
 struct SC {
   const int a;
 };
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};
 struct SCNest {
   struct SCN {
 const int a;
   } scn;
 };
 SCNest extSCN = {.scn = {.a = 9}};
-SCNest::SCN extSubSCN = {.a = 1};
+extern SCNest::SCN const extSubSCN = {.a = 1};
 struct SCC {
   SCC(int c) : a(c) {}
   const int a;
@@ -130,7 +136,7 @@
   const int a;

[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Priyansh Singh via Phabricator via cfe-commits
ps-19 added a comment.

okay now i understand the issue completely.
If i just mentioned that i am formatting a test file it would be correct then 
according to my patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Balázs Benics via Phabricator via cfe-commits
steakhal accepted this revision.
steakhal added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

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


[PATCH] D122894: [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet created this revision.
kadircet added a reviewer: adamcz.
Herald added subscribers: usaxena95, arphaman, javed.absar.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122894

Files:
  clang-tools-extra/clangd/TUScheduler.cpp


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
 PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, "first_build");
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
 PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, "first_build");
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e63b81d - [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via cfe-commits

Author: Gabor Marton
Date: 2022-04-01T13:49:39+02:00
New Revision: e63b81d10e023b4d8e9f61ca29a678c74ce2c1cb

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

LOG: [analyzer][ctu] Only import const and trivial VarDecls

Do import the definition of objects from a foreign translation unit if that's 
type is const and trivial.

Differential Revision: https://reviews.llvm.org/D122805

Added: 


Modified: 
clang/include/clang/CrossTU/CrossTranslationUnit.h
clang/lib/CrossTU/CrossTranslationUnit.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
clang/test/Analysis/Inputs/ctu-other.cpp
clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
clang/test/Analysis/ctu-main.cpp
clang/test/Analysis/func-mapping-test.cpp
clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Removed: 




diff  --git a/clang/include/clang/CrossTU/CrossTranslationUnit.h 
b/clang/include/clang/CrossTU/CrossTranslationUnit.h
index a09826f93afc0..a41c32d4068b2 100644
--- a/clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -109,8 +109,10 @@ llvm::Expected parseInvocationList(
 StringRef FileContent,
 llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix);
 
-// Returns true if the variable or any field of a record variable is const.
-bool containsConst(const VarDecl *VD, const ASTContext &ACtx);
+/// Returns true if it makes sense to import a foreign variable definition.
+/// For instance, we don't want to import variables that have non-trivial types
+/// because the constructor might have side-effects.
+bool shouldImport(const VarDecl *VD, const ASTContext &ACtx);
 
 /// This class is used for tools that requires cross translation
 ///unit capability.

diff  --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp 
b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index cbe07acb76fb1..ee6cc60f31e1d 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -220,14 +220,9 @@ createCrossTUIndexString(const 
llvm::StringMap &Index) {
   return Result.str();
 }
 
-bool containsConst(const VarDecl *VD, const ASTContext &ACtx) {
+bool shouldImport(const VarDecl *VD, const ASTContext &ACtx) {
   CanQualType CT = ACtx.getCanonicalType(VD->getType());
-  if (!CT.isConstQualified()) {
-const RecordType *RTy = CT->getAs();
-if (!RTy || !RTy->hasConstFields())
-  return false;
-  }
-  return true;
+  return CT.isConstQualified() && VD->getType().isTrivialType(ACtx);
 }
 
 static bool hasBodyOrInit(const FunctionDecl *D, const FunctionDecl *&DefD) {

diff  --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp 
b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 9e96e00011f4f..fcc73b3767d4b 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -289,7 +289,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
   return true;
 
 if (VD->hasExternalStorage() || VD->isStaticDataMember()) {
-  if (!cross_tu::containsConst(VD, *Ctx))
+  if (!cross_tu::shouldImport(VD, *Ctx))
 return true;
 } else {
   // Cannot be initialized in another TU.

diff  --git a/clang/test/Analysis/Inputs/ctu-other.cpp 
b/clang/test/Analysis/Inputs/ctu-other.cpp
index ff37947d5b7e9..a7bf1cef65b92 100644
--- a/clang/test/Analysis/Inputs/ctu-other.cpp
+++ b/clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@ struct S {
   int a;
 };
 extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+  int a;
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
 struct A {
   static const int a;
 };
@@ -109,18 +115,18 @@ const int A::a = 3;
 struct SC {
   const int a;
 };
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};
 struct SCNest {
   struct SCN {
 const int a;
   } scn;
 };
 SCNest extSCN = {.scn = {.a = 9}};
-SCNest::SCN extSubSCN = {.a = 1};
+extern SCNest::SCN const extSubSCN = {.a = 1};
 struct SCC {
   SCC(int c) : a(c) {}
   const int a;
@@ -130,7 +136,7 @@ union U {
   const int a;
   const unsigned int b;
 };
-U extU = {.a = 4};
+extern const U extU = {.a = 4};
 
 class TestAnonUnionUSR {
 public:

diff  --git 
a/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt 
b/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
index 476b8f1867042..439232333b609 100644
--- a/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ b/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dum

[PATCH] D122805: [analyzer][ctu] Only import const and trivial VarDecls

2022-04-01 Thread Gabor Marton via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe63b81d10e02: [analyzer][ctu] Only import const and trivial 
VarDecls (authored by martong).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122805

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp
  clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
  clang/test/Analysis/ctu-main.cpp
  clang/test/Analysis/func-mapping-test.cpp
  clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp

Index: clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
===
--- clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -64,7 +64,7 @@
   if (const Stmt *Body = FD->getBody())
 addIfInMain(FD, Body->getBeginLoc());
   } else if (const auto *VD = dyn_cast(D)) {
-if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+if (cross_tu::shouldImport(VD, Ctx) && VD->hasInit())
   if (const Expr *Init = VD->getInit())
 addIfInMain(VD, Init->getBeginLoc());
   }
Index: clang/test/Analysis/func-mapping-test.cpp
===
--- clang/test/Analysis/func-mapping-test.cpp
+++ clang/test/Analysis/func-mapping-test.cpp
@@ -23,7 +23,7 @@
 struct SF {
   const int a;
 };
-SF sf = {.a = 2};
+extern const SF sf = {.a = 2};
 // CHECK-DAG: 5:c:@sf
 
 struct SStatic {
@@ -39,7 +39,7 @@
   const int a;
   const unsigned int b;
 };
-U u = {.a = 6};
+extern const U u = {.a = 6};
 // CHECK-DAG: 4:c:@u
 
 // No USR can be generated for this.
Index: clang/test/Analysis/ctu-main.cpp
===
--- clang/test/Analysis/ctu-main.cpp
+++ clang/test/Analysis/ctu-main.cpp
@@ -74,6 +74,13 @@
   int a;
 };
 extern const S extS;
+extern S extNonConstS;
+struct NonTrivialS {
+  int a;
+  // User declaring a dtor makes it non-trivial.
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS;
 extern const int extHere;
 const int extHere = 6;
 struct A {
@@ -82,9 +89,9 @@
 struct SC {
   const int a;
 };
-extern SC extSC;
+extern const SC extSC;
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
 struct SCNest {
   struct SCN {
@@ -92,7 +99,7 @@
   } scn;
 };
 extern SCNest extSCN;
-extern SCNest::SCN extSubSCN;
+extern const SCNest::SCN extSubSCN;
 struct SCC {
   SCC(int c);
   const int a;
@@ -102,7 +109,7 @@
   const int a;
   const unsigned int b;
 };
-extern U extU;
+extern const U extU;
 
 void test_virtual_functions(mycls* obj) {
   // The dynamic type is known.
@@ -153,6 +160,9 @@
   clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
   clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+  clang_analyzer_eval(extNonConstS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+  // Do not import non-trivial classes' initializers.
+  clang_analyzer_eval(extNTS.a == 4); // expected-warning{{TRUE}} expected-warning{{FALSE}}
   clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
   clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
   clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
Index: clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
===
--- clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
+++ clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
@@ -18,6 +18,7 @@
 9:c:@extInt ctu-other.cpp.ast
 17:c:@N@intns@extInt ctu-other.cpp.ast
 7:c:@extS ctu-other.cpp.ast
+9:c:@extNTS ctu-other.cpp.ast
 8:c:@S@A@a ctu-other.cpp.ast
 8:c:@extSC ctu-other.cpp.ast
 10:c:@S@ST@sc ctu-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-other.cpp
===
--- clang/test/Analysis/Inputs/ctu-other.cpp
+++ clang/test/Analysis/Inputs/ctu-other.cpp
@@ -102,6 +102,12 @@
   int a;
 };
 extern const S extS = {.a = 4};
+extern S extNonConstS = {.a = 4};
+struct NonTrivialS {
+  int a;
+  ~NonTrivialS();
+};
+extern const NonTrivialS extNTS = {.a = 4};
 struct A {
   static const int a;
 };
@@ -109,18 +115,18 @@
 struct SC {
   const int a;
 };
-SC extSC = {.a = 8};
+extern const SC extSC = {.a = 8};
 struct ST {
-  static struct SC sc;
+  static const struct SC sc;
 };
-struct SC ST::sc = {.a = 2};
+const struct SC ST::sc = {.a = 2};
 struct SCNest {
   struct SCN {
 const int a;
   } scn;
 };
 SCNest extSCN = {.scn = {.a = 9}};
-SCNest::SCN extSubSCN = {.a = 1};
+extern SCNest::SCN

[PATCH] D122894: [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added a comment.

Thanks, I was just about to fix that!




Comment at: clang-tools-extra/clangd/TUScheduler.cpp:115
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
 PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");

You're not using Label anywhere. Replace first_build below with Label.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122894

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


[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D122871#3422061 , @ps-19 wrote:

> okay now i understand the issue completely.
> If i just mentioned that i am formatting a test file it would be correct then 
> according to my patch.

We don't typically reformat whole files for no reason (it adds churn to the 
code base which makes things like `git blame` harder to use). We will accept a 
reformat like this when there's going to be immediate follow-up work in the 
file where having it properly formatted will make the second code review easier 
to understand, but that doesn't sound like the case here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Jun Zhang via Phabricator via cfe-commits
junaire added a comment.

You are not supposed to format the test, because the comment is actually 
something we called regression tests. If you reformat it (put it in the wrong 
place), the test will fail.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D121375: [clang] NFC, move the utility function CompilerInvocation::setLangDefaults to LangOptions.h

2022-04-01 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

in case you missed that, friendly ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121375

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


[PATCH] D122677: [prototype] include-cleaner library

2022-04-01 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 419723.
sammccall added a comment.
Herald added a project: clang.

Add "hints", used for ranking candidates for suggestions.

Not totally happy with this design:

- its intrusive to a bunch of the types
- computing/sorting these eagerly seems wasteful when they're rarely needed

However it is nice to be able to share the code easily.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122677

Files:
  clang-tools-extra/CMakeLists.txt
  clang-tools-extra/clang-tidy/misc/CMakeLists.txt
  clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
  clang-tools-extra/clang-tidy/misc/UnusedIncludesCheck.cpp
  clang-tools-extra/clang-tidy/misc/UnusedIncludesCheck.h
  clang-tools-extra/clangd/CMakeLists.txt
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/IncludeCleaner.h
  clang-tools-extra/include-cleaner/CMakeLists.txt
  clang-tools-extra/include-cleaner/README.md
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Hooks.h
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Policy.h
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/lib/AnalysisInternal.h
  clang-tools-extra/include-cleaner/lib/CMakeLists.txt
  clang-tools-extra/include-cleaner/lib/Headers.cpp
  clang-tools-extra/include-cleaner/lib/Hooks.cpp
  clang-tools-extra/include-cleaner/lib/Locations.cpp
  clang-tools-extra/include-cleaner/lib/Types.cpp
  clang-tools-extra/include-cleaner/lib/WalkAST.cpp
  clang-tools-extra/include-cleaner/tool/CMakeLists.txt
  clang-tools-extra/include-cleaner/tool/ClangIncludeCleaner.cpp
  clang/include/clang/Tooling/Inclusions/StandardLibrary.h

Index: clang/include/clang/Tooling/Inclusions/StandardLibrary.h
===
--- clang/include/clang/Tooling/Inclusions/StandardLibrary.h
+++ clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -49,6 +49,9 @@
   friend bool operator==(const Header &L, const Header &R) {
 return L.ID == R.ID;
   }
+  friend bool operator<(const Header &L, const Header &R) {
+return L.ID <= R.ID;
+  }
 };
 
 // A top-level standard library symbol, such as std::vector
Index: clang-tools-extra/include-cleaner/tool/ClangIncludeCleaner.cpp
===
--- /dev/null
+++ clang-tools-extra/include-cleaner/tool/ClangIncludeCleaner.cpp
@@ -0,0 +1,187 @@
+//===--- ClangIncludeCleaner.cpp - Standalone used-header analysis ===//
+//
+// 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
+//
+//===--===//
+//
+// clang-include-cleaner finds violations of include-what-you-use policy.
+//
+// It scans a file, finding referenced symbols and headers providing them.
+//   - if a reference is satisfied only by indirect #include dependencies,
+// this violates the policy and direct #includes are suggested.
+//   - if some #include directive doesn't satisfy any references, this violates
+// the policy (don't include what you don't use!) and removal is suggested.
+//
+// With the -satisfied flag, it will also explain things that were OK:
+// satisfied references and used #includes.
+//
+// This tool doesn't fix broken code where missing #includes prevent parsing,
+// try clang-include-fixer for this instead.
+//
+//===--===//
+
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Hooks.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InitLLVM.h"
+
+llvm::cl::OptionCategory OptionsCat{"clang-include-cleaner"};
+llvm::cl::opt ShowSatisfied{
+"satisfied",
+llvm::cl::cat(OptionsCat),
+llvm::cl::desc(
+"Show references whose header is included, and used includes"),
+llvm::cl::init(false),
+};
+llvm::cl::opt Recover{
+"recover",
+llvm::cl::cat(OptionsCat),
+llvm::cl::desc("Suppress further errors for the same header"),
+llvm::cl::init(true),
+};
+
+namespace clang {
+namespace include_cleaner {
+namespace {
+
+class Action : public clang::ASTFrontendAction {
+public:
+  bool BeginSourceFileAction(CompilerInstance &CI) override {
+Diag = &CI.getDiagnostics();
+ID.emplace(Diag);
+Ctx.emplace(Policy{}, CI.getPreprocess

[PATCH] D122895: [C89/C2x] Improve diagnostics around strict prototypes in C

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman created this revision.
aaron.ballman added reviewers: jyknight, eli.friedman, hubert.reinterpretcast, 
erichkeane, clang-language-wg.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
aaron.ballman requested review of this revision.
Herald added a project: clang.

Functions without prototypes in C (also known as K&R C functions) were 
introduced into C89 as a deprecated feature and C2x is now reclaiming that 
syntax space with different semantics. However, Clang's `-Wstrict-prototypes` 
diagnostic is off-by-default (even in pedantic mode) and does not suffice to 
warn users about issues in their code.

This patch changes the behavior of `-Wstrict-prototypes` to only diagnose 
declarations and definitions which are not going to change behavior in C2x 
mode, and enables the diagnostic in `-pedantic` mode. The diagnostic is now 
specifically about the fact that the feature is deprecated.

It also adds `-Wdeprecated-non-prototype`, which is grouped under 
`-Wstrict-prototypes` and diagnoses declarations or definitions which will 
change behavior in C2x mode. This diagnostic is enabled by default because the 
risk is higher for the user to continue to use the deprecated feature.

A few things to note:

- The RFC for this can be found at: 
https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c
- There is some awkward overlap between the diagnostics, but the best time to 
diagnose a function type without a prototype is when forming the function type, 
but we don't know whether the behavior will change in C2x at that point. So we 
alter the behavior sometimes depending on whether `-Wstrict-prototypes` is 
enabled in an effort to keep the diagnostics understandable and not too chatty.
- There will be another patch for handling call site behavior as a follow-up.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122895

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/2009-06-01-addrofknr.c
  clang/test/FixIt/fixit.c
  clang/test/Parser/declarators.c
  clang/test/Parser/knr_parameter_attributes.c
  clang/test/Parser/opencl-kernel.cl
  clang/test/Parser/traditional_arg_scope.c
  clang/test/Sema/arg-duplicate.c
  clang/test/Sema/block-return.c
  clang/test/Sema/implicit-decl.c
  clang/test/Sema/knr-def-call.c
  clang/test/Sema/knr-variadic-def.c
  clang/test/Sema/vfprintf-valid-redecl.c
  clang/test/Sema/warn-deprecated-non-prototype.c
  clang/test/Sema/warn-missing-prototypes.c
  clang/test/Sema/warn-strict-prototypes.c
  clang/test/Sema/warn-strict-prototypes.m
  clang/test/SemaOpenCL/address-spaces.cl
  clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
  clang/test/SemaOpenCL/func.cl

Index: clang/test/SemaOpenCL/func.cl
===
--- clang/test/SemaOpenCL/func.cl
+++ clang/test/SemaOpenCL/func.cl
@@ -43,9 +43,9 @@
 #endif
 
 // Expect no diagnostics for an empty parameter list.
-void bar();
+void bar(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 
-void bar()
+void bar() // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 {
   // declaring a function pointer is an error
   void (*fptr)(int);
Index: clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
===
--- clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
+++ clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
@@ -11,7 +11,7 @@
 
 typedef struct {int a;} ndrange_t;
 // Diagnostic tests for different overloads of enqueue_kernel from Table 6.13.17.1 of OpenCL 2.0 Spec.
-kernel void enqueue_kernel_tests() {
+kernel void enqueue_kernel_tests(void) {
   queue_t default_queue;
   unsigned flags = 0;
   QUALS ndrange_t ndrange;
@@ -169,7 +169,7 @@
 }
 
 // Diagnostic tests for get_kernel_work_group_size and allowed block parameter types in dynamic parallelism.
-kernel void work_group_size_tests() {
+kernel void work_group_size_tests(void) {
   void (^const block_A)(void) = ^{
 return;
   };
@@ -223,16 +223,22 @@
 kernel void foo(global unsigned int *buf)
 {
   ndrange_t n;
-  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){});
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
+  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected 'ndrange_t' argument type}}
+// expected-warning@-1 {{a

[PATCH] D122852: [OPENMP] Fix assertion in clang::ASTContext::getTypeInfoImpl

2022-04-01 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev added inline comments.



Comment at: clang/lib/CodeGen/CGOpenMPRuntime.cpp:8072-8088
+  QualType CanonType =
+  I->getAssociatedExpression()->getType().getCanonicalType();
+  if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
+const auto *OASE = cast(
+I->getAssociatedExpression()->IgnoreParenImpCasts());
+QualType BaseType =
+   OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());

Why not something like:
```
llvm::Value *TypeSize = CGF.getTypeSize(CanonType);
llvm::Value *Idx = CGF.Builder.CreateSub(TypeSize, 1);
Address HB = CGF.Builder.CreateGEP(
  CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
  LowestElem, CGF.VoidPtrTy, CGF.Int8Ty),
 Idx);
```


Repository:
  rC Clang

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

https://reviews.llvm.org/D122852

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


[PATCH] D114235: [clang] Extend ParsedAttr to allow custom handling for type attributes

2022-04-01 Thread Martin Böhme via Phabricator via cfe-commits
mboehme added a comment.

As mentioned in my previous comment, here is the RFC proposing a new 
`annotate_type` attribute:

https://discourse.llvm.org/t/rfc-new-attribute-annotate-type-iteration-2/61378


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114235

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


[PATCH] D122529: [ASTMatchers] Output currently matching node on crash

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

This looks good? to me. :-)

Despite this complicating things by a fair amount, I don't have a better 
suggestion to offer. LGTM




Comment at: clang/lib/ASTMatchers/ASTMatchFinder.cpp:771
+// We don't have enough free low bits in 32bit builds to discriminate 8 pointer
+// types in PointerUnion. so split the union in 2 using a free bit from the
+// callback pointer.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122529

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


[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Priyansh Singh via Phabricator via cfe-commits
ps-19 added a comment.

Pardon, it was my mistake i didn't see that the file i was amending was 
actually a test file i just search "switch" statement in my script.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D122871: Clang-Formatting

2022-04-01 Thread Priyansh Singh via Phabricator via cfe-commits
ps-19 abandoned this revision.
ps-19 added a comment.

Closed as:

1. Formating test file causes build to fail.
2. Formatting of whole page is not accpeted in LLVM as it created problem 
future with commands like `git blame` .


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122871

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


[PATCH] D122587: [clang][NFC] Extract the EmitAssemblyHelper::TargetTriple member

2022-04-01 Thread Pavel Samolysov via Phabricator via cfe-commits
psamolysov-intel added a comment.

All tests have been passed. Could anyone with the committer privileges help me 
with landing, please?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122587

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


[PATCH] D122895: [C89/C2x] Improve diagnostics around strict prototypes in C

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman updated this revision to Diff 419734.
aaron.ballman added a comment.

Rebased, no changes.


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

https://reviews.llvm.org/D122895

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/2009-06-01-addrofknr.c
  clang/test/FixIt/fixit.c
  clang/test/Parser/declarators.c
  clang/test/Parser/knr_parameter_attributes.c
  clang/test/Parser/opencl-kernel.cl
  clang/test/Parser/traditional_arg_scope.c
  clang/test/Sema/arg-duplicate.c
  clang/test/Sema/block-return.c
  clang/test/Sema/implicit-decl.c
  clang/test/Sema/knr-def-call.c
  clang/test/Sema/knr-variadic-def.c
  clang/test/Sema/vfprintf-valid-redecl.c
  clang/test/Sema/warn-deprecated-non-prototype.c
  clang/test/Sema/warn-missing-prototypes.c
  clang/test/Sema/warn-strict-prototypes.c
  clang/test/Sema/warn-strict-prototypes.m
  clang/test/SemaOpenCL/address-spaces.cl
  clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
  clang/test/SemaOpenCL/func.cl

Index: clang/test/SemaOpenCL/func.cl
===
--- clang/test/SemaOpenCL/func.cl
+++ clang/test/SemaOpenCL/func.cl
@@ -43,9 +43,9 @@
 #endif
 
 // Expect no diagnostics for an empty parameter list.
-void bar();
+void bar(); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 
-void bar()
+void bar() // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
 {
   // declaring a function pointer is an error
   void (*fptr)(int);
Index: clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
===
--- clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
+++ clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
@@ -11,7 +11,7 @@
 
 typedef struct {int a;} ndrange_t;
 // Diagnostic tests for different overloads of enqueue_kernel from Table 6.13.17.1 of OpenCL 2.0 Spec.
-kernel void enqueue_kernel_tests() {
+kernel void enqueue_kernel_tests(void) {
   queue_t default_queue;
   unsigned flags = 0;
   QUALS ndrange_t ndrange;
@@ -169,7 +169,7 @@
 }
 
 // Diagnostic tests for get_kernel_work_group_size and allowed block parameter types in dynamic parallelism.
-kernel void work_group_size_tests() {
+kernel void work_group_size_tests(void) {
   void (^const block_A)(void) = ^{
 return;
   };
@@ -223,16 +223,22 @@
 kernel void foo(global unsigned int *buf)
 {
   ndrange_t n;
-  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){});
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
+  buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected 'ndrange_t' argument type}}
+// expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected block argument type}}
 }
 
 kernel void bar(global unsigned int *buf)
 {
   __private ndrange_t n;
-  buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){});
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
+  buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-warning {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_sub_group_count_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected 'ndrange_t' argument type}}
+ // expected-warning@-1 {{a function declaration without a prototype is deprecated in all versions of C}}
   buf[0] = get_kernel_sub_group_count_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected block argument type}}
 }
 
@@ -241,12 +247,18 @@
 kernel void foo1(global unsigned int *buf)
 {
   ndrange_t n;
+  // FIXME: this should be diagnosed as a block instead of a function, but
+  // block literals don't track the ^ as part of their declarator.
   buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups or __opencl_c_subgroups support}}
+ 

[PATCH] D122894: [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet updated this revision to Diff 419737.
kadircet added a comment.

- Fix c/p error..


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122894

Files:
  clang-tools-extra/clangd/TUScheduler.cpp


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
-PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
+PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
-PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
+PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122894: [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet marked an inline comment as done.
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/TUScheduler.cpp:115
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
 PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");

adamcz wrote:
> You're not using Label anywhere. Replace first_build below with Label.
oops, did that


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122894

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


[clang-tools-extra] e2f598b - [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Kadir Cetinkaya via cfe-commits

Author: Kadir Cetinkaya
Date: 2022-04-01T15:12:37+02:00
New Revision: e2f598bc1b377f7e5fe2f7044fb653faf3c18bb6

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

LOG: [clangd] Record IO precentage for first preamble build of the instance

Differential Revision: https://reviews.llvm.org/D122894

Added: 


Modified: 
clang-tools-extra/clangd/TUScheduler.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/TUScheduler.cpp 
b/clang-tools-extra/clangd/TUScheduler.cpp
index d905a58fea50b..928ab56d21ae3 100644
--- a/clang-tools-extra/clangd/TUScheduler.cpp
+++ b/clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@ constexpr trace::Metric 
PreambleBuildFilesystemLatencyRatio(
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
-PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
+PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;



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


[PATCH] D122894: [clangd] Record IO precentage for first preamble build of the instance

2022-04-01 Thread Kadir Cetinkaya via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
kadircet marked an inline comment as done.
Closed by commit rGe2f598bc1b37: [clangd] Record IO precentage for first 
preamble build of the instance (authored by kadircet).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122894

Files:
  clang-tools-extra/clangd/TUScheduler.cpp


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
-PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
+PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;


Index: clang-tools-extra/clangd/TUScheduler.cpp
===
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -112,17 +112,16 @@
 
 void reportPreambleBuild(const PreambleBuildStats &Stats,
  bool IsFirstPreamble) {
-  static llvm::once_flag OnceFlag;
-  llvm::call_once(OnceFlag, [&] {
-PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, "first_build");
-  });
+  auto RecordWithLabel = [&Stats](llvm::StringRef Label) {
+PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
+if (Stats.TotalBuildTime > 0) // Avoid division by zero.
+  PreambleBuildFilesystemLatencyRatio.record(
+  Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  };
 
-  const std::string Label =
-  IsFirstPreamble ? "first_build_for_file" : "rebuild";
-  PreambleBuildFilesystemLatency.record(Stats.FileSystemTime, Label);
-  if (Stats.TotalBuildTime > 0) // Avoid division by zero.
-PreambleBuildFilesystemLatencyRatio.record(
-Stats.FileSystemTime / Stats.TotalBuildTime, Label);
+  static llvm::once_flag OnceFlag;
+  llvm::call_once(OnceFlag, [&] { RecordWithLabel("first_build"); });
+  RecordWithLabel(IsFirstPreamble ? "first_build_for_file" : "rebuild");
 }
 
 class ASTWorker;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122874: [clang] Add GNU spelling for no_unqiue_address attribute

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

I'm not opposed, but this does muddy the waters about the target-specific 
nature of the attribute. Currently, the semantic attribute cannot be used 
outside of Itanium ABI targets, so it doesn't work on Windows (and we don't 
want it to -- Microsoft hasn't picked their ABI for the standard attribute and 
we want to avoid ABI breaks). But should we pick an ABI for the GNU attribute 
on Windows and just assume that Microsoft gets no say in the ABI for that 
because it's not their vendor extension? Or, if we disallow the GNU spelling on 
Windows because we want it to match the ABI of the standard attribute, does it 
actually help libc++ to expose the GNU spelling?

Also, the change is missing test coverage and a release note.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122874

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


[PATCH] D122808: [clang] Fix warnings when `-Wdeprecated-enum-enum-conversion` is enabled

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

The changes here look correct to me, but they complicate the code a reasonable 
amount. I almost wonder whether we want to add a helper function (perhaps even 
to STLExtras.h?) along the lines of a cleaned up version of:

  template 
  auto addEnumValues(EnumTy1 LHS, EnumTy2 RHS) {
return static_cast>(LHS) +
  static_cast>(RHS);
  }

(We'd probably want some `enable_if` magic to protect the interface a bit more 
as well). WDYT of something like that? (That change would require some unit 
testing coverage as well, but this strikes me as something we're likely to want 
to reuse given that the functionality is deprecated.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122808

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


[PATCH] D122608: Fix behavior of ifuncs with 'used' extern "C" static functions

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 419741.
erichkeane marked 9 inline comments as done.
erichkeane added a comment.

Fix all the things @tahonermann  found.


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

https://reviews.llvm.org/D122608

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/test/CodeGenCXX/externc-ifunc-resolver.cpp
  clang/test/SemaCXX/externc-ifunc-resolver.cpp

Index: clang/test/SemaCXX/externc-ifunc-resolver.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/externc-ifunc-resolver.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s
+
+extern "C" {
+__attribute__((used)) static void *resolve_foo() { return 0; }
+namespace NS {
+__attribute__((used)) static void *resolve_foo() { return 0; }
+} // namespace NS
+
+// FIXME: This diagnostic is pretty confusing, the issue is that the existence
+// of the two functions suppresses the 'alias' creation, and thus the ifunc
+// resolution via the alias as well. In the future we should probably find
+// some way to improve this diagnostic (likely by diagnosing when we decide
+// this case suppresses alias creation).
+__attribute__((ifunc("resolve_foo"))) void foo(); // expected-error{{ifunc must point to a defined function}}
+}
+
Index: clang/test/CodeGenCXX/externc-ifunc-resolver.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/externc-ifunc-resolver.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+extern "C" {
+__attribute__((used)) static void *resolve_foo() { return 0; }
+__attribute__((ifunc("resolve_foo"))) char *foo();
+__attribute__((ifunc("resolve_foo"))) void foo2(int);
+__attribute__((ifunc("resolve_foo"))) char foo3(float);
+__attribute__((ifunc("resolve_foo"))) char foo4(float);
+}
+
+// CHECK: @resolve_foo = internal alias i8* (), i8* ()* @_ZL11resolve_foov
+// CHECK: @foo = ifunc i8* (), bitcast (i8* ()* @_ZL11resolve_foov to i8* ()* ()*)
+// CHECK: @foo2 = ifunc void (i32), bitcast (i8* ()* @_ZL11resolve_foov to void (i32)* ()*)
+// CHECK: @foo3 = ifunc i8 (float), bitcast (i8* ()* @_ZL11resolve_foov to i8 (float)* ()*)
+// CHECK: @foo4 = ifunc i8 (float), bitcast (i8* ()* @_ZL11resolve_foov to i8 (float)* ()*)
+// CHECK: define internal noundef i8* @_ZL11resolve_foov()
Index: clang/lib/CodeGen/CodeGenModule.h
===
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -1570,6 +1570,12 @@
   /// Emit the link options introduced by imported modules.
   void EmitModuleLinkOptions();
 
+  /// Helper function for EmitStaticExternCAliases that clears the uses of
+  /// 'Elem' if it is used exclusively by ifunc resolvers. Returns 'true' if it
+  /// was successful erases Elem.
+  bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem,
+llvm::GlobalValue *CppFunc);
+
   /// Emit aliases for internal-linkage declarations inside "C" language
   /// linkage specifications, giving them the "expected" name where possible.
   void EmitStaticExternCAliases();
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -507,7 +507,6 @@
   EmitVTablesOpportunistically();
   applyGlobalValReplacements();
   applyReplacements();
-  checkAliases();
   emitMultiVersionFunctions();
   EmitCXXGlobalInitFunc();
   EmitCXXGlobalCleanUpFunc();
@@ -539,6 +538,7 @@
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
   EmitStaticExternCAliases();
+  checkAliases();
   EmitDeferredUnusedCoverageMappings();
   CodeGenPGO(*this).setValueProfilingFlag(getModule());
   if (CoverageMapping)
@@ -6315,6 +6315,68 @@
   GlobalMetadata->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
 }
 
+bool CodeGenModule::CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem,
+ llvm::GlobalValue *CppFunc) {
+  // Store the list of ifuncs we need to replace uses in.
+  llvm::SmallVector IFuncs;
+  // List of ConstantExprs that we should be able to delete when we're done
+  // here.
+  llvm::SmallVector CEs;
+
+  // First make sure that all users of this are ifuncs (or ifuncs via a
+  // bitcast), and collect the list of ifuncs and CEs so we can work on them
+  // later.
+  for (llvm::User *User : Elem->users()) {
+// Users can either be a bitcast ConstExpr that is used by the ifuncs, OR an
+// ifunc directly. In any other case, just give up, as we don't know what we
+// could break by changing those.
+if (auto *ConstExpr = dyn_cast(User)) {
+  if (ConstExpr->getOpcode() != llvm::Instruction::BitCast)
+return false;
+
+  for (llvm::User *CEU

[PATCH] D122608: Fix behavior of ifuncs with 'used' extern "C" static functions

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:6390-6391
 llvm::GlobalValue *Val = I.second;
-if (Val && !getModule().getNamedValue(Name->getName()))
+llvm::GlobalValue *ExistingElem =
+getModule().getNamedValue(Name->getName());
+

tahonermann wrote:
> I suggest moving the declaration of `ExistingElem` after the break on `!Val` 
> given that the former is not relevant if `Val` is null.
> 
> I think the `!Val` check is worth a comment here. I suggest:
>   // If Val is null, that implies that there were multiple declarations that 
> each
>   // had a claim to the unmangled name. In this case, generation of the alias
>   // is suppressed. See CodeGenModule::MaybeHandleStaticInExternC().
> 
> The lack of checking for an existing element with the desired alias name was 
> a pre-existing oversight, yes?
SGTM, thanks!



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:6396-6397
+
+// Simple case, where there are no ifuncs involved.
+if (!ExistingElem || CheckAndReplaceExternCIFuncs(ExistingElem, Val))
   addCompilerUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));

tahonermann wrote:
> This comment seems inconsistent with the code. If there are no ifuncs 
> involved, then why call `CheckAndReplaceExternCIFuncs()`?
Woops!  Artifact of a previous implementation of this. Replaced the comment.


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

https://reviews.llvm.org/D122608

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


[PATCH] D122273: [clang][dataflow] Fix handling of base-class fields

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 419743.
ymandel added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122273

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1009,6 +1009,169 @@
   });
 }
 
+TEST_F(TransferTest, DerivedBaseMemberClass) {
+  std::string Code = R"(
+class A {
+  int ADefault;
+protected:
+  int AProtected;
+private:
+  int APrivate;
+public:
+  int APublic;
+};
+
+class B : public A {
+  int BDefault;
+protected:
+  int BProtected;
+private:
+  int BPrivate;
+};
+
+void target() {
+  B Foo;
+  // [[p]]
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const Environment &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+ASSERT_TRUE(FooDecl->getType()->isRecordType());
+
+// Derived-class fields.
+const FieldDecl *BDefaultDecl = nullptr;
+const FieldDecl *BProtectedDecl = nullptr;
+const FieldDecl *BPrivateDecl = nullptr;
+for (const FieldDecl *Field :
+ FooDecl->getType()->getAsRecordDecl()->fields()) {
+  if (Field->getNameAsString() == "BDefault") {
+BDefaultDecl = Field;
+  } else if (Field->getNameAsString() == "BProtected") {
+BProtectedDecl = Field;
+  } else if (Field->getNameAsString() == "BPrivate") {
+BPrivateDecl = Field;
+  } else {
+FAIL() << "Unexpected field: " << Field->getNameAsString();
+  }
+}
+ASSERT_THAT(BDefaultDecl, NotNull());
+ASSERT_THAT(BProtectedDecl, NotNull());
+ASSERT_THAT(BPrivateDecl, NotNull());
+
+// Base-class fields.
+const FieldDecl *ADefaultDecl = nullptr;
+const FieldDecl *APrivateDecl = nullptr;
+const FieldDecl *AProtectedDecl = nullptr;
+const FieldDecl *APublicDecl = nullptr;
+for (const clang::CXXBaseSpecifier &Base :
+ FooDecl->getType()->getAsCXXRecordDecl()->bases()) {
+  QualType BaseType = Base.getType();
+  ASSERT_TRUE(BaseType->isRecordType());
+  for (const FieldDecl *Field : BaseType->getAsRecordDecl()->fields()) {
+if (Field->getNameAsString() == "ADefault") {
+  ADefaultDecl = Field;
+} else if (Field->getNameAsString() == "AProtected") {
+  AProtectedDecl = Field;
+} else if (Field->getNameAsString() == "APrivate") {
+  APrivateDecl = Field;
+} else if (Field->getNameAsString() == "APublic") {
+  APublicDecl = Field;
+} else {
+  FAIL() << "Unexpected field: " << Field->getNameAsString();
+}
+  }
+}
+ASSERT_THAT(ADefaultDecl, NotNull());
+ASSERT_THAT(AProtectedDecl, NotNull());
+ASSERT_THAT(APrivateDecl, NotNull());
+ASSERT_THAT(APublicDecl, NotNull());
+
+const auto &FooLoc = *cast(
+Env.getStorageLocation(*FooDecl, SkipPast::None));
+const auto &FooVal = *cast(Env.getValue(FooLoc));
+
+// Base-class fields.
+EXPECT_THAT(FooVal.getChild(*ADefaultDecl), IsNull());
+EXPECT_THAT(FooVal.getChild(*APrivateDecl), IsNull());
+
+EXPECT_THAT(FooVal.getChild(*AProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*APublicDecl)),
+  FooVal.getChild(*APublicDecl));
+EXPECT_THAT(FooVal.getChild(*APublicDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*AProtectedDecl)),
+  FooVal.getChild(*AProtectedDecl));
+
+// Derived-class fields.
+EXPECT_THAT(FooVal.getChild(*BDefaultDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BDefaultDecl)),
+  FooVal.getChild(*BDefaultDecl));
+EXPECT_THAT(FooVal.getChild(*BProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BProtectedDecl)),
+  FooVal.getChild(*BProtectedDecl));
+EXPECT_THAT(FooVal.getChild(*BPrivateDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BPrivateDecl)),
+  FooVal.getChild(*BPrivateD

[clang] 69a7777 - [OpenMP] Make linker wrapper thin-lto default thread count use all

2022-04-01 Thread Joseph Huber via cfe-commits

Author: Joseph Huber
Date: 2022-04-01T09:44:28-04:00
New Revision: 69a1a9f5e577083338c3cebd61bbeb417843

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

LOG: [OpenMP] Make linker wrapper thin-lto default thread count use all

Summary:
Currently there is no option to configure the number of thin-backend
threads to use when performing thin-lto on the device, but we should
default to use all the threads rather than just one. In the future we
should use the same arguments that gold / lld use and parse it here.

Added: 


Modified: 
clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Removed: 




diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp 
b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index e9f616653d33e..618b181e92b53 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -858,8 +858,8 @@ std::unique_ptr createLTO(
   lto::Config Conf;
   lto::ThinBackend Backend;
   // TODO: Handle index-only thin-LTO
-  Backend = lto::createInProcessThinBackend(
-  llvm::heavyweight_hardware_concurrency(1));
+  Backend =
+  
lto::createInProcessThinBackend(llvm::heavyweight_hardware_concurrency());
   Conf.UseDefaultPipeline = true;
 
   Conf.CPU = Arch.str();



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


[PATCH] D122273: [clang][dataflow] Fix handling of base-class fields

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 419744.
ymandel marked 5 inline comments as done.
ymandel added a comment.

add clarifying comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122273

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1009,6 +1009,174 @@
   });
 }
 
+TEST_F(TransferTest, DerivedBaseMemberClass) {
+  std::string Code = R"(
+class A {
+  int ADefault;
+protected:
+  int AProtected;
+private:
+  int APrivate;
+public:
+  int APublic;
+};
+
+class B : public A {
+  int BDefault;
+protected:
+  int BProtected;
+private:
+  int BPrivate;
+};
+
+void target() {
+  B Foo;
+  // [[p]]
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const Environment &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+ASSERT_TRUE(FooDecl->getType()->isRecordType());
+
+// Derived-class fields.
+const FieldDecl *BDefaultDecl = nullptr;
+const FieldDecl *BProtectedDecl = nullptr;
+const FieldDecl *BPrivateDecl = nullptr;
+for (const FieldDecl *Field :
+ FooDecl->getType()->getAsRecordDecl()->fields()) {
+  if (Field->getNameAsString() == "BDefault") {
+BDefaultDecl = Field;
+  } else if (Field->getNameAsString() == "BProtected") {
+BProtectedDecl = Field;
+  } else if (Field->getNameAsString() == "BPrivate") {
+BPrivateDecl = Field;
+  } else {
+FAIL() << "Unexpected field: " << Field->getNameAsString();
+  }
+}
+ASSERT_THAT(BDefaultDecl, NotNull());
+ASSERT_THAT(BProtectedDecl, NotNull());
+ASSERT_THAT(BPrivateDecl, NotNull());
+
+// Base-class fields.
+const FieldDecl *ADefaultDecl = nullptr;
+const FieldDecl *APrivateDecl = nullptr;
+const FieldDecl *AProtectedDecl = nullptr;
+const FieldDecl *APublicDecl = nullptr;
+for (const clang::CXXBaseSpecifier &Base :
+ FooDecl->getType()->getAsCXXRecordDecl()->bases()) {
+  QualType BaseType = Base.getType();
+  ASSERT_TRUE(BaseType->isRecordType());
+  for (const FieldDecl *Field : BaseType->getAsRecordDecl()->fields()) {
+if (Field->getNameAsString() == "ADefault") {
+  ADefaultDecl = Field;
+} else if (Field->getNameAsString() == "AProtected") {
+  AProtectedDecl = Field;
+} else if (Field->getNameAsString() == "APrivate") {
+  APrivateDecl = Field;
+} else if (Field->getNameAsString() == "APublic") {
+  APublicDecl = Field;
+} else {
+  FAIL() << "Unexpected field: " << Field->getNameAsString();
+}
+  }
+}
+ASSERT_THAT(ADefaultDecl, NotNull());
+ASSERT_THAT(AProtectedDecl, NotNull());
+ASSERT_THAT(APrivateDecl, NotNull());
+ASSERT_THAT(APublicDecl, NotNull());
+
+const auto &FooLoc = *cast(
+Env.getStorageLocation(*FooDecl, SkipPast::None));
+const auto &FooVal = *cast(Env.getValue(FooLoc));
+
+// Note: we can't test presence of children in `FooLoc`, because
+// `getChild` requires its argument be present (or fails an assert). So,
+// we limit to testing presence in `FooVal` and coherence between the
+// two.
+
+// Base-class fields.
+EXPECT_THAT(FooVal.getChild(*ADefaultDecl), IsNull());
+EXPECT_THAT(FooVal.getChild(*APrivateDecl), IsNull());
+
+EXPECT_THAT(FooVal.getChild(*AProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*APublicDecl)),
+  FooVal.getChild(*APublicDecl));
+EXPECT_THAT(FooVal.getChild(*APublicDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*AProtectedDecl)),
+  FooVal.getChild(*AProtectedDecl));
+
+// Derived-class fields.
+EXPECT_THAT(FooVal.getChild(*BDefaultDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BDefaultDecl)),
+  FooVal.getChild(*BDefaultDecl));
+EXPECT_THAT(FooVal.getChild(*BProtectedDecl), NotNul

[PATCH] D122273: [clang][dataflow] Fix handling of base-class fields

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel added inline comments.



Comment at: clang/include/clang/Analysis/FlowSensitive/StorageLocation.h:59-60
 /// can be traced independently by abstract interpretation. For example: a
-/// struct with public members.
+/// struct with public members. Note that the corresponding `StructValue` has a
+/// flat layout that does not contain the child locations stored here.
 class AggregateStorageLocation final : public StorageLocation {

sgatev wrote:
> I find this a bit confusing. `StructValue` does not contain storage locations 
> in general. I think we should make it clear that the layout of 
> `AggregateStorageLocation` is flat, i.e. if it's used for a `struct` or 
> `class` type it will contain child storage locations for all accessible 
> members of base `struct` and `class` types.
Updated. I misunderstood what you meant as "flat" in the previous round of 
comments. Thanks for clarifying!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122273

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


[PATCH] D122699: [HLSL] Add Semantic syntax, and SV_GroupIndex

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

General question about the new syntax -- how does this work on field 
declarations of a record? e.g.,

  struct S {
int i : SV_GroupIndex;
  };

(Please tell me the answer is: it doesn't, because bit-fields are a thing.) 
Similar question applies to other places where a colon can show up. like `for 
(int i : SV_GroupIndex)` or `class C : SV_GroupIndex`.




Comment at: clang/include/clang/Basic/AttrDocs.td:6386
+  let Content = [{
+The ``SV_GroupIndex`` semantic when applied to an input parameter, specifies a
+data binding to map the group index to the specified parameter. This attribute

Minor grammar nit



Comment at: clang/test/SemaHLSL/Semantics/semantic_parsing.hlsl:7
+// expected-warning@+1 {{unknown attribute 'SV_IWantAPony' ignored}}
+void Pony(int GI : SV_IWantAPony) { }

There doesn't appear to be a test for parsing on global variables, you should 
add one for that.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122699

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


[PATCH] D122155: Add warning when eval-method is set in the presence of value unsafe floating-point calculations.

2022-04-01 Thread Zahira Ammarguellat via Phabricator via cfe-commits
zahiraam updated this revision to Diff 419746.
Herald added a subscriber: pengfei.

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

https://reviews.llvm.org/D122155

Files:
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/X86/32bit-behavior.c
  clang/test/Driver/eval-method-with-unsafe-math.c
  clang/test/Sema/eval-method-with-unsafe-math.c

Index: clang/test/Sema/eval-method-with-unsafe-math.c
===
--- /dev/null
+++ clang/test/Sema/eval-method-with-unsafe-math.c
@@ -0,0 +1,56 @@
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -freciprocal-math \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -mreassociate \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -fapprox-func \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-FUNC,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -verify \
+// RUN: %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -fapprox-func \
+// RUN: -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-FUNC,CHECK-ASSOC,CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-FFP-OPT,CHECK-PRGM
+
+// expected-no-diagnostics
+
+float f1(float a, float b, float c) {
+  a = b + c;
+  return a * b + c;
+}
+
+float f2(float a, float b, float c) {
+  // CHECK-FFP-OPT: option 'ffp-eval-method' cannot be used with '#pragma clang fp reassociate'.
+#pragma clang fp reassociate(on)
+  return (a + b) + c;
+}
+
+float f3(float a, float b, float c) {
+#pragma clang fp reassociate(off)
+  return (a - b) - c;
+}
+
+float f4(float a, float b, float c) {
+#pragma clang fp eval_method(double)
+  // CHECK-FUNC: '#pragma clang fp eval_method' cannot be used with option 'fapprox-func'.
+  // CHECK-ASSOC: '#pragma clang fp eval_method' cannot be used with option 'mreassociate'.
+  // CHECK-RECPR: '#pragma clang fp eval_method' cannot be used with option 'freciprocal'.
+  // CHECK-PRGM: '#pragma clang fp eval_method' cannot be used with '#pragma clang fp reassociate'.
+#pragma clang fp reassociate(on)
+  return (a * c) - (b * c);
+}
Index: clang/test/Driver/eval-method-with-unsafe-math.c
===
--- /dev/null
+++ clang/test/Driver/eval-method-with-unsafe-math.c
@@ -0,0 +1,29 @@
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -fapprox-func \
+// RUN: -Xclang -verify -ffp-eval-method=source %s 2>&1  \
+// RUN: | FileCheck %s --check-prefixes=CHECK-FUNC
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -mreassociate \
+// RUN: -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-RECPR
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -Xclang -mreassociate -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -Xclang -mreassociate -fapprox-func -ffp-eval-method=source \
+// RUN: -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR,CHECK-FUNC
+
+// CHECK-FUNC: (frontend): option 'ffp-eval-method' cannot be used with option 'fapprox-func'.
+// CHECK-ASSOC: (frontend): option 'ffp-eval-method' cannot be used with option 'mreassociate'.
+// CHECK-RECPR: (frontend): option 'ffp-eval-method' cannot be used with option 'freciprocal'.
Index: clang/test/CodeGen/X86/32bit-behavior.c

[PATCH] D122895: [C89/C2x] Improve diagnostics around strict prototypes in C

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:5566-5567
+def warn_non_prototype_changes_behavior : Warning<
+  "this function declaration without a prototype is deprecated in all versions 
"
+  "of C and changes behavior in C2x">, InGroup;
+def warn_prototype_changes_behavior : Warning<

"declaration of a function without a prototype is deprecated", may be slightly 
better?



Comment at: clang/lib/Sema/SemaDecl.cpp:3881
+  if (WithProto->getNumParams() != 0) {
+// The function definition has parameters, so this will change
+// behavior in C2x.

I wonder if

  - This shouldn't be placed in a separate function for clarity
  - We  could bail out early for built ins ?





Comment at: clang/lib/Sema/SemaType.cpp:5560-5562
   if (!LangOpts.CPlusPlus &&
-  D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) {
+  (D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration ||
+   D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition)) {

`if (!LangOpts.CPlusPlus)` is probably enough here


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

https://reviews.llvm.org/D122895

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


[PATCH] D122766: [clang] Use forward slash as the path separator for Windows in __FILE__, __builtin_FILE(), and std::source_location

2022-04-01 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

In D122766#3421410 , @mstorsjo wrote:

> In D122766#3420925 , @thakis wrote:
>
>> Windows can handle slashes, but several tools can't. I worry that if we do 
>> something different than cl, some random corner case might break (dbghelp, 
>> or some source server thing or some custom debug info processor somewhere).
>
> Yup, that's a valid concern. Especially PDB handling is pretty particular 
> about requiring backslashes, as far as I've seen.
>
>>> Then secondly - if the source paths are relative paths, making them 
>>> OS-agnostic in this way does make sense. But if they are absolute, they are 
>>> pretty much by definition specific to the build host,
>>
>> We use `/pdbsourcepath:X:\fake\prefix` to write a deterministic absolute 
>> path to the output file at link time (and `-fdebug-compilation-dir .` to get 
>> deterministic compiler output – see 
>> https://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html). 
>> The motivation is to get exactly the same output when building on linux and 
>> windows hosts.
>
> Ok, nice.
>
> Do you agree that if we go down this path doing this, we should also do it 
> whenever the host OS is windows, i.e. also for windows->linux cross 
> compilation, for consistency?

Yes, to me it makes sense that this should depend on the target triple, not on 
the host system (ie always use slashes when targeting non-Windows, and jury 
still a bit out on what exactly to do when targeting Windows).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122766

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


[PATCH] D122699: [HLSL] Add Semantic syntax, and SV_GroupIndex

2022-04-01 Thread Chris Bieneman via Phabricator via cfe-commits
beanz added a comment.

In D122699#3422298 , @aaron.ballman 
wrote:

> General question about the new syntax -- how does this work on field 
> declarations of a record? e.g.,
>
>   struct S {
> int i : SV_GroupIndex;
>   };
>
> (Please tell me the answer is: it doesn't, because bit-fields are a thing.)

Oh @aaron.ballman… you’re such an optimist… Thankfully HLSL does’t support 
bitfields… or didn’t, until HLSL 2021…

This patch doesn’t add support for the semantic syntax anywhere other than on 
parameter declarations, which is enough to get us rolling to start. I was 
hoping to flesh out the rest of the places it is used over time so that we can 
figure out good ways to handle the bitfield ambiguity…

> Similar question applies to other places where a colon can show up. like `for 
> (int i : SV_GroupIndex)` or `class C : SV_GroupIndex`.

Thankfully it can’t be used like that! HLSL doesn’t support range-based for, 
and it wouldn’t be valid in a for loop declaration anyways.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122699

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


[PATCH] D122820: [GH54588]Fix ItaniumMangler for NTTP unnamed unions w/ unnamed structs

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 419748.
erichkeane added a comment.

Update to 'diag' instead of crash, as implied/requested by @rjmccall


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

https://reviews.llvm.org/D122820

Files:
  clang/lib/AST/ItaniumMangle.cpp
  clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp

Index: clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | llvm-cxxfilt | FileCheck %s --check-prefix DEMANGLED
+
+template
+struct wrapper1 {
+  union {
+struct {
+  T RightName;
+};
+  };
+};
+
+template
+struct wrapper2 {
+  union {
+struct {
+  T RightName;
+};
+T WrongName;
+  };
+};
+
+struct Base {
+  int WrongName;
+};
+
+template 
+struct wrapper3 {
+  union {
+struct : Base {
+  T RightName; };
+T WrongName;
+  };
+};
+
+template 
+struct wrapper4 {
+  union {
+int RightName;
+struct {
+  T WrongName;
+};
+T AlsoWrongName;
+  };
+};
+
+template 
+struct wrapper5 {
+  union {
+struct {
+  struct {
+T RightName;
+  };
+  T WrongName;
+};
+  };
+};
+
+template
+struct wrapper6 {
+  union {
+union{
+int : 5;
+T RightName;
+};
+  };
+};
+
+
+
+template void dummy(){}
+
+
+void uses() {
+  // Zero init'ed cases.
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper1Iivv
+  // DEMANGLED: call void @void dummy{}>()()
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper2Ifvv
+  // DEMANGLED: call void @void dummy{}>()()
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper3Isvv
+  // DEMANGLED: call void @void dummy{}>()()
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper4Idvv
+  // DEMANGLED: call void @void dummy{}>()()
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper5Ixvv
+  // DEMANGLED: call void @void dummy{}>()()
+  dummy{}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper6Iivv
+  // DEMANGLED: call void @void dummy{}>()()
+
+  dummy{123.0}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper1IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_ELd405ec000EEvv
+  // DEMANGLED: call void @void dummy{wrapper1::'unnamed'{.RightName = wrapper1::'unnamed'::'unnamed'{0x1.ecp+6}}}>()()
+  dummy{123.0}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper2IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_ELd405ec000EEvv
+  // DEMANGLED: call void @void dummy{wrapper2::'unnamed'{.RightName = wrapper2::'unnamed'::'unnamed'{0x1.ecp+6}}}>()()
+  dummy{123, 456}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper3IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_Etl4BaseLi123EELd407c8000EEvv
+  // DEMANGLED: call void @void dummy{wrapper3::'unnamed'{.RightName = wrapper3::'unnamed'::'unnamed'{Base{123}, 0x1.c8p+8}}}>()()
+  dummy{123}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper4IdEtlNS1_Ut_Edi9RightNameLi123Evv
+  // DEMANGLED: call void @void dummy{wrapper4::'unnamed'{.RightName = 123}}>()()
+  dummy{123.0, 456.0}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper5IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_EtlNS3_Ut_ELd405ec000EELd407c8000EEvv
+  // DEMANGLED: call void @void dummy{wrapper5::'unnamed'{.RightName = wrapper5::'unnamed'::'unnamed'{wrapper5::'unnamed'::'unnamed'::'unnamed'{0x1.ecp+6}, 0x1.c8p+8}}}>()()
+  dummy{1}>();
+  // CHECK: call void @_Z5dummyIXtl8wrapper6IdEtlNS1_Ut_Edi9RightNametlNS2_Ut_Edi9RightNameLd3ff0EEvv
+  // DEMANGELD: call void @void dummy{wrapper6::'unnamed'{.RightName = wrapper6::'unnamed'::'unnamed'{.RightName = 0x1p+0}}}>()()   
+}
Index: clang/lib/AST/ItaniumMangle.cpp
===
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -5545,6 +5545,47 @@
   return T;
 }
 
+static IdentifierInfo *getUnionInitName(SourceLocation UnionLoc,
+DiagnosticsEngine &Diags,
+const FieldDecl *FD) {
+  // According to:
+  // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling.anonymous
+  // For the purposes of mangling, the name of an anonymous union is considered
+  // to be the name of the first named data member found by a pre-order,
+  // depth-first, declaration-order walk of the data members of the anonymous
+  // union.
+
+  if (FD->getIdentifier())
+return FD->getIdentifier();
+
+  // The only cases where the identifer of a FieldDecl would be blank is if the
+  // field represents an anonymous record type or if it is an unnamed bitfield.
+  // There is no type to descend into in the case of a bitfield, so we can just
+  // return nullptr in that case.
+  if (FD->isBitField())
+return nullptr;

[PATCH] D122820: [GH54588]Fix ItaniumMangler for NTTP unnamed unions w/ unnamed structs

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/AST/ItaniumMangle.cpp:5576
+  "program to refer to the anonymous union, and there is therefore no need 
"
+  "to mangle its name. '");
+}

rjmccall wrote:
> erichkeane wrote:
> > rjmccall wrote:
> > > Unfortunately, I think class value mangling has a counter-example to 
> > > this: you can have an anonymous struct or union which doesn't declare any 
> > > named members but will of course nonetheless show up in the list of 
> > > members in the enclosing class.  Code can even give it a non-zero 
> > > initializer using list-initialization; that value can never be read, but 
> > > it's there, and presumably it's part of uniquely determining a different 
> > > template argument value and therefore needs to be mangled.
> > > 
> > > I don't know what we should do about this in the ABI, but we shouldn't 
> > > crash in the compiler.
> > I'm not really understanding what you mean?  Can you provide an example?  
> > All of the cases I could come up with like this ended up getting caught by 
> > the 'zero -init' case.
> > 
> > That said, I considered this 'unreachable' to be a distinct improvement 
> > over our current behavior which is to crash at effectively line 5558. 
> > 
> > Would you prefer some sort of 'fatal-error' emit here?  
> I think the test case would be something like:
> 
> ```
> struct A {
>   union { unsigned: 10; };
>   int x;
>   constexpr A(int x) : x(x) {}
> };
> 
> template  void foo() {}
> template void foo();
> ```
> 
> But also consider:
> 
> ```
> struct B {
>   struct Nested {
> union { unsigned: 10; };
> int x;
>   } nested;
>   constexpr B(int x) : nested{5, x} {}
> };
> 
> template  void bar() {}
> template void bar();
> ```
With my current patch, that first example mangles to:
`@_Z3fooIXtl1ALNS0_Ut_EELi5vv` (that is, it doesn't touch this crash).  
Unfortunately, that doesn't 'demangle' with llvm-cxxfilt.

For the 2nd example, i had to modify it to be:

```
   struct B {
 struct Nested {
   union {
 unsigned : 10;
   };
   int x;
 } nested;
 constexpr B(int x) : nested{{}, x} {}
   };
  
  
   template  void bar() {}
   template void bar();

```

As you wrote it, we get the error:
`temp.cpp:20:31: error: initializer for aggregate with no elements requires 
explicit braces `

I tried putting a '5' in those brackets, and get:
`temp.cpp:20:32: error: excess elements in union initializer`


HOWEVER, I think it makes sense to have a Diag here rather than an 
llvm-unreachable, so I've done that instead.


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

https://reviews.llvm.org/D122820

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


[PATCH] D122781: Refactor sanitizer options handling for AMDGPU Toolchain

2022-04-01 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl accepted this revision.
yaxunl added a comment.

LGTM. Thanks.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122781

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


[PATCH] D122273: [clang][dataflow] Fix handling of base-class fields

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 419751.
ymandel added a comment.

tweak comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122273

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1009,6 +1009,174 @@
   });
 }
 
+TEST_F(TransferTest, DerivedBaseMemberClass) {
+  std::string Code = R"(
+class A {
+  int ADefault;
+protected:
+  int AProtected;
+private:
+  int APrivate;
+public:
+  int APublic;
+};
+
+class B : public A {
+  int BDefault;
+protected:
+  int BProtected;
+private:
+  int BPrivate;
+};
+
+void target() {
+  B Foo;
+  // [[p]]
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const Environment &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+ASSERT_TRUE(FooDecl->getType()->isRecordType());
+
+// Derived-class fields.
+const FieldDecl *BDefaultDecl = nullptr;
+const FieldDecl *BProtectedDecl = nullptr;
+const FieldDecl *BPrivateDecl = nullptr;
+for (const FieldDecl *Field :
+ FooDecl->getType()->getAsRecordDecl()->fields()) {
+  if (Field->getNameAsString() == "BDefault") {
+BDefaultDecl = Field;
+  } else if (Field->getNameAsString() == "BProtected") {
+BProtectedDecl = Field;
+  } else if (Field->getNameAsString() == "BPrivate") {
+BPrivateDecl = Field;
+  } else {
+FAIL() << "Unexpected field: " << Field->getNameAsString();
+  }
+}
+ASSERT_THAT(BDefaultDecl, NotNull());
+ASSERT_THAT(BProtectedDecl, NotNull());
+ASSERT_THAT(BPrivateDecl, NotNull());
+
+// Base-class fields.
+const FieldDecl *ADefaultDecl = nullptr;
+const FieldDecl *APrivateDecl = nullptr;
+const FieldDecl *AProtectedDecl = nullptr;
+const FieldDecl *APublicDecl = nullptr;
+for (const clang::CXXBaseSpecifier &Base :
+ FooDecl->getType()->getAsCXXRecordDecl()->bases()) {
+  QualType BaseType = Base.getType();
+  ASSERT_TRUE(BaseType->isRecordType());
+  for (const FieldDecl *Field : BaseType->getAsRecordDecl()->fields()) {
+if (Field->getNameAsString() == "ADefault") {
+  ADefaultDecl = Field;
+} else if (Field->getNameAsString() == "AProtected") {
+  AProtectedDecl = Field;
+} else if (Field->getNameAsString() == "APrivate") {
+  APrivateDecl = Field;
+} else if (Field->getNameAsString() == "APublic") {
+  APublicDecl = Field;
+} else {
+  FAIL() << "Unexpected field: " << Field->getNameAsString();
+}
+  }
+}
+ASSERT_THAT(ADefaultDecl, NotNull());
+ASSERT_THAT(AProtectedDecl, NotNull());
+ASSERT_THAT(APrivateDecl, NotNull());
+ASSERT_THAT(APublicDecl, NotNull());
+
+const auto &FooLoc = *cast(
+Env.getStorageLocation(*FooDecl, SkipPast::None));
+const auto &FooVal = *cast(Env.getValue(FooLoc));
+
+// Note: we can't test presence of children in `FooLoc`, because
+// `getChild` requires its argument be present (or fails an assert). So,
+// we limit to testing presence in `FooVal` and coherence between the
+// two.
+
+// Base-class fields.
+EXPECT_THAT(FooVal.getChild(*ADefaultDecl), IsNull());
+EXPECT_THAT(FooVal.getChild(*APrivateDecl), IsNull());
+
+EXPECT_THAT(FooVal.getChild(*AProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*APublicDecl)),
+  FooVal.getChild(*APublicDecl));
+EXPECT_THAT(FooVal.getChild(*APublicDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*AProtectedDecl)),
+  FooVal.getChild(*AProtectedDecl));
+
+// Derived-class fields.
+EXPECT_THAT(FooVal.getChild(*BDefaultDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BDefaultDecl)),
+  FooVal.getChild(*BDefaultDecl));
+EXPECT_THAT(FooVal.getChild(*BProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChi

[PATCH] D119544: Deferred Concept Instantiation Implementation

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane updated this revision to Diff 419750.
erichkeane added a comment.

Do a rebase, only conflict was with ReleaseNotes.rst.


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

https://reviews.llvm.org/D119544

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/Template.h
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  clang/test/SemaTemplate/deferred-concept-inst.cpp
  clang/test/SemaTemplate/instantiate-requires-clause.cpp
  clang/test/SemaTemplate/trailing-return-short-circuit.cpp

Index: clang/test/SemaTemplate/trailing-return-short-circuit.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/trailing-return-short-circuit.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+template 
+requires(sizeof(T) > 2) || T::value // #FOO_REQ
+void Foo(T){};  // #FOO
+
+template 
+void TrailingReturn(T) // #TRAILING
+requires(sizeof(T) > 2) || // #TRAILING_REQ
+T::value{};// #TRAILING_REQ_VAL
+template 
+struct HasValue {
+  static constexpr bool value = B;
+};
+static_assert(sizeof(HasValue) <= 2);
+
+template 
+struct HasValueLarge {
+  static constexpr bool value = B;
+  int I;
+};
+static_assert(sizeof(HasValueLarge) > 2);
+
+void usage() {
+  // Passes the 1st check, short-circuit so the 2nd ::value is not evaluated.
+  Foo(1.0);
+  TrailingReturn(1.0);
+
+  // Fails the 1st check, but has a ::value, so the check happens correctly.
+  Foo(HasValue{});
+  TrailingReturn(HasValue{});
+
+  // Passes the 1st check, but would have passed the 2nd one.
+  Foo(HasValueLarge{});
+  TrailingReturn(HasValueLarge{});
+
+  // Fails the 1st check, fails 2nd because there is no ::value.
+  Foo(true);
+  // expected-error@-1{{no matching function for call to 'Foo'}}
+  // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = bool]}}
+  // expected-note@#FOO_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}}
+  // expected-note@#FOO_REQ{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}}
+
+  TrailingReturn(true);
+  // expected-error@-1{{no matching function for call to 'TrailingReturn'}}
+  // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = bool]}}
+  // expected-note@#TRAILING_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}}
+  // expected-note@#TRAILING_REQ_VAL{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}}
+
+  // Fails the 1st check, fails 2nd because ::value is false.
+  Foo(HasValue{});
+  // expected-error@-1 {{no matching function for call to 'Foo'}}
+  // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = HasValue]}}
+  // expected-note@#FOO_REQ{{because 'sizeof(HasValue) > 2' (1 > 2) evaluated to false}}
+  // expected-note@#FOO_REQ{{and 'HasValue::value' evaluated to false}}
+  TrailingReturn(HasValue{});
+  // expected-error@-1 {{no matching function for call to 'TrailingReturn'}}
+  // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = HasValue]}}
+  // expected-note@#TRAILING_REQ{{because 'sizeof(HasValue) > 2' (1 > 2) evaluated to false}}
+  // expected-note@#TRAILING_REQ_VAL{{and 'HasValue::value' evaluated to false}}
+}
Index: clang/test/SemaTemplate/instantiate-requires-clause.cpp
===
--- clang/test/SemaTemplate/instantiate-requires-clause.cpp
+++ clang/test/SemaTemplate/instantiate-requires-clause.cpp
@@ -40,6 +40,18 @@
 
 static_assert(S::f(1));
 
+// Similar to the 'S' test, but tries to use 'U' in the requires clause.
+template 
+struct S1 {
+  // expected-note@+3 {{candidate template ignored: constraints not satisfied [with U = int]}}
+  // expected-note@+2 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}
+  template 
+  static constexpr auto f(U const index) requires(U::foo) { return true; }
+};
+
+// expected-error@+1 {{no matching function for call to 'f'}}
+static_assert(S1::f(1));
+
 constexpr auto value = 0;
 
 template
Index: clang/test/SemaTemplate/deferred-concept-inst.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/deferred-concept-inst.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value
+// expected-no-diagnostics
+
+namespace GithubBug44178 {
+template 
+struct CRTP {
+  void

[PATCH] D119544: Deferred Concept Instantiation Implementation

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:489
+  // Attn Reviewers: we need to do this for the function constraints for
+  // comparison of constraints to work, but do we also need to do it for
+  // CheckInstantiatedFunctionConstraints?  That one is more difficult, but we

ChuanqiXu wrote:
> erichkeane wrote:
> > ChuanqiXu wrote:
> > > Would you mind to elaborate for the issue "function constraints for 
> > > comparison of constraints to work" more? Maybe it is said in previous 
> > > messages, but the history is hard to follow...
> > Yep, this one is difficult :/  Basically, when we instantiate the 
> > constraints at 'checking' time, if the function is NOT a template, we call 
> > `CheckFunctionConstraints`. When we go to check the 'subsumption' type 
> > things with a fully instantiated version, they fail if they are dependent 
> > (as it is expected that way).  See the `setTrailingRequiresClause` here.
> > 
> > HOWEVER, it seems we ALWAYS pick constraints off the primary template, 
> > rather than the 'stored' version of the constraint on the current 
> > declaration.  I tried to do something similar here for those cases, but 1: 
> > it had no effect seemingly, and 2: it ended up getting complicated in many 
> > cases (as figuring out the relationship between the constraints in the two 
> > nodes was difficult/near impossible).
> > 
> > I opted to not do it, and I don't THINK it needs to happen over there, but 
> > I wanted to point out that I was skipping it in case reviewers had a better 
> > idea.
> > 
> > 
> Let me ask some questions to get in consensus for the problem:
> 
> > Basically, when we instantiate the constraints at 'checking' time, if the 
> > function is NOT a template, we call CheckFunctionConstraints.
> 
> I think the function who contains a trailing require clause should be 
> template one. Do you want to say independent ? Or do you refer the following 
> case?
> 
> ```C++
> template struct A {
>   static void f(int) requires ;
> };
> ```
> 
> And the related question would be what's the cases that 
> `CheckFunctionConstraints` would be called and what's the cases that 
> `CheckinstantiatedFunctionTemplateConstraints` would be called?
> 
> > When we go to check the 'subsumption' type things with a fully instantiated 
> > version, they fail if they are dependent (as it is expected that way).
> 
> If it is fully instantiated, how could it be dependent?
> 
> > HOWEVER, it seems we ALWAYS pick constraints off the primary template, 
> > rather than the 'stored' version of the constraint on the current 
> > declaration.
> 
> 1. What is `we`? I mean what's the function would pick up the constraints 
> from the primary template.
> 2. Does `the stored version of the constraint` means the trailing require 
> clause of FD? Would it be the original one or `Converted[0]`.
>>Or do you refer the following case?

Yeah, thats exactly the case I am talking about.  A case where the function 
itself isn't a template, but is dependent. 

>>And the related question would be what's the cases that 
>>CheckFunctionConstraints would be called and what's the cases that 
>>CheckinstantiatedFunctionTemplateConstraints would be called?

The former when either the function is not dependent at all, OR it is 
dependent-but-fully-instantiated (like in the example you gave).  All other 
cases (where the template is NOT fully instantiated) calls the other function.

>>If it is fully instantiated, how could it be dependent?

By "Fully Instantiated" I mean "everything except the constraints (and 
technically, some noexcept)", since we are deferring constraint checking until 
that point. A bunch of the changes in this commit STOP us from instantiating 
the constraint except when checking, since that is the point of the patch!  SO, 
the constriant is still 'dependent' (like in your example above).  


>>What is we? I mean what's the function would pick up the constraints from the 
>>primary template.

Royal 'we', or clang. The function is `getAssociatedConstraints`.

>>Does the stored version of the constraint means the trailing require clause 
>>of FD? Would it be the original one or Converted[0].

The 'stored' version (that is, not on the primary template) is the one that we 
partially instantiated when going through earlier instantiations.  In the case 
that it was a template, we seem to always ignore these instantiated versions.  
IN the case where it is NOT a template, we use that for checking (which is why 
Converted[0] needs replacing here).



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

https://reviews.llvm.org/D119544

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


[clang] cd55e51 - Add prototypes to functions which need them; NFC

2022-04-01 Thread Aaron Ballman via cfe-commits

Author: Aaron Ballman
Date: 2022-04-01T10:32:46-04:00
New Revision: cd55e51516f03203f3bf632ff4a65ae7518a8319

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

LOG: Add prototypes to functions which need them; NFC

Added: 


Modified: 
clang/test/Sema/array-init.c
clang/test/SemaOpenCL/numbered-address-space.cl

Removed: 




diff  --git a/clang/test/Sema/array-init.c b/clang/test/Sema/array-init.c
index 5ce5075dc9725..931d718fd24a8 100644
--- a/clang/test/Sema/array-init.c
+++ b/clang/test/Sema/array-init.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -std=gnu99 -fsyntax-only -Wgnu -Wc11-extensions -verify %s
 // REQUIRES: LP64
 
-extern int foof() = 1; // expected-error{{illegal initializer (only variables 
can be initialized)}}
+extern int foof(void) = 1; // expected-error{{illegal initializer (only 
variables can be initialized)}}
 
 static int x, y, z;
 
@@ -13,7 +13,7 @@ extern int fileScopeExtern[3] = { 1, 3, 5 }; // 
expected-warning{{'extern' varia
 
 static long ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible 
pointer to integer conversion initializing 'long' with an expression of type 
'char[4]'}}
 
-void func() {
+void func(void) {
   int x = 1;
 
   typedef int TInt = 1; // expected-error{{illegal initializer (only variables 
can be initialized)}}
@@ -55,7 +55,7 @@ void func() {
  5.8 }; // expected-warning {{implicit conversion from 
'double' to 'long' changes value from 5.8 to 5}}
 }
 
-void test() {
+void test(void) {
   int y1[3] = { 
 { 1, 2, 3 } // expected-warning{{excess elements in scalar initializer}}
   };
@@ -74,7 +74,7 @@ void test() {
   };
 }
 
-void allLegalAndSynonymous() {
+void allLegalAndSynonymous(void) {
   short q[4][3][2] = {
 { 1 },
 { 2, 3 },
@@ -99,7 +99,7 @@ void allLegalAndSynonymous() {
   };
 }
 
-void legal() {
+void legal(void) {
   short q[][3][2] = {
 { 1 },
 { 2, 3 },
@@ -109,11 +109,11 @@ void legal() {
 }
 
 unsigned char asso_values[] = { 34 };
-int legal2() { 
+int legal2(void) { 
   return asso_values[0]; 
 }
 
-void illegal() {
+void illegal(void) {
   short q2[4][][2] = { // expected-error{{array has incomplete element type 
'short[][2]'}}
 { 1, 0, 0, 0, 0, 0 },
 { 2, 3, 0, 0, 0, 0 },
@@ -136,7 +136,7 @@ void illegal() {
 
 typedef int AryT[];
 
-void testTypedef()
+void testTypedef(void)
 {
   AryT a = { 1, 2 }, b = { 3, 4, 5 };
   int a_sizecheck[(sizeof(a) / sizeof(int)) == 2? 1 : -1];
@@ -153,7 +153,7 @@ static char const zz[3] = "test"; // 
expected-warning{{initializer-string for ch
 static char const zz_quiet[3] = "test";
 #pragma clang diagnostic pop
 
-void charArrays() {
+void charArrays(void) {
   static char const test[] = "test";
   int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1];
   static char const test2[] = { "weird stuff" };
@@ -178,7 +178,7 @@ void charArrays() {
   int i3[] = {}; //expected-warning{{zero size arrays are an extension}} 
expected-warning{{use of GNU empty initializer extension}}
 }
 
-void variableArrayInit() {
+void variableArrayInit(void) {
   int a = 4;
   char strlit[a] = "foo"; //expected-error{{variable-sized object may not be 
initialized}}
   int b[a] = { 1, 2, 4 }; //expected-error{{variable-sized object may not be 
initialized}}
@@ -200,7 +200,7 @@ unsigned char r10[] = __extension__ (_Generic(0, int: 
(__extension__ "foo" )));
 int r11[0] = {}; //expected-warning{{zero size arrays are an extension}} 
expected-warning{{use of GNU empty initializer extension}}
 
 // Some struct tests
-void autoStructTest() {
+void autoStructTest(void) {
 struct s1 {char a; char b;} t1;
 struct s2 {struct s1 c;} t2 = { t1 };
 // The following is a less than great diagnostic (though it's on par with EDG).
@@ -226,15 +226,15 @@ int u1 = {}; //expected-warning{{use of GNU empty 
initializer extension}} expect
 int u2 = {{3}}; //expected-warning{{too many braces around scalar initializer}}
 
 // PR2362
-void varArray() {
+void varArray(void) {
   int c[][x] = { 0 }; //expected-error{{variable-sized object may not be 
initialized}}
 }
 
 // PR2151
-void emptyInit() {struct {} x[] = {6};} //expected-warning{{empty struct is a 
GNU extension}} \
+void emptyInit(void) {struct {} x[] = {6};} //expected-warning{{empty struct 
is a GNU extension}} \
 // expected-error{{initializer for aggregate with no elements}}
 
-void noNamedInit() {
+void noNamedInit(void) {
   struct {int:5;} x[] = {6}; //expected-error{{initializer for aggregate with 
no elements}} \
 // expected-warning {{struct without named members is a GNU extension}}
 }
@@ -255,13 +255,13 @@ struct soft_segment_descriptor gdt_segs[] = {
   { (long)xpto},
 };
 
-static void sppp_ipv6cp_up();
+static void sppp_ipv6cp_up(void);
 const struct {} ipcp = { sppp_ipv6cp_up }; //ex

[PATCH] D122895: [C89/C2x] Improve diagnostics around strict prototypes in C

2022-04-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman marked an inline comment as done.
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:5566-5567
+def warn_non_prototype_changes_behavior : Warning<
+  "this function declaration without a prototype is deprecated in all versions 
"
+  "of C and changes behavior in C2x">, InGroup;
+def warn_prototype_changes_behavior : Warning<

cor3ntin wrote:
> "declaration of a function without a prototype is deprecated", may be 
> slightly better?
Sure, I can reword the rest so they're consistent.



Comment at: clang/lib/Sema/SemaDecl.cpp:3881
+  if (WithProto->getNumParams() != 0) {
+// The function definition has parameters, so this will change
+// behavior in C2x.

cor3ntin wrote:
> I wonder if
> 
>   - This shouldn't be placed in a separate function for clarity
>   - We  could bail out early for built ins ?
> 
> 
The change looks more complicated than it is because of the indentation changes 
-- I'm not certain putting this in its own function gains a whole lot (it's not 
reusable below; I already looked into doing that and wasn't happy with the 
results).

We can't bail out early for builtins because we still issue diagnostics in 
cases where only one side is a builtin. e.g.,
```
void exit(); // We still want to diagnose this as changing behavior specifically
```
See test/Sema/knr-variadic-def.c for this test case.




Comment at: clang/lib/Sema/SemaType.cpp:5560-5562
   if (!LangOpts.CPlusPlus &&
-  D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration) {
+  (D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration ||
+   D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition)) {

cor3ntin wrote:
> `if (!LangOpts.CPlusPlus)` is probably enough here
Hmm, yeah, you're right. Good catch!


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

https://reviews.llvm.org/D122895

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


[PATCH] D122822: [Clang][CodeGen]Add constant array support for __builtin_dump_sturct

2022-04-01 Thread Wang Yihan via Phabricator via cfe-commits
yihanaa added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2052
 Types[Context.BoolTy] = "%d";
 Types[Context.SignedCharTy] = "%hhd";
 Types[Context.UnsignedCharTy] = "%hhu";

I think this types should have been promoted according to the integer 
promotions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122822

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


[PATCH] D122838: [clang][dataflow] Add support for correlation of boolean (tracked) values

2022-04-01 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun accepted this revision.
xazax.hun added inline comments.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:79
+for (BoolValue *Constraint : Env1.getFlowConditionConstraints()) {
+  Expr1 = &Env1.makeAnd(*Expr1, *Constraint);
+}

ymandel wrote:
> sgatev wrote:
> > xazax.hun wrote:
> > > Hmm, interesting.
> > > I think we view every boolean formula at a certain program point 
> > > implicitly as `FlowConditionAtThatPoint && Formula`. And the flow 
> > > condition at a program point should already be a disjunction of its 
> > > predecessors.
> > > 
> > > So it would be interpreted as: `(FlowConditionPred1 || 
> > > FlowConditionPred2) && (FormulaAtPred1 || FormulaAtPred2)`.
> > > While this is great, this is not the strongest condition we could derive. 
> > > `(FlowConditionPred1 && FormulaAtPred1)  || (FormulaAtPred2 && 
> > > FlowConditionPred2)` created by this code snippet is stronger which is 
> > > great.
> > > 
> > > My main concern is whether we would end up seeing an exponential 
> > > explosion in the size of these formulas in the number of branches 
> > > following each other in a sequence.
> > > 
> > Yeap, I agree this is suboptimal and I believe I'm the one to blame for 
> > introducing it downstream.
> > 
> > I wonder if we can represent the flow condition of each environment using a 
> > bool atom and have a mapping of bi-conditionals between flow condition 
> > atoms and flow condition constraints. Something like:
> > 
> > ```
> > FC1 <=> C1 ^ C2
> > FC2 <=> C2 ^ C3 ^ C4
> > FC3 <=> (FC1 v FC2) ^ C5
> > ... 
> > ```
> > 
> > We can use that to simplify the formulas here and in `joinConstraints`. The 
> > mapping can be stored in `DataflowAnalysisContext`. We can track 
> > dependencies between flow conditions (e.g. above `FC3` depends on `FC1` and 
> > `FC2`) and modify `flowConditionImplies` to construct a formula that 
> > includes the bi-conditionals for all flow condition atoms in the transitive 
> > set before invoking the solver.
> > 
> > I suggest putting the optimization in its own patch. I'd love to look into 
> > it right after this patch is submitted if both of you think it makes sense 
> > on a high level.
> This sounds good to me. That said, I'm not sure how often we'd expect this to 
> be an issue in practice, since, IIUC, this specialized merge only occurs when 
> the value is handled differently in the two branches. So, a series of 
> branches alone won't trigger the exponential behavior.
Fair point. It might never cause a problem in practice. Since we already have 
one proposal how to try to fix this if a problem ever surfaces, I'd love to 
have a comment about this in the code. But I think this is something that 
probably does not need to be addressed in the near future. 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122838

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


[PATCH] D122822: [Clang][CodeGen]Add constant array support for __builtin_dump_sturct

2022-04-01 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D122822#3421089 , @yihanaa wrote:

> I also agree that this is a useful debugging builtin, and no program logic 
> should be forced to depend on the output of this builtin. It's just used to 
> print out some useful debugging information

FWIW, @rsmith is the clang-codeowner, so he's the one to convince (and 
@rjmccall is also a very senior reviewer).  So I wouldn't be able to approve 
this patch without their consent/agreement.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122822

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


[PATCH] D122895: [C89/C2x] Improve diagnostics around strict prototypes in C

2022-04-01 Thread James Y Knight via Phabricator via cfe-commits
jyknight added a comment.

Starting by looking at the test cases, I've got some suggestions on making the 
diagnostics a bit less confusing.




Comment at: clang/test/CodeGen/2009-06-01-addrofknr.c:8
 
-static int func(f)
+static int func(f) // expected-warning {{this function declaration without a 
prototype is deprecated in all versions of C and changes behavior in C2x}}
   void *f;

This message seems vaguer than necessary, since we know _for sure_ this is 
invalid.

Can we say something like: "K&R-style function definitions are deprecated in 
all versions of C and not supported in C2x"?



Comment at: clang/test/Parser/declarators.c:5
 
-void f0();
+void f0(); /* expected-warning {{a function declaration without a prototype is 
deprecated in all versions of C}} */
 void f1(int [*]);

Perhaps we should add an explanation to the message like
 `(specify '(void)' if you intended to accept no arguments)`
to make it clearer to folks who aren't familiar with this weirdness yet?



Comment at: clang/test/Sema/implicit-decl.c:25
+Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t 
**vector, int32_t count) { // expected-error {{conflicting types}} \
+   
 // expected-warning {{this function declaration with a 
prototype changes behavior in C2x because it is preceded by a function without 
a prototype}}
  return 0;

It's not "preceded by a function without a prototype", though, it's preceeded 
by a implicit declaration due to a call. Which we would've already diagnosed 
with the default-on -Wimplicit-function-declaration diagnostic.

Although...what _is_ the desired behavior of an implicit function declaration 
in C2x mode? If we permit it _at all_, it must still create a non-prototype 
function declaration, I expect. In that case this decl with types would still 
be valid, so the warning is just wrong.




Comment at: clang/test/Sema/knr-def-call.c:15
+void f2(float); // expected-note{{previous declaration is here}} \
+   expected-warning {{this function declaration with a 
prototype changes behavior in C2x because it is followed by a function without 
a prototype}}
+void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R 
function parameter is not compatible with the parameter type 'float' declared 
in a previous prototype}} \

I think we don't want to emit a warning here. If a declaration with params 
doesn't match a K&R definition, we already emit a conflicting-types error.

[[Well...except for one case, I've noticed -- we don't current emit any warning 
when a definition with no parameters fails to match a preceding declaration 
with params, e.g. `void f(int); void f() { }`. I'm quite surprised -- I'm 
willing to say that such code is 100% just a bug, not intentional. I note that 
GCC unconditionally rejects it. I think we should also be emitting an 
unconditional error in that case.]]]

Anyhow, when you have a K&R style definition with parameters, that -- all by 
itself -- is definitely invalid in C2x, so we don't need to emit any warning on 
the declaration.



Comment at: clang/test/Sema/warn-deprecated-non-prototype.c:46
+ strict-note {{this function declaration without a 
prototype changes behavior in C2x}}
+void order1(int i);   // both-warning {{this function declaration with a 
prototype changes behavior in C2x because it is preceded by a function without 
a prototype}}
+

Maybe something like "this function declaration will conflict with the 
preceding declaration in C2x, because the preceding declaration does not 
specify arguments."


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

https://reviews.llvm.org/D122895

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


[clang] 36d4e84 - [clang][dataflow] Fix handling of base-class fields.

2022-04-01 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2022-04-01T15:01:32Z
New Revision: 36d4e84427a704599bfd8bd72edf46ecd27ff5e5

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

LOG: [clang][dataflow] Fix handling of base-class fields.

Currently, the framework does not track derived class access to base
fields. This patch adds that support and a corresponding test.

Differential Revision: https://reviews.llvm.org/D122273

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
clang/include/clang/Analysis/FlowSensitive/Value.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h 
b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
index 5532813d6d29b..f965486537e61 100644
--- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
+++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
@@ -56,7 +56,9 @@ class ScalarStorageLocation final : public StorageLocation {
 
 /// A storage location which is subdivided into smaller storage locations that
 /// can be traced independently by abstract interpretation. For example: a
-/// struct with public members.
+/// struct with public members. The child map is flat, so when used for a 
struct
+/// or class type, all accessible members of base struct and class types are
+/// directly accesible as children of this location.
 class AggregateStorageLocation final : public StorageLocation {
 public:
   explicit AggregateStorageLocation(QualType Type)

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Value.h 
b/clang/include/clang/Analysis/FlowSensitive/Value.h
index 98df8f6539f7b..859cf7ff21b5b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Value.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Value.h
@@ -189,7 +189,9 @@ class PointerValue final : public IndirectionValue {
   }
 };
 
-/// Models a value of `struct` or `class` type.
+/// Models a value of `struct` or `class` type, with a flat map of fields to
+/// child storage locations, containing all accessible members of base struct
+/// and class types.
 class StructValue final : public Value {
 public:
   StructValue() : StructValue(llvm::DenseMap()) {}

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 0e75b1a3be016..79bbfa091f6cb 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -164,6 +164,42 @@ joinConstraints(DataflowAnalysisContext *Context,
   return JoinedConstraints;
 }
 
+static void
+getFieldsFromClassHierarchy(QualType Type, bool IgnorePrivateFields,
+llvm::DenseSet &Fields) {
+  if (Type->isIncompleteType() || Type->isDependentType() ||
+  !Type->isRecordType())
+return;
+
+  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) {
+if (IgnorePrivateFields &&
+(Field->getAccess() == AS_private ||
+ (Field->getAccess() == AS_none && 
Type->getAsRecordDecl()->isClass(
+  continue;
+Fields.insert(Field);
+  }
+  if (auto *CXXRecord = Type->getAsCXXRecordDecl()) {
+for (const CXXBaseSpecifier &Base : CXXRecord->bases()) {
+  // Ignore private fields (including default access in C++ classes) in
+  // base classes, because they are not visible in derived classes.
+  getFieldsFromClassHierarchy(Base.getType(), /*IgnorePrivateFields=*/true,
+  Fields);
+}
+  }
+}
+
+/// Gets the set of all fields accesible from the type.
+///
+/// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
+/// field decl will be modeled for all instances of the inherited field.
+static llvm::DenseSet
+getAccessibleObjectFields(QualType Type) {
+  llvm::DenseSet Fields;
+  // Don't ignore private fields for the class itself, only its super classes.
+  getFieldsFromClassHierarchy(Type, /*IgnorePrivateFields=*/false, Fields);
+  return Fields;
+}
+
 Environment::Environment(DataflowAnalysisContext &DACtx,
  const DeclContext &DeclCtx)
 : Environment(DACtx) {
@@ -296,7 +332,7 @@ StorageLocation 
&Environment::createStorageLocation(QualType Type) {
 // FIXME: Explore options to avoid eager initialization of fields as some 
of
 // them might not be needed for a particular analysis.
 llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) {
+for (const FieldDecl *Field : getAccessibleObjectFields(Type)) {
   FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
 }
 retur

[PATCH] D122273: [clang][dataflow] Fix handling of base-class fields

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG36d4e84427a7: [clang][dataflow] Fix handling of base-class 
fields. (authored by ymandel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122273

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1009,6 +1009,174 @@
   });
 }
 
+TEST_F(TransferTest, DerivedBaseMemberClass) {
+  std::string Code = R"(
+class A {
+  int ADefault;
+protected:
+  int AProtected;
+private:
+  int APrivate;
+public:
+  int APublic;
+};
+
+class B : public A {
+  int BDefault;
+protected:
+  int BProtected;
+private:
+  int BPrivate;
+};
+
+void target() {
+  B Foo;
+  // [[p]]
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const Environment &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+ASSERT_TRUE(FooDecl->getType()->isRecordType());
+
+// Derived-class fields.
+const FieldDecl *BDefaultDecl = nullptr;
+const FieldDecl *BProtectedDecl = nullptr;
+const FieldDecl *BPrivateDecl = nullptr;
+for (const FieldDecl *Field :
+ FooDecl->getType()->getAsRecordDecl()->fields()) {
+  if (Field->getNameAsString() == "BDefault") {
+BDefaultDecl = Field;
+  } else if (Field->getNameAsString() == "BProtected") {
+BProtectedDecl = Field;
+  } else if (Field->getNameAsString() == "BPrivate") {
+BPrivateDecl = Field;
+  } else {
+FAIL() << "Unexpected field: " << Field->getNameAsString();
+  }
+}
+ASSERT_THAT(BDefaultDecl, NotNull());
+ASSERT_THAT(BProtectedDecl, NotNull());
+ASSERT_THAT(BPrivateDecl, NotNull());
+
+// Base-class fields.
+const FieldDecl *ADefaultDecl = nullptr;
+const FieldDecl *APrivateDecl = nullptr;
+const FieldDecl *AProtectedDecl = nullptr;
+const FieldDecl *APublicDecl = nullptr;
+for (const clang::CXXBaseSpecifier &Base :
+ FooDecl->getType()->getAsCXXRecordDecl()->bases()) {
+  QualType BaseType = Base.getType();
+  ASSERT_TRUE(BaseType->isRecordType());
+  for (const FieldDecl *Field : BaseType->getAsRecordDecl()->fields()) {
+if (Field->getNameAsString() == "ADefault") {
+  ADefaultDecl = Field;
+} else if (Field->getNameAsString() == "AProtected") {
+  AProtectedDecl = Field;
+} else if (Field->getNameAsString() == "APrivate") {
+  APrivateDecl = Field;
+} else if (Field->getNameAsString() == "APublic") {
+  APublicDecl = Field;
+} else {
+  FAIL() << "Unexpected field: " << Field->getNameAsString();
+}
+  }
+}
+ASSERT_THAT(ADefaultDecl, NotNull());
+ASSERT_THAT(AProtectedDecl, NotNull());
+ASSERT_THAT(APrivateDecl, NotNull());
+ASSERT_THAT(APublicDecl, NotNull());
+
+const auto &FooLoc = *cast(
+Env.getStorageLocation(*FooDecl, SkipPast::None));
+const auto &FooVal = *cast(Env.getValue(FooLoc));
+
+// Note: we can't test presence of children in `FooLoc`, because
+// `getChild` requires its argument be present (or fails an assert). So,
+// we limit to testing presence in `FooVal` and coherence between the
+// two.
+
+// Base-class fields.
+EXPECT_THAT(FooVal.getChild(*ADefaultDecl), IsNull());
+EXPECT_THAT(FooVal.getChild(*APrivateDecl), IsNull());
+
+EXPECT_THAT(FooVal.getChild(*AProtectedDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*APublicDecl)),
+  FooVal.getChild(*APublicDecl));
+EXPECT_THAT(FooVal.getChild(*APublicDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*AProtectedDecl)),
+  FooVal.getChild(*AProtectedDecl));
+
+// Derived-class fields.
+EXPECT_THAT(FooVal.getChild(*BDefaultDecl), NotNull());
+EXPECT_EQ(Env.getValue(FooLoc.getChild(*BDefaultDecl)),
+  

[PATCH] D122908: [clang][dataflow] Add support for clang's `__builtin_expect`.

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel created this revision.
ymandel added reviewers: sgatev, xazax.hun.
Herald added subscribers: tschuett, steakhal, rnkovacs.
Herald added a project: All.
ymandel requested review of this revision.
Herald added a project: clang.

This patch adds basic modeling of `__builtin_expect`, just to propagate the
(first) argument, making the call transparent.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122908

Files:
  clang/lib/Analysis/FlowSensitive/Transfer.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp


Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2199,6 +2199,32 @@
   });
 }
 
+TEST_F(TransferTest, BuiltinExpect) {
+  std::string Code = R"(
+void target(long Foo) {
+  long Bar = __builtin_expect(Foo, true);
+  /*[[p]]*/
+}
+  )";
+  runDataflow(Code,
+  [](llvm::ArrayRef<
+ std::pair>>
+ Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const auto &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+EXPECT_EQ(Env.getValue(*FooDecl, SkipPast::None),
+  Env.getValue(*BarDecl, SkipPast::None));
+  });
+}
+
 TEST_F(TransferTest, StaticIntSingleVarDecl) {
   std::string Code = R"(
 void target() {
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Casting.h"
@@ -426,6 +427,18 @@
 return;
 
   Env.setStorageLocation(*S, *ArgLoc);
+} else if (S->getDirectCallee() != nullptr &&
+   S->getDirectCallee()->getBuiltinID() ==
+   Builtin::BI__builtin_expect) {
+  assert(S->getNumArgs() > 0);
+  assert(S->getArg(0) != nullptr);
+  // `__builtin_expect` returns by-value, so strip away any potential
+  // references in the argument.
+  auto *ArgLoc = Env.getStorageLocation(
+  *S->getArg(0)->IgnoreParenImpCasts(), SkipPast::Reference);
+  if (ArgLoc == nullptr)
+return;
+  Env.setStorageLocation(*S, *ArgLoc);
 }
   }
 


Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2199,6 +2199,32 @@
   });
 }
 
+TEST_F(TransferTest, BuiltinExpect) {
+  std::string Code = R"(
+void target(long Foo) {
+  long Bar = __builtin_expect(Foo, true);
+  /*[[p]]*/
+}
+  )";
+  runDataflow(Code,
+  [](llvm::ArrayRef<
+ std::pair>>
+ Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+const auto &Env = Results[0].second.Env;
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+EXPECT_EQ(Env.getValue(*FooDecl, SkipPast::None),
+  Env.getValue(*BarDecl, SkipPast::None));
+  });
+}
+
 TEST_F(TransferTest, StaticIntSingleVarDecl) {
   std::string Code = R"(
 void target() {
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Casting.h"
@@ -426,6 +427,18 @@
 return;
 
   Env.setStorageLocation(*S, *ArgLoc);
+} else if (S->getDirectCallee() != nullptr &&
+   S->getDirectCallee()->getBuiltinID() ==
+   Builtin::BI__builtin_expect) {
+  ass

[PATCH] D122874: [clang] Add GNU spelling for no_unqiue_address attribute

2022-04-01 Thread Nikolas Klauser via Phabricator via cfe-commits
philnik added a comment.

In D122874#3422263 , @aaron.ballman 
wrote:

> I'm not opposed, but this does muddy the waters about the target-specific 
> nature of the attribute. Currently, the semantic attribute cannot be used 
> outside of Itanium ABI targets, so it doesn't work on Windows (and we don't 
> want it to -- Microsoft hasn't picked their ABI for the standard attribute 
> and we want to avoid ABI breaks). But should we pick an ABI for the GNU 
> attribute on Windows and just assume that Microsoft gets no say in the ABI 
> for that because it's not their vendor extension? Or, if we disallow the GNU 
> spelling on Windows because we want it to match the ABI of the standard 
> attribute, does it actually help libc++ to expose the GNU spelling?
>
> Also, the change is missing test coverage and a release note.

The best option for libc++ would probably be having the same ABI for 
`__atrribute__((no_unique_address))` and `[[msvc::no_unique_address]]` on 
Windows. We already have code that uses 
`[[no_unique_address]]`/`[[msvc::no_unique_address]]` but clang-cl currently 
supports none of them, so there will be an ABI break if we declare these things 
stable before clang-cl has implemented one of these (although we don't 
//really// care about ABI stability on Windows AFAICT).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122874

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


[PATCH] D122155: Add warning when eval-method is set in the presence of value unsafe floating-point calculations.

2022-04-01 Thread Zahira Ammarguellat via Phabricator via cfe-commits
zahiraam updated this revision to Diff 419763.

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

https://reviews.llvm.org/D122155

Files:
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaAttr.cpp
  clang/test/CodeGen/X86/32bit-behavior.c
  clang/test/Driver/eval-method-with-unsafe-math.c
  clang/test/Sema/eval-method-with-unsafe-math.c

Index: clang/test/Sema/eval-method-with-unsafe-math.c
===
--- /dev/null
+++ clang/test/Sema/eval-method-with-unsafe-math.c
@@ -0,0 +1,56 @@
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -freciprocal-math \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -mreassociate \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu  -fapprox-func \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-FUNC,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -verify \
+// RUN: %s 2>&1 | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -freciprocal-math -mreassociate -fapprox-func \
+// RUN: -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-FUNC,CHECK-ASSOC,CHECK-RECPR,CHECK-PRGM
+
+// RUN: not %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -ffp-eval-method=source \
+// RUN: -verify %s 2>&1 | FileCheck %s --check-prefixes=CHECK-FFP-OPT,CHECK-PRGM
+
+// expected-no-diagnostics
+
+float f1(float a, float b, float c) {
+  a = b + c;
+  return a * b + c;
+}
+
+float f2(float a, float b, float c) {
+  // CHECK-FFP-OPT: option 'ffp-eval-method' cannot be used with '#pragma clang fp reassociate'.
+#pragma clang fp reassociate(on)
+  return (a + b) + c;
+}
+
+float f3(float a, float b, float c) {
+#pragma clang fp reassociate(off)
+  return (a - b) - c;
+}
+
+float f4(float a, float b, float c) {
+#pragma clang fp eval_method(double)
+  // CHECK-FUNC: '#pragma clang fp eval_method' cannot be used with option 'fapprox-func'.
+  // CHECK-ASSOC: '#pragma clang fp eval_method' cannot be used with option 'mreassociate'.
+  // CHECK-RECPR: '#pragma clang fp eval_method' cannot be used with option 'freciprocal'.
+  // CHECK-PRGM: '#pragma clang fp eval_method' cannot be used with '#pragma clang fp reassociate'.
+#pragma clang fp reassociate(on)
+  return (a * c) - (b * c);
+}
Index: clang/test/Driver/eval-method-with-unsafe-math.c
===
--- /dev/null
+++ clang/test/Driver/eval-method-with-unsafe-math.c
@@ -0,0 +1,29 @@
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -fapprox-func \
+// RUN: -Xclang -verify -ffp-eval-method=source %s 2>&1  \
+// RUN: | FileCheck %s --check-prefixes=CHECK-FUNC
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -mreassociate \
+// RUN: -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-RECPR
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -Xclang -mreassociate -ffp-eval-method=source -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR
+
+// RUN: not %clang -Xclang -fexperimental-strict-floating-point \
+// RUN: -Xclang -triple -Xclang x86_64-linux-gnu -Xclang -freciprocal-math \
+// RUN: -Xclang -mreassociate -fapprox-func -ffp-eval-method=source \
+// RUN: -Xclang -verify %s 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ASSOC,CHECK-RECPR,CHECK-FUNC
+
+// CHECK-FUNC: (frontend): option 'ffp-eval-method' cannot be used with option 'fapprox-func'.
+// CHECK-ASSOC: (frontend): option 'ffp-eval-method' cannot be used with option 'mreassociate'.
+// CHECK-RECPR: (frontend): option 'ffp-eval-method' cannot be used with option 'freciprocal'.
Index: clang/test/CodeGen/X86/32bit-behavior.c

[PATCH] D122838: [clang][dataflow] Add support for correlation of boolean (tracked) values

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 419764.
ymandel added a comment.

Add comment about future optimization potential.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122838

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -35,6 +35,7 @@
 using ::testing::IsNull;
 using ::testing::NotNull;
 using ::testing::Pair;
+using ::testing::SizeIs;
 
 class TransferTest : public ::testing::Test {
 protected:
@@ -2410,4 +2411,58 @@
   });
 }
 
+TEST_F(TransferTest, CorrelatedBranches) {
+  std::string Code = R"(
+void target(bool B, bool C) {
+  if (B) {
+return;
+  }
+  (void)0;
+  /*[[p0]]*/
+  if (C) {
+B = true;
+/*[[p1]]*/
+  }
+  if (B) {
+(void)0;
+/*[[p2]]*/
+  }
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, SizeIs(3));
+
+const ValueDecl *CDecl = findValueDecl(ASTCtx, "C");
+ASSERT_THAT(CDecl, NotNull());
+
+{
+  ASSERT_THAT(Results[2], Pair("p0", _));
+  const Environment &Env = Results[2].second.Env;
+  const ValueDecl *BDecl = findValueDecl(ASTCtx, "B");
+  ASSERT_THAT(BDecl, NotNull());
+  auto &BVal = *cast(Env.getValue(*BDecl, SkipPast::None));
+
+  EXPECT_TRUE(Env.flowConditionImplies(Env.makeNot(BVal)));
+}
+
+{
+  ASSERT_THAT(Results[1], Pair("p1", _));
+  const Environment &Env = Results[1].second.Env;
+  auto &CVal = *cast(Env.getValue(*CDecl, SkipPast::None));
+  EXPECT_TRUE(Env.flowConditionImplies(CVal));
+}
+
+{
+  ASSERT_THAT(Results[0], Pair("p2", _));
+  const Environment &Env = Results[0].second.Env;
+  auto &CVal = *cast(Env.getValue(*CDecl, SkipPast::None));
+  EXPECT_TRUE(Env.flowConditionImplies(CVal));
+}
+  });
+}
+
 } // namespace
Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -65,6 +65,49 @@
   return Model.compareEquivalent(Type, *Val1, Env1, *Val2, Env2);
 }
 
+/// Attempts to merge distinct values `Val1` and `Val1` in `Env1` and `Env2`,
+/// respectively, of the same type `Type`. Merging generally produces a single
+/// value that (soundly) approximates the two inputs, although the actual
+/// meaning depends on `Model`.
+static Value *mergeDistinctValues(QualType Type, Value *Val1, Environment &Env1,
+  Value *Val2, const Environment &Env2,
+  Environment::ValueModel &Model) {
+  // Join distinct boolean values preserving information about the constraints
+  // in the respective path conditions. Note: this construction can, in
+  // principle, result in exponential growth in the size of boolean values.
+  // Potential optimizations may be worth considering. For example, represent
+  // the flow condition of each environment using a bool atom and store, in
+  // `DataflowAnalysisContext`, a mapping of bi-conditionals between flow
+  // condition atoms and flow condition constraints. Something like:
+  // \code
+  //   FC1 <=> C1 ^ C2
+  //   FC2 <=> C2 ^ C3 ^ C4
+  //   FC3 <=> (FC1 v FC2) ^ C5
+  // \code
+  // Then, we can track dependencies between flow conditions (e.g. above `FC3`
+  // depends on `FC1` and `FC2`) and modify `flowConditionImplies` to construct
+  // a formula that includes the bi-conditionals for all flow condition atoms in
+  // the transitive set, before invoking the solver.
+  if (auto *Expr1 = dyn_cast(Val1)) {
+for (BoolValue *Constraint : Env1.getFlowConditionConstraints()) {
+  Expr1 = &Env1.makeAnd(*Expr1, *Constraint);
+}
+auto *Expr2 = cast(Val2);
+for (BoolValue *Constraint : Env2.getFlowConditionConstraints()) {
+  Expr2 = &Env1.makeAnd(*Expr2, *Constraint);
+}
+return &Env1.makeOr(*Expr1, *Expr2);
+  }
+
+  // FIXME: Consider destroying `MergedValue` immediately if `ValueModel::merge`
+  // returns false to avoid storing unneeded values in `DACtx`.
+  if (Value *MergedVal = Env1.createValue(Type))
+if (Model.merge(Type, *Val1, Env1, *Val2, Env2, *MergedVal, Env1))
+  return MergedVal;
+
+  return nullptr;
+}
+
 /// Initializes a global storage value.
 stat

[PATCH] D122768: [WIP][Clang] Support capturing structured bindings in lambdas

2022-04-01 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 419765.
cor3ntin added a comment.

Add a diagnostic in openmp mode.

Supporting structured bindings in OpenMP mode requires OpenMP expertise,
so we emit a diagnostic in -fopenmp mode informing that feature is not supported
yet.
My idea is that whether and how openmp should handle this feature should not 
delay support of the c++20 features for people who do not depend on OpenMP.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122768

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/LambdaCapture.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Sema/ScopeInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
  clang/test/SemaCXX/cxx1z-decomposition.cpp
  clang/test/SemaCXX/cxx20-decomposition.cpp
  clang/test/SemaCXX/decomposition-blocks.cpp
  clang/test/SemaCXX/decomposition-openmp.cpp
  clang/tools/libclang/CIndex.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1144,7 +1144,7 @@
 
   Structured binding extensions
   https://wg21.link/p1091r3";>P1091R3
-  Partial
+  Clang 15
 
   
 https://wg21.link/p1381r1";>P1381R1
Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -3350,9 +3350,11 @@
C != CEnd; ++C) {
 if (!C->capturesVariable())
   continue;
-
-if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
-TU)))
+// TODO: hamdle structured bindings here ?
+if (!isa(C->getCapturedVar()))
+  continue;
+if (Visit(MakeCursorVariableRef(cast(C->getCapturedVar()),
+C->getLocation(), TU)))
   return true;
   }
   // Visit init captures
Index: clang/test/SemaCXX/decomposition-openmp.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-openmp.cpp
@@ -0,0 +1,13 @@
+
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fopenmp %s
+
+// FIXME: OpenMP should support capturing structured bindings
+auto f() {
+int i[2] = {};
+auto [a, b] = i; // expected-note 2{{declared here}}
+return [=, &a] {
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+return a + b;
+// expected-error@-1 {{capturing a structured binding is not yet supported in OpenMP}}
+};
+}
Index: clang/test/SemaCXX/decomposition-blocks.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/decomposition-blocks.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -fblocks
+
+struct S {
+  int i : 1;
+  int j;
+};
+
+void run(void (^)());
+void test() {
+  auto [i, j] = S{1, 42}; // expected-note {{'i' declared here}}
+  run(^{
+(void)i; // expected-error {{reference to local binding 'i' declared in enclosing function 'test'}}
+  });
+}
Index: clang/test/SemaCXX/cxx20-decomposition.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx20-decomposition.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template 
+constexpr bool is_same = false;
+template 
+constexpr bool is_same = true;
+
+struct S {
+  int i;
+  int &j;
+};
+
+void check_category() {
+  int a = 42;
+  {
+auto [v, r] = S{1, a};
+(void)[ v, r ] {
+  static_assert(is_same);
+  static_assert(is_same);
+};
+  }
+  {
+

[PATCH] D122838: [clang][dataflow] Add support for correlation of boolean (tracked) values

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel marked an inline comment as done.
ymandel added inline comments.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:79
+for (BoolValue *Constraint : Env1.getFlowConditionConstraints()) {
+  Expr1 = &Env1.makeAnd(*Expr1, *Constraint);
+}

xazax.hun wrote:
> ymandel wrote:
> > sgatev wrote:
> > > xazax.hun wrote:
> > > > Hmm, interesting.
> > > > I think we view every boolean formula at a certain program point 
> > > > implicitly as `FlowConditionAtThatPoint && Formula`. And the flow 
> > > > condition at a program point should already be a disjunction of its 
> > > > predecessors.
> > > > 
> > > > So it would be interpreted as: `(FlowConditionPred1 || 
> > > > FlowConditionPred2) && (FormulaAtPred1 || FormulaAtPred2)`.
> > > > While this is great, this is not the strongest condition we could 
> > > > derive. 
> > > > `(FlowConditionPred1 && FormulaAtPred1)  || (FormulaAtPred2 && 
> > > > FlowConditionPred2)` created by this code snippet is stronger which is 
> > > > great.
> > > > 
> > > > My main concern is whether we would end up seeing an exponential 
> > > > explosion in the size of these formulas in the number of branches 
> > > > following each other in a sequence.
> > > > 
> > > Yeap, I agree this is suboptimal and I believe I'm the one to blame for 
> > > introducing it downstream.
> > > 
> > > I wonder if we can represent the flow condition of each environment using 
> > > a bool atom and have a mapping of bi-conditionals between flow condition 
> > > atoms and flow condition constraints. Something like:
> > > 
> > > ```
> > > FC1 <=> C1 ^ C2
> > > FC2 <=> C2 ^ C3 ^ C4
> > > FC3 <=> (FC1 v FC2) ^ C5
> > > ... 
> > > ```
> > > 
> > > We can use that to simplify the formulas here and in `joinConstraints`. 
> > > The mapping can be stored in `DataflowAnalysisContext`. We can track 
> > > dependencies between flow conditions (e.g. above `FC3` depends on `FC1` 
> > > and `FC2`) and modify `flowConditionImplies` to construct a formula that 
> > > includes the bi-conditionals for all flow condition atoms in the 
> > > transitive set before invoking the solver.
> > > 
> > > I suggest putting the optimization in its own patch. I'd love to look 
> > > into it right after this patch is submitted if both of you think it makes 
> > > sense on a high level.
> > This sounds good to me. That said, I'm not sure how often we'd expect this 
> > to be an issue in practice, since, IIUC, this specialized merge only occurs 
> > when the value is handled differently in the two branches. So, a series of 
> > branches alone won't trigger the exponential behavior.
> Fair point. It might never cause a problem in practice. Since we already have 
> one proposal how to try to fix this if a problem ever surfaces, I'd love to 
> have a comment about this in the code. But I think this is something that 
> probably does not need to be addressed in the near future. 
Good idea -- I reformatted essentially sgatev's response above as a comment in 
the code. 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122838

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


[PATCH] D122822: [Clang][CodeGen]Add constant array support for __builtin_dump_sturct

2022-04-01 Thread Wang Yihan via Phabricator via cfe-commits
yihanaa added a comment.

In D122822#3422463 , @erichkeane 
wrote:

> In D122822#3421089 , @yihanaa wrote:
>
>> I also agree that this is a useful debugging builtin, and no program logic 
>> should be forced to depend on the output of this builtin. It's just used to 
>> print out some useful debugging information
>
> FWIW, @rsmith is the clang-codeowner, so he's the one to convince (and 
> @rjmccall is also a very senior reviewer).  So I wouldn't be able to approve 
> this patch without their consent/agreement.

Thank you for your information, @erichkeane I really hope we can find a 
solution and reach a consensus😊


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122822

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


[PATCH] D122248: [clang][CodeGen]Fix clang crash and add bitfield support in __builtin_dump_struct

2022-04-01 Thread Wang Yihan via Phabricator via cfe-commits
yihanaa marked 3 inline comments as done.
yihanaa added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2113-2117
 if (CanonicalType->isRecordType()) {
-  TmpRes = dumpRecord(CGF, CanonicalType, FieldPtr, Align, Func, Lvl + 1);
+  TmpRes = dumpRecord(CGF, CanonicalType, FieldLV, Align, Func, Lvl + 1);
   Res = CGF.Builder.CreateAdd(TmpRes, Res);
   continue;
 }

rsmith wrote:
> After this patch, this case no longer prints the field name. Eg: 
> https://godbolt.org/z/o7vcbWaEf
> 
> ```
> #include 
> 
> struct A {};
> 
> struct B {
> A a;
> };
> 
> 
> int main() {
> B x;
> __builtin_dump_struct(&x, &printf);
> }
> ```
> 
> now prints:
> 
> ```
> B {
> A {
> }
> }
> ```
> 
> This seems like an important regression; please can you take a look? This 
> also suggests to me that there's a hole in our test coverage.
Thanks for taking the time to review my patch and writing the Compiler Explorer 
examples, I'll take a look at this  problem


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122248

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


[PATCH] D121951: [AMDGPU][OpenCL] Remove "printf and hostcall" diagnostic

2022-04-01 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl accepted this revision.
yaxunl added a comment.

LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121951

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


[PATCH] D122766: [clang] Use forward slash as the path separator for Windows in __FILE__, __builtin_FILE(), and std::source_location

2022-04-01 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In D122766#3420925 , @thakis wrote:

> Do you know what cl.exe does to paths in pdb files? Does it write 
> mixed-slashiness for foo/bar.h includes, or does it write backslashes 
> throughout?

Looks like just backslashes:

  cl /nologo /Zi a.cc && a.exe
  llvm-pdbutil.exe dump --files \src\tmp\a.pdb | grep foo
  - (MD5: B97B3B57F55C87D06A0379A4FBCA51F0) C:\src\tmp\foo\a.h

(To make sure llvm-pdbutil didn't canonicalize, I looked at the pdb in vim and 
the backslashes are there.)

It appears that lld does the same.

> Windows can handle slashes, but several tools can't. I worry that if we do 
> something different than cl, some random corner case might break (dbghelp, or 
> some source server thing or some custom debug info processor somewhere).

Since cl is already mixing back and forward slashes, any tools consuming 
__FILE__ can presumably handle both. So diverging msvc by canonicalizing here 
doesn't seem that risky, we just have to decide in which direction.




Comment at: clang/lib/AST/Expr.cpp:2193
 SmallString<256> Path(PLoc.getFilename());
 Ctx.getLangOpts().remapPathPrefix(Path);
+if (Ctx.getTargetInfo().getTriple().isOSWindows()) {

ayzhao wrote:
> hans wrote:
> > I was going to say perhaps we should put a comment about why Windows needs 
> > different treatment, but as we'd need to put the comment in three different 
> > places, maybe this (remapPathPrefix() and make_preferred()) should be 
> > factored out to a utility function?
> Extracting these lines into a separate function (say, for example, 
> `handle_file_macro(...)`?) makes sense. However, I'm not sure which file this 
> function would belong:
> 
> * The function would need to accept a `LangOpts` and a `TargetInfo` object. 
> Both of these classes are Clang specific.
> * It shouldn't belong in `llvm::sys::path::Style` because the file declaring 
> that namespace exists in the llvm directory, which shouldn't depend on things 
> in Clang.
> * We could put it in `LangOpts`, but `TargetInfo.h` includes `LangOpts.h`, so 
> this would create a circular dependency.
> * `TargetInfo` doesn't make much sense as it doesn't have any code generation 
> / language specific logic.
> 
> WDYT?
It would have to be somewhere in Clang.
Maybe it could be a method in Preprocessor.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122766

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


[PATCH] D122248: [clang][CodeGen]Fix clang crash and add bitfield support in __builtin_dump_struct

2022-04-01 Thread Wang Yihan via Phabricator via cfe-commits
yihanaa added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:2113-2117
 if (CanonicalType->isRecordType()) {
-  TmpRes = dumpRecord(CGF, CanonicalType, FieldPtr, Align, Func, Lvl + 1);
+  TmpRes = dumpRecord(CGF, CanonicalType, FieldLV, Align, Func, Lvl + 1);
   Res = CGF.Builder.CreateAdd(TmpRes, Res);
   continue;
 }

yihanaa wrote:
> rsmith wrote:
> > After this patch, this case no longer prints the field name. Eg: 
> > https://godbolt.org/z/o7vcbWaEf
> > 
> > ```
> > #include 
> > 
> > struct A {};
> > 
> > struct B {
> > A a;
> > };
> > 
> > 
> > int main() {
> > B x;
> > __builtin_dump_struct(&x, &printf);
> > }
> > ```
> > 
> > now prints:
> > 
> > ```
> > B {
> > A {
> > }
> > }
> > ```
> > 
> > This seems like an important regression; please can you take a look? This 
> > also suggests to me that there's a hole in our test coverage.
> Thanks for taking the time to review my patch and writing the Compiler 
> Explorer examples, I'll take a look at this  problem
> After this patch, this case no longer prints the field name. Eg: 
> https://godbolt.org/z/o7vcbWaEf
> 
> ```
> #include 
> 
> struct A {};
> 
> struct B {
> A a;
> };
> 
> 
> int main() {
> B x;
> __builtin_dump_struct(&x, &printf);
> }
> ```
> 
> now prints:
> 
> ```
> B {
> A {
> }
> }
> ```
> 
> This seems like an important regression; please can you take a look? This 
> also suggests to me that there's a hole in our test coverage.

I'm sorry for introducing this bug. 😔 Do you think the following is correct 
behavior? If yes I will try to fix it.
```
struct B {
struct A a = {
}
}
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122248

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


[PATCH] D122908: [clang][dataflow] Add support for clang's `__builtin_expect`.

2022-04-01 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun accepted this revision.
xazax.hun added a comment.

Nice!

Speaking of builtins, it might be great to add tests for 
`__builtin_unreachable`, `__builtin_trap`, `__builtin_debugtrap`. The CFG might 
already have the right shape so we might not need to add any code to support 
them. But it would be nice to know :) Maybe we could even add a comment to 
`VisitCallExpr` why those wouldn't need explicit support.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122908

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


[PATCH] D122529: [ASTMatchers] Output currently matching node on crash

2022-04-01 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D122529#3422158 , @aaron.ballman 
wrote:

> This looks good? to me. :-)
>
> Despite this complicating things by a fair amount, I don't have a better 
> suggestion to offer. LGTM

This was the "nicest" cheapest way I could think to implement this, It's also 
why I thought it best to resubmit this for review.
Annoyingly this is now suboptimal for 64bit code, but I'm not sure it's worth 
writing 2 implementations for 64 and 32 bit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122529

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


[PATCH] D122830: [clang][dataflow] Add support for (built-in) (in)equality operators

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 419793.
ymandel marked 2 inline comments as done.
ymandel added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122830

Files:
  clang/lib/Analysis/FlowSensitive/Transfer.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2410,4 +2410,74 @@
   });
 }
 
+TEST_F(TransferTest, BooleanEquality) {
+  std::string Code = R"(
+void target(bool Bar) {
+  bool Foo = true;
+  if (Bar == Foo) {
+(void)0;
+/*[[p-then]]*/
+  } else {
+(void)0;
+/*[[p-else]]*/
+  }
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p-else", _), Pair("p-then", _)));
+const Environment &EnvElse = Results[0].second.Env;
+const Environment &EnvThen = Results[1].second.Env;
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+auto &BarValThen =
+*cast(EnvThen.getValue(*BarDecl, SkipPast::None));
+EXPECT_TRUE(EnvThen.flowConditionImplies(BarValThen));
+
+auto &BarValElse =
+*cast(EnvElse.getValue(*BarDecl, SkipPast::None));
+EXPECT_FALSE(EnvElse.flowConditionImplies(BarValElse));
+  });
+}
+
+TEST_F(TransferTest, BooleanInequality) {
+  std::string Code = R"(
+void target(bool Bar) {
+  bool Foo = true;
+  if (Bar != Foo) {
+(void)0;
+/*[[p-then]]*/
+  } else {
+(void)0;
+/*[[p-else]]*/
+  }
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p-else", _), Pair("p-then", _)));
+const Environment &EnvElse = Results[0].second.Env;
+const Environment &EnvThen = Results[1].second.Env;
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+auto &BarValThen =
+*cast(EnvThen.getValue(*BarDecl, SkipPast::None));
+EXPECT_FALSE(EnvThen.flowConditionImplies(BarValThen));
+
+auto &BarValElse =
+*cast(EnvElse.getValue(*BarDecl, SkipPast::None));
+EXPECT_TRUE(EnvElse.flowConditionImplies(BarValElse));
+  });
+}
+
 } // namespace
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Casting.h"
@@ -37,6 +38,26 @@
   return E;
 }
 
+static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
+  Environment &Env) {
+  // Equality of booleans involves implicit integral casts. Ignore these casts
+  // for now and focus on the values associated with the wrapped expressions.
+  // FIXME: Consider changing this once the framework offers better support for
+  // integral casts.
+  const Expr *LHSNorm = LHS.IgnoreCasts();
+  const Expr *RHSNorm = RHS.IgnoreCasts();
+  assert(LHSNorm != nullptr);
+  assert(RHSNorm != nullptr);
+
+  if (auto *LHSValue = dyn_cast_or_null(
+  Env.getValue(*LHSNorm, SkipPast::Reference)))
+if (auto *RHSValue = dyn_cast_or_null(
+Env.getValue(*RHSNorm, SkipPast::Reference)))
+  return Env.makeIff(*LHSValue, *RHSValue);
+
+  return Env.makeAtomicBoolValue();
+}
+
 class TransferVisitor : public ConstStmtVisitor {
 public:
   TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env)
@@ -83,8 +104,16 @@
 Env.setValue(Loc, Env.makeOr(LHSVal, RHSVal));
   break;
 }
+case BO_NE:
+case BO_EQ: {
+  auto &LHSEqRHSValue = evaluateBooleanEquality(*LHS, *RHS, Env);
+  auto &Loc = Env.createStorageLocation(*S);
+  Env.setStorageLocation(*S, Loc);
+  Env.setValue(Loc, S->getOpcode() == BO_EQ ? LHSEqRHSValue
+: Env.makeNot(LHSEqRHSValue));
+  break;
+}
 default:
-  // FIXME: Add support for BO_EQ, BO_NE.
   break;
 }
   }
___
cfe-commits mailing list
cfe-commits@li

[PATCH] D122830: [clang][dataflow] Add support for (built-in) (in)equality operators

2022-04-01 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel marked 3 inline comments as done.
ymandel added inline comments.



Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:53
+  if (auto *LHSValue = dyn_cast_or_null(
+  Env.getValue(*LHSNorm, SkipPast::Reference)))
+if (auto *RHSValue = dyn_cast_or_null(

sgatev wrote:
> Do we need to skip past references here? If so, then let's add a test that 
> fails if these are changed to `SkipPast::None`.
Yes -- both of the new tests fail when we don't do this. It's actually hard to 
construct a test that passes without this, since `DeclRefExpr`s of boolean type 
are `ReferenceValue`.



Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:56
+Env.getValue(*RHSNorm, SkipPast::Reference)))
+  return Env.makeIff(*LHSValue, *RHSValue);
+

ymandel wrote:
> xazax.hun wrote:
> > I think a possible alternative way to handle this is to do some sort of 
> > "unification" for the two values. The current approach is superior in the 
> > sense that solving and generating constraints are clearly separate. Also 
> > this might be better for generating useful error messages. In case the 
> > solver ever becomes a bottleneck, I wonder whether replacing this with a 
> > unification step would speed things up a bit. 
> > Although that would only work for the equality case.
> That's a good point. Although I wonder if we could get the best of both 
> worlds by adding a unification pre-step to the solver itself, basically 
> looking for `iff` patterns of this sort. Then, the solver could keep a record 
> of such unifications which it could export for diagnostic purposes.
> 
> On a related note, another potential use of unification is in equivalence 
> testing of environments. Instead of strict equality of flow conditions, for 
> example, I could imagine equivalence up to unification (aka. renaming of 
> atoms).
I think this connects to our discussion here: 
https://reviews.llvm.org/D122838?id=419518#inline-1175582

This seems like another example where tracking equivalences in the environment 
would be beneficial.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122830

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


[clang] ef1e1b3 - [clang][dataflow] Add support for (built-in) (in)equality operators

2022-04-01 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2022-04-01T17:13:21Z
New Revision: ef1e1b3106a544389cf393647cda57b5b0642ef3

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

LOG: [clang][dataflow] Add support for (built-in) (in)equality operators

Adds logical interpretation of built-in equality operators, `==` and `!=`.s

Differential Revision: https://reviews.llvm.org/D122830

Added: 


Modified: 
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp 
b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index a3ff345ce5e84..1f5de9d67c135 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Casting.h"
@@ -37,6 +38,26 @@ static const Expr *skipExprWithCleanups(const Expr *E) {
   return E;
 }
 
+static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
+  Environment &Env) {
+  // Equality of booleans involves implicit integral casts. Ignore these casts
+  // for now and focus on the values associated with the wrapped expressions.
+  // FIXME: Consider changing this once the framework offers better support for
+  // integral casts.
+  const Expr *LHSNorm = LHS.IgnoreCasts();
+  const Expr *RHSNorm = RHS.IgnoreCasts();
+  assert(LHSNorm != nullptr);
+  assert(RHSNorm != nullptr);
+
+  if (auto *LHSValue = dyn_cast_or_null(
+  Env.getValue(*LHSNorm, SkipPast::Reference)))
+if (auto *RHSValue = dyn_cast_or_null(
+Env.getValue(*RHSNorm, SkipPast::Reference)))
+  return Env.makeIff(*LHSValue, *RHSValue);
+
+  return Env.makeAtomicBoolValue();
+}
+
 class TransferVisitor : public ConstStmtVisitor {
 public:
   TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env)
@@ -83,8 +104,16 @@ class TransferVisitor : public 
ConstStmtVisitor {
 Env.setValue(Loc, Env.makeOr(LHSVal, RHSVal));
   break;
 }
+case BO_NE:
+case BO_EQ: {
+  auto &LHSEqRHSValue = evaluateBooleanEquality(*LHS, *RHS, Env);
+  auto &Loc = Env.createStorageLocation(*S);
+  Env.setStorageLocation(*S, Loc);
+  Env.setValue(Loc, S->getOpcode() == BO_EQ ? LHSEqRHSValue
+: Env.makeNot(LHSEqRHSValue));
+  break;
+}
 default:
-  // FIXME: Add support for BO_EQ, BO_NE.
   break;
 }
   }

diff  --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d9b38f0d67170..0e474c84a1b5f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2578,4 +2578,74 @@ TEST_F(TransferTest, AssignMemberBeforeCopy) {
   });
 }
 
+TEST_F(TransferTest, BooleanEquality) {
+  std::string Code = R"(
+void target(bool Bar) {
+  bool Foo = true;
+  if (Bar == Foo) {
+(void)0;
+/*[[p-then]]*/
+  } else {
+(void)0;
+/*[[p-else]]*/
+  }
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p-else", _), Pair("p-then", 
_)));
+const Environment &EnvElse = Results[0].second.Env;
+const Environment &EnvThen = Results[1].second.Env;
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+auto &BarValThen =
+*cast(EnvThen.getValue(*BarDecl, SkipPast::None));
+EXPECT_TRUE(EnvThen.flowConditionImplies(BarValThen));
+
+auto &BarValElse =
+*cast(EnvElse.getValue(*BarDecl, SkipPast::None));
+EXPECT_FALSE(EnvElse.flowConditionImplies(BarValElse));
+  });
+}
+
+TEST_F(TransferTest, BooleanInequality) {
+  std::string Code = R"(
+void target(bool Bar) {
+  bool Foo = true;
+  if (Bar != Foo) {
+(void)0;
+/*[[p-then]]*/
+  } else {
+(void)0;
+/*[[p-else]]*/
+  }
+}
+  )";
+  runDataflow(
+  Code, [](llvm::ArrayRef<
+   std::pair>>
+   Results,
+   ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p-else", _), Pair("p-then", 
_)));
+const Environment &EnvElse = Results[0].second.Env;
+const E

  1   2   >