0xdc03 updated this revision to Diff 502660.
0xdc03 added a comment.

- Reword the diagnostic messages
- Refactor tests to match updated diagnostic


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143803

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/alias.cpp
  clang/test/CodeGen/attr-ifunc.c
  clang/test/CodeGen/attr-ifunc.cpp
  clang/test/Sema/attr-alias-elf.c
  clang/test/SemaCXX/externc-ifunc-resolver.cpp

Index: clang/test/SemaCXX/externc-ifunc-resolver.cpp
===================================================================
--- clang/test/SemaCXX/externc-ifunc-resolver.cpp
+++ clang/test/SemaCXX/externc-ifunc-resolver.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s
+// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 extern "C" {
 __attribute__((used)) static void *resolve_foo() { return 0; }
@@ -12,5 +13,10 @@
 // some way to improve this diagnostic (likely by diagnosing when we decide
 // this case suppresses alias creation).
 __attribute__((ifunc("resolve_foo"))) void foo(); // expected-error{{ifunc must point to a defined function}}
+// expected-note@-1 {{must refer to its mangled name}}
+// expected-note@-2 {{function by that name is mangled as}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:36}:"ifunc(\"_ZL11resolve_foov\")"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:36}:"ifunc(\"_ZN2NSL11resolve_fooEv\")"
 }
 
Index: clang/test/Sema/attr-alias-elf.c
===================================================================
--- clang/test/Sema/attr-alias-elf.c
+++ clang/test/Sema/attr-alias-elf.c
@@ -5,9 +5,10 @@
 }
 
 void f2(void) __attribute__((alias("g2"))); // expected-error {{alias must point to a defined variable or function}}
-
+// expected-note@-1 {{must refer to its mangled name}}
 
 void f3(void) __attribute__((alias("g3"))); // expected-error {{alias must point to a defined variable or function}}
+// expected-note@-1 {{must refer to its mangled name}}
 void g3(void);
 
 
@@ -46,11 +47,14 @@
 int b1 = 42;
 
 extern int a2 __attribute__((alias("b2"))); // expected-error {{alias must point to a defined variable or function}}
+// expected-note@-1 {{must refer to its mangled name}}
 
 extern int a3 __attribute__((alias("b3"))); // expected-error {{alias must point to a defined variable or function}}
+// expected-note@-1 {{must refer to its mangled name}}
 extern int b3;
 
 extern int a4 __attribute__((alias("b4"))); // expected-error {{alias must point to a defined variable or function}}
+// expected-note@-1 {{must refer to its mangled name}}
 typedef int b4;
 
 void test2_bar() {}
Index: clang/test/CodeGen/attr-ifunc.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-ifunc.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s
+// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+void *f1_ifunc(void) { return nullptr; }
+void f1(void) __attribute__((ifunc("f1_ifunc")));
+// expected-error@-1 {{ifunc must point to a defined function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:47}:"ifunc(\"_Z8f1_ifuncv\")"
+
+void *f6_resolver_resolver(void) { return 0; }
+void *f6_resolver(void) __attribute__((ifunc("f6_resolver_resolver")));
+// expected-error@-1 {{ifunc must point to a defined function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:40-[[@LINE-4]]:69}:"ifunc(\"_Z20f6_resolver_resolverv\")"
+void f6(void) __attribute__((ifunc("f6_resolver")));
+// expected-error@-1 {{ifunc must point to a defined function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:50}:"ifunc(\"_Z11f6_resolverv\")"
+
+__attribute__((unused, ifunc("resolver"), deprecated("hahahaha, isn't C great?")))
+void func();
+// expected-error@-2 {{ifunc must point to a defined function}}
+// expected-note@-3 {{must refer to its mangled name}}
+
Index: clang/test/CodeGen/attr-ifunc.c
===================================================================
--- clang/test/CodeGen/attr-ifunc.c
+++ clang/test/CodeGen/attr-ifunc.c
@@ -12,6 +12,7 @@
 void *f1_ifunc(void);
 void f1(void) __attribute__((ifunc("f1_ifunc")));
 // expected-error@-1 {{ifunc must point to a defined function}}
+// expected-note@-2 {{must refer to its mangled name}}
 
 void *f2_a(void) __attribute__((alias("f2_b")));
 void *f2_b(void) __attribute__((ifunc("f2_a")));
