[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits


@@ -449,3 +451,22 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter ) 
const {
   if (!getNote().empty())
 DP << ": " << getNote();
 }
+
+SmallVector DiagnosticInfoDontCall::getInliningDecisions() const {
+  SmallVector InliningDecisions;
+
+  if (MDN) {
+const MDOperand  = MDN->getOperand(0);
+if (auto *MDT = dyn_cast(MO)) {

nickdesaulniers wrote:

Copying @aeubanks 's [comment](https://reviews.llvm.org/D141451#inline-1446137) 
from the phab review:

> seems simpler if this is always a MDTuple instead of special casing one entry 
> to be MDString

For the life of me I cannot figure out why when an MDTuple is created via:
```c++
Metadata *MD = MDString::get(CI->getContext(), CalledFunc->getName());
MDTuple *MDT = MDNode::get(CI->getContext(), {MD});
CI->setMetadata("inlined.from", MDT);
```
you get
```llvm
!10 = !{!"my_memcpy"}
```

but when you copy a `MDTuple` and then append to it, you get a layer of 
indirection:
```c++
Metadata *MD = MDString::get(CI->getContext(), CalledFunc->getName());  

 
if (MDNode *N = CI->getMetadata("inlined.from")) {  

 
  TempMDTuple Temp = cast(N)->clone(); 

 
  Temp->push_back(MD);  

 
  MD = MDNode::replaceWithUniqued(std::move(Temp)); 

 
}   

 
MDTuple *MDT = MDNode::get(CI->getContext(), {MD}); 

 
CI->setMetadata("inlined.from", MDT);
```
```llvm
!10 = !{!11}
!11 = !{!"my_memcpy", !"my_driver"}
```
when I would have expected:
```llvm
!10 = !{!"my_memcpy", !"my_driver"}
```
am I holding the API wrong??

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Kees Cook via cfe-commits


@@ -455,18 +455,11 @@ void DiagnosticInfoDontCall::print(DiagnosticPrinter ) 
const {
 SmallVector DiagnosticInfoDontCall::getInliningDecisions() const {
   SmallVector InliningDecisions;
 
-  if (MDN) {
-const MDOperand  = MDN->getOperand(0);
-if (auto *MDT = dyn_cast(MO)) {
-  for (const MDOperand  : MDT->operands()) {
-if (auto *S = dyn_cast(MO)) {
+  if (MDN)
+if (auto *MDT = dyn_cast(MDN->getOperand(0)))
+  for (const MDOperand  : MDT->operands())
+if (auto *S = dyn_cast(MO))
   InliningDecisions.push_back(S->getString().str());
-}
-  }
-} else if (auto *S = dyn_cast(MO)) {
-  InliningDecisions.push_back(S->getString().str());
-}
-  }

kees wrote:

We want it to read like "before", yes?

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits


@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;

nickdesaulniers wrote:

All of the diagnostics for backend warnings are defined in this file. (see 
existing lines 66-95).

As is, this note is emitted alongside the err/warn from existing lines 91-95, 
so it makes sense to put the new notes immediately after those existing 
definitions.

If my newly added backend warning notes belong in a new file, then all of the 
above belong in a new file.  But that seems orthogonal to my patch.

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Erich Keane via cfe-commits


@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;

erichkeane wrote:

IDK, that is why I asked.  It SOUNDS wrong, so I'm hopeful someone else can 
come along and tell us.

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits


@@ -794,6 +796,13 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions = D.getInliningDecisions();
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto [index, value] : llvm::enumerate(InliningDecisions))

nickdesaulniers wrote:

done in d3a221a9aea4f60244adc7d726b398abeb2775b3 PTAL

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Erich Keane via cfe-commits


@@ -794,6 +796,13 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions = D.getInliningDecisions();

erichkeane wrote:

Could we use `StringRef` here instead?  It seems to make more sense to me.

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits

https://github.com/nickdesaulniers updated 
https://github.com/llvm/llvm-project/pull/73552

>From cea177222b421c67dabbe9e267f8b9a4ead4d51e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers 
Date: Tue, 10 Jan 2023 17:42:18 -0800
Subject: [PATCH 01/10] [clang] report inlining decisions with
 -Wattribute-{warning|error}

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

Differential Revision: https://reviews.llvm.org/D141451
---
 .../clang/Basic/DiagnosticFrontendKinds.td|  2 +
 clang/lib/CodeGen/CodeGenAction.cpp   | 10 +++
 ...backend-attribute-error-warning-optimize.c | 21 +
 .../backend-attribute-error-warning.c |  6 ++
 .../backend-attribute-error-warning.cpp   | 12 +++
 llvm/docs/LangRef.rst |  8 +-
 llvm/include/llvm/IR/DiagnosticInfo.h | 14 +++-
 llvm/lib/IR/DiagnosticInfo.cpp| 23 -
 llvm/lib/Transforms/Utils/InlineFunction.cpp  | 13 +++
 .../Transforms/Inline/dontcall-attributes.ll  | 84 +++
 10 files changed, 185 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/dontcall-attributes.ll

diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 715e0c0dc8fa84e5..0909b1f59175be9e 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;
+def note_fe_backend_inlined : Note<"inlined by function '%0'">;
 
 def err_fe_invalid_code_complete_file : Error<
 "cannot locate code-completion file %0">, DefaultFatal;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp 
b/clang/lib/CodeGen/CodeGenAction.cpp
index a31a271ed77d1ca9..66e040741e2718dc 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 
 #include 
+#include 
+
 using namespace clang;
 using namespace llvm;
 
@@ -794,6 +796,14 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions;
+  D.getInliningDecisions(InliningDecisions);
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto Dec : llvm::enumerate(InliningDecisions))
+Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
+ : diag::note_fe_backend_in)
+<< llvm::demangle(Dec.value());
 }
 
 void BackendConsumer::MisExpectDiagHandler(
diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c 
b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index d3951e3b6b1f57da..0bfc50ff8985c398 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -9,6 +9,7 @@ int x(void) {
 }
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar();
 }
@@ -20,3 +21,23 @@ void indirect(void) {
   quux = foo;
   quux();
 }
+
+static inline void a(int x) {
+if (x == 10)
+foo(); // expected-error {{call to 'foo' declared with 'error' 
attribute: oh no foo}}
+   // expected-note@* {{called by function 'a'}}
+   // expected-note@* {{inlined by function 'b'}}
+   // expected-note@* {{inlined by function 'd'}}
+}
+
+static inline void b() {
+a(10);
+}
+
+void c() {
+a(9);
+}
+
+void d() {
+  b();
+}
diff --git a/clang/test/Frontend/backend-attribute-error-warning.c 
b/clang/test/Frontend/backend-attribute-error-warning.c
index c3c7803479aac963..c87a47053e5c0f8e 100644
--- a/clang/test/Frontend/backend-attribute-error-warning.c
+++ b/clang/test/Frontend/backend-attribute-error-warning.c
@@ -23,11 +23,17 @@ duplicate_warnings(void);
 
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar(); // expected-error {{call to 'bar' declared with 'error' attribute: 
oh no bar}}
+   // 

