[PATCH] D56992: Mark lambda-to-function-pointer conversion as noexcept

2019-01-20 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov created this revision.
loskutov added reviewers: llvm-commits, aaron.ballman, doug.gregor.
Herald added a subscriber: cfe-commits.

Starting from C++17, [expr.prim.lambda.closure]p9 requires that "The [lambda to 
function pointer] conversion function [...] has a non-throwing exception 
specification".
This commit adds such a specification to the generated conversion functions.
Pre-C++17 standards don't have this requirement; however, they don't forbid the 
conversion functions to have this specification either.
For the sake of consistency, the specification is added unconditionally, no 
matter what standard revision is used.

Issue related: https://bugs.llvm.org/show_bug.cgi?id=40309


Repository:
  rC Clang

https://reviews.llvm.org/D56992

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/AST/ast-dump-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp


Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
===
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+  const auto lambda = [](int x) { return x + 1; };
+  static_assert(noexcept((int (*)(int))(lambda)),
+"Lambda-to-function-pointer conversion is expected to be 
noexcept");
+}
Index: clang/test/AST/ast-dump-expr.cpp
===
--- clang/test/AST/ast-dump-expr.cpp
+++ clang/test/AST/ast-dump-expr.cpp
@@ -290,7 +290,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -307,7 +307,7 @@
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto (int, ...) const' inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const)(int, ...)' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto (int, ...)' static inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
@@ -455,7 +455,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 constexpr 
operator() 'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -471,7 +471,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto ()' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -487,7 +487,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const noexcept' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto () noexcept' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -505,7 +505,7 @@
   // CHECK-NEXT: CompoundStmt
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}}  'int' 0
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const)() -> int' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const noexcept)() -> int'

[PATCH] D56992: [clang] Mark lambda-to-function-pointer conversion as noexcept

2019-01-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov updated this revision to Diff 182779.
loskutov added a comment.

Fixed the comment.


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

https://reviews.llvm.org/D56992

Files:
  clang/lib/Sema/SemaLambda.cpp


Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1227,9 +1227,7 @@
   FunctionProtoType::ExtProtoInfo ConvExtInfo(
   S.Context.getDefaultCallingConvention(
   /*IsVariadic=*/false, /*IsCXXMethod=*/true));
-  // The conversion function is always const.
-  // C++17 also obliges it to be noexcept (which it in fact is),
-  // and previous standards don't forbid that either.
+  // The conversion function is always const and noexcept.
   ConvExtInfo.TypeQuals = Qualifiers();
   ConvExtInfo.TypeQuals.addConst();
   ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept;


Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1227,9 +1227,7 @@
   FunctionProtoType::ExtProtoInfo ConvExtInfo(
   S.Context.getDefaultCallingConvention(
   /*IsVariadic=*/false, /*IsCXXMethod=*/true));
-  // The conversion function is always const.
-  // C++17 also obliges it to be noexcept (which it in fact is),
-  // and previous standards don't forbid that either.
+  // The conversion function is always const and noexcept.
   ConvExtInfo.TypeQuals = Qualifiers();
   ConvExtInfo.TypeQuals.addConst();
   ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56992: [clang] Mark lambda-to-function-pointer conversion as noexcept

2019-01-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov updated this revision to Diff 182782.
loskutov marked an inline comment as done.
loskutov added a comment.

Uploaded an updated diff instead of a diff-from-previous-diff


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

https://reviews.llvm.org/D56992

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/AST/ast-dump-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp


Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
===
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+  const auto lambda = [](int x) { return x + 1; };
+  static_assert(noexcept((int (*)(int))(lambda)),
+"Lambda-to-function pointer conversion is expected to be 
noexcept");
+}
Index: clang/test/AST/ast-dump-expr.cpp
===
--- clang/test/AST/ast-dump-expr.cpp
+++ clang/test/AST/ast-dump-expr.cpp
@@ -290,7 +290,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -307,7 +307,7 @@
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto (int, ...) const' inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const)(int, ...)' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto (int, ...)' static inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
@@ -455,7 +455,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 constexpr 
operator() 'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -471,7 +471,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto ()' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -487,7 +487,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const noexcept' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto () noexcept' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -505,7 +505,7 @@
   // CHECK-NEXT: CompoundStmt
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}}  'int' 0
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const)() -> int' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const noexcept)() -> int' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto () -> int' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
@@ -568,4 +568,4 @@
   // CHECK: CallExpr 0x{{[^ ]*}} ]+}}> 'void'{{$}}
   f(x);
 }
