[PATCH] D124038: [clang] Prevent folding of non-const compound expr

2022-05-15 Thread serge via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG924acb624f58: [clang] Prevent folding of non-const compound 
expr (authored by serge-sans-paille).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124038

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaTemplate/constexpr-instantiate.cpp


Index: clang/test/SemaTemplate/constexpr-instantiate.cpp
===
--- clang/test/SemaTemplate/constexpr-instantiate.cpp
+++ clang/test/SemaTemplate/constexpr-instantiate.cpp
@@ -219,7 +219,9 @@
   static int n;
 };
 template struct B {};
-template constexpr int A::k = *(int[N]){N}; // expected-error 
1+{{negative}}
+template  constexpr int A::k = *(int[N]){N}; // expected-error 
1+{{negative}} expected-note 1+{{not valid in a constant expression}} 
expected-note 1+{{declared here}}
+// expected-error@-1 1+{{must be initialized by a constant expression}}
+
 template int A::n = *(int[N]){0};
 
 template  void f() {
@@ -230,9 +232,9 @@
 };
 
 decltype(A<-3>::k) d1 = 0; // ok
-decltype(char{A<-4>::k}) d2 = 0; // expected-note {{instantiation of }} 
expected-error {{narrow}} expected-note {{cast}}
-decltype(char{A<1>::k}) d3 = 0; // ok
-decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error 
{{narrow}} expected-note {{cast}}
+decltype(char{A<-4>::k}) d2 = 0;// expected-note 
1+{{instantiation of }} expected-error {{narrow}} expected-note {{cast}}
+decltype(char{A<1>::k}) d3 = 0; // expected-note 
1+{{instantiation of }} expected-error {{narrow}} expected-note {{cast}}
+decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error 
{{narrow}} expected-note {{cast}}  expected-note {{instantiation of}}
   }
 }
 
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1596,8 +1596,13 @@
   // Matching GCC, file-scope array compound literals initialized by constants
   // are lifetime-extended.
   constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
-  static_assert(*p == 3, "");
+  static_assert(*p == 3, "");   // expected-error {{static_assert 
expression is not an integral constant expression}}
+// expected-note@-1 {{subexpression 
not valid}}
+// expected-note@-3 {{declared here}}
   static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+  // expected-error@-1 {{static_assert expression is not an integral constant 
expression}}
+  // expected-note@-2 {{subexpression not valid}}
+  // expected-note@-3 {{declared here}}
 
   // Other kinds are not.
   struct X { int a[2]; };
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4259,9 +4259,33 @@
 Info.FFDiag(Conv);
 return false;
   }
+
   APValue Lit;
   if (!Evaluate(Lit, Info, CLE->getInitializer()))
 return false;
+
+  // According to GCC info page:
+  //
+  // 6.28 Compound Literals
+  //
+  // As an optimization, G++ sometimes gives array compound literals longer
+  // lifetimes: when the array either appears outside a function or has a
+  // const-qualified type. If foo and its initializer had elements of type
+  // char *const rather than char *, or if foo were a global variable, the
+  // array would have static storage duration. But it is probably safest
+  // just to avoid the use of array compound literals in C++ code.
+  //
+  // Obey that rule by checking constness for converted array types.
+
+  QualType CLETy = CLE->getType();
+  if (CLETy->isArrayType() && !Type->isArrayType()) {
+if (!CLETy.isConstant(Info.Ctx)) {
+  Info.FFDiag(Conv);
+  Info.Note(CLE->getExprLoc(), diag::note_declared_at);
+  return false;
+}
+  }
+
   CompleteObject LitObj(LVal.Base, , Base->getType());
   return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal, AK);
 } else if (isa(Base) || isa(Base)) {


Index: clang/test/SemaTemplate/constexpr-instantiate.cpp
===
--- clang/test/SemaTemplate/constexpr-instantiate.cpp
+++ clang/test/SemaTemplate/constexpr-instantiate.cpp
@@ -219,7 +219,9 @@
   static int n;
 };
 template struct B {};
-template constexpr int A::k = *(int[N]){N}; // expected-error 1+{{negative}}
+template  constexpr int A::k = *(int[N]){N}; // 

[clang] 924acb6 - [clang] Prevent folding of non-const compound expr

2022-05-15 Thread via cfe-commits

Author: serge-sans-paille
Date: 2022-05-16T07:50:39+02:00
New Revision: 924acb624f58030652ecc8c07db313fde0f31395

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

LOG: [clang] Prevent folding of non-const compound expr

When a non-const compound statement is used to initialize a constexpr pointer,
the pointed value is not const itself and cannot be folded at codegen time.

This matches GCC behavior for compound literal expr arrays.

Fix issue #39324.

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

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constant-expression-cxx11.cpp
clang/test/SemaTemplate/constexpr-instantiate.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 650ba305c48b1..519be84a342b3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4259,9 +4259,33 @@ handleLValueToRValueConversion(EvalInfo , const 
Expr *Conv, QualType Type,
 Info.FFDiag(Conv);
 return false;
   }
+
   APValue Lit;
   if (!Evaluate(Lit, Info, CLE->getInitializer()))
 return false;
+
+  // According to GCC info page:
+  //
+  // 6.28 Compound Literals
+  //
+  // As an optimization, G++ sometimes gives array compound literals longer
+  // lifetimes: when the array either appears outside a function or has a
+  // const-qualified type. If foo and its initializer had elements of type
+  // char *const rather than char *, or if foo were a global variable, the
+  // array would have static storage duration. But it is probably safest
+  // just to avoid the use of array compound literals in C++ code.
+  //
+  // Obey that rule by checking constness for converted array types.
+
+  QualType CLETy = CLE->getType();
+  if (CLETy->isArrayType() && !Type->isArrayType()) {
+if (!CLETy.isConstant(Info.Ctx)) {
+  Info.FFDiag(Conv);
+  Info.Note(CLE->getExprLoc(), diag::note_declared_at);
+  return false;
+}
+  }
+
   CompleteObject LitObj(LVal.Base, , Base->getType());
   return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal, AK);
 } else if (isa(Base) || isa(Base)) {

diff  --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 733653af6369c..b03cb7696aae5 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1596,8 +1596,13 @@ namespace CompoundLiteral {
   // Matching GCC, file-scope array compound literals initialized by constants
   // are lifetime-extended.
   constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
-  static_assert(*p == 3, "");
+  static_assert(*p == 3, "");   // expected-error {{static_assert 
expression is not an integral constant expression}}
+// expected-note@-1 {{subexpression 
not valid}}
+// expected-note@-3 {{declared here}}
   static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
+  // expected-error@-1 {{static_assert expression is not an integral constant 
expression}}
+  // expected-note@-2 {{subexpression not valid}}
+  // expected-note@-3 {{declared here}}
 
   // Other kinds are not.
   struct X { int a[2]; };

diff  --git a/clang/test/SemaTemplate/constexpr-instantiate.cpp 
b/clang/test/SemaTemplate/constexpr-instantiate.cpp
index 31dbdb617a6ac..0a34f63553aae 100644
--- a/clang/test/SemaTemplate/constexpr-instantiate.cpp
+++ b/clang/test/SemaTemplate/constexpr-instantiate.cpp
@@ -219,7 +219,9 @@ namespace Unevaluated {
   static int n;
 };
 template struct B {};