[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits

nickdesaulniers wrote:

(Initial import from https://reviews.llvm.org/D141451)

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: Nick Desaulniers (nickdesaulniers)


Changes

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

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


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


10 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+2) 
- (modified) clang/lib/CodeGen/CodeGenAction.cpp (+10) 
- (modified) clang/test/Frontend/backend-attribute-error-warning-optimize.c 
(+21) 
- (modified) clang/test/Frontend/backend-attribute-error-warning.c (+6) 
- (modified) clang/test/Frontend/backend-attribute-error-warning.cpp (+12) 
- (modified) llvm/docs/LangRef.rst (+6-2) 
- (modified) llvm/include/llvm/IR/DiagnosticInfo.h (+10-4) 
- (modified) llvm/lib/IR/DiagnosticInfo.cpp (+21-2) 
- (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+13) 
- (added) llvm/test/Transforms/Inline/dontcall-attributes.ll (+84) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 715e0c0dc8fa84e..0909b1f59175be9 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;
+def note_fe_backend_inlined : Note<"inlined by function '%0'">;
 
 def err_fe_invalid_code_complete_file : Error<
 "cannot locate code-completion file %0">, DefaultFatal;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp 
b/clang/lib/CodeGen/CodeGenAction.cpp
index a31a271ed77d1ca..66e040741e2718d 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 
 #include 
+#include 
+
 using namespace clang;
 using namespace llvm;
 
@@ -794,6 +796,14 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions;
+  D.getInliningDecisions(InliningDecisions);
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto Dec : llvm::enumerate(InliningDecisions))
+Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
+ : diag::note_fe_backend_in)
+<< llvm::demangle(Dec.value());
 }
 
 void BackendConsumer::MisExpectDiagHandler(
diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c 
b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index d3951e3b6b1f57d..0bfc50ff8985c39 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -9,6 +9,7 @@ int x(void) {
 }
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar();
 }