-} // namespace test_adl_call_three
\ No newline at end of file
+} // namespace test_adl_call_three
Index: clang/lib/Sema/SemaLambda.cpp
=

[PATCH] D56992: [clang] Mark lambda-to-function-pointer conversion as noexcept

2019-01-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov updated this revision to Diff 182783.

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

https://reviews.llvm.org/D56992

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/AST/ast-dump-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp


Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
===
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+  const auto lambda = [](int x) { return x + 1; };
+  static_assert(noexcept((int (*)(int))(lambda)),
+"Lambda-to-function-pointer conversion is expected to be 
noexcept");
+}
Index: clang/test/AST/ast-dump-expr.cpp
===
--- clang/test/AST/ast-dump-expr.cpp
+++ clang/test/AST/ast-dump-expr.cpp
@@ -290,7 +290,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -307,7 +307,7 @@
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto (int, ...) const' inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const)(int, ...)' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto (int, ...)' static inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
@@ -455,7 +455,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 constexpr 
operator() 'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -471,7 +471,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto ()' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -487,7 +487,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 
'auto () const noexcept' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' 
inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto () noexcept' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -505,7 +505,7 @@
   // CHECK-NEXT: CompoundStmt
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}}  'int' 0
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const)() -> int' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit 
constexpr operator int (*)() 'auto (*() const noexcept)() -> int' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit 
__invoke 'auto () -> int' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
@@ -568,4 +568,4 @@
   // CHECK: CallExpr 0x{{[^ ]*}} ]+}}> 'void'{{$}}
   f(x);
 }
-} // namespace test_adl_call_three
\ No newline at end of file
+} // namespace test_adl_call_three
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1227,9 +1227,10 @@
   FunctionProtoType::ExtProtoInfo Conv

[PATCH] D56992: [clang] Mark lambda-to-function-pointer conversion as noexcept

2019-01-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov updated this revision to Diff 182792.
loskutov edited the summary of this revision.
loskutov added a comment.

Reflected the change in cxx_dr_status.html and specified `-std=c++17` for the 
test.


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

https://reviews.llvm.org/D56992

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/AST/ast-dump-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
  clang/www/cxx_dr_status.html

Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -10147,7 +10147,7 @@
 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722";>1722
 CD4
 Should lambda to function pointer conversion function be noexcept?
-Unknown
+Yes
   
   
 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1723";>1723
Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
===
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+  const auto lambda = [](int x) { return x + 1; };
+  static_assert(noexcept((int (*)(int))(lambda)),
+"Lambda-to-function-pointer conversion is expected to be noexcept");
+}
Index: clang/test/AST/ast-dump-expr.cpp
===
--- clang/test/AST/ast-dump-expr.cpp
+++ clang/test/AST/ast-dump-expr.cpp
@@ -290,7 +290,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit __invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -307,7 +307,7 @@
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 'auto (int, ...) const' inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)(int, ...) 'auto (*() const)(int, ...)' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit __invoke 'auto (int, ...)' static inline
   // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}}  col:10 a 'int'
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
@@ -455,7 +455,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 constexpr operator() 'auto () const' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit __invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -471,7 +471,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 'auto ()' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit __invoke 'auto ()' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -487,7 +487,7 @@
   // CHECK-NEXT: Destructor
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 operator() 'auto () const noexcept' inline
   // CHECK-NEXT: CompoundStmt
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' inline
   // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}}  col:3 implicit __invoke 'auto () noexcept' static inline
   // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} 
 
@@ -505,7 +505,7 @@
   // CHECK-NEXT: CompoundStmt
   // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} 
   // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}}  'int' 0
