if (!strcmp (name, "siglongjmp"))
return true;
- if (m_built_in && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
+ if (m_built_in
+ && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
&& m_built_in == DECL_FUNCTION_CODE (fndecl))
{
- /* The call is being made from the definition of a built-in
- (e.g., in a replacement of one) to itself. */
- m_calls->safe_push (stmt);
- return false;
+ const char *cname
+ = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+ /* Don't warn about gnu_inline extern inline function
+ like strcpy calling __builtin_strcpy, that is fine,
+ if some call is made (the builtin isn't expanded inline),
+ a call is made to the external definition. */
+ if (!(DECL_DECLARED_INLINE_P (current_function_decl)
+ && DECL_EXTERNAL (current_function_decl))
+ || strcmp (name, cname) == 0)
+ {
+ /* The call is being made from the definition of a built-in
+ (e.g., in a replacement of one) to itself. */
+ m_calls->safe_push (stmt);
+ return false;
+ }
}
}
--- /dev/null
+/* PR c/104633 */
+/* { dg-do compile } */
+/* { dg-options "-Winfinite-recursion" } */
+
+typedef __SIZE_TYPE__ size_t;
+int memcmp (const void *, const void *, size_t);
+
+extern inline __attribute__((always_inline, gnu_inline)) int
+memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */
+{
+ return __builtin_memcmp (p, q, size); /* { dg-bogus "recursive call" } */
+}
+
+int
+foo (const void *p, const void *q, size_t size)
+{
+ return memcmp (p, q, size);
+}
--- /dev/null
+/* PR c/104633 */
+/* { dg-do compile } */
+/* { dg-options "-Winfinite-recursion" } */
+
+typedef __SIZE_TYPE__ size_t;
+int memcmp (const void *, const void *, size_t);
+__typeof (memcmp) __memcmp_alias __asm ("memcmp");
+
+extern inline __attribute__((always_inline, gnu_inline)) int
+memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */
+{
+ return __memcmp_alias (p, q, size); /* { dg-bogus "recursive call" } */
+}
+
+int
+foo (const void *p, const void *q, size_t size)
+{
+ return memcmp (p, q, size);
+}
--- /dev/null
+/* PR c/104633 */
+/* { dg-do compile } */
+/* { dg-options "-Winfinite-recursion" } */
+
+typedef __SIZE_TYPE__ size_t;
+int memcmp (const void *, const void *, size_t);
+
+extern inline __attribute__((always_inline, gnu_inline)) int
+memcmp (const void *p, const void *q, size_t size) /* { dg-warning "infinite recursion detected" } */
+{ /* { dg-error "inlining failed in call to" "" { target *-*-* } .-1 } */
+ return memcmp (p, q, size); /* { dg-message "recursive call" } */
+} /* { dg-message "called from here" "" { target *-*-* } .-1 } */
+
+int
+foo (const void *p, const void *q, size_t size)
+{
+ return memcmp (p, q, size);
+}