[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

https://github.com/anematode created 
https://github.com/llvm/llvm-project/pull/82966

Will resolve https://github.com/llvm/llvm-project/issues/66059 . GCC's behavior 
in the case of inlining 
(https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) is that a caller's 
return/frame address may be returned, if the function in question gets inlined. 
Their docs encourage the function to be marked noinline. Therefore, it would be 
courteous to produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.

Marking this as draft because it's not fully ready, and I'd like to see whether 
this is a welcome change.

>From ef4c372a4d9364e6457c88a940c9af8666de0b74 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Mon, 26 Feb 2024 00:01:27 -0800
Subject: [PATCH] Add noinline check for __builtin_frame_address and
 __builtin_return_address

Resolves https://github.com/llvm/llvm-project/issues/66059 . GCC's behavior in 
the case of inlining (https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) 
is that a caller's return/frame address may be returned, if the function in 
question gets inlined. Their docs encourage the function to be marked noinline. 
Therefore, produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 +++
 clang/lib/Sema/SemaChecking.cpp   | 29 +
 clang/test/Sema/builtin-returnaddress.c   | 32 +++
 3 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..8f1cc611203694 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2029,6 +2029,10 @@ def warn_frame_address : Warning<
   "calling '%0' with a nonzero argument is unsafe">,
   InGroup, DefaultIgnore;
 
+def warn_frame_address_missing_noinline: Warning<
+  "calling '%0' in function not marked __attribute__((noinline)) may return a 
caller's %1 address">
+  InGroup, DefaultIgnore;
+
 def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
   "%select{anonymous struct|union}0 member %1 with a non-trivial "
   "%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7fa295ebd94044..1861f7dace3c6e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2733,13 +2733,28 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 // return/frame address.
 Expr::EvalResult Result;
 if (!TheCall->getArg(0)->isValueDependent() &&
-TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
-Result.Val.getInt() != 0)
-  Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
-  << ((BuiltinID == Builtin::BI__builtin_return_address)
-  ? "__builtin_return_address"
-  : "__builtin_frame_address")
-  << TheCall->getSourceRange();
+TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
+  const char *BuiltinName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+   ? "__builtin_return_address"
+   : "__builtin_frame_address";
+
+  if (Result.Val.getInt() != 0) {
+Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+<< BuiltinName << TheCall->getSourceRange();
+  }
+
+  // Check if enclosing function is marked noinline
+  if (const FunctionDecl *FD = dyn_cast(CurContext)) {
+if (!FD->hasAttr() && !FD->isMain()) {
+  const char *ShortName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+  ? "return" : "frame";
+  Diag(TheCall->getBeginLoc(), 
diag::warn_frame_address_missing_noinline)
+  << BuiltinName << ShortName << TheCall->getSourceRange();
+}
+  }
+}
 break;
   }
 
diff --git a/clang/test/Sema/builtin-returnaddress.c 
b/clang/test/Sema/builtin-returnaddress.c
index 16d2a517ac12f2..feb5a2ae05def7 100644
--- a/clang/test/Sema/builtin-returnaddress.c
+++ b/clang/test/Sema/builtin-returnaddress.c
@@ -2,24 +2,32 @@
 // RUN: %clang_cc1 -fsyntax-only -Wmost -verify %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wframe-address -verify %s
 
-void* a(unsigned x) {
+__attribute__((noinline)) void* a(unsigned x) {
 return __builtin_return_address(0);
 }
 
-void* b(unsigned x) {
+__attribute__((noinline)) void* b(unsigned x) {
 return __builtin_return_address(1); // expected-warning{{calling 
'__builtin_return_address' with a nonzero argument is unsafe}}
 }
 