-  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator int (*)() 'auto (*() const)() -> int' inline
+  // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}}  col:3 implicit constexpr operator int (*)() 'auto (*() const noexcept)

[PATCH] D56992: [clang] Mark lambda-to-function-pointer conversion as noexcept

2019-01-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov marked an inline comment as done.
loskutov added a comment.

Yes, I'm not able to commit by myself, so it would be nice if you did that. 
Apache 2.0 with LLVM Exceptions is fine.


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

https://reviews.llvm.org/D56992



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


[PATCH] D158371: [clang-tidy] Fix DanglingHandleCheck to work in C++17 and later mode

2023-08-20 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov created this revision.
loskutov added reviewers: sbenza, PiotrZSL.
loskutov added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
loskutov requested review of this revision.
Herald added a subscriber: cfe-commits.

Due to guaranteed copy elision, not only do some nodes get removed from the AST,
but also some existing nodes change the source locations they correspond to.
Hence, the check works slightly differently in pre-C++17 and C++17-and-later 
modes
in terms of what gets highlighted.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158371

Files:
  clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
@@ -1,8 +1,12 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-dangling-handle %t -- \
+// RUN: %check_clang_tidy -std=c++11,c++14 -check-suffix=,CXX14 %s bugprone-dangling-handle %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN: {bugprone-dangling-handle.HandleClasses: \
+// RUN:   'std::basic_string_view; ::llvm::StringRef;'}}"
+
+// RUN: %check_clang_tidy -std=c++17-or-later -check-suffix=,CXX17 %s bugprone-dangling-handle %t -- \
 // RUN:   -config="{CheckOptions: \
 // RUN: {bugprone-dangling-handle.HandleClasses: \
 // RUN:   'std::basic_string_view; ::llvm::StringRef;'}}"
