[gcc r16-7121] C/C++: Better notification if misused a function like macro [PR102846]
Andrew Pinski
pinskia@gcc.gnu.org
Wed Jan 28 18:33:45 GMT 2026
https://gcc.gnu.org/g:00956e55dd2fbbee751e953ca2f6b8a87151f85b
commit r16-7121-g00956e55dd2fbbee751e953ca2f6b8a87151f85b
Author: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Date: Tue Oct 14 17:50:13 2025 -0700
C/C++: Better notification if misused a function like macro [PR102846]
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>
Diff:
---
gcc/c-family/known-headers.cc | 20 ++++++++++++++++++++
gcc/c-family/known-headers.h | 13 +++++++++++++
gcc/c/c-decl.cc | 12 +++++++++++-
gcc/cp/name-lookup.cc | 12 +++++++++++-
gcc/testsuite/c-c++-common/function-like-macro-1.c | 10 ++++++++++
gcc/testsuite/c-c++-common/function-like-macro-2.c | 11 +++++++++++
6 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index 4af8f6637cb6..36f3f88601fb 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -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);
+}
diff --git a/gcc/c-family/known-headers.h b/gcc/c-family/known-headers.h
index 1dc4d1da6663..72fe3d745226 100644
--- a/gcc/c-family/known-headers.h
+++ b/gcc/c-family/known-headers.h
@@ -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 */
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 7e94430435c2..7dddc23b5e17 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -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));
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 823e28bef76f..460c9d30201f 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -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
index 000000000000..8f108887985f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/function-like-macro-1.c
@@ -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
index 000000000000..340e83932a09
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/function-like-macro-2.c
@@ -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 }*/
+}
More information about the Gcc-cvs
mailing list