-void* c(unsigned x) {
+__attribute__((noinline)) void* c(unsigned x) {
 return __builtin_frame_address(0);
 }
 
-void* d(unsigned x) {
+__attribute__((

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

https://github.com/anematode updated 
https://github.com/llvm/llvm-project/pull/82966

>From ef4c372a4d9364e6457c88a940c9af8666de0b74 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Mon, 26 Feb 2024 00:01:27 -0800
Subject: [PATCH] Add noinline check for __builtin_frame_address and
 __builtin_return_address

Resolves https://github.com/llvm/llvm-project/issues/66059 . GCC's behavior in 
the case of inlining (https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) 
is that a caller's return/frame address may be returned, if the function in 
question gets inlined. Their docs encourage the function to be marked noinline. 
Therefore, produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 +++
 clang/lib/Sema/SemaChecking.cpp   | 29 +
 clang/test/Sema/builtin-returnaddress.c   | 32 +++
 3 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..8f1cc611203694 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2029,6 +2029,10 @@ def warn_frame_address : Warning<
   "calling '%0' with a nonzero argument is unsafe">,
   InGroup, DefaultIgnore;
 
+def warn_frame_address_missing_noinline: Warning<
+  "calling '%0' in function not marked __attribute__((noinline)) may return a 
caller's %1 address">
+  InGroup, DefaultIgnore;
+
 def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
   "%select{anonymous struct|union}0 member %1 with a non-trivial "
   "%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7fa295ebd94044..1861f7dace3c6e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2733,13 +2733,28 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 // return/frame address.
 Expr::EvalResult Result;
 if (!TheCall->getArg(0)->isValueDependent() &&
-TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
-Result.Val.getInt() != 0)
-  Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
-  << ((BuiltinID == Builtin::BI__builtin_return_address)
-  ? "__builtin_return_address"
-  : "__builtin_frame_address")
-  << TheCall->getSourceRange();
+TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
+  const char *BuiltinName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+   ? "__builtin_return_address"
+   : "__builtin_frame_address";
+
+  if (Result.Val.getInt() != 0) {
+Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+<< BuiltinName << TheCall->getSourceRange();
+  }
+
+  // Check if enclosing function is marked noinline
+  if (const FunctionDecl *FD = dyn_cast(CurContext)) {
+if (!FD->hasAttr() && !FD->isMain()) {
+  const char *ShortName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+  ? "return" : "frame";
+  Diag(TheCall->getBeginLoc(), 
diag::warn_frame_address_missing_noinline)
+  << BuiltinName << ShortName << TheCall->getSourceRange();
+}
+  }
+}
 break;
   }
 
diff --git a/clang/test/Sema/builtin-returnaddress.c 
b/clang/test/Sema/builtin-returnaddress.c
index 16d2a517ac12f2..feb5a2ae05def7 100644
--- a/clang/test/Sema/builtin-returnaddress.c
+++ b/clang/test/Sema/builtin-returnaddress.c
@@ -2,24 +2,32 @@
 // RUN: %clang_cc1 -fsyntax-only -Wmost -verify %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wframe-address -verify %s
 
-void* a(unsigned x) {
+__attribute__((noinline)) void* a(unsigned x) {
 return __builtin_return_address(0);
 }
 
-void* b(unsigned x) {
+__attribute__((noinline)) void* b(unsigned x) {
 return __builtin_return_address(1); // expected-warning{{calling 
'__builtin_return_address' with a nonzero argument is unsafe}}
 }
 
-void* c(unsigned x) {
+__attribute__((noinline)) void* c(unsigned x) {
 return __builtin_frame_address(0);
 }
 
-void* d(unsigned x) {
+__attribute__((noinline)) void* d(unsigned x) {
 return __builtin_frame_address(1); // expected-warning{{calling 
'__builtin_frame_address' with a nonzero argument is unsafe}}
 }
 
+void* e(unsigned x) {
+  return __builtin_frame_address(0); // expected-warning{{calling 
'__builtin_frame_address' in function that is not marked 
__attribute__((noinline)) might return a caller's frame address}}
+}
+
+void* f(unsigned x) {
+  return __builtin_return_address(0); // expected-warning{{calling 
'__builtin_return_address' in function that is not marked 
__attribute__((noinline)) might return a caller's return address}

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

https://github.com/anematode updated 
https://github.com/llvm/llvm-project/pull/82966

>From cd68484e851040fc84e66933454f6fd910566b81 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Mon, 26 Feb 2024 12:21:40 -0800
Subject: [PATCH] Add noinline check for __builtin_frame_address and
 __builtin_return_address

Resolves #66059. GCC's behavior in the case of inlining 
(https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) is that a caller's 
return/frame address may be returned, if the function in question gets inlined. 
Their docs encourage the function to be marked noinline to prevent this 
behavior. Therefore, produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/lib/Sema/SemaChecking.cpp   | 34 ++
 clang/test/Sema/builtin-returnaddress.c   | 44 ---
 3 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a7f2858477bee6..6afd34d50086ce 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2029,6 +2029,10 @@ def warn_frame_address : Warning<
   "calling '%0' with a nonzero argument is unsafe">,
   InGroup, DefaultIgnore;
 
+def warn_frame_address_missing_noinline: Warning<
+  "calling '%0' in function not marked __attribute__((noinline)) may return a 
caller's %1 address">,
+  InGroup, DefaultIgnore;
+
 def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
   "%select{anonymous struct|union}0 member %1 with a non-trivial "
   "%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7fa295ebd94044..7fd34816dbcda9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2729,17 +2729,33 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 if (SemaBuiltinConstantArgRange(TheCall, 0, 0, 0x))
   return ExprError();
 
-// -Wframe-address warning if non-zero passed to builtin
-// return/frame address.
 Expr::EvalResult Result;
 if (!TheCall->getArg(0)->isValueDependent() &&
-TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
-Result.Val.getInt() != 0)
-  Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
-  << ((BuiltinID == Builtin::BI__builtin_return_address)
-  ? "__builtin_return_address"
-  : "__builtin_frame_address")
-  << TheCall->getSourceRange();
+TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
+  const char *BuiltinName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+  ? "__builtin_return_address"
+  : "__builtin_frame_address";
+
+  // -Wframe-address warning if non-zero passed to builtin
+  // return/frame address.
+  if (Result.Val.getInt() != 0) {
+Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+<< BuiltinName << TheCall->getSourceRange();
+  }
+
+  // -Wframe-address warning if enclosing function is not marked noinline.
+  if (const FunctionDecl *FD = dyn_cast(CurContext)) {
+if (!FD->hasAttr() && !FD->isMain()) {
+  const char *ShortName =
+  (BuiltinID == Builtin::BI__builtin_return_address) ? "return"
+ : "frame";
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_frame_address_missing_noinline)
+  << BuiltinName << ShortName << TheCall->getSourceRange();
+}
+  }
+}
 break;
   }
 
