]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
C/C++: Better notification if misused a function like macro [PR102846]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Wed, 15 Oct 2025 00:50:13 +0000 (17:50 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Wed, 28 Jan 2026 18:20:38 +0000 (10:20 -0800)
Currently if assert is misused, e.g. like passing to a function like a
function pointer, GCC suggests to include assert.h/cassert. But since
it is already included that is just a bogus suggestion. Instead we should
see if a function-like macro is that same name (in the case of assert it will be),
and inform the user that it is being mis-used.

PR c++/102846
PR c/102846

gcc/c-family/ChangeLog:

* known-headers.cc (macro_like_function_used::macro_like_function_used): New.
(macro_like_function_used::~macro_like_function_used): New.
* known-headers.h (class macro_like_function_used): New class.

gcc/c/ChangeLog:

* c-decl.cc (lookup_name_fuzzy): Lookup function-like macro and
notify of misuse there.

gcc/cp/ChangeLog:

* name-lookup.cc (lookup_name_fuzzy): Lookup function-like macro and
notify of misuse there.

gcc/testsuite/ChangeLog:

* c-c++-common/function-like-macro-1.c: New test.
* c-c++-common/function-like-macro-2.c: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/c-family/known-headers.cc
gcc/c-family/known-headers.h
gcc/c/c-decl.cc
gcc/cp/name-lookup.cc
gcc/testsuite/c-c++-common/function-like-macro-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/function-like-macro-2.c [new file with mode: 0644]

index 4af8f6637cb65dcf9a6aa4b301841825620d1000..36f3f88601fb8786b6364f5c4eebd65945bb7d64 100644 (file)
@@ -352,3 +352,23 @@ suggest_missing_option::~suggest_missing_option ()
          " this is probably fixable by adding %qs to the command-line options",
          m_name_str, option_name, option_name);
 }
+
+/* macro_like_function_used's ctor.  */
+
+macro_like_function_used::macro_like_function_used (location_t loc, const char *name)
+: deferred_diagnostic (loc), m_name_str (name)
+{
+  gcc_assert (name);
+}
+
+/* macro_like_function_used's dtor.  */
+
+macro_like_function_used::~macro_like_function_used ()
+{
+  if (is_suppressed_p ())
+    return;
+
+  inform (get_location (),
+         "%qs is a function-like macro and might be used incorrectly",
+         m_name_str);
+}
index 1dc4d1da6663ff28802bb8af1251f9777e595576..72fe3d745226d814f2cebd8953f9143802dc176d 100644 (file)
@@ -56,4 +56,17 @@ class suggest_missing_option : public deferred_diagnostic
   diagnostics::option_id m_option_id;
 };
 
+/* Subclass of deferred_diagnostic for suggesting to the user
+   that they have misused a function like macro.  */
+class macro_like_function_used : public deferred_diagnostic
+{
+ public:
+  macro_like_function_used (location_t loc, const char *name);
+
+  ~macro_like_function_used ();
+
+ private:
+  const char *m_name_str;
+};
+
 #endif /* GCC_KNOWN_HEADERS_H */
index 7e94430435c2ea0c7171158a6b001c382e00c20c..7dddc23b5e1785d9ea27f732626c25b9581f3108 100644 (file)
@@ -4671,7 +4671,17 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc)
 {
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
-  /* First, try some well-known names in the C standard library, in case
+  /* Look up function-like macros first; maybe misusing them. */
+  auto cpp_node = cpp_lookup (parse_in,
+                             (const unsigned char*)IDENTIFIER_POINTER (name),
+                             IDENTIFIER_LENGTH (name));
+  if (cpp_node && cpp_fun_like_macro_p (cpp_node))
+    return name_hint
+      (nullptr,
+       std::make_unique<macro_like_function_used> (loc,
+                                                  IDENTIFIER_POINTER (name)));
+
+  /* Next, try some well-known names in the C standard library, in case
      the user forgot a #include.  */
   const char *header_hint
     = get_c_stdlib_header_for_name (IDENTIFIER_POINTER (name));
index 823e28bef76f5627915c25593981241458c0e5c7..460c9d30201fc66ed282ba35b49c7acf48375b5e 100644 (file)
@@ -7931,7 +7931,17 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc)
 {
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
-  /* First, try some well-known names in the C++ standard library, in case
+  /* Look up function-like macros first; maybe misusing them. */
+  auto cpp_node = cpp_lookup (parse_in,
+                             (const unsigned char*)IDENTIFIER_POINTER (name),
+                             IDENTIFIER_LENGTH (name));
+  if (cpp_node && cpp_fun_like_macro_p (cpp_node))
+    return name_hint
+      (nullptr,
+       std::make_unique<macro_like_function_used> (loc,
+                                                  IDENTIFIER_POINTER (name)));
+
+  /* Then, try some well-known names in the C++ standard library, in case
      the user forgot a #include.  */
   const char *header_hint
     = get_cp_stdlib_header_for_name (IDENTIFIER_POINTER (name));
diff --git a/gcc/testsuite/c-c++-common/function-like-macro-1.c b/gcc/testsuite/c-c++-common/function-like-macro-1.c
new file mode 100644 (file)
index 0000000..8f10888
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* PR c/102846 */
+
+#define f(a) ((void)0)
+
+void g(int a)
+{
+  (f)(a); /* { dg-error "was not declared|undeclared" "undeclared" } */
+  /* { dg-message "is a function-like macro and might be used incorrectly" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/function-like-macro-2.c b/gcc/testsuite/c-c++-common/function-like-macro-2.c
new file mode 100644 (file)
index 0000000..340e839
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* PR c/102846 */
+
+#include <assert.h>
+
+void g(int a)
+{
+  (assert)(a); /* { dg-error "was not declared|undeclared" "undeclared" } */
+  /* { dg-message "is a function-like macro and might be used incorrectly" "macro" { target *-*-* } .-1 } */
+  /* { dg-bogus "is defined in header" "header" { target *-*-* } .-2  }*/
+}