================
@@ -302,27 +307,43 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S, 
unsigned DiagID) {
     if (const Decl *FD = CE->getCalleeDecl()) {
       if (ShouldSuppress)
         return;
-      if (FD->hasAttr<PureAttr>()) {
-        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
-        return;
-      }
-      if (FD->hasAttr<ConstAttr>()) {
-        Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
+
+      const InheritableAttr *A = nullptr;
+      if (const auto *PA = FD->getAttr<PureAttr>())
+        A = PA;
+      else if (const auto *CA = FD->getAttr<ConstAttr>())
+        A = CA;
+
+      if (A) {
+        StringRef type = (isa<PureAttr>(A) ? "pure" : "const");
+        Diag(Loc, diag::warn_unused_call) << R1 << R2 << type;
+        if (const auto *ND = dyn_cast<NamedDecl>(OffendingDecl)) {
+          if (!ND->getIdentifier()->getBuiltinID())
----------------
Mick235711 wrote:

As I said above, the real motivation for avoiding marking here is twofold:
1. Builtins like `isdigit` are just marked pure internally, the note 
"explicitly marked pure/const here" is just wrong, there is no such attribute 
on that line.
```cpp
int isdigit(int c) __attribute__((overloadable)); // The note actually fires on 
this line, which doesn't have a pure attribute
int isdigit(int c) __attribute__((overloadable)) // expected-note {{'isdigit' 
has been explicitly marked unavailable here}}
  __attribute__((enable_if(c <= -1 || c > 255, "'c' must have the value of an 
unsigned char or EOF")))
  __attribute__((unavailable("'c' must have the value of an unsigned char or 
EOF")));

void test3(int c) {
  isdigit(c); // expected-warning{{ignoring return value of function declared 
with pure attribute}}
  isdigit(10); // expected-warning{{ignoring return value of function declared 
with pure attribute}}
#ifndef CODEGEN
  isdigit(-10);  // expected-error{{'isdigit' is unavailable: 'c' must have the 
value of an unsigned char or EOF}}
#endif
}
```
Unless `A->getLocation()` is not the right invocation to find the attribute 
location, I don't think there is a "builtin" declaration line that can be 
referenced by the note.
2. Language builtins like `__builtin_operator_new` will just fire the note on 
the first use:
```cpp
void test_typo_in_args() {
  __builtin_operator_new(DNE);          // expected-error {{undeclared 
identifier 'DNE'}}
  __builtin_operator_new(DNE, DNE2);    // expected-error {{undeclared 
identifier 'DNE'}} expected-error {{'DNE2'}}
  __builtin_operator_delete(DNE);       // expected-error {{'DNE'}}
  __builtin_operator_delete(DNE, DNE2); // expected-error {{'DNE'}} 
expected-error {{'DNE2'}}
}
```
In this test case (`SemaCXX/builtin-operator-new-delete.cpp`), the note is 
generated on the second line, i.e. first use of builtin, which is even more 
wrong as it is not even a declaration.

Excluding builtins from note generation fixes both errors, I think...

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

Reply via email to