@@ -20,3 +21,23 @@ void indirect(void) {
   quux = foo;
   quux();
 }
+
+static inline void a(int x) {
+if (x == 10)
+foo(); // expected-error {{call to 'foo' declared with 'error' 
attribute: oh no foo}}
+   // expected-note@* {{called by function 'a'}}
+   // expected-note@* {{inlined by function 'b'}}
+   // expected-note@* {{inlined by function 'd'}}
+}
+
+static inline void b() {
+a(10);
+}
+
+void c() {
+a(9);
+}
+
+void d() {
+  b();
+}
diff --git a/clang/test/Frontend/backend-attribute-error-warning.c 
b/clang/test/Frontend/backend-attribute-error-warning.c
index c3c7803479aac96..c87a47053e5c0f8 100644
--- a/clang/test/Frontend/backend-attribute-error-warning.c
+++ b/clang/test/Frontend/backend-attribute-error-warning.c
@@ -23,11 +23,17 @@ duplicate_warnings(void);
 
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar(); // expected-error {{call to 'bar' declared with 'error' attribute: 
oh no bar}}
+   // expected-note@* {{called by function 'baz'}}
 
   quux(); // enabled-warning {{call to 'quux' declared 
with 'warning' attribute: oh no quux}}
+

[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits

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


[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nick Desaulniers (nickdesaulniers)


Changes

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

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


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


10 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+2) 
- (modified) clang/lib/CodeGen/CodeGenAction.cpp (+10) 
- (modified) clang/test/Frontend/backend-attribute-error-warning-optimize.c 
(+21) 
- (modified) clang/test/Frontend/backend-attribute-error-warning.c (+6) 
- (modified) clang/test/Frontend/backend-attribute-error-warning.cpp (+12) 
- (modified) llvm/docs/LangRef.rst (+6-2) 
- (modified) llvm/include/llvm/IR/DiagnosticInfo.h (+10-4) 
- (modified) llvm/lib/IR/DiagnosticInfo.cpp (+21-2) 
- (modified) llvm/lib/Transforms/Utils/InlineFunction.cpp (+13) 
- (added) llvm/test/Transforms/Inline/dontcall-attributes.ll (+84) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 715e0c0dc8fa84e..0909b1f59175be9 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;
+def note_fe_backend_inlined : Note<"inlined by function '%0'">;
 
 def err_fe_invalid_code_complete_file : Error<
 "cannot locate code-completion file %0">, DefaultFatal;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp 
b/clang/lib/CodeGen/CodeGenAction.cpp
index a31a271ed77d1ca..66e040741e2718d 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 
 #include 
+#include 
+
 using namespace clang;
 using namespace llvm;
 
@@ -794,6 +796,14 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions;
+  D.getInliningDecisions(InliningDecisions);
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto Dec : llvm::enumerate(InliningDecisions))
+Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
+ : diag::note_fe_backend_in)
+<< llvm::demangle(Dec.value());
 }
 
 void BackendConsumer::MisExpectDiagHandler(
diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c 
b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index d3951e3b6b1f57d..0bfc50ff8985c39 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -9,6 +9,7 @@ int x(void) {
 }
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar();
 }
@@ -20,3 +21,23 @@ void indirect(void) {
   quux = foo;
   quux();
 }
+
+static inline void a(int x) {
+if (x == 10)
+foo(); // expected-error {{call to 'foo' declared with 'error' 
attribute: oh no foo}}
+   // expected-note@* {{called by function 'a'}}
+   // expected-note@* {{inlined by function 'b'}}
+   // expected-note@* {{inlined by function 'd'}}
+}
+
+static inline void b() {
+a(10);
+}
+
+void c() {
+a(9);
+}
+
+void d() {
+  b();
+}
diff --git a/clang/test/Frontend/backend-attribute-error-warning.c 
b/clang/test/Frontend/backend-attribute-error-warning.c
index c3c7803479aac96..c87a47053e5c0f8 100644
--- a/clang/test/Frontend/backend-attribute-error-warning.c
+++ b/clang/test/Frontend/backend-attribute-error-warning.c
@@ -23,11 +23,17 @@ duplicate_warnings(void);
 
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar(); // expected-error {{call to 'bar' declared with 'error' attribute: 
oh no bar}}
+   // expected-note@* {{called by function 'baz'}}
 
   quux(); // enabled-warning {{call to 'quux' declared 