diff --git a/clang/test/Sema/builtin-returnaddress.c 
b/clang/test/Sema/builtin-returnaddress.c
index 16d2a517ac12f2..0b6733f9381c9f 100644
--- a/clang/test/Sema/builtin-returnaddress.c
+++ b/clang/test/Sema/builtin-returnaddress.c
@@ -2,24 +2,32 @@
 // RUN: %clang_cc1 -fsyntax-only -Wmost -verify %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wframe-address -verify %s
 
-void* a(unsigned x) {
+__attribute__((noinline)) void* a(unsigned x) {
 return __builtin_return_address(0);
 }
 
-void* b(unsigned x) {
+__attribute__((noinline)) void* b(unsigned x) {
 return __builtin_return_address(1); // expected-warning{{calling 
'__builtin_return_address' with a nonzero argument is unsafe}}
 }
 
-void* c(unsigned x) {
+__attribute__((noinline)) void* c(unsigned x) {
 return __builtin_frame_address(0);
 }
 
-void* d(unsigned x) {
+__attribute__((noinline)) void* d(unsigned x) {
 return __builtin_frame_address(1); // expected-warning{{calling 
'__builtin_frame_address' with a nonzero argument is unsafe}}
 }
 
+void* e(unsigned x) {
+  return __builtin_frame_address(0); // expected-warning{{calling 
'__builtin_frame_address' in functio

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

https://github.com/anematode updated 
https://github.com/llvm/llvm-project/pull/82966

>From e5646f3f4967847ef68d428c84b30dbd4d2e8e49 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Mon, 26 Feb 2024 12:21:40 -0800
Subject: [PATCH] Add noinline check for __builtin_frame_address and
 __builtin_return_address

Resolves #66059. GCC's behavior in the case of inlining 
(https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) is that a caller's 
return/frame address may be returned, if the function in question gets inlined. 
Their docs encourage the function to be marked noinline to prevent this 
behavior. Therefore, produce a warning if the function containing the call to 
__builtin_frame_address and __builtin_return_address is not marked noinline.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  4 ++
 clang/lib/Sema/SemaChecking.cpp   | 34 ++
 clang/test/Sema/builtin-returnaddress.c   | 44 ---
 3 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 57784a4ba2e388..21cfd69dc69fc4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2029,6 +2029,10 @@ def warn_frame_address : Warning<
   "calling '%0' with a nonzero argument is unsafe">,
   InGroup, DefaultIgnore;
 
+def warn_frame_address_missing_noinline: Warning<
+  "calling '%0' in function not marked __attribute__((noinline)) may return a 
caller's %1 address">,
+  InGroup, DefaultIgnore;
+
 def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning<
   "%select{anonymous struct|union}0 member %1 with a non-trivial "
   "%sub{select_special_member_kind}2 is incompatible with C++98">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 984088e345c806..3c0a5a8a402ae9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2730,17 +2730,33 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 if (SemaBuiltinConstantArgRange(TheCall, 0, 0, 0x))
   return ExprError();
 
-// -Wframe-address warning if non-zero passed to builtin
-// return/frame address.
 Expr::EvalResult Result;
 if (!TheCall->getArg(0)->isValueDependent() &&
-TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext()) &&
-Result.Val.getInt() != 0)
-  Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
-  << ((BuiltinID == Builtin::BI__builtin_return_address)
-  ? "__builtin_return_address"
-  : "__builtin_frame_address")
-  << TheCall->getSourceRange();
+TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())) {
+  const char *BuiltinName =
+  (BuiltinID == Builtin::BI__builtin_return_address)
+  ? "__builtin_return_address"
+  : "__builtin_frame_address";
+
+  // -Wframe-address warning if non-zero passed to builtin
+  // return/frame address.
+  if (Result.Val.getInt() != 0) {
+Diag(TheCall->getBeginLoc(), diag::warn_frame_address)
+<< BuiltinName << TheCall->getSourceRange();
+  }
+
+  // -Wframe-address warning if enclosing function is not marked noinline.
+  if (const FunctionDecl *FD = dyn_cast(CurContext)) {
+if (!FD->hasAttr() && !FD->isMain()) {
+  const char *ShortName =
+  (BuiltinID == Builtin::BI__builtin_return_address) ? "return"
+ : "frame";
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_frame_address_missing_noinline)
+  << BuiltinName << ShortName << TheCall->getSourceRange();
+}
+  }
+}
 break;
   }
 