-template constexpr int A::k = *(int[N]){N}; // expected-error 
1+{{negative}}
+template  constexpr int A::k = *(int[N]){N}; // expected-error 
1+{{negative}} expected-note 1+{{not valid in a constant expression}} 
expected-note 1+{{declared here}}
+// expected-error@-1 1+{{must be initialized by a constant expression}}
+
 template int A::n = *(int[N]){0};
 
 template  void f() {
@@ -230,9 +232,9 @@ namespace Unevaluated {
 };
 
 decltype(A<-3>::k) d1 = 0; // ok
-decltype(char{A<-4>::k}) d2 = 0; // expected-note {{instantiation of }} 
expected-error {{narrow}} expected-note {{cast}}
-decltype(char{A<1>::k}) d3 = 0; // ok
-decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error 
{{narrow}} expected-note {{cast}}
+decltype(char{A<-4>::k}) d2 = 0;// expected-note 
1+{{instantiation of }} expected-error {{narrow}} expected-note {{cast}}
+decltype(char{A<1>::k}) d3 = 0; // expected-note 

[PATCH] D115187: [clangd] Expose CoawaitExpr's operand in the AST

2022-05-15 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 429611.
nridge added a comment.

Fix last test case and review comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115187

Files:
  clang-tools-extra/clangd/unittests/FindTargetTests.cpp
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/AST/coroutine-locals-cleanup-exp-namespace.cpp
  clang/test/AST/coroutine-locals-cleanup.cpp
  clang/test/AST/coroutine-source-location-crash-exp-namespace.cpp
  clang/test/AST/coroutine-source-location-crash.cpp
  clang/test/SemaCXX/co_await-ast.cpp

Index: clang/test/SemaCXX/co_await-ast.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/co_await-ast.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -ast-dump -ast-dump-filter=foo %s | FileCheck %s --strict-whitespace
+
+namespace std {
+template  struct coroutine_traits;
+template  struct coroutine_handle {
+  template 
+  coroutine_handle(coroutine_handle &&) noexcept;
+  static coroutine_handle from_address(void *__addr) noexcept;
+};
+} // namespace std
+
+struct executor {};
+struct awaitable {};
+struct awaitable_frame {
+  awaitable get_return_object();
+  void return_void();
+  void unhandled_exception();
+  struct result_t {
+~result_t();
+bool await_ready() const noexcept;
+void await_suspend(std::coroutine_handle) noexcept;
+void await_resume() const noexcept;
+  };
+  result_t initial_suspend() noexcept;
+  result_t final_suspend() noexcept;
+  result_t await_transform(executor) noexcept;
+};
+
+namespace std {
+template <>
+struct coroutine_traits {
+  typedef awaitable_frame promise_type;
+};
+} // namespace std
+
+awaitable foo() {
+  co_await executor();
+}
+
+// Check that CoawaitExpr contains the correct subexpressions, including
+// the operand expression as written in the source.
+
+// CHECK-LABEL: Dumping foo:
+// CHECK: FunctionDecl {{.*}} foo 'awaitable ()'
+// CHECK: `-CoroutineBodyStmt {{.*}}
+// CHECK:   |-CompoundStmt {{.*}}
+// CHECK:   | `-ExprWithCleanups {{.*}} 'void'
+// CHECK:   |   `-CoawaitExpr {{.*}} 'void'
+// CHECK:   | |-CXXTemporaryObjectExpr {{.*}} 'executor' 'void () noexcept' zeroing
+// CHECK:   | |-MaterializeTemporaryExpr {{.*}} 'awaitable_frame::result_t' lvalue
+// CHECK:   | | `-CXXBindTemporaryExpr {{.*}} 'awaitable_frame::result_t' (CXXTemporary {{.*}})
+// CHECK:   | |   `-CXXMemberCallExpr {{.*}} 'awaitable_frame::result_t'
+// CHECK:   | | |-MemberExpr {{.*}} '' .await_transform {{.*}}
+// CHECK:   | | | `-DeclRefExpr {{.*}} 'std::coroutine_traits::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits::promise_type':'awaitable_frame'
+// CHECK:   | | `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void () noexcept' zeroing
+// CHECK:   | |-ExprWithCleanups {{.*}} 'bool'
+// CHECK:   | | `-CXXMemberCallExpr {{.*}} 'bool'
+// CHECK:   | |   `-MemberExpr {{.*}} '' .await_ready {{.*}}
+// CHECK:   | | `-ImplicitCastExpr {{.*}} 'const awaitable_frame::result_t' lvalue 
+// CHECK:   | |   `-OpaqueValueExpr {{.*}} 'awaitable_frame::result_t' lvalue
+// CHECK:   | | `-MaterializeTemporaryExpr {{.*}} 'awaitable_frame::result_t' lvalue
+// CHECK:   | |   `-CXXBindTemporaryExpr {{.*}} 'awaitable_frame::result_t' (CXXTemporary {{.*}})
+// CHECK:   | | `-CXXMemberCallExpr {{.*}} 'awaitable_frame::result_t'
+// CHECK:   | |   |-MemberExpr {{.*}} '' .await_transform {{.*}}
+// CHECK:   | |   | `-DeclRefExpr {{.*}} 'std::coroutine_traits::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits::promise_type':'awaitable_frame'
+// CHECK:   | |   `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void () noexcept' zeroing
+// CHECK:   | |-ExprWithCleanups {{.*}} 'void'
+// CHECK:   | | `-CXXMemberCallExpr {{.*}} 'void'
+// CHECK:   | |   |-MemberExpr {{.*}} '' .await_suspend {{.*}}
+// CHECK:   | |   | `-OpaqueValueExpr {{.*}} 'awaitable_frame::result_t' lvalue
+// CHECK:   | |   |   `-MaterializeTemporaryExpr {{.*}} 'awaitable_frame::result_t' lvalue
+// CHECK:   | |   | `-CXXBindTemporaryExpr {{.*}} 'awaitable_frame::result_t' (CXXTemporary {{.*}})
+// CHECK:   | |   |   `-CXXMemberCallExpr {{.*}} 'awaitable_frame::result_t'
+// CHECK:   | |   | |-MemberExpr {{.*}} '' .await_transform {{.*}}
+// CHECK:   | |   | | `-DeclRefExpr {{.*}} 'std::coroutine_traits::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits::promise_type':'awaitable_frame'
+// CHECK:   | |   | `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void () noexcept' zeroing
+// 

[PATCH] D125655: [HLSL] add -P option for dxc mode.

2022-05-15 Thread Xiang Li via Phabricator via cfe-commits
python3kgae created this revision.
python3kgae added reviewers: amccarth, craig.topper, hans, rnk, 
stefan_reinalter, beanz, pow2clk.
Herald added subscribers: Anastasia, StephenFan.
Herald added a project: All.
python3kgae requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

A new option -P is added for dxc mode.
The format is -P proprecossed_file_name
It will make compile preprocess only and output to proprecossed_file_name.

Internally it will be translated into -E -o proprecossed_file_name.

When -P exists, other output compile option like -Fo will be ignored because 
compiler will run preprocess only.
A warning will be report if this happened.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125655

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/HLSL.cpp
  clang/test/Driver/dxc_P.hlsl

Index: clang/test/Driver/dxc_P.hlsl
===
--- /dev/null
+++ clang/test/Driver/dxc_P.hlsl
@@ -0,0 +1,11 @@
+// RUN: %clang_dxc  -P a.txt -### %s 2>&1 | FileCheck %s
+// RUN: %clang_dxc  -Fo b.txt -P a.txt -### %s 2>&1 | FileCheck %s --check-prefix=WARNING
+
+// Make sure -P option flag which translated into "-E" + "-o" "a.txt".
+// CHECK:"-E" {{.*}} "-o" "a.txt"
+
+// Make sure got warning when -Fo and -P at same time.
+// WARNING: warning: output compiler options like -Fo ignored with Preprocess [-Woption-ignored]
+// WARNING:"-E" {{.*}} "-o" "a.txt"
+
+
Index: clang/lib/Driver/ToolChains/HLSL.cpp
===
--- clang/lib/Driver/ToolChains/HLSL.cpp
+++ clang/lib/Driver/ToolChains/HLSL.cpp
@@ -165,7 +165,6 @@
   for (Arg *A : Args) {
 if (A->getOption().getID() == options::OPT_dxil_validator_version) {
   StringRef ValVerStr = A->getValue();
-  std::string ErrorMsg;
   if (!isLegalValidatorVersion(ValVerStr, getDriver()))
 continue;
 }
@@ -178,6 +177,15 @@
   A->claim();
   continue;
 }
+if (A->getOption().getID() == options::OPT_dxc_P) {
+  // Translate dxc_P into -E and -o.
+  DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_E));
+  // The -o part is done at clang::driver::Driver::GetNamedOutputPath.
+  A->claim();
+  if (Args.getLastArg(options::OPT_o))
+getDriver().Diag(diag::warn_drv_dxc_ignore_output_for_preprocess);
+  continue;
+}
 DAL->append(A);
   }
   // Add default validator version if not set.
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3475,9 +3475,9 @@
 
 static void RenderHLSLOptions(const ArgList , ArgStringList ,
   types::ID InputType) {
-  const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version,
- options::OPT_S, options::OPT_emit_llvm,
- options::OPT_disable_llvm_passes};
+  const unsigned ForwardedArguments[] = {
+  options::OPT_dxil_validator_version, options::OPT_E, options::OPT_S,
+  options::OPT_emit_llvm, options::OPT_disable_llvm_passes};
 
   for (const auto  : ForwardedArguments)
 if (const auto *A = Args.getLastArg(Arg))
Index: clang/lib/Driver/Driver.cpp
===
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -5507,6 +5507,12 @@
   }
 
   llvm::PrettyStackTraceString CrashInfo("Computing output path");
+
+  // For dxc_P,Output to user requested destination.
+  // When dxc_P is set, -Fo (which is aliased to OPT_o) will be ignored.
+  if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_dxc_P))
+return C.addResultFile(FinalOutput->getValue(), );
+
   // Output to a user requested destination?
   if (AtTopLevel && !isa(JA) && !isa(JA)) {
 if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -6790,3 +6790,7 @@
   HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all."
"Same as -S + -emit-llvm + -disable-llvm-passes.">;
 def fcgl : DXCFlag<"fcgl">, Alias;
+def dxc_P : Option<["--", "/", "-"], "P", KIND_SEPARATE>,
+  Group, Flags<[DXCOption, NoXarchOption]>,
+  HelpText<"Preprocess to file (must be used alone)."
+   "Same as -E + -o.">;
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ 

[PATCH] D125517: [Frontend] [Coroutines] Emit error when we found incompatible allocation function in promise_type

2022-05-15 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu marked an inline comment as done.
ChuanqiXu added inline comments.



Comment at: clang/lib/Sema/SemaCoroutine.cpp:1312
+
+  bool PromiseContainNew = [this, ]() -> bool {
+DeclarationName NewName =

erichkeane wrote:
> Slight preference to just have this as a part of LookupAllocationFunction.
Yeah, the code would look better in that way. But it would do redundant lookups 
in that way. So I prefer the current style.


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

https://reviews.llvm.org/D125517

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


[PATCH] D125517: [Frontend] [Coroutines] Emit error when we found incompatible allocation function in promise_type

2022-05-15 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 429595.
ChuanqiXu added a comment.

Address comments.


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

https://reviews.llvm.org/D125517

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaCoroutine.cpp
  clang/test/SemaCXX/coroutine-allocs.cpp

Index: clang/test/SemaCXX/coroutine-allocs.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/coroutine-allocs.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify
+#include "Inputs/std-coroutine.h"
+
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+}
+
+struct Allocator {};
+
+struct resumable {
+  struct promise_type {
+void *operator new(std::size_t sz, Allocator &);
+
+resumable get_return_object() { return {}; }
+auto initial_suspend() { return std::suspend_always(); }
+auto final_suspend() noexcept { return std::suspend_always(); }
+void unhandled_exception() {}
+void return_void(){};
+  };
+};
+
+resumable f1() { // expected-error {{'operator new' provided by 'std::coroutine_traits::promise_type' (aka 'resumable::promise_type') is not usable}}
+  co_return;
+}
+
+// NOTE: Although the argument here is a rvalue reference and the corresponding
+// allocation function in resumable::promise_type have lvalue references, it looks
+// the signature of f2 is invalid. But according to [dcl.fct.def.coroutine]p4:
+//
+//   In the following, pi is an lvalue of type Pi, where p1 denotes the object 
+//   parameter and pi+1 denotes the ith non-object function parameter for a
+//   non-static member function.
+//
+// And [dcl.fct.def.coroutine]p9.1
+//
+//   overload resolution is performed on a function call created by assembling an argument list.
+//   The first argument is the amount of space requested, and has type std::size_­t.
+//   The lvalues p1…pn are the succeeding arguments.
+//
+// So the acctual type passed to resumable::promise_type::operator new is lvalue
+// Allocator. It is allowed  to convert a lvalue to a lvalue reference. So the 
+// following one is valid.
+resumable f2(Allocator &&) {
+  co_return;
+}
+
+resumable f3(Allocator &) {
+  co_return;
+}
+
+resumable f4(Allocator) {
+  co_return;
+}
+
+resumable f5(const Allocator) { // expected-error {{operator new' provided by 'std::coroutine_traits::promise_type' (aka 'resumable::promise_type') is not usable}}
+  co_return;
+}
+
+resumable f6(const Allocator &) { // expected-error {{operator new' provided by 'std::coroutine_traits::promise_type' (aka 'resumable::promise_type') is not usable}}
+  co_return;
+}
Index: clang/lib/Sema/SemaCoroutine.cpp
===
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -1308,10 +1308,33 @@
 
 PlacementArgs.push_back(PDRefExpr.get());
   }
-  S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Class,
-/*DeleteScope*/ Sema::AFS_Both, PromiseType,
-/*isArray*/ false, PassAlignment, PlacementArgs,
-OperatorNew, UnusedResult, /*Diagnose*/ false);
+
+  bool PromiseContainNew = [this, ]() -> bool {
+DeclarationName NewName =
+S.getASTContext().DeclarationNames.getCXXOperatorName(OO_New);
+LookupResult R(S, NewName, Loc, Sema::LookupOrdinaryName);
+
+if (PromiseType->isRecordType())
+  S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
+
+return !R.empty() && !R.isAmbiguous();
+  }();
+
+  auto LookupAllocationFunction = [&]() {
+// [dcl.fct.def.coroutine]p9
+//   The allocation function's name is looked up by searching for it in the
+// scope of the promise type.
+// - If any declarations are found, ...
+// - Otherwise, a search is performed in the global scope.
+Sema::AllocationFunctionScope NewScope = PromiseContainNew ? Sema::AFS_Class : Sema::AFS_Global;
+S.FindAllocationFunctions(Loc, SourceRange(),
+  NewScope,
+  /*DeleteScope*/ Sema::AFS_Both, PromiseType,
+  /*isArray*/ false, PassAlignment, PlacementArgs,
+  OperatorNew, UnusedResult, /*Diagnose*/ false);
+  };
+
+  LookupAllocationFunction();
 
   // [dcl.fct.def.coroutine]p9
   //   If no viable function is found ([over.match.viable]), overload resolution
@@ -1319,22 +1342,7 @@
   // space required as an argument of type std::size_t.
   if (!OperatorNew && !PlacementArgs.empty()) {
 PlacementArgs.clear();
-S.FindAllocationFunctions(Loc, SourceRange(), /*NewScope*/ Sema::AFS_Class,
-  /*DeleteScope*/ Sema::AFS_Both, PromiseType,
-  /*isArray*/ false, PassAlignment, PlacementArgs,
-  OperatorNew, UnusedResult, /*Diagnose*/ false);

[PATCH] D125521: [Diagnostic] Warn if the size argument of memset is character literal zero

2022-05-15 Thread Chuanqi Xu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3bef90dff64f: [Diagnostic] Warn if the size argument of 
memset is character literal (authored by ChuanqiXu).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125521

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/transpose-memset.c


Index: clang/test/Sema/transpose-memset.c
===
--- clang/test/Sema/transpose-memset.c
+++ clang/test/Sema/transpose-memset.c
@@ -11,8 +11,10 @@
 int main(void) {
   memset(array, sizeof(array), 0); // expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}} 
expected-warning{{'memset' will always overflow; destination buffer has size 
40, but size argument is 255}}
+  memset(array, sizeof(array), '\0'); // expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(ptr), 0); // expected-warning{{'size' argument to memset 
is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(*ptr) * 10, 1); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}}
+  memset(ptr, sizeof(ptr), '\0');// expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, 10 * sizeof(int *), 1); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}}
   memset(ptr, 10 * sizeof(int *) + 10, 0xff); // expected-warning{{setting 