with 'warning' attribute: oh no quux}}
+  

[llvm] [clang] [clang] report inlining decisions with -Wattribute-{warning|error} (PR #73552)

2023-11-27 Thread Nick Desaulniers via cfe-commits

https://github.com/nickdesaulniers created 
https://github.com/llvm/llvm-project/pull/73552

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

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


>From cea177222b421c67dabbe9e267f8b9a4ead4d51e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers 
Date: Tue, 10 Jan 2023 17:42:18 -0800
Subject: [PATCH] [clang] report inlining decisions with
 -Wattribute-{warning|error}

Due to inlining, descovering which specific call site to a function with
the attribute "warning" or "error" is painful.

In the IR record inlining decisions in metadata when inlining a callee
that itself contains a call to a dontcall-error or dontcall-warn fn.

Print this info so that it's clearer which call site is problematic.

There's still some limitations with this approach; macro expansion is
not recorded.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571

Differential Revision: https://reviews.llvm.org/D141451
---
 .../clang/Basic/DiagnosticFrontendKinds.td|  2 +
 clang/lib/CodeGen/CodeGenAction.cpp   | 10 +++
 ...backend-attribute-error-warning-optimize.c | 21 +
 .../backend-attribute-error-warning.c |  6 ++
 .../backend-attribute-error-warning.cpp   | 12 +++
 llvm/docs/LangRef.rst |  8 +-
 llvm/include/llvm/IR/DiagnosticInfo.h | 14 +++-
 llvm/lib/IR/DiagnosticInfo.cpp| 23 -
 llvm/lib/Transforms/Utils/InlineFunction.cpp  | 13 +++
 .../Transforms/Inline/dontcall-attributes.ll  | 84 +++
 10 files changed, 185 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/dontcall-attributes.ll

diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 715e0c0dc8fa84e5..0909b1f59175be9e 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -93,6 +93,8 @@ def err_fe_backend_error_attr :
 def warn_fe_backend_warning_attr :
   Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
   InGroup;
+def note_fe_backend_in : Note<"called by function '%0'">;
+def note_fe_backend_inlined : Note<"inlined by function '%0'">;
 
 def err_fe_invalid_code_complete_file : Error<
 "cannot locate code-completion file %0">, DefaultFatal;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp 
b/clang/lib/CodeGen/CodeGenAction.cpp
index a31a271ed77d1ca9..66e040741e2718dc 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 
 #include 
+#include 
+
 using namespace clang;
 using namespace llvm;
 
@@ -794,6 +796,14 @@ void BackendConsumer::DontCallDiagHandler(const 
DiagnosticInfoDontCall ) {
   ? diag::err_fe_backend_error_attr
   : diag::warn_fe_backend_warning_attr)
   << llvm::demangle(D.getFunctionName()) << D.getNote();
+
+  SmallVector InliningDecisions;
+  D.getInliningDecisions(InliningDecisions);
+  InliningDecisions.push_back(D.getCaller().str());
+  for (auto Dec : llvm::enumerate(InliningDecisions))
+Diags.Report(Dec.index() ? diag::note_fe_backend_inlined
+ : diag::note_fe_backend_in)
+<< llvm::demangle(Dec.value());
 }
 
 void BackendConsumer::MisExpectDiagHandler(
diff --git a/clang/test/Frontend/backend-attribute-error-warning-optimize.c 
b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
index d3951e3b6b1f57da..0bfc50ff8985c398 100644
--- a/clang/test/Frontend/backend-attribute-error-warning-optimize.c
+++ b/clang/test/Frontend/backend-attribute-error-warning-optimize.c
@@ -9,6 +9,7 @@ int x(void) {
 }
 void baz(void) {
   foo(); // expected-error {{call to 'foo' declared with 'error' attribute: oh 
no foo}}
+ // expected-note@* {{called by function 'baz'}}
   if (x())
 bar();
 }
@@ -20,3 +21,23 @@ void indirect(void) {
   quux = foo;
   quux();
 }
+
+static inline void a(int x) {
+if (x == 10)
+foo(); // expected-error {{call to 'foo' declared with 'error' 
attribute: oh no foo}}
+   // expected-note@* {{called by function 'a'}}
+   // expected-note@* {{inlined by function 'b'}}
+   // expected-note@* {{inlined by function 'd'}}
+}
+
+static inline void b() {
+a(10);
+}
+
+void c() {
+a(9);
+}
+
+void d() {
+  b();
+}
diff --git a/clang/test/Frontend/backend-attribute-error-warning.c