+2019-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/89703
+ * tree-ssa-strlen.c (valid_builtin_call): Punt if stmt call types
+ aren't compatible also with builtin_decl_explicit. Check pure
+ or non-pure status of BUILT_IN_STR{{,N}CMP,N{LEN,{CAT,CPY}{,_CHK}}}
+ and BUILT_IN_STPNCPY{,_CHK}.
+
2019-03-14 H.J. Lu <hongjiu.lu@intel.com>
PR target/89523
+2019-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/89703
+ * gcc.c-torture/compile/pr89703-1.c: New test.
+ * gcc.c-torture/compile/pr89703-2.c: New test.
+
2019-03-14 H.J. Lu <hongjiu.lu@intel.com>
PR target/89523
--- /dev/null
+/* PR tree-optimization/89703 */
+
+typedef __SIZE_TYPE__ size_t;
+extern char *strlen (const char *);
+extern char *strnlen (const char *, size_t);
+extern char c[2];
+
+void
+foo (char **q)
+{
+ q[0] = strlen (c);
+ q[1] = strnlen (c, 2);
+}
--- /dev/null
+/* PR tree-optimization/89703 */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *memcpy (void *, const void *, size_t);
+extern char *strlen (const char *);
+extern char c[2];
+
+void
+foo (char **q)
+{
+ memcpy (c, "a", 2);
+ q[0] = strlen (c);
+}
return false;
tree callee = gimple_call_fndecl (stmt);
+ tree decl = builtin_decl_explicit (DECL_FUNCTION_CODE (callee));
+ if (decl
+ && decl != callee
+ && !gimple_builtin_call_types_compatible_p (stmt, decl))
+ return false;
+
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_MEMCMP:
case BUILT_IN_MEMCMP_EQ:
+ case BUILT_IN_STRCMP:
+ case BUILT_IN_STRNCMP:
case BUILT_IN_STRCHR:
case BUILT_IN_STRLEN:
+ case BUILT_IN_STRNLEN:
/* The above functions should be pure. Punt if they aren't. */
if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE)
return false;
case BUILT_IN_MEMSET:
case BUILT_IN_STPCPY:
case BUILT_IN_STPCPY_CHK:
+ case BUILT_IN_STPNCPY:
+ case BUILT_IN_STPNCPY_CHK:
case BUILT_IN_STRCAT:
case BUILT_IN_STRCAT_CHK:
case BUILT_IN_STRCPY:
case BUILT_IN_STRCPY_CHK:
+ case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCAT_CHK:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
/* The above functions should be neither const nor pure. Punt if they
aren't. */
if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)