buffer to a 'sizeof' expression; did you mean to transpose the last two 
arguments?}} expected-note{{cast the second argument to 'int' to silence}}
   memset(ptr, sizeof(char) * sizeof(int *), 0xff); // 
expected-warning{{setting buffer to a 'sizeof' expression; did you mean to 
transpose the last two arguments?}} expected-note{{cast the second argument to 
'int' to silence}}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -11200,7 +11200,10 @@
 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
 
   auto isLiteralZero = [](const Expr *E) {
-return isa(E) && cast(E)->getValue() == 0;
+return (isa(E) &&
+cast(E)->getValue() == 0) ||
+   (isa(E) &&
+cast(E)->getValue() == 0);
   };
 
   // If we're memsetting or bzeroing 0 bytes, then this is likely an error.


Index: clang/test/Sema/transpose-memset.c
===
--- clang/test/Sema/transpose-memset.c
+++ clang/test/Sema/transpose-memset.c
@@ -11,8 +11,10 @@
 int main(void) {
   memset(array, sizeof(array), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
   memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} expected-warning{{'memset' will always overflow; destination buffer has size 40, but size argument is 255}}
+  memset(array, sizeof(array), '\0'); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(ptr), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(*ptr) * 10, 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}}
+  memset(ptr, sizeof(ptr), '\0');// expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
   memset(ptr, 10 * sizeof(int *), 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} 

[clang] 3bef90d - [Diagnostic] Warn if the size argument of memset is character literal

2022-05-15 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2022-05-16T10:07:01+08:00
New Revision: 3bef90dff64fc717c5d5e33a4d5fb47a4566d04a

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

LOG: [Diagnostic] Warn if the size argument of memset is character literal
zero

Closing https://github.com/llvm/llvm-project/issues/55402

Reviewed By: efriedma

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

Added: 


Modified: 
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/transpose-memset.c

Removed: 




diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0cdceb47b7389..4c4041a2d68ab 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11200,7 +11200,10 @@ static void CheckMemaccessSize(Sema , unsigned BId, 
const CallExpr *Call) {
 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
 
   auto isLiteralZero = [](const Expr *E) {
-return isa(E) && cast(E)->getValue() == 0;
+return (isa(E) &&
+cast(E)->getValue() == 0) ||
+   (isa(E) &&
+cast(E)->getValue() == 0);
   };
 
   // If we're memsetting or bzeroing 0 bytes, then this is likely an error.

diff  --git a/clang/test/Sema/transpose-memset.c 
b/clang/test/Sema/transpose-memset.c
index 2503fe43458c8..7d83b8e336a08 100644
--- a/clang/test/Sema/transpose-memset.c
+++ b/clang/test/Sema/transpose-memset.c
@@ -11,8 +11,10 @@ int *ptr;
 int main(void) {
   memset(array, sizeof(array), 0); // expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}} 
expected-warning{{'memset' will always overflow; destination buffer has size 
40, but size argument is 255}}
+  memset(array, sizeof(array), '\0'); // expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(ptr), 0); // expected-warning{{'size' argument to memset 
is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, sizeof(*ptr) * 10, 1); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}}
+  memset(ptr, sizeof(ptr), '\0');// expected-warning{{'size' argument to 
memset is '0'; did you mean to transpose the last two arguments?}} 
expected-note{{parenthesize the third argument to silence}}
   memset(ptr, 10 * sizeof(int *), 1); // expected-warning{{setting buffer to a 
'sizeof' expression; did you mean to transpose the last two arguments?}} 
expected-note{{cast the second argument to 'int' to silence}}
   memset(ptr, 10 * sizeof(int *) + 10, 0xff); // expected-warning{{setting 
buffer to a 'sizeof' expression; did you mean to transpose the last two 
arguments?}} expected-note{{cast the second argument to 'int' to silence}}
   memset(ptr, sizeof(char) * sizeof(int *), 0xff); // 
expected-warning{{setting buffer to a 'sizeof' expression; did you mean to 
transpose the last two arguments?}} expected-note{{cast the second argument to 
'int' to silence}}



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


[PATCH] D125487: [Tooling/DependencyScanning] Refactor dependency scanning to produce pre-lexed preprocessor directive tokens, instead of minimized sources

2022-05-15 Thread Argyrios Kyrtzidis via Phabricator via cfe-commits
akyrtzi updated this revision to Diff 429580.
akyrtzi added a comment.

Fix issue where an empty '#' in a line was causing the immediately following 
preprocessor directive to be skipped.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125487

Files:
  clang/include/clang/Lex/DependencyDirectivesScanner.h
  clang/include/clang/Lex/Lexer.h
  clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Lex/DependencyDirectivesScanner.cpp
  clang/lib/Lex/Lexer.cpp
  clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
  clang/test/Lexer/minimize_source_to_dependency_directives_invalid_macro_name.c
  clang/test/Lexer/minimize_source_to_dependency_directives_pragmas.c
  clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
  clang/unittests/Tooling/DependencyScannerTest.cpp

Index: clang/unittests/Tooling/DependencyScannerTest.cpp
===
--- clang/unittests/Tooling/DependencyScannerTest.cpp
+++ clang/unittests/Tooling/DependencyScannerTest.cpp
@@ -204,51 +204,5 @@
   EXPECT_EQ(convert_to_slash(Deps[5]), "/root/symlink.h");
 }
 
-namespace dependencies {
-TEST(DependencyScanningFilesystem, IgnoredFilesAreCachedSeparately1) {
-  auto VFS = llvm::makeIntrusiveRefCnt();
-  VFS->addFile("/mod.h", 0,
-   llvm::MemoryBuffer::getMemBuffer("#include \n"
-"// hi there!\n"));
-
-  DependencyScanningFilesystemSharedCache SharedCache;
-  DependencyScanningWorkerFilesystem DepFS(SharedCache, VFS);
-
-  DepFS.enableDirectivesScanningOfAllFiles(); // Let's be explicit for clarity.
-  auto StatusMinimized0 = DepFS.status("/mod.h");
-  DepFS.disableDirectivesScanning("/mod.h");
-  auto StatusFull1 = DepFS.status("/mod.h");
-
-  EXPECT_TRUE(StatusMinimized0);
-  EXPECT_TRUE(StatusFull1);
-  EXPECT_EQ(StatusMinimized0->getSize(), 17u);
-  EXPECT_EQ(StatusFull1->getSize(), 30u);
-  EXPECT_EQ(StatusMinimized0->getName(), StringRef("/mod.h"));
-  EXPECT_EQ(StatusFull1->getName(), StringRef("/mod.h"));
-}
-
-TEST(DependencyScanningFilesystem, IgnoredFilesAreCachedSeparately2) {
-  auto VFS = llvm::makeIntrusiveRefCnt();
-  VFS->addFile("/mod.h", 0,
-   llvm::MemoryBuffer::getMemBuffer("#include \n"
-"// hi there!\n"));
-
-  DependencyScanningFilesystemSharedCache SharedCache;
-  DependencyScanningWorkerFilesystem DepFS(SharedCache, VFS);
-
-  DepFS.disableDirectivesScanning("/mod.h");
-  auto StatusFull0 = DepFS.status("/mod.h");
-  DepFS.enableDirectivesScanningOfAllFiles();
-  auto StatusMinimized1 = DepFS.status("/mod.h");
-
-  EXPECT_TRUE(StatusFull0);
-  EXPECT_TRUE(StatusMinimized1);
-  EXPECT_EQ(StatusFull0->getSize(), 30u);
-  EXPECT_EQ(StatusMinimized1->getSize(), 17u);
-  EXPECT_EQ(StatusFull0->getName(), StringRef("/mod.h"));
-  EXPECT_EQ(StatusMinimized1->getName(), StringRef("/mod.h"));
-}
-
-} // end namespace dependencies
 } // end namespace tooling
 } // end namespace clang
Index: clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
===
--- clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
+++ clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
@@ -14,39 +14,58 @@
 using namespace clang;
 using namespace clang::dependency_directives_scan;
 