Index: clang/test/CodeGen/alias.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/alias.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-linux -verify -emit-llvm-only %s
+// RUN: not %clang_cc1 -triple x86_64-linux -emit-llvm-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+void *f1_ifunc(void) { return nullptr; }
+void f1(void) __attribute__((alias("f1_ifunc")));
+// expected-error@-1 {{alias must point to a defined variable or function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:47}:"alias(\"_Z8f1_ifuncv\")"
+
+void *f6_resolver_resolver(void) { return 0; }
+void *f6_resolver(void) __attribute__((alias("f6_resolver_resolver")));
+// expected-error@-1 {{alias must point to a defined variable or function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:40-[[@LINE-4]]:69}:"alias(\"_Z20f6_resolver_resolverv\")"
+void f6(void) __attribute__((alias("f6_resolver")));
+// expected-error@-1 {{alias must point to a defined variable or function}}
+// expected-note@-2 {{must refer to its mangled name}}
+// expected-note@-3 {{function by that name is mangled as}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:30-[[@LINE-4]]:50}:"alias(\"_Z11f6_resolverv\")"
+
+__attribute__((unused, alias("resolver"), deprecated("hahahaha, isn't C great?")))
+void func();
+// expected-error@-2 {{alias must point to a defined variable or function}}
+// expected-note@-3 {{must refer to its mangled name}}
+
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -338,10 +338,11 @@
   return FinalGV;
 }
 
-static bool checkAliasedGlobal(DiagnosticsEngine &Diags,
-                               SourceLocation Location, bool IsIFunc,
-                               const llvm::GlobalValue *Alias,
-                               const llvm::GlobalValue *&GV) {
+static bool checkAliasedGlobal(
+    DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc,
+    const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV,
+    const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames,
+    SourceRange AliasRange) {
   GV = getAliasedGlobal(Alias);
   if (!GV) {
     Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc;
@@ -350,6 +351,22 @@
 
   if (GV->isDeclaration()) {
     Diags.Report(Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc;
+    Diags.Report(Location, diag::note_alias_requires_mangled_name)
+        << IsIFunc << IsIFunc;
+    // Provide a note if the given function is not found and exists as a
+    // mangled name.
+    for (const auto &[Decl, Name] : MangledDeclNames) {
+      if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) {
+        if (ND->getName() == GV->getName()) {
+          Diags.Report(Location, diag::note_alias_mangled_name_alternative)
+              << Name
+              << FixItHint::CreateReplacement(
+                     AliasRange,
+                     (Twine(IsIFunc ? "ifunc" : "alias") + "(\"" + Name + "\")")
+                         .str());
+        }
+      }
+    }
     return false;
   }
 
@@ -381,16 +398,19 @@
   for (const GlobalDecl &GD : Aliases) {
     const auto *D = cast<ValueDecl>(GD.getDecl());
     SourceLocation Location;
+    SourceRange Range;
     bool IsIFunc = D->hasAttr<IFuncAttr>();
-    if (const Attr *A = D->getDefiningAttr())
+    if (const Attr *A = D->getDefiningAttr()) {
       Location = A->getLocation();
-    else
+      Range = A->getRange();
+    } else
       llvm_unreachable("Not an alias or ifunc?");
 
     StringRef MangledName = getMangledName(GD);
     llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
     const llvm::GlobalValue *GV = nullptr;
-    if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV)) {
+    if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV,
+                            MangledDeclNames, Range)) {
       Error = true;
       continue;
     }
Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -278,6 +278,10 @@
 def err_alias_to_undefined : Error<
   "%select{alias|ifunc}0 must point to a defined "
   "%select{variable or |}1function">;
+def note_alias_requires_mangled_name : Note<
+  "the %select{function or variable|function}0 specified in an %select{alias|ifunc}1 must refer to its mangled name">;
+def note_alias_mangled_name_alternative: Note<
+  "function by that name is mangled as \"%0\"">;
 def warn_alias_to_weak_alias : Warning<
   "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of "
   "%1 is overridden">,
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -148,6 +148,8 @@
 - Clang now warns by default for C++20 and later about deprecated capture of
   ``this`` with a capture default of ``=``. This warning can be disabled with
   ``-Wno-deprecated-this-capture``.
+- Diagnostic notes and fix-its are now generated for ``ifunc``/``alias`` attributes
+  which point to functions whose names are mangled.
 
 Bug Fixes in This Version
 -------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to