[PATCH] D106030: [Clang] add support for error+warning fn attrs

Eli Friedman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 14 20:12:07 PDT 2021


efriedma added a comment.

In D106030#2878897 <https://reviews.llvm.org/D106030#2878897>, @arsenm wrote:

> Adding something to the IR for the sole purpose of producing a diagnostic feels really weird. I'm not sure I see why the frontend can't see this attribute and directly warn

In C++, you can do trickery with template arguments to trigger compile errors, for example, the following:

  #include <type_traits>
  template<int T> struct dependent_false : std::false_type {};
  template<int x> inline void f() {
    if constexpr (x == 0) {
      /* do something */
    } else if constexpr (x == 1) {
      /* do something else */
    } else {
      static_assert(dependent_false<x>() && "Invalid argument");
    }
  }
  void g() { f<1>(); }

Now suppose you're an enterprising Linux kernel developer, and you decide you want this in C.  You don't really care about portability to compilers other than gcc, or compiling at any optimization level less than -O2, so instead of using a real language feature, you decide to depend on a combination of unintentional compiler semantics and linker diagnostics.  So you write something like the following:

  #define BUILD_BUG() undefined_symbol()
  extern void undefined_symbol();
  
  inline void f(int x) {
    if (x == 0) {
      /* do something */
    } else if (x == 1) {
      /* do something else */
    } else {
      BUILD_BUG();
    }
  }
  void g() { f(1); }

Then, after you're doing this for a while, you ask the gcc developers for a simple feature: an attribute you can apply to undefined_symbol that makes the compiler print the error message at compile-time instead of link-time.

-------

Actually, in clang, you could probably use inline asm like the following to accomplish roughly the same thing, assuming you aren't building with -fno-integrated-as:

  #define BUILD_BUG() asm(".err \"BUILD_BUG\"")
  static inline void f(int x) {
    if (x == 0) {
      /* do something */
    } else if (x == 1) {
      /* do something else */
    } else {
      BUILD_BUG();
    }
  }
  void g() { f(2); }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D106030



More information about the cfe-commits mailing list