-static bool minimizeSourceToDependencyDirectives(StringRef Input,
- SmallVectorImpl ) {
-  SmallVector Directives;
-  return scanSourceForDependencyDirectives(Input, Out, Directives);
+static bool minimizeSourceToDependencyDirectives(
+StringRef Input, SmallVectorImpl ,
+SmallVectorImpl ,
+SmallVectorImpl ) {
+  Out.clear();
+  Tokens.clear();
+  Directives.clear();
+  if (scanSourceForDependencyDirectives(Input, Tokens, Directives))
+return true;
+
+  raw_svector_ostream OS(Out);
+  printDependencyDirectivesAsSource(Input, Directives, OS);
+  if (!Out.empty() && Out.back() != '\n')
+Out.push_back('\n');
+  Out.push_back('\0');
+  Out.pop_back();
+
+  return false;
 }
 
-static bool
-minimizeSourceToDependencyDirectives(StringRef Input,
- SmallVectorImpl ,
- SmallVectorImpl ) {
-  return scanSourceForDependencyDirectives(Input, Out, Directives);
+static bool minimizeSourceToDependencyDirectives(StringRef Input,
+ SmallVectorImpl ) {
+  SmallVector Tokens;
+  SmallVector Directives;
+  return minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives);
 }
 
 namespace {
 
 TEST(MinimizeSourceToDependencyDirectivesTest, Empty) {
   SmallVector Out;
+  SmallVector Tokens;
   SmallVector Directives;
 
-  ASSERT_FALSE(minimizeSourceToDependencyDirectives("", Out, 

[PATCH] D125635: Move NumStmts from CompoundStmtBitfields to fields of CompoundStmt

2022-05-15 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

On the one hand, I'm not sure 8M statements in a block — or 1M, for that matter 
— is an unreasonable implementation limit.  On the other hand, this patch looks 
like it only changes overall memory use on 32-bit hosts, because `CompoundStmt` 
has a 32-bit field prior to its pointer-aligned trailing storage.  Can you 
check how memory use actually changes?  Ideally you'd be able to test it on a 
32-bit host, but if you don't have one, just knowing the raw count of allocated 
`CompoundStmt` objects for a few large compilation benchmarks would be nice — 
the ideal stress test is probably something in C++ that instantiates a lot of 
function templates.

This is finicky, but: the `FooBitfields` structs are designed to be <= 64 bits, 
not just a 32-bit bitfield.  Currently, `CompoundStmt` puts the leading brace 
location in there just to save some space on 32-bit hosts, but it seems to me 
that, if we're going to put a 32-bit count somewhere, it'd be nice to put it in 
the `CompoundStmtBitfields` and move the leading brace location out to the main 
class.  I know, it's finicky.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125635

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


[PATCH] D125626: [clang-format][NFC] Don't call mightFitOnOneLine() unnecessarily

2022-05-15 Thread Owen Pan via Phabricator via cfe-commits
owenpan updated this revision to Diff 429560.
owenpan added a reviewer: sstwcw.
owenpan removed a subscriber: sstwcw.
owenpan added a comment.

Fixes typos and makes `KeepElseBraces` depend on `KeepIfBraces`.


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

https://reviews.llvm.org/D125626

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h

Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -92,12 +92,12 @@
   void reset();
   void parseFile();
   bool precededByCommentOrPPDirective() const;
-  bool parseLevel(bool HasOpeningBrace, bool CanContainBracedList,
+  bool parseLevel(const FormatToken *OpeningBrace, bool CanContainBracedList,
   IfStmtKind *IfKind = nullptr,
   TokenType NextLBracesType = TT_Unknown);
   bool mightFitOnOneLine(UnwrappedLine ) const;
   IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u,
-bool MunchSemi = true,
+bool MunchSemi = true, bool KeepBraces = true,
 bool UnindentWhitesmithsBraces = false,
 bool CanContainBracedList = true,
 TokenType NextLBracesType = TT_Unknown);
@@ -126,7 +126,7 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
-  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
+  void parseLoopBody(bool KeepBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -394,7 +394,7 @@
   if (Style.Language == FormatStyle::LK_TextProto)
 parseBracedList();
   else
-parseLevel(/*HasOpeningBrace=*/false, /*CanContainBracedList=*/true);
+parseLevel(/*OpeningBrace=*/nullptr, /*CanContainBracedList=*/true);
   // Make sure to format the remaining tokens.
   //
   // LK_TextProto is special since its top-level is parsed as the body of a
@@ -463,13 +463,13 @@
 }
 
 /// \brief Parses a level, that is ???.
-/// \param HasOpeningBrace If that level is started by an opening brace.
+/// \param OpeningBrace Opening brace (\p nullptr if absent) of that level
 /// \param CanContainBracedList If the content can contain (at any level) a
 /// braced list.
 /// \param NextLBracesType The type for left brace found in this level.
-/// \returns true if a simple block, or false otherwise. (A simple block has a
-/// single statement.)
-bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
+/// \returns true if a simple block of if/else/for/while, or false otherwise.
+/// (A simple block has a single statement.)
+bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
  bool CanContainBracedList,
  IfStmtKind *IfKind,
  TokenType NextLBracesType) {
@@ -492,9 +492,9 @@
 else if (FormatTok->getType() == TT_MacroBlockEnd)
   kind = tok::r_brace;
 
-auto ParseDefault = [this, HasOpeningBrace, IfKind, NextLevelLBracesType,
+auto ParseDefault = [this, OpeningBrace, IfKind, NextLevelLBracesType,
  , ] {
-  parseStructuralElement(IfKind, !HasOpeningBrace, NextLevelLBracesType,
+  parseStructuralElement(IfKind, !OpeningBrace, NextLevelLBracesType,
  HasLabel ? nullptr : );
   ++StatementCount;
   assert(StatementCount > 0 && "StatementCount overflow!");
@@ -519,16 +519,17 @@
   tryToParseBracedList())
 continue;
   parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,
- /*MunchSemi=*/true, /*UnindentWhitesmithBraces=*/false,
- CanContainBracedList,
- /*NextLBracesType=*/NextLBracesType);
+ /*MunchSemi=*/true, /*KeepBraces=*/true,
+ /*UnindentWhitesmithsBraces=*/false, CanContainBracedList,
+ NextLBracesType);
   ++StatementCount;
   assert(StatementCount > 0 && "StatementCount overflow!");
   addUnwrappedLine();
   break;
 case tok::r_brace:
-  if (HasOpeningBrace) {
-if (!Style.RemoveBracesLLVM)
+  if (OpeningBrace) {
+if (!Style.RemoveBracesLLVM ||
+!OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace))
   return false;
 if (FormatTok->isNot(tok::r_brace) || StatementCount != 1 || HasLabel ||
 IsPrecededByCommentOrPPDirective ||
@@ -797,11 +798,10 @@
   return Line.Level * 

[PATCH] D125513: [clang-cl] Add /Zc:wchar_t- option

2022-05-15 Thread Pengxuan Zheng via Phabricator via cfe-commits
pzheng marked an inline comment as done.
pzheng added inline comments.



Comment at: clang/include/clang/Driver/Options.td:6663
 def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
 def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">;

thakis wrote:
> Can you move this up (next to the `-` flag), and add a help text? It's no 
> longer ignored now (if you do e.g. `/Zc:wchar_t- /Zc:wchar_t`)
Thanks for the comment, @thakis. I have made the change accordingly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125513

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


[PATCH] D125513: [clang-cl] Add /Zc:wchar_t- option

2022-05-15 Thread Pengxuan Zheng via Phabricator via cfe-commits
pzheng updated this revision to Diff 429559.
pzheng added a comment.

Address @thakis's comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125513

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/cl-zc.cpp


Index: clang/test/Driver/cl-zc.cpp
===
--- clang/test/Driver/cl-zc.cpp
+++ clang/test/Driver/cl-zc.cpp
@@ -47,7 +47,7 @@
 // RUN: %clang_cl /c -### /Zc:wchar_t -- %s 2>&1 | FileCheck 
-check-prefix=WCHAR_T-ON %s
 // WCHAR_T-ON-NOT: argument unused during compilation
 // RUN: %clang_cl /c -### /Zc:wchar_t- -- %s 2>&1 | FileCheck 
-check-prefix=WCHAR_T-OFF %s
-// WCHAR_T-OFF: argument unused during compilation
+// WCHAR_T-OFF: "-fno-wchar"
 
 // RUN: %clang_cl /c -### /Zc:auto -- %s 2>&1 | FileCheck 
-check-prefix=AUTO-ON %s
 // AUTO-ON-NOT: argument unused during compilation
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7589,6 +7589,11 @@
   CmdArgs.push_back("-fno-dllexport-inlines");
  }
 
+ if (Args.hasFlag(options::OPT__SLASH_Zc_wchar_t_,
+  options::OPT__SLASH_Zc_wchar_t, false)) {
+   CmdArgs.push_back("-fno-wchar");
+ }
+
   Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
   Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
   if (MostGeneralArg && BestCaseArg)
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -6487,6 +6487,10 @@
 def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
   HelpText<"Disable two-phase name lookup in templates (default)">,
   Alias;
+def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">,
+  HelpText<"Enable C++ builtin type wchar_t (default)">;
+def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">,
+  HelpText<"Disable C++ builtin type wchar_t">;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>,
@@ -6674,7 +6678,6 @@
 def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
 def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
 def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
-def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">;
 def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">;
 def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">;


Index: clang/test/Driver/cl-zc.cpp
===
--- clang/test/Driver/cl-zc.cpp
+++ clang/test/Driver/cl-zc.cpp
@@ -47,7 +47,7 @@
 // RUN: %clang_cl /c -### /Zc:wchar_t -- %s 2>&1 | FileCheck -check-prefix=WCHAR_T-ON %s
 // WCHAR_T-ON-NOT: argument unused during compilation
 // RUN: %clang_cl /c -### /Zc:wchar_t- -- %s 2>&1 | FileCheck -check-prefix=WCHAR_T-OFF %s
-// WCHAR_T-OFF: argument unused during compilation
+// WCHAR_T-OFF: "-fno-wchar"
 
 // RUN: %clang_cl /c -### /Zc:auto -- %s 2>&1 | FileCheck -check-prefix=AUTO-ON %s
 // AUTO-ON-NOT: argument unused during compilation
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7589,6 +7589,11 @@
   CmdArgs.push_back("-fno-dllexport-inlines");
  }
 
+ if (Args.hasFlag(options::OPT__SLASH_Zc_wchar_t_,
+  options::OPT__SLASH_Zc_wchar_t, false)) {
+   CmdArgs.push_back("-fno-wchar");
+ }
+
   Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
   Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
   if (MostGeneralArg && BestCaseArg)
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -6487,6 +6487,10 @@
 def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
   HelpText<"Disable two-phase name lookup in templates (default)">,
   Alias;
+def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">,
+  HelpText<"Enable C++ builtin type wchar_t (default)">;
+def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">,
+  HelpText<"Disable C++ builtin type wchar_t">;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>,
@@ -6674,7 +6678,6 @@
 def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
 def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
 def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
-def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">;
 def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">;
 def _SLASH_ZH_SHA_256 : 

[PATCH] D125513: [clang-cl] Add /Zc:wchar_t- option

2022-05-15 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

Seems generally ok.




Comment at: clang/include/clang/Driver/Options.td:6663
 def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
 def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">;

Can you move this up (next to the `-` flag), and add a help text? It's no 
longer ignored now (if you do e.g. `/Zc:wchar_t- /Zc:wchar_t`)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125513

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


[libunwind] fd86423 - Revert "[libunwind][AArch64] Add support for DWARF expression for RA_SIGN_STATE."

2022-05-15 Thread Daniel Kiss via cfe-commits

Author: Daniel Kiss
Date: 2022-05-15T21:42:07+02:00
New Revision: fd864238fca1435cb1ceffdca0d4294cf3419ac7

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

LOG: Revert "[libunwind][AArch64] Add support for DWARF expression for 
RA_SIGN_STATE."

This reverts commit f6366ef7f4f3cf1182fd70e0c50a9fa54374b612.

Added: 


Modified: 
libunwind/src/DwarfInstructions.hpp

Removed: 
libunwind/test/aarch64.ra_sign_state.pass.cpp



diff  --git a/libunwind/src/DwarfInstructions.hpp 
b/libunwind/src/DwarfInstructions.hpp
index a4fac5afa9b82..ab83b0c87acdc 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -72,10 +72,6 @@ class DwarfInstructions {
 assert(0 && "getCFA(): unknown location");
 __builtin_unreachable();
   }
-#if defined(_LIBUNWIND_TARGET_AARCH64)
-  static bool getRA_SIGN_STATE(A , R registers, pint_t cfa,
-   PrologInfo );
-#endif
 };
 
 template 
@@ -170,21 +166,6 @@ v128 DwarfInstructions::getSavedVectorRegister(
   }
   _LIBUNWIND_ABORT("unsupported restore location for vector register");
 }
-#if defined(_LIBUNWIND_TARGET_AARCH64)
-template 
-bool DwarfInstructions::getRA_SIGN_STATE(A , R registers,
-   pint_t cfa, PrologInfo ) 
{
-  pint_t raSignState;
-  auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
-  if (regloc.location == CFI_Parser::kRegisterUnused)
-raSignState = static_cast(regloc.value);
-  else
-raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
-
-  // Only bit[0] is meaningful.
-  return raSignState & 0x01;
-}
-#endif
 
 template 
 int DwarfInstructions::stepWithDwarf(A , pint_t pc,
@@ -254,7 +235,7 @@ int DwarfInstructions::stepWithDwarf(A , 
pint_t pc,
   // restored. autia1716 is used instead of autia as autia1716 assembles
   // to a NOP on pre-v8.3a architectures.
   if ((R::getArch() == REGISTERS_ARM64) &&
-  getRA_SIGN_STATE(addressSpace, registers, cfa, prolog) &&
+  prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value &&
   returnAddress != 0) {
 #if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
 return UNW_ECROSSRASIGNING;

diff  --git a/libunwind/test/aarch64.ra_sign_state.pass.cpp 
b/libunwind/test/aarch64.ra_sign_state.pass.cpp
deleted file mode 100644
index 1e09c936d664b..0
--- a/libunwind/test/aarch64.ra_sign_state.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// -*- C++ -*-
-//===--===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===--===//
-
-// REQUIRES: linux && target={{aarch64-.+}}
-
-// This test ensures the .cfi_negate_ra_state the RA_SIGN_STATE pseudo register
-// could be set directly set by a DWARF expression and the unwinder handles it
-// correctly. The two directives can't be mixed in one CIE/FDE sqeuence.
-
-#include 
-
-__attribute__((noinline, target("branch-protection=pac-ret+leaf")))
-void bar() {
-  // ".cfi_negate_ra_state" is emitted by the compiler.
-  throw 1;
-}
-
-__attribute__((noinline, target("branch-protection=none")))
-void foo() {
-  // Here a DWARF expression sets RA_SIGN_STATE.
-  // The LR is signed manually and stored on the stack.
-  asm volatile(
-  ".cfi_escape 0x16,"// DW_CFA_val_expression
-"34,"// REG_34(RA_SIGN_STATE)
- "1,"// expression_length(1)
-"0x31\n" // DW_OP_lit1
-  "add sp, sp, 16\n" // Restore SP's value before the stack frame is
- // created.
-  "paciasp\n"// Sign the LR.
-  "str lr, [sp, -0x8]\n" // Overwrite LR on the stack.
-  "sub sp, sp, 16\n" // Restore SP's value.
-  );
-  bar();
-  _Exit(-1);
-}
-
-__attribute__((noinline, target("branch-protection=pac-ret")))
-void bazz() {
-  // ".cfi_negate_ra_state" is emitted by the compiler.
-  try {
-foo();
-  } catch (int i) {
-if (i == 1)
-  throw i;
-throw 2;
-  }
-}
-
-int main() {
-  try {
-bazz();
-  } catch (int i) {
-if (i == 1)
-  _Exit(0);
-  }
-  return -1;
-}



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


[PATCH] D123952: [FPEnv] Allow CompoundStmt to keep FP options

2022-05-15 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff added a comment.

In D123952#3488638 , @aaron.ballman 
wrote:

> Thanks for working on this! One thing that's not clear to me is what bugs 
> this is solving -- the test coverage only shows a change to textual AST 
> dumping behavior. Is this otherwise expected to be an NFC change, or should 
> there be some codegen tests that show a difference in behavior?

Thanks for feedback!
This change is a prerequisite for implementation of pragma STDC FENV_ROUND in 
D125625 . FP options stored in CompoundStmt 
are used to set up proper rounding mode on entry to compound statement.




Comment at: clang/include/clang/AST/Stmt.h:134
+/// floating-point features.
+unsigned HasFPFeatures : 1;
+

aaron.ballman wrote:
> I don't think this is a bad approach, but it does further reduce the number 
> of statements we support in a compound statement.
> 
> There's a part of me that wonders if the approach is to introduce a new AST 
> node for a stateful compound statement; I suspect if we dig around, we'll 
> find other pragmas that want to behave similar to floating-point feature 
> pragmas (the idea of a pragma scoped to a block is not really new). Having 
> something more general means we're less likely to keep stealing bits here.
Possible solution is presented in D125635.
Spending a bit for state variable reduces number of bits for NumStmts to 23 
bits (about 8M statements). And yes, other pragmas (or anything else) can 
require allocation of additional bits. As the number of statements is 
potentially large, it would be better to keep in an integer rather than 
bit-field.



Comment at: clang/include/clang/Sema/ScopeInfo.h:77-78
 
-  CompoundScopeInfo(bool IsStmtExpr) : IsStmtExpr(IsStmtExpr) {}
+  /// FP options at the beginning of the compound statement, prior to
+  /// any pragma.
+  FPOptions FPFeatures;

aaron.ballman wrote:
> So these are the initial FPOptions inherited by the scope from its 
> surrounding context? And it's never updated by a pragma?
Yes, this FPOption is used to calculate the effect of pragmas in the compound 
statement as a difference with FPOptions stored in Sema, so that CompoundStmt 
keeps only FP features that are changed in it.



Comment at: clang/lib/AST/TextNodeDumper.cpp:2372-2376
+void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
+  VisitStmt(S);
+  if (S->hasStoredFPFeatures())
+printFPOptions(S->getStoredFPFeatures());
+}

aaron.ballman wrote:
> Should we have a similar change for the JSON node dumper?
Implemented.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123952

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


[PATCH] D125635: Move NumStmts from CompoundStmtBitfields to fields of CompoundStmt

2022-05-15 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: aaron.ballman, rsmith, rjmccall.
Herald added a project: All.
sepavloff requested review of this revision.
Herald added a project: clang.

Number of statements in CompoundStmt is kept in a bit-field of Stmt
common part. The field has 24 bits for the number. To allocate a new
bit field (as attempted in https://reviews.llvm.org/D123952), this
number must be reduced, maximal number of statements in a compound
statement becomes smaller. It can result in compilation errors of some
programs.

With this change the number of statements is kept in a field of
CompoundStmt rather than in bit-field of the common part.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125635

Files:
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/Stmt.cpp


Index: clang/lib/AST/Stmt.cpp
===
--- clang/lib/AST/Stmt.cpp
+++ clang/lib/AST/Stmt.cpp
@@ -363,14 +363,13 @@
 
 CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB,
SourceLocation RB)
-: Stmt(CompoundStmtClass), RBraceLoc(RB) {
-  CompoundStmtBits.NumStmts = Stmts.size();
+: Stmt(CompoundStmtClass), NumStmts(Stmts.size()), RBraceLoc(RB) {
   setStmts(Stmts);
   CompoundStmtBits.LBraceLoc = LB;
 }
 
 void CompoundStmt::setStmts(ArrayRef Stmts) {
-  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
+  assert(NumStmts == Stmts.size() &&
  "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
 
   std::copy(Stmts.begin(), Stmts.end(), body_begin());
@@ -388,7 +387,7 @@
   void *Mem =
   C.Allocate(totalSizeToAlloc(NumStmts), alignof(CompoundStmt));
   CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
-  New->CompoundStmtBits.NumStmts = NumStmts;
+  New->NumStmts = NumStmts;
   return New;
 }
 
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -128,8 +128,6 @@
 
 unsigned : NumStmtBits;
 
-unsigned NumStmts : 32 - NumStmtBits;
-
 /// The location of the opening "{".
 SourceLocation LBraceLoc;
   };
@@ -1406,6 +1404,8 @@
   friend class ASTStmtReader;
   friend TrailingObjects;
 
+  unsigned NumStmts;
+
   /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
   SourceLocation RBraceLoc;
 
@@ -1420,16 +1420,15 @@
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
-  : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
-CompoundStmtBits.NumStmts = 0;
+  : Stmt(CompoundStmtClass), NumStmts(0), RBraceLoc(Loc) {
 CompoundStmtBits.LBraceLoc = Loc;
   }
 
   // Build an empty compound statement.
   static CompoundStmt *CreateEmpty(const ASTContext , unsigned NumStmts);
 
-  bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
-  unsigned size() const { return CompoundStmtBits.NumStmts; }
+  bool body_empty() const { return NumStmts == 0; }
+  unsigned size() const { return NumStmts; }
 
   using body_iterator = Stmt **;
   using body_range = llvm::iterator_range;


Index: clang/lib/AST/Stmt.cpp
===
--- clang/lib/AST/Stmt.cpp
+++ clang/lib/AST/Stmt.cpp
@@ -363,14 +363,13 @@
 
 CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB,
SourceLocation RB)
-: Stmt(CompoundStmtClass), RBraceLoc(RB) {
-  CompoundStmtBits.NumStmts = Stmts.size();
+: Stmt(CompoundStmtClass), NumStmts(Stmts.size()), RBraceLoc(RB) {
   setStmts(Stmts);
   CompoundStmtBits.LBraceLoc = LB;
 }
 
 void CompoundStmt::setStmts(ArrayRef Stmts) {
-  assert(CompoundStmtBits.NumStmts == Stmts.size() &&
+  assert(NumStmts == Stmts.size() &&
  "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
 
   std::copy(Stmts.begin(), Stmts.end(), body_begin());
@@ -388,7 +387,7 @@
   void *Mem =
   C.Allocate(totalSizeToAlloc(NumStmts), alignof(CompoundStmt));
   CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
-  New->CompoundStmtBits.NumStmts = NumStmts;
+  New->NumStmts = NumStmts;
   return New;
 }
 
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -128,8 +128,6 @@
 
 unsigned : NumStmtBits;
 
-unsigned NumStmts : 32 - NumStmtBits;
-
 /// The location of the opening "{".
 SourceLocation LBraceLoc;
   };
@@ -1406,6 +1404,8 @@
   friend class ASTStmtReader;
   friend TrailingObjects;
 
+  unsigned NumStmts;
+
   /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
   SourceLocation RBraceLoc;
 
@@ -1420,16 +1420,15 @@
 
   // Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
-  : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
-

[PATCH] D124688: [clangd] parse all make_unique-like functions in preamble

2022-05-15 Thread Tobias Ribizel via Phabricator via cfe-commits
upsj added a comment.

@sammccall @nridge can you give this another look? :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124688

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


[PATCH] D124749: [clang-format] Handle Verilog preprocessor directives

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

The two parents of this revision change the same file, so the build bot says 
patch does not apply.  Does that mean I have to submit the parent patches with 
less context?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124749

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


[PATCH] D125626: [clang-format][NFC] Don't call mightFitOnOneLine() unnecessarily

2022-05-15 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius accepted this revision.
curdeius added a comment.
This revision is now accepted and ready to land.

LGTM. I like it! Thanks!




Comment at: clang/lib/Format/UnwrappedLineParser.cpp:523
+ /*MunchSemi=*/true, /*KeepBraces=*/true,
+ /*UnindentWhitesmithBraces=*/false, CanContainBracedList,
+ NextLBracesType);





Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2832
 
-  parseLoopBody(false, Style.BraceWrapping.BeforeWhile);
+  parseLoopBody(true, Style.BraceWrapping.BeforeWhile);
 




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125626

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


[PATCH] D124749: [clang-format] Handle Verilog preprocessor directives

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/FormatTokenLexer.cpp:1105
+  static const llvm::Regex VerilogToken(
+  "^(\'|``?|((\r?\n|\r)|[^[:space:]])*)");
+

HazardyKnusperkeks wrote:
> Consider a raw string, for a better reading.
You mean like this?

static const llvm::Regex VerilogToken(R"re(^('|``?|\\(\\)re"
  "(\r?\n|\r)|[^[:space:]])*)");




Comment at: clang/lib/Format/FormatTokenLexer.cpp:1129
 void FormatTokenLexer::readRawToken(FormatToken ) {
-  Lex->LexFromRawLexer(Tok.Tok);
+  if (!(Style.isVerilog() && readRawTokenVerilogSpecific(Tok.Tok)))
+Lex->LexFromRawLexer(Tok.Tok);

HazardyKnusperkeks wrote:
> Otherwise I don't see why you change that.
The function is only supposed to be used for Verilog, so `&&` is correct. If 
you mean why this part is different from D121758, I changed the name from 
`readRawTokenLanguageSpecific` to `readRawTokenVerilogSpecific` as suggested by 
a reviewer. Then I moved the check for language out of that function like what 
`tryParseJSRegexLiteral` does.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124749

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


[PATCH] D124749: [clang-format] Handle Verilog preprocessor directives

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 429532.
sstwcw added a comment.

- add tests and remove __LINE__ and __FILE__ special cases


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124749

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/FormatTokenLexer.cpp
  clang/lib/Format/FormatTokenLexer.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTestVerilog.cpp

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -43,6 +43,30 @@
   }
 };
 
+TEST_F(FormatTestVerilog, Delay) {
+  // Delay by the default unit.
+  verifyFormat("#0;");
+  verifyFormat("#1;");
+  verifyFormat("#10;");
+  verifyFormat("#1.5;");
+  // Explicit unit.
+  verifyFormat("#1fs;");
+  verifyFormat("#1.5fs;");
+  verifyFormat("#1ns;");
+  verifyFormat("#1.5ns;");
+  verifyFormat("#1us;");
+  verifyFormat("#1.5us;");
+  verifyFormat("#1ms;");
+  verifyFormat("#1.5ms;");
+  verifyFormat("#1s;");
+  verifyFormat("#1.5s;");
+  // The following expression should be on the same line.
+  verifyFormat("#1 x = x;");
+  EXPECT_EQ("#1 x = x;", format("#1\n"
+"x = x;",
+getLLVMStyle(FormatStyle::LK_Verilog)));
+}
+
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
@@ -114,5 +138,113 @@
"  {x} = {x};");
 }
 
+TEST_F(FormatTestVerilog, Preprocessor) {
+  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.ColumnLimit = 20;
+
+  // Macro definitions.
+  EXPECT_EQ("`define X  \\\n"
+"  if (x)   \\\n"
+"x = x;",
+format("`define X if(x)x=x;", Style));
+  EXPECT_EQ("`define X(x)   \\\n"
+"  if (x)   \\\n"
+"x = x;",
+format("`define X(x) if(x)x=x;", Style));
+  EXPECT_EQ("`define X  \\\n"
+"  x = x;   \\\n"
+"  x = x;",
+format("`define X x=x;x=x;", Style));
+  // Macro definitions with invocations inside.
+  EXPECT_EQ("`define LIST   \\\n"
+"  `ENTRY   \\\n"
+"  `ENTRY",
+format("`define LIST \\\n"
+   "`ENTRY \\\n"
+   "`ENTRY",
+   Style));
+  EXPECT_EQ("`define LIST   \\\n"
+"  `x = `x; \\\n"
+"  `x = `x;",
+format("`define LIST \\\n"
+   "`x = `x; \\\n"
+   "`x = `x;",
+   Style));
+  EXPECT_EQ("`define LIST   \\\n"
+"  `x = `x; \\\n"
+"  `x = `x;",
+format("`define LIST `x=`x;`x=`x;", Style));
+  // Macro invocations.
+  verifyFormat("`x = (`x1 + `x2 + x);");
+  // Lines starting with a preprocessor directive should not be indented.
+  std::string Directives[] = {
+  "begin_keywords",
+  "celldefine",
+  "default_nettype",
+  "define",
+  "else",
+  "elsif",
+  "end_keywords",
+  "endcelldefine",
+  "endif",
+  "ifdef",
+  "ifndef",
+  "include",
+  "line",
+  "nounconnected_drive",
+  "pragma",
+  "resetall",
+  "timescale",
+  "unconnected_drive",
+  "undef",
+  "undefineall",
+  };
+  for (auto  : Directives) {
+EXPECT_EQ("if (x)\n"
+  "`" +
+  Name +
+  "\n"
+  "  ;",
+  format("if (x)\n"
+ "`" +
+ Name +
+ "\n"
+ ";",
+ Style));
+  }
+  // Lines starting with a regular macro invocation should be indented as a
+  // normal line.
+  EXPECT_EQ("if (x)\n"
+"  `x = `x;\n"
+"`timescale 1ns / 1ps",
+format("if (x)\n"
+   "`x = `x;\n"
+   "`timescale 1ns / 1ps",
+   Style));
+  EXPECT_EQ("if (x)\n"
+"`timescale 1ns / 1ps\n"
+"  `x = `x;",
+format("if (x)\n"
+   "`timescale 1ns / 1ps\n"
+   "`x = `x;",
+   Style));
+  std::string NonDirectives[] = {
+  // For `__FILE__` and `__LINE__`, although the standard classifies them as
+  // preprocessor directives, they are used like regular macros.
+  "__FILE__", "__LINE__", "elif", "foo", "x",
+  };
+  for (auto  : NonDirectives) {
+EXPECT_EQ("if (x)\n"
+  "  `" +
+  Name + ";",
+  format("if (x)\n"
+ "`" +
+ Name +
+ "\n"
+ ";",
+ Style));
+  }
+}
+
 } // namespace format
 } // end 

[PATCH] D124748: [clang-format] Fix whitespace counting stuff

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 8 inline comments as done.
sstwcw added a comment.

This patch is not NFC.  But there would not be change in behavior if the
input is valid C as far as I know.

  input:
  #define LIST \
  `ENTRY \
  `ENTRY
  output before, note extra line:
  #define LIST  
 \

 \
`ENTRY \
  `ENTRY
  output after:
  #define LIST \
  `ENTRY \
  `ENTRY

I don't know how I would add a test for this.

The tests in D124749  depend on this though.




Comment at: clang/lib/Format/FormatTokenLexer.cpp:839
 
+void FormatTokenLexer::resizeToken(size_t NewLen) {
+  resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(

HazardyKnusperkeks wrote:
> Can you add some documentation?
Is this comment enough?



Comment at: clang/lib/Format/FormatTokenLexer.cpp:923-924
+  case '\r':
+if (i + 1 < e && Text[i + 1] == '\n')
+  break;
+LLVM_FALLTHROUGH;

owenpan wrote:
> `\r\n` is a newline on Windows.
I added a comment to make it clear the code is correct.



Comment at: clang/lib/Format/FormatTokenLexer.cpp:946-948
+  case '?':
+  case '/':
+InEscape = true;

owenpan wrote:
> Don't you need to look ahead for a `??/`?
It has to be `??/`.  Now there's an assertion.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124748

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


[PATCH] D124748: [clang-format] Fix whitespace counting stuff

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 429530.
sstwcw added a comment.

- address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124748

Files:
  clang/lib/Format/FormatTokenLexer.cpp
  clang/lib/Format/FormatTokenLexer.h

Index: clang/lib/Format/FormatTokenLexer.h
===
--- clang/lib/Format/FormatTokenLexer.h
+++ clang/lib/Format/FormatTokenLexer.h
@@ -92,6 +92,8 @@
 
   bool tryMergeConflictMarkers();
 
+  void resizeToken(size_t NewLen);
+
   FormatToken *getStashedToken();
 
   FormatToken *getNextToken();
Index: clang/lib/Format/FormatTokenLexer.cpp
===
--- clang/lib/Format/FormatTokenLexer.cpp
+++ clang/lib/Format/FormatTokenLexer.cpp
@@ -836,6 +836,51 @@
   return FormatTok;
 }
 
+/// Resize the current token to the new length and make the lexer continue from
+/// the end of the resized token.
+void FormatTokenLexer::resizeToken(size_t NewLen) {
+  resetLexer(SourceMgr.getFileOffset(Lex->getSourceLocation(
+  Lex->getBufferLocation() - FormatTok->TokenText.size() + NewLen)));
+  FormatTok->TokenText = FormatTok->TokenText.substr(0, NewLen);
+  FormatTok->ColumnWidth = encoding::columnWidthWithTabs(
+  FormatTok->TokenText, FormatTok->OriginalColumn, Style.TabWidth,
+  Encoding);
+  FormatTok->Tok.setLength(NewLen);
+}
+
+/// Count the length of leading whitespace in a token.
+static size_t countLeadingWhitespace(StringRef Text) {
+  // Basically counting the length matched by this regex.
+  // "^([\n\r\f\v \t]|(|\\?\\?/)[\n\r])+"
+  // Directly using the regex turned out to be slow. With the regex
+  // version formatting all files in this directory took about 1.25
+  // seconds. This version took about 0.5 seconds.
+  const char *Cur = Text.begin();
+  while (Cur < Text.end()) {
+if (isspace(Cur[0])) {
+  ++Cur;
+} else if (Cur[0] == '\\' && (Cur[1] == '\n' || Cur[1] == '\r')) {
+  // A '\' followed by a newline always escapes the newline, regardless
+  // of whether there is another '\' before it.
+  // The source has a null byte at the end. So the end of the entire input
+  // isn't reached yet. Also the lexer doesn't break apart an escaped
+  // newline.
+  assert(Text.end() - Cur >= 2);
+  Cur += 2;
+} else if (Cur[0] == '?' && Cur[1] == '?' && Cur[2] == '/' &&
+   (Cur[3] == '\n' || Cur[3] == '\r')) {
+  // Newlines can also be escaped by a '?' '?' '/' trigraph. By the way, the
+  // characters are quoted individually in this comment because if we write
+  // them together some compilers warn that we have a trigraph in the code.
+  assert(Text.end() - Cur >= 4);
+  Cur += 4;
+} else {
+  break;
+}
+  }
+  return Cur - Text.begin();
+}
+
 FormatToken *FormatTokenLexer::getNextToken() {
   if (StateStack.top() == LexerState::TOKEN_STASHED) {
 StateStack.pop();
@@ -850,34 +895,33 @@
   IsFirstToken = false;
 
   // Consume and record whitespace until we find a significant token.
+  // Some tok::unknown tokens are not just whitespace, e.g. whitespace
+  // followed by a symbol such as backtick. Those symbols may be
+  // significant in other languages.
   unsigned WhitespaceLength = TrailingWhitespace;
-  while (FormatTok->is(tok::unknown)) {
+  while (FormatTok->isNot(tok::eof)) {
+auto LeadingWhitespace = countLeadingWhitespace(FormatTok->TokenText);
+if (LeadingWhitespace == 0)
+  break;
+if (LeadingWhitespace < FormatTok->TokenText.size())
+  resizeToken(LeadingWhitespace);
 StringRef Text = FormatTok->TokenText;
-auto EscapesNewline = [&](int pos) {
-  // A '\r' here is just part of '\r\n'. Skip it.
-  if (pos >= 0 && Text[pos] == '\r')
---pos;
-  // See whether there is an odd number of '\' before this.
-  // FIXME: This is wrong. A '\' followed by a newline is always removed,
-  // regardless of whether there is another '\' before it.
-  // FIXME: Newlines can also be escaped by a '?' '?' '/' trigraph.
-  unsigned count = 0;
-  for (; pos >= 0; --pos, ++count)
-if (Text[pos] != '\\')
-  break;
-  return count & 1;
-};
-// FIXME: This miscounts tok:unknown tokens that are not just
-// whitespace, e.g. a '`' character.
+bool InEscape = false;
 for (int i = 0, e = Text.size(); i != e; ++i) {
   switch (Text[i]) {
+  case '\r':
+// If this is a CRLF sequence, break here and the LF will be handled on
+// the next loop iteration. Otherwise, this is a single Mac CR, treat it
+// the same as a single LF.
+if (i + 1 < e && Text[i + 1] == '\n')
+  break;
+LLVM_FALLTHROUGH;
   case '\n':
 ++FormatTok->NewlinesBefore;
-FormatTok->HasUnescapedNewline = !EscapesNewline(i - 1);
-

[PATCH] D125626: [clang-format][NFC] Don't call mightFitOnOneLine() unnecessarily

2022-05-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2732
+parseBlock(/*MustBeDeclaration=*/true, AddLevels, /*MunchSemi=*/true,
+   /*KeepBracces=*/true, ManageWhitesmithsBraces);
 




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125626

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


[PATCH] D125628: [flang][driver] Add support for generating executables on MacOSX/Darwin

2022-05-15 Thread Andrzej Warzynski via Phabricator via cfe-commits
awarzynski created this revision.
awarzynski added reviewers: rovka, rouson, MaskRay, h-vetinari, schweitz, 
kiranchandramohan.
Herald added a reviewer: sscalpone.
Herald added subscribers: StephenFan, mehdi_amini.
Herald added projects: Flang, All.
awarzynski requested review of this revision.
Herald added subscribers: cfe-commits, jdoerfert.
Herald added a project: clang.

This patch basically extends https://reviews.llvm.org/D122008 with
support for MacOSX/Darwin.

To facilitate this, I've added `MacOSX` to the list of supported OSes in
Target.cpp. Flang already supports `Darwin` and it doesn't really do
anything OS-specific there (it could probably safely skip checking the
OS for now).

Note that generating executables remains hidden behind the
`-flang-experimental-exec` flag.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125628

Files:
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.h
  clang/lib/Driver/ToolChains/Darwin.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  flang/lib/Optimizer/CodeGen/Target.cpp
  flang/test/Driver/linker-flags.f90

Index: flang/test/Driver/linker-flags.f90
===
--- flang/test/Driver/linker-flags.f90
+++ flang/test/Driver/linker-flags.f90
@@ -2,12 +2,12 @@
 ! invocation. These libraries are added on top of other standard runtime
 ! libraries that the Clang driver will include.
 
-! NOTE: The additional linker flags tested here are currently specified in
-! clang/lib/Driver/Toolchains/Gnu.cpp. This makes the current implementation GNU
-! (Linux) specific. The following line will make sure that this test is skipped
-! on Windows. Ideally we should find a more robust way of testing this.
-! REQUIRES: shell
-! UNSUPPORTED: darwin, macos, system-windows
+! NOTE: The additional linker flags tested here are currently only specified for
+! GNU and Darwin. The following line will make sure that this test is skipped on
+! Windows. If you are running this test on a yet another platform and it is
+! failing for you, please either update the following or (preferably) update the
+! linker invocation accordingly.
+! UNSUPPORTED: system-windows
 
 !
 ! RUN COMMAND
Index: flang/lib/Optimizer/CodeGen/Target.cpp
===
--- flang/lib/Optimizer/CodeGen/Target.cpp
+++ flang/lib/Optimizer/CodeGen/Target.cpp
@@ -251,6 +251,7 @@
   break;
 case llvm::Triple::OSType::Linux:
 case llvm::Triple::OSType::Darwin:
+case llvm::Triple::OSType::MacOSX:
 case llvm::Triple::OSType::Win32:
   return std::make_unique(ctx, std::move(trp),
   std::move(kindMap));
@@ -262,6 +263,7 @@
   break;
 case llvm::Triple::OSType::Linux:
 case llvm::Triple::OSType::Darwin:
+case llvm::Triple::OSType::MacOSX:
 case llvm::Triple::OSType::Win32:
   return std::make_unique(ctx, std::move(trp),
 std::move(kindMap));
@@ -273,6 +275,7 @@
   break;
 case llvm::Triple::OSType::Linux:
 case llvm::Triple::OSType::Darwin:
+case llvm::Triple::OSType::MacOSX:
 case llvm::Triple::OSType::Win32:
   return std::make_unique(ctx, std::move(trp),
  std::move(kindMap));
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -382,28 +382,6 @@
  Exec, CmdArgs, Inputs, Output));
 }
 
-static void addFortranRuntimeLibraryPath(const ToolChain ,
- const ArgList ,
- ArgStringList ) {
-  // Default to the /../lib directory. This works fine on the
-  // platforms that we have tested so far. We will probably have to re-fine
-  // this in the future. In particular:
-  //* on some platforms, we may need to use lib64 instead of lib
-  //* this logic should also work on other similar platforms too, so we
-  //should move it to one of Gnu's parent tool{chain} classes
-  SmallString<256> DefaultLibPath =
-  llvm::sys::path::parent_path(TC.getDriver().Dir);
-  llvm::sys::path::append(DefaultLibPath, "lib");
-  CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
-}
-
-static void addFortranLinkerFlags(ArgStringList ) {
-  CmdArgs.push_back("-lFortran_main");
-  CmdArgs.push_back("-lFortranRuntime");
-  CmdArgs.push_back("-lFortranDecimal");
-  CmdArgs.push_back("-lm");
-}
-
 void tools::gnutools::Linker::ConstructJob(Compilation , const JobAction ,
const InputInfo ,
const InputInfoList ,
@@ -621,7 +599,7 @@
   // TODO: Make this work unconditionally once Flang is mature enough.
   if (D.IsFlangMode() && 

[clang] f66596c - [clang][docs] Add escape code to fix missing '*' in reduction operation list

2022-05-15 Thread Simon Pilgrim via cfe-commits

Author: Simon Pilgrim
Date: 2022-05-15T12:32:11+01:00
New Revision: f66596c94f772e214fd9d96cc78f7fec17209281

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

LOG: [clang][docs] Add escape code to fix missing '*' in reduction operation 
list

Added: 


Modified: 
clang/docs/LanguageExtensions.rst

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 3cdac02d8d3fb..44848a20dca3c 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -647,7 +647,7 @@ Let ``VT`` be a vector type and ``ET`` the element type of 
``VT``.
  is a NaN, return the other argument. 
If both arguments are
  NaNs, fmax() return a NaN.
  ET __builtin_reduce_add(VT a)   \+
   integer and floating point types
- ET __builtin_reduce_mul(VT a)   * 
   integer and floating point types
+ ET __builtin_reduce_mul(VT a)   \*
   integer and floating point types
  ET __builtin_reduce_and(VT a)   & 
   integer types
  ET __builtin_reduce_or(VT a)\|
   integer types
  ET __builtin_reduce_xor(VT a)   ^ 
   integer types



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


[PATCH] D123952: [FPEnv] Allow CompoundStmt to keep FP options

2022-05-15 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 429525.
sepavloff added a comment.

Addressed review notes

- Added support in JSON node dumper,
- Added support in ast-print


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123952

Files:
  clang/include/clang/AST/JSONNodeDumper.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/ScopeInfo.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Analysis/BodyFarm.cpp
  clang/lib/Basic/LangOptions.cpp
  clang/lib/CodeGen/CGCoroutine.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-fpfeatures.cpp
  clang/test/AST/ast-dump-pragma-json.c
  clang/test/AST/ast-print-fp-pragmas.c

Index: clang/test/AST/ast-print-fp-pragmas.c
===
--- /dev/null
+++ clang/test/AST/ast-print-fp-pragmas.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+float func_1(float x, float y) {
+#pragma STDC FENV_ACCESS ON
+  if (x != 0) {
+return y;
+  }
+  return x + y;
+}
+
+// CHECK-LABEL: float func_1(float x, float y) {
+// CHECK-NEXT:  #pragma STDC FENV_ACCESS ON
+// CHECK-NEXT:  if (x != 0) {
+// CHECK-NEXT:  return y;
+// CHECK-NEXT:  }
+// CHECK-NEXT:  return x + y;
+// CHECK-NEXT:  }
+
+float func_2(float x, float y) {
+#pragma STDC FENV_ACCESS ON
+  if (x != 0) {
+  #pragma STDC FENV_ACCESS OFF
+return y;
+  }
+  return x + y;
+}
+
+// CHECK-LABEL: float func_2(float x, float y) {
+// CHECK-NEXT:  #pragma STDC FENV_ACCESS ON
+// CHECK-NEXT:  if (x != 0) {
+// CHECK-NEXT:  #pragma STDC FENV_ACCESS OFF
+// CHECK-NEXT:  return y;
+// CHECK-NEXT:  }
+// CHECK-NEXT:  return x + y;
+// CHECK-NEXT:  }
+
+float func_3(float x, float y) {
+#pragma STDC FENV_ROUND FE_DOWNWARD
+  return x + y;
+}
+
+// CHECK-LABEL: float func_3(float x, float y) {
+// CHECK-NEXT:  #pragma STDC FENV_ROUND FE_UPWARD
+// CHECK-NEXT:  return x + y;
+// CHECK-NEXT:  }
+
+float func_4(float x, float y, float z) {
+#pragma STDC FENV_ACCESS ON
+#pragma clang fp exceptions(maytrap)
+#pragma STDC FENV_ROUND FE_UPWARD
+  if (z != 0) {
+  #pragma STDC FENV_ACCESS OFF
+  #pragma STDC FENV_ROUND FE_TOWARDZERO
+return z + x;
+  }
+  return x + y;
+}
+
+// CHECK-LABEL: float func_4(float x, float y, float z) {
+// CHECK-NEXT:  #pragma STDC FENV_ACCESS ON
+// CHECK-NEXT:  #pragma clang fp exceptions(maytrap)
+// CHECK-NEXT:  #pragma STDC FENV_ROUND FE_DOWNWARD
+// CHECK-NEXT:  if (z != 0) {
+// CHECK-NEXT:  #pragma STDC FENV_ACCESS OFF
+// CHECK-NEXT:  #pragma STDC FENV_ROUND FE_TOWARDZERO
+// CHECK-NEXT:  return z + x;
+// CHECK-NEXT:  }
+// CHECK-NEXT:  return x + y;
+// CHECK-NEXT:  }
Index: clang/test/AST/ast-dump-pragma-json.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-pragma-json.c
@@ -0,0 +1,485 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump=json %s | FileCheck %s
+
+float func_16(float x, float y) {
+  #pragma STDC FENV_ROUND FE_TOWARDZERO
+  if (x < 0) {
+#pragma STDC FENV_ROUND FE_UPWARD
+return x - y;
+  }
+  return x + y;
+}
+
+// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
+// using --filters=CompoundStmt
+
+
+// CHECK-NOT: {{^}}Dumping
+// CHECK:  "kind": "CompoundStmt",
+// CHECK-NEXT:  "range": {
+// CHECK-NEXT:   "begin": {
+// CHECK-NEXT:"offset": 116,
+// CHECK-NEXT:"col": 33,
+// CHECK-NEXT:"tokLen": 1
+// CHECK-NEXT:   },
+// CHECK-NEXT:   "end": {
+// CHECK-NEXT:"offset": 249,
+// CHECK-NEXT:"line": 10,
+// CHECK-NEXT:"col": 1,
+// CHECK-NEXT:"tokLen": 1
+// CHECK-NEXT:   }
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "fpoptions": {
+// CHECK-NEXT:   "RoundingMode": 0
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "IfStmt",
+// CHECK-NEXT:"range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT:  "offset": 160,
+// CHECK-NEXT:  "line": 5,
+// CHECK-NEXT:  "col": 3,
+// CHECK-NEXT:  "tokLen": 2
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT:  "offset": 231,
+// CHECK-NEXT:  "line": 8,
+// CHECK-NEXT:  "col": 3,
+// CHECK-NEXT:  "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT:},
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "id": "0x{{.*}}",
+// CHECK-NEXT:  "kind": "BinaryOperator",
+// CHECK-NEXT:  "range": {
+// 

[PATCH] D125626: [clang-format][NFC] Don't call mightFitOnOneLine() unnecessarily

2022-05-15 Thread Owen Pan via Phabricator via cfe-commits
owenpan created this revision.
owenpan added reviewers: curdeius, HazardyKnusperkeks, MyDeveloperDay.
owenpan added a project: clang-format.
Herald added a project: All.
owenpan requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Clean up `UnwrappedLineParser` for `RemoveBracesLLVM` to avoid calling 
`mightFitOnOneLine()` as much as possible.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125626

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h

Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -92,12 +92,12 @@
   void reset();
   void parseFile();
   bool precededByCommentOrPPDirective() const;
-  bool parseLevel(bool HasOpeningBrace, bool CanContainBracedList,
+  bool parseLevel(const FormatToken *OpeningBrace, bool CanContainBracedList,
   IfStmtKind *IfKind = nullptr,
   TokenType NextLBracesType = TT_Unknown);
   bool mightFitOnOneLine(UnwrappedLine ) const;
   IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u,
-bool MunchSemi = true,
+bool MunchSemi = true, bool KeepBraces = true,
 bool UnindentWhitesmithsBraces = false,
 bool CanContainBracedList = true,
 TokenType NextLBracesType = TT_Unknown);
@@ -126,7 +126,7 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
-  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
+  void parseLoopBody(bool KeepBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -394,7 +394,7 @@
   if (Style.Language == FormatStyle::LK_TextProto)
 parseBracedList();
   else
-parseLevel(/*HasOpeningBrace=*/false, /*CanContainBracedList=*/true);
+parseLevel(/*OpeningBrace=*/nullptr, /*CanContainBracedList=*/true);
   // Make sure to format the remaining tokens.
   //
   // LK_TextProto is special since its top-level is parsed as the body of a
@@ -463,13 +463,13 @@
 }
 
 /// \brief Parses a level, that is ???.
-/// \param HasOpeningBrace If that level is started by an opening brace.
+/// \param OpeningBrace Opening brace (\p nullptr if absent) of that level
 /// \param CanContainBracedList If the content can contain (at any level) a
 /// braced list.
 /// \param NextLBracesType The type for left brace found in this level.
-/// \returns true if a simple block, or false otherwise. (A simple block has a
-/// single statement.)
-bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace,
+/// \returns true if a simple block of if/else/for/while, or false otherwise.
+/// (A simple block has a single statement.)
+bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
  bool CanContainBracedList,
  IfStmtKind *IfKind,
  TokenType NextLBracesType) {
@@ -492,9 +492,9 @@
 else if (FormatTok->getType() == TT_MacroBlockEnd)
   kind = tok::r_brace;
 
-auto ParseDefault = [this, HasOpeningBrace, IfKind, NextLevelLBracesType,
+auto ParseDefault = [this, OpeningBrace, IfKind, NextLevelLBracesType,
  , ] {
-  parseStructuralElement(IfKind, !HasOpeningBrace, NextLevelLBracesType,
+  parseStructuralElement(IfKind, !OpeningBrace, NextLevelLBracesType,
  HasLabel ? nullptr : );
   ++StatementCount;
   assert(StatementCount > 0 && "StatementCount overflow!");
@@ -519,16 +519,17 @@
   tryToParseBracedList())
 continue;
   parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,
- /*MunchSemi=*/true, /*UnindentWhitesmithBraces=*/false,
- CanContainBracedList,
- /*NextLBracesType=*/NextLBracesType);
+ /*MunchSemi=*/true, /*KeepBraces=*/true,
+ /*UnindentWhitesmithBraces=*/false, CanContainBracedList,
+ NextLBracesType);
   ++StatementCount;
   assert(StatementCount > 0 && "StatementCount overflow!");
   addUnwrappedLine();
   break;
 case tok::r_brace:
-  if (HasOpeningBrace) {
-if (!Style.RemoveBracesLLVM)
+  if (OpeningBrace) {
+if (!Style.RemoveBracesLLVM ||
+!OpeningBrace->isOneOf(TT_ControlStatementLBrace, TT_ElseLBrace))
   return false;
 if 

[PATCH] D125625: Implementation of '#pragma STDC FENV_ROUND'

2022-05-15 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: rsmith, rjmccall, aaron.ballman, kpn, 
andrew.w.kaylor.
Herald added a project: All.
sepavloff requested review of this revision.
Herald added a project: clang.

This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.

This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Some targets however allow specifying rounding mode as a
field in instructions, in this case setting dynamic rounding mode is not
mandatory. However the standard draft requests that invocations of
functions shall be evaluated using dynamic rounding mode. So the dynamic
rounding mode is set even if actually later it is unused. Removal of
unneeded manipulation on dynamic rounding mode can be made by a separate
IR optimization.

The implementation uses intrinsic functions 'flt_rounds' and
'set_rounding' to save/restore dynamic rounding mode. It is not the best
way, because these functions need to extract rounding mode from the
content of some control register or pack into it. More efficient
implementation could save/restore entire value of the control register. It
requires functions 'fegetmode' and 'fesetmode' to be implemented as LLVM
intrinsic functions. When these functions will be implemented, the same
mechanism could be used in implementation of other similar fp pragmas.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D125625

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Parse/ParsePragma.cpp
  clang/test/CodeGen/complex-strictfp.c
  clang/test/CodeGen/pragma-fenv_round.c
  clang/test/Parser/pragma-fenv_round.c

Index: clang/test/Parser/pragma-fenv_round.c
===
--- clang/test/Parser/pragma-fenv_round.c
+++ clang/test/Parser/pragma-fenv_round.c
@@ -6,6 +6,5 @@
   if (x)
 return y + 2;
   #pragma STDC FENV_ROUND FE_DOWNWARD // expected-error{{'#pragma STDC FENV_ROUND' can only appear at file scope or at the start of a compound statement}}
-  // expected-warning@-1{{pragma STDC FENV_ROUND is not supported}}
   return x + y;
 }
Index: clang/test/CodeGen/pragma-fenv_round.c
===
--- /dev/null
+++ clang/test/CodeGen/pragma-fenv_round.c
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -S -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+float func_1(float w, float x, float y, float z) {
+  #pragma STDC FENV_ROUND FE_TOWARDZERO
+  float result = x * y;
+  {
+#pragma STDC FENV_ROUND FE_UPWARD
+result += z;
+  }
+  return result - w;
+}
+
+// CHECK-LABEL: @func_1
+// CHECK:  call void @llvm.set.rounding(i32 0)
+// CHECK:  call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call void @llvm.set.rounding(i32 2)
+// CHECK:  call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.upward", metadata !"fpexcept.ignore")
+// CHECK:  call void @llvm.set.rounding(i32 0)
+// CHECK:  call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call void @llvm.set.rounding(i32 1)
+
+
+float func_2(float w, float x, float y, float z) {
+  #pragma STDC FENV_ROUND FE_TOWARDZERO
+  float result = x * y;
+  {
+#pragma STDC FENV_ROUND FE_TOWARDZERO
+result += z;
+  }
+  return result - w;
+}
+
+// CHECK-LABEL: @func_2
+// CHECK:  call void @llvm.set.rounding(i32 0)
+// CHECK:  call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call float @llvm.experimental.constrained.fadd.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call float @llvm.experimental.constrained.fsub.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call void @llvm.set.rounding(i32 1)
+
+
+float func_3(float w, float x, float y, float z) {
+  #pragma STDC FENV_ROUND FE_TOWARDZERO
+  float result = x * y;
+  {
+#pragma STDC FENV_ROUND FE_DYNAMIC
+result += z;
+  }
+  return result - w;
+}
+
+// CHECK-LABEL: @func_3
+// CHECK:  call void @llvm.set.rounding(i32 0)
+// CHECK:  call float @llvm.experimental.constrained.fmul.f32({{.*}}, metadata !"round.towardzero", metadata !"fpexcept.ignore")
+// CHECK:  call void @llvm.set.rounding(i32 1)
+// CHECK:  call float 

[PATCH] D125593: [clang-format] Handle "if consteval { ... }" for RemoveBracesLLVM

2022-05-15 Thread Owen Pan via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2cdabc032292: [clang-format] Handle if consteval { ... 
} for RemoveBracesLLVM (authored by owenpan).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D125593

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -25379,6 +25379,25 @@
"}",
Style);
 
+  verifyFormat("if consteval {\n"
+   "  f();\n"
+   "} else {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if not consteval {\n"
+   "  f();\n"
+   "} else if (a) {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if !consteval {\n"
+   "  g();\n"
+   "}",
+   Style);
+
   Style.ColumnLimit = 65;
 
   verifyFormat("if (condition) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2473,7 +2473,12 @@
   nextToken();
   if (FormatTok->is(tok::exclaim))
 nextToken();
+
+  bool KeepIfBraces = false;
+  bool KeepElseBraces = false;
   if (FormatTok->is(tok::kw_consteval)) {
+KeepIfBraces = true;
+KeepElseBraces = true;
 nextToken();
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
@@ -2501,10 +2506,10 @@
 parseUnbracedBody();
   }
 
-  bool KeepIfBraces = false;
   if (Style.RemoveBracesLLVM) {
 assert(!NestedTooDeep.empty());
-KeepIfBraces = (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
+KeepIfBraces = KeepIfBraces ||
+   (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
IfBlockKind == IfStmtKind::IfElseIf;
   }
@@ -2558,8 +2563,9 @@
 return nullptr;
 
   assert(!NestedTooDeep.empty());
-  const bool KeepElseBraces =
-  (ElseLeftBrace && !ElseLeftBrace->MatchingParen) || NestedTooDeep.back();
+  KeepElseBraces = KeepElseBraces ||
+   (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
+   NestedTooDeep.back();
 
   NestedTooDeep.pop_back();
 


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -25379,6 +25379,25 @@
"}",
Style);
 
+  verifyFormat("if consteval {\n"
+   "  f();\n"
+   "} else {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if not consteval {\n"
+   "  f();\n"
+   "} else if (a) {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if !consteval {\n"
+   "  g();\n"
+   "}",
+   Style);
+
   Style.ColumnLimit = 65;
 
   verifyFormat("if (condition) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2473,7 +2473,12 @@
   nextToken();
   if (FormatTok->is(tok::exclaim))
 nextToken();
+
+  bool KeepIfBraces = false;
+  bool KeepElseBraces = false;
   if (FormatTok->is(tok::kw_consteval)) {
+KeepIfBraces = true;
+KeepElseBraces = true;
 nextToken();
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
@@ -2501,10 +2506,10 @@
 parseUnbracedBody();
   }
 
-  bool KeepIfBraces = false;
   if (Style.RemoveBracesLLVM) {
 assert(!NestedTooDeep.empty());
-KeepIfBraces = (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
+KeepIfBraces = KeepIfBraces ||
+   (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
IfBlockKind == IfStmtKind::IfElseIf;
   }
@@ -2558,8 +2563,9 @@
 return nullptr;
 
   assert(!NestedTooDeep.empty());
-  const bool KeepElseBraces =
-  (ElseLeftBrace && !ElseLeftBrace->MatchingParen) || NestedTooDeep.back();
+  KeepElseBraces = KeepElseBraces ||
+   (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
+   NestedTooDeep.back();
 
   NestedTooDeep.pop_back();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2cdabc0 - [clang-format] Handle "if consteval { ... }" for RemoveBracesLLVM

2022-05-15 Thread via cfe-commits

Author: owenca
Date: 2022-05-15T01:33:44-07:00
New Revision: 2cdabc0322929a3954b63c1f29f23959e2e50278

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

LOG: [clang-format] Handle "if consteval { ... }" for RemoveBracesLLVM

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

Added: 


Modified: 
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/FormatTest.cpp

Removed: 




diff  --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 6ba8edccbb117..c5135222af698 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2473,7 +2473,12 @@ FormatToken 
*UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
   nextToken();
   if (FormatTok->is(tok::exclaim))
 nextToken();
+
+  bool KeepIfBraces = false;
+  bool KeepElseBraces = false;
   if (FormatTok->is(tok::kw_consteval)) {
+KeepIfBraces = true;
+KeepElseBraces = true;
 nextToken();
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
@@ -2501,10 +2506,10 @@ FormatToken 
*UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
 parseUnbracedBody();
   }
 
-  bool KeepIfBraces = false;
   if (Style.RemoveBracesLLVM) {
 assert(!NestedTooDeep.empty());
-KeepIfBraces = (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
+KeepIfBraces = KeepIfBraces ||
+   (IfLeftBrace && !IfLeftBrace->MatchingParen) ||
NestedTooDeep.back() || IfBlockKind == IfStmtKind::IfOnly ||
IfBlockKind == IfStmtKind::IfElseIf;
   }
@@ -2558,8 +2563,9 @@ FormatToken 
*UnwrappedLineParser::parseIfThenElse(IfStmtKind *IfKind,
 return nullptr;
 
   assert(!NestedTooDeep.empty());
-  const bool KeepElseBraces =
-  (ElseLeftBrace && !ElseLeftBrace->MatchingParen) || NestedTooDeep.back();
+  KeepElseBraces = KeepElseBraces ||
+   (ElseLeftBrace && !ElseLeftBrace->MatchingParen) ||
+   NestedTooDeep.back();
 
   NestedTooDeep.pop_back();
 

diff  --git a/clang/unittests/Format/FormatTest.cpp 
b/clang/unittests/Format/FormatTest.cpp
index 8ac59dc4a5131..e4fea9085b574 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -25379,6 +25379,25 @@ TEST_F(FormatTest, RemoveBraces) {
"}",
Style);
 
+  verifyFormat("if consteval {\n"
+   "  f();\n"
+   "} else {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if not consteval {\n"
+   "  f();\n"
+   "} else if (a) {\n"
+   "  g();\n"
+   "}",
+   Style);
+
+  verifyFormat("if !consteval {\n"
+   "  g();\n"
+   "}",
+   Style);
+
   Style.ColumnLimit = 65;
 
   verifyFormat("if (condition) {\n"



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