-// FIXME: Fix the checker to work in C++17 or later mode.
 
 namespace std {
 
@@ -84,27 +88,32 @@
 
 void Positives() {
   std::string_view view1 = std::string();
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:28: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
 
   std::string_view view_2 = ReturnsAString();
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:29: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
 
   view1 = std::string();
   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
 
   const std::string& str_ref = "";
   std::string_view view3 = true ? "A" : str_ref;
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:28: warning: std::basic_string_view outlives
   view3 = true ? "A" : str_ref;
   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
 
   std::string_view view4(ReturnsAString());
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:26: warning: std::basic_string_view outlives
 }
 
 void OtherTypes() {
   llvm::StringRef ref = std::string();
-  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: llvm::StringRef outlives its value
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:19: warning: llvm::StringRef outlives its value
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:25: warning: llvm::StringRef outlives its value
 }
 
 const char static_array[] = "A";
Index: clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
@@ -37,8 +37,8 @@
   // temporary value. If one of them is not a temporary then it must be copied
   // into one to satisfy the type of the operator.
   const auto TemporaryTernary =
-  conditionalOperator(hasTrueExpression(cxxBindTemporaryExpr()),
-  hasFalseExpression(cxxBindTemporaryExpr()));
+  conditionalOperator(hasTrueExpression(ignoringParenImpCasts(cxxBindTemporaryExpr())),
+  hasFalseExpression(ignoringParenImpCasts(cxxBindTemporaryExpr(;
 
   return handleFrom(IsAHandle, anyOf(cxxBindTemporaryExpr(), TemporaryTernary));
 }
@@ -103,26 +103,17 @@
 void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {
   const auto ConvertedHandle = handleFromTemporaryValue(IsAHandle);
 
-  // Find 'Handle foo(ReturnsAValue());'
+  // Find 'Handle foo(ReturnsAValue())

[PATCH] D158371: [clang-tidy] Fix DanglingHandleCheck to work in C++17 and later mode

2023-08-21 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov updated this revision to Diff 552164.
loskutov added a comment.

git clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D158371

Files:
  clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/dangling-handle.cpp
@@ -1,8 +1,12 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-dangling-handle %t -- \
+// RUN: %check_clang_tidy -std=c++11,c++14 -check-suffix=,CXX14 %s bugprone-dangling-handle %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN: {bugprone-dangling-handle.HandleClasses: \
+// RUN:   'std::basic_string_view; ::llvm::StringRef;'}}"
+
+// RUN: %check_clang_tidy -std=c++17-or-later -check-suffix=,CXX17 %s bugprone-dangling-handle %t -- \
 // RUN:   -config="{CheckOptions: \
 // RUN: {bugprone-dangling-handle.HandleClasses: \
 // RUN:   'std::basic_string_view; ::llvm::StringRef;'}}"
-// FIXME: Fix the checker to work in C++17 or later mode.
 
 namespace std {
 
@@ -84,27 +88,32 @@
 
 void Positives() {
   std::string_view view1 = std::string();
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:28: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
 
   std::string_view view_2 = ReturnsAString();
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:29: warning: std::basic_string_view outlives its value [bugprone-dangling-handle]
 
   view1 = std::string();
   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
 
   const std::string& str_ref = "";
   std::string_view view3 = true ? "A" : str_ref;
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:28: warning: std::basic_string_view outlives
   view3 = true ? "A" : str_ref;
   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: std::basic_string_view outlives
 
   std::string_view view4(ReturnsAString());
-  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:20: warning: std::basic_string_view outlives
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:26: warning: std::basic_string_view outlives
 }
 
 void OtherTypes() {
   llvm::StringRef ref = std::string();
-  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: llvm::StringRef outlives its value
+  // CHECK-MESSAGES-CXX14: [[@LINE-1]]:19: warning: llvm::StringRef outlives its value
+  // CHECK-MESSAGES-CXX17: [[@LINE-2]]:25: warning: llvm::StringRef outlives its value
 }
 
 const char static_array[] = "A";
Index: clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp
@@ -36,9 +36,9 @@
   // If a ternary operator returns a temporary value, then both branches hold a
   // temporary value. If one of them is not a temporary then it must be copied
   // into one to satisfy the type of the operator.
-  const auto TemporaryTernary =
-  conditionalOperator(hasTrueExpression(cxxBindTemporaryExpr()),
-  hasFalseExpression(cxxBindTemporaryExpr()));
+  const auto TemporaryTernary = conditionalOperator(
+  hasTrueExpression(ignoringParenImpCasts(cxxBindTemporaryExpr())),
+  hasFalseExpression(ignoringParenImpCasts(cxxBindTemporaryExpr(;
 
   return handleFrom(IsAHandle, anyOf(cxxBindTemporaryExpr(), TemporaryTernary));
 }
@@ -103,26 +103,17 @@
 void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {
   const auto ConvertedHandle = handleFromTemporaryValue(IsAHandle);
 
-  // Find 'Handle foo(ReturnsAValue());'
+  // Find 'Handle foo(ReturnsAValue());', 'Handle foo = ReturnsAValue();'
   Finder->addMatcher(
   varDecl(hasType(hasUnqualifiedDesugaredType(
   recordType(hasDeclaration(cxxRecordDecl(IsAHandle),
+  unless(parmVarDecl()),
   hasInitializer(
-  exprWithCleanups(has(ignoringParenImpCasts(ConvertedHandle)))
+ 

[PATCH] D158371: [clang-tidy] Fix DanglingHandleCheck to work in C++17 and later mode

2023-09-10 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov added a comment.

In D158371#4642758 , @PiotrZSL wrote:

> Name / Email (to be used as author) ?

Ignat Loskutov 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D158371

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


[PATCH] D158371: [clang-tidy] Fix DanglingHandleCheck to work in C++17 and later mode

2023-09-07 Thread Ignat Loskutov via Phabricator via cfe-commits
loskutov added a comment.

In D158371#4619348 , @PiotrZSL wrote:

> Please wait like 2 weeks before pushing this, so someone else could be able 
> to verify this if they need.

It's been 2 weeks, so I guess nothing prevents from getting this change merged. 
However, I don't have push access to the repo, so could you commit the change?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D158371

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