[PATCH] C/C++: Better notification if misused a function like macro [PR102846]

Jason Merrill jason@redhat.com
Wed Jan 28 10:58:48 GMT 2026


On 10/15/25 8:50 AM, Andrew Pinski wrote:
> 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                 | 20 +++++++++++++++++++
>   gcc/c-family/known-headers.h                  | 13 ++++++++++++
>   gcc/c/c-decl.cc                               | 12 ++++++++++-
>   gcc/cp/name-lookup.cc                         | 12 ++++++++++-
>   .../c-c++-common/function-like-macro-1.c      | 10 ++++++++++
>   .../c-c++-common/function-like-macro-2.c      | 11 ++++++++++
>   6 files changed, 76 insertions(+), 2 deletions(-)
>   create mode 100644 gcc/testsuite/c-c++-common/function-like-macro-1.c
>   create mode 100644 gcc/testsuite/c-c++-common/function-like-macro-2.c
> 
> diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
> index e3c01130639..65e92d226cd 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 3ffe5f364ce..1f2feacb975 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 miss-used a function like macro.  */

"misused"

OK with that fixed.

> +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 4a940d5eec3..73535cbafab 100644
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -4637,7 +4637,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 b7530616ef0..41c1548ca33 100644
> --- a/gcc/cp/name-lookup.cc
> +++ b/gcc/cp/name-lookup.cc
> @@ -7858,7 +7858,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 00000000000..8f108887985
> --- /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 00000000000..340e83932a0
> --- /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-patches mailing list