diff --git a/clang/test/Sema/builtin-returnaddress.c 
b/clang/test/Sema/builtin-returnaddress.c
index 16d2a517ac12f2..0b6733f9381c9f 100644
--- a/clang/test/Sema/builtin-returnaddress.c
+++ b/clang/test/Sema/builtin-returnaddress.c
@@ -2,24 +2,32 @@
 // RUN: %clang_cc1 -fsyntax-only -Wmost -verify %s
 // RUN: %clang_cc1 -x c++ -fsyntax-only -Wframe-address -verify %s
 
-void* a(unsigned x) {
+__attribute__((noinline)) void* a(unsigned x) {
 return __builtin_return_address(0);
 }
 
-void* b(unsigned x) {
+__attribute__((noinline)) void* b(unsigned x) {
 return __builtin_return_address(1); // expected-warning{{calling 
'__builtin_return_address' with a nonzero argument is unsafe}}
 }
 
-void* c(unsigned x) {
+__attribute__((noinline)) void* c(unsigned x) {
 return __builtin_frame_address(0);
 }
 
-void* d(unsigned x) {
+__attribute__((noinline)) void* d(unsigned x) {
 return __builtin_frame_address(1); // expected-warning{{calling 
'__builtin_frame_address' with a nonzero argument is unsafe}}
 }
 
+void* e(unsigned x) {
+  return __builtin_frame_address(0); // expected-warning{{calling 
'__builtin_frame_address' in functio

[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

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


[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

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


[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-02-26 Thread Timothy Herchen via cfe-commits

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


[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-03-04 Thread Timothy Herchen via cfe-commits

anematode wrote:

> I'm seeing evidence that this might be a chatty diagnostic in practice:
> 
> https://sourcegraph.com/github.com/torvalds/linux@90d35da658da8cff0d4ecbb5113f5fac9d00eb72/-/blob/kernel/fork.c?L311
>  
> https://sourcegraph.com/github.com/torvalds/linux@90d35da658da8cff0d4ecbb5113f5fac9d00eb72/-/blob/mm/util.c?L644
>  
> https://sourcegraph.com/github.com/torvalds/linux@90d35da658da8cff0d4ecbb5113f5fac9d00eb72/-/blob/arch/arm/mm/nommu.c?L224
>  
> https://sourcegraph.com/github.com/torvalds/linux@90d35da658da8cff0d4ecbb5113f5fac9d00eb72/-/blob/kernel/scs.c?L48
>  (and quite a few others).

Are any of these logic errors if the function gets inlined?

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


[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-03-04 Thread Timothy Herchen via cfe-commits

anematode wrote:

> Although I seem to remember having seen code that uses `always_inline` in 
> order to force `__builtin_return_address` to actually apply to its caller.

Right; that's why I thought just disabling inlining would be a suboptimal 
choice, although I guess you could have `always_inline` override it.

If the diagnostic is so noisy then maybe I don't see the point of it. Is there 
any case in Linux where it's a correctness issue to use a caller's address? 
(Presumably in this case it would just give a confusing call site when you're 
debugging.)

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


[clang] [clang][Sema] Add noinline check for __builtin_frame_address and __builtin_return_address (PR #82966)

2024-03-04 Thread Timothy Herchen via cfe-commits

anematode wrote:

It's used 100+ more times through the macro `_RET_IP_`. 
https://elixir.bootlin.com/linux/latest/source/include/linux/instruction_pointer.h#L7

https://elixir.bootlin.com/linux/latest/source/include/linux/kasan.h#L164 has 
some example uses where `always_inline` is important for correctness.

https://elixir.bootlin.com/linux/latest/source/kernel/kcsan/core.c#L912 might 
be interesting? (This is way out of my depth.) Function isn't marked noinline 
and the return pointer is actually important. Also, many other functions in 
that file seem to be marked noinline, e.g. 
https://elixir.bootlin.com/linux/latest/source/kernel/kcsan/core.c#L1327, but 
not that one.

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


[clang] [clang][docs] Fix typos concerning wasm __funcref (PR #124365)

2025-01-24 Thread Timothy Herchen via cfe-commits

https://github.com/anematode created 
https://github.com/llvm/llvm-project/pull/124365

The docs conflate `__funcref` with an actual type in a couple places.

>From 2508da6fd7f38101011573460724f13df1c1616d Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Fri, 24 Jan 2025 15:13:30 -0800
Subject: [PATCH] [clang][docs] Fix typos concerning wasm __funcref

---
 clang/docs/LanguageExtensions.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c42b88015e2695..ddb11cc6efb232 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2632,7 +2632,7 @@ with the current table size.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   size_t getSize() {
 return __builtin_wasm_table_size(table);
@@ -2654,10 +2654,10 @@ or -1. It will return -1 if not enough space could be 
allocated.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   // grow returns the new table size or -1 on error.
-  int grow(__funcref fn, int delta) {
+  int grow(funcref_t fn, int delta) {
 int prevSize = __builtin_wasm_table_grow(table, fn, delta);
 if (prevSize == -1)
   return -1;

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


[clang] [clang][docs] Fix typos concerning wasm __funcref (PR #124365)

2025-01-27 Thread Timothy Herchen via cfe-commits

https://github.com/anematode updated 
https://github.com/llvm/llvm-project/pull/124365

>From 2508da6fd7f38101011573460724f13df1c1616d Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Fri, 24 Jan 2025 15:13:30 -0800
Subject: [PATCH] [clang][docs] Fix typos concerning wasm __funcref

---
 clang/docs/LanguageExtensions.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c42b88015e2695..ddb11cc6efb232 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2632,7 +2632,7 @@ with the current table size.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   size_t getSize() {
 return __builtin_wasm_table_size(table);
@@ -2654,10 +2654,10 @@ or -1. It will return -1 if not enough space could be 
allocated.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   // grow returns the new table size or -1 on error.
-  int grow(__funcref fn, int delta) {
+  int grow(funcref_t fn, int delta) {
 int prevSize = __builtin_wasm_table_grow(table, fn, delta);
 if (prevSize == -1)
   return -1;

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


[clang] [llvm] [clang][docs] Fix typos concerning wasm __funcref (PR #124365)

2025-01-27 Thread Timothy Herchen via cfe-commits


@@ -1211,6 +1211,15 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo 
&CLI,
 }
   }
 }
+
+// If outgoing arguments are passed via the stack, we cannot tail call
+for (const ISD::OutputArg &Out : CLI.Outs) {

anematode wrote:

Whoops! 😅

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


[clang] [llvm] [clang][docs] Fix typos concerning wasm __funcref (PR #124365)

2025-01-25 Thread Timothy Herchen via cfe-commits

https://github.com/anematode updated 
https://github.com/llvm/llvm-project/pull/124365

>From 2508da6fd7f38101011573460724f13df1c1616d Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Fri, 24 Jan 2025 15:13:30 -0800
Subject: [PATCH 1/2] [clang][docs] Fix typos concerning wasm __funcref

---
 clang/docs/LanguageExtensions.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index c42b88015e2695..ddb11cc6efb232 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -2632,7 +2632,7 @@ with the current table size.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   size_t getSize() {
 return __builtin_wasm_table_size(table);
@@ -2654,10 +2654,10 @@ or -1. It will return -1 if not enough space could be 
allocated.
 .. code-block:: c++
 
   typedef void (*__funcref funcref_t)();
-  static __funcref table[0];
+  static funcref_t table[0];
 
   // grow returns the new table size or -1 on error.
-  int grow(__funcref fn, int delta) {
+  int grow(funcref_t fn, int delta) {
 int prevSize = __builtin_wasm_table_grow(table, fn, delta);
 if (prevSize == -1)
   return -1;

>From 5721ec3228edebb3170df3a8dc80ef12076f5ea8 Mon Sep 17 00:00:00 2001
From: Timothy Herchen 
Date: Sat, 25 Jan 2025 20:19:00 -0800
Subject: [PATCH 2/2] [wasm] disallow tail calls when passing structs on the
 stack

---
 llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | 9 +
 1 file changed, 9 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 02db1b142a22b5..ec745ebabb4f63 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1211,6 +1211,15 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo 
&CLI,
 }
   }
 }
+
+// If outgoing arguments are passed via the stack, we cannot tail call
+for (const ISD::OutputArg &Out : CLI.Outs) {
+  if (Out.Flags.isByVal() && Out.Flags.getByValSize() != 0) {
+NoTail(
+"WebAssembly does not support tail calling with stack arguments");
+break;
+  }
+}
   }
 
   SmallVectorImpl &Ins = CLI.Ins;

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


[clang] [clang][docs] Fix typos concerning wasm __funcref (PR #124365)

2025-02-17 Thread Timothy Herchen via cfe-commits

anematode wrote:

Pardon? (Last time I made a PR my commit was merged directly, but I don't mind 
if you commit a trivial